aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
diff options
context:
space:
mode:
authorChenj168 <62330325+Chenj168@users.noreply.github.com>2020-03-29 16:52:56 +0800
committerGitHub <noreply@github.com>2020-03-29 19:52:56 +1100
commit7ad8b3ef7556bd5cfc552cad90017ab2247ffa8c (patch)
treefc9cc08cdfc73e17f545416244ceb1f5641d8b32 /Ryujinx.Graphics.Shader/Decoders/Decoder.cs
parent2816b2bf175ccf3d27eabca9c59772fb4800e101 (diff)
Move the OpActivator to OpCodeTable class for improve performance (#1001)
* Move the OpActivator to OpCodeTable class, for reduce the use of ConcurrentDictionary * Modify code style.
Diffstat (limited to 'Ryujinx.Graphics.Shader/Decoders/Decoder.cs')
-rw-r--r--Ryujinx.Graphics.Shader/Decoders/Decoder.cs49
1 files changed, 7 insertions, 42 deletions
diff --git a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
index cda88302..3e322e45 100644
--- a/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/Decoder.cs
@@ -1,10 +1,8 @@
using Ryujinx.Graphics.Shader.Instructions;
using System;
using System.Buffers.Binary;
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection.Emit;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
@@ -12,15 +10,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
{
static class Decoder
{
- private delegate object OpActivator(InstEmitter emitter, ulong address, long opCode);
-
- private static ConcurrentDictionary<Type, OpActivator> _opActivators;
-
- static Decoder()
- {
- _opActivators = new ConcurrentDictionary<Type, OpActivator>();
- }
-
public static Block[] Decode(ReadOnlySpan<byte> code, ulong headerSize)
{
List<Block> blocks = new List<Block>();
@@ -245,7 +234,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
long opCode = word0 | (long)word1 << 32;
- (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode);
+ (InstEmitter emitter, OpCodeTable.OpActivator opActivator) = OpCodeTable.GetEmitter(opCode);
if (emitter == null)
{
@@ -256,7 +245,12 @@ namespace Ryujinx.Graphics.Shader.Decoders
continue;
}
- OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode);
+ if (opActivator == null)
+ {
+ throw new ArgumentNullException(nameof(opActivator));
+ }
+
+ OpCode op = (OpCode)opActivator(emitter, opAddress, opCode);
block.OpCodes.Add(op);
}
@@ -295,35 +289,6 @@ namespace Ryujinx.Graphics.Shader.Decoders
return opCode is OpCodeExit;
}
- private static OpCode MakeOpCode(Type type, InstEmitter emitter, ulong address, long opCode)
- {
- if (type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- OpActivator createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
-
- return (OpCode)createInstance(emitter, address, opCode);
- }
-
- private static OpActivator CacheOpActivator(Type type)
- {
- Type[] argTypes = new Type[] { typeof(InstEmitter), typeof(ulong), typeof(long) };
-
- DynamicMethod mthd = new DynamicMethod($"Make{type.Name}", type, argTypes);
-
- ILGenerator generator = mthd.GetILGenerator();
-
- generator.Emit(OpCodes.Ldarg_0);
- generator.Emit(OpCodes.Ldarg_1);
- generator.Emit(OpCodes.Ldarg_2);
- generator.Emit(OpCodes.Newobj, type.GetConstructor(argTypes));
- generator.Emit(OpCodes.Ret);
-
- return (OpActivator)mthd.CreateDelegate(typeof(OpActivator));
- }
-
private struct PathBlockState
{
public Block Block { get; }