aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChenj168 <62330325+Chenj168@users.noreply.github.com>2020-03-20 13:15:37 +0900
committerGitHub <noreply@github.com>2020-03-20 15:15:37 +1100
commit31b94f4641894060349a55d56b22f47829c9bef6 (patch)
treee19909d51c5f39784f7aa1a53d1191888a34e616
parent8e649841582242a2f4826e9429fd926316e6f2cb (diff)
Move the MakeOp to OpCodeTable class, for reduce the use of ConcurrentDictionary (#996)
-rw-r--r--ARMeilleure/Decoders/Decoder.cs47
-rw-r--r--ARMeilleure/Decoders/OpCodeTable.cs35
2 files changed, 35 insertions, 47 deletions
diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs
index 9675dc8d..dd99f78f 100644
--- a/ARMeilleure/Decoders/Decoder.cs
+++ b/ARMeilleure/Decoders/Decoder.cs
@@ -3,9 +3,7 @@ using ARMeilleure.Instructions;
using ARMeilleure.Memory;
using ARMeilleure.State;
using System;
-using System.Collections.Concurrent;
using System.Collections.Generic;
-using System.Reflection.Emit;
namespace ARMeilleure.Decoders
{
@@ -19,15 +17,6 @@ namespace ARMeilleure.Decoders
// For lower code quality translation, we set a lower limit since we're blocking execution.
private const int MaxInstsPerFunctionLowCq = 500;
- private delegate object MakeOp(InstDescriptor inst, ulong address, int opCode);
-
- private static ConcurrentDictionary<Type, MakeOp> _opActivators;
-
- static Decoder()
- {
- _opActivators = new ConcurrentDictionary<Type, MakeOp>();
- }
-
public static Block[] DecodeBasicBlock(MemoryManager memory, ulong address, ExecutionMode mode)
{
Block block = new Block(address);
@@ -319,56 +308,32 @@ namespace ARMeilleure.Decoders
InstDescriptor inst;
- Type type;
+ OpCodeTable.MakeOp makeOp;
if (mode == ExecutionMode.Aarch64)
{
- (inst, type) = OpCodeTable.GetInstA64(opCode);
+ (inst, makeOp) = OpCodeTable.GetInstA64(opCode);
}
else
{
if (mode == ExecutionMode.Aarch32Arm)
{
- (inst, type) = OpCodeTable.GetInstA32(opCode);
+ (inst, makeOp) = OpCodeTable.GetInstA32(opCode);
}
else /* if (mode == ExecutionMode.Aarch32Thumb) */
{
- (inst, type) = OpCodeTable.GetInstT32(opCode);
+ (inst, makeOp) = OpCodeTable.GetInstT32(opCode);
}
}
- if (type != null)
+ if (makeOp != null)
{
- return MakeOpCode(inst, type, address, opCode);
+ return (OpCode)makeOp(inst, address, opCode);
}
else
{
return new OpCode(inst, address, opCode);
}
}
-
- private static OpCode MakeOpCode(InstDescriptor inst, Type type, ulong address, int opCode)
- {
- MakeOp createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
-
- return (OpCode)createInstance(inst, address, opCode);
- }
-
- private static MakeOp CacheOpActivator(Type type)
- {
- Type[] argTypes = new Type[] { typeof(InstDescriptor), typeof(ulong), typeof(int) };
-
- 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 (MakeOp)mthd.CreateDelegate(typeof(MakeOp));
- }
}
} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs
index f255b528..93234b3f 100644
--- a/ARMeilleure/Decoders/OpCodeTable.cs
+++ b/ARMeilleure/Decoders/OpCodeTable.cs
@@ -2,11 +2,14 @@ using ARMeilleure.Instructions;
using ARMeilleure.State;
using System;
using System.Collections.Generic;
+using System.Reflection.Emit;
namespace ARMeilleure.Decoders
{
static class OpCodeTable
{
+ public delegate object MakeOp(InstDescriptor inst, ulong address, int opCode);
+
private const int FastLookupSize = 0x1000;
private struct InstInfo
@@ -18,12 +21,32 @@ namespace ARMeilleure.Decoders
public Type Type { get; }
+ public MakeOp MakeOp { get; }
+
public InstInfo(int mask, int value, InstDescriptor inst, Type type)
{
Mask = mask;
Value = value;
Inst = inst;
Type = type;
+ MakeOp = CacheOpActivator(type);
+ }
+
+ private static MakeOp CacheOpActivator(Type type)
+ {
+ Type[] argTypes = new Type[] { typeof(InstDescriptor), typeof(ulong), typeof(int) };
+
+ 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 (MakeOp)mthd.CreateDelegate(typeof(MakeOp));
}
}
@@ -1034,32 +1057,32 @@ namespace ARMeilleure.Decoders
}
}
- public static (InstDescriptor inst, Type type) GetInstA32(int opCode)
+ public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode)
{
return GetInstFromList(_instA32FastLookup[ToFastLookupIndex(opCode)], opCode);
}
- public static (InstDescriptor inst, Type type) GetInstT32(int opCode)
+ public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode)
{
return GetInstFromList(_instT32FastLookup[ToFastLookupIndex(opCode)], opCode);
}
- public static (InstDescriptor inst, Type type) GetInstA64(int opCode)
+ public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode)
{
return GetInstFromList(_instA64FastLookup[ToFastLookupIndex(opCode)], opCode);
}
- private static (InstDescriptor inst, Type type) GetInstFromList(InstInfo[] insts, int opCode)
+ private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode)
{
foreach (InstInfo info in insts)
{
if ((opCode & info.Mask) == info.Value)
{
- return (info.Inst, info.Type);
+ return (info.Inst, info.MakeOp);
}
}
- return (new InstDescriptor(InstName.Und, InstEmit.Und), typeof(OpCode));
+ return (new InstDescriptor(InstName.Und, InstEmit.Und), null);
}
private static int ToFastLookupIndex(int value)