diff options
author | Chenj168 <62330325+Chenj168@users.noreply.github.com> | 2020-03-29 16:52:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-29 19:52:56 +1100 |
commit | 7ad8b3ef7556bd5cfc552cad90017ab2247ffa8c (patch) | |
tree | fc9cc08cdfc73e17f545416244ceb1f5641d8b32 /Ryujinx.Graphics.Shader/Decoders/Decoder.cs | |
parent | 2816b2bf175ccf3d27eabca9c59772fb4800e101 (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.cs | 49 |
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; } |