diff --git a/ARMeilleure/Common/Counter.cs b/ARMeilleure/Common/Counter.cs index d3d28730e..f8c5d2732 100644 --- a/ARMeilleure/Common/Counter.cs +++ b/ARMeilleure/Common/Counter.cs @@ -1,20 +1,23 @@ -namespace ARMeilleure.Common +using System; + +namespace ARMeilleure.Common { /// - /// Represents an 8-bit counter. + /// Represents a numeric counter. /// - class Counter + /// Type of the counter + class Counter where T : unmanaged { private readonly int _index; - private readonly EntryTable _countTable; + private readonly EntryTable _countTable; /// - /// Initializes a new instance of the class from the specified - /// instance and index. + /// Initializes a new instance of the class from the specified + /// instance and index. /// /// instance - /// Index in the - private Counter(EntryTable countTable, int index) + /// Index in the + private Counter(EntryTable countTable, int index) { _countTable = countTable; _index = index; @@ -23,7 +26,7 @@ /// /// Gets a reference to the value of the counter. /// - public ref byte Value => ref _countTable.GetValue(_index); + public ref T Value => ref _countTable.GetValue(_index); /// /// Tries to create a instance from the specified instance. @@ -31,11 +34,28 @@ /// from which to create the /// instance if success; otherwise /// if success; otherwise - public static bool TryCreate(EntryTable countTable, out Counter counter) + /// is + /// is unsupported + public static bool TryCreate(EntryTable countTable, out Counter counter) { + if (countTable == null) + { + throw new ArgumentNullException(nameof(countTable)); + } + + if (typeof(T) != typeof(byte) && typeof(T) != typeof(sbyte) && + typeof(T) != typeof(short) && typeof(T) != typeof(ushort) && + typeof(T) != typeof(int) && typeof(T) != typeof(uint) && + typeof(T) != typeof(long) && typeof(T) != typeof(ulong) && + typeof(T) != typeof(nint) && typeof(T) != typeof(nuint) && + typeof(T) != typeof(float) && typeof(T) != typeof(double)) + { + throw new ArgumentException("Counter does not support the specified type", nameof(countTable)); + } + if (countTable.TryAllocate(out int index)) { - counter = new Counter(countTable, index); + counter = new Counter(countTable, index); return true; } diff --git a/ARMeilleure/Translation/ArmEmitterContext.cs b/ARMeilleure/Translation/ArmEmitterContext.cs index ac24a45c9..ad44b0cfb 100644 --- a/ARMeilleure/Translation/ArmEmitterContext.cs +++ b/ARMeilleure/Translation/ArmEmitterContext.cs @@ -42,7 +42,7 @@ namespace ARMeilleure.Translation public IMemoryManager Memory { get; } public JumpTable JumpTable { get; } - public EntryTable CountTable { get; } + public EntryTable CountTable { get; } public ulong EntryAddress { get; } public bool HighCq { get; } @@ -51,7 +51,7 @@ namespace ARMeilleure.Translation public ArmEmitterContext( IMemoryManager memory, JumpTable jumpTable, - EntryTable countTable, + EntryTable countTable, ulong entryAddress, bool highCq, Aarch32Mode mode) diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index d643086e3..0142934eb 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -540,7 +540,8 @@ namespace ARMeilleure.Translation.PTC } } - internal static void LoadTranslations(ConcurrentDictionary funcs, IMemoryManager memory, JumpTable jumpTable, EntryTable countTable) + internal static void LoadTranslations(ConcurrentDictionary funcs, IMemoryManager memory, + JumpTable jumpTable, EntryTable countTable) { if (AreCarriersEmpty()) { @@ -569,7 +570,7 @@ namespace ARMeilleure.Translation.PTC { byte[] code = ReadCode(index, infoEntry.CodeLength); - Counter callCounter = null; + Counter callCounter = null; if (infoEntry.RelocEntriesCount != 0) { @@ -679,7 +680,8 @@ namespace ARMeilleure.Translation.PTC return relocEntries; } - private static bool PatchCode(Span code, RelocEntry[] relocEntries, IntPtr pageTablePointer, JumpTable jumpTable, EntryTable countTable, out Counter callCounter) + private static bool PatchCode(Span code, RelocEntry[] relocEntries, IntPtr pageTablePointer, + JumpTable jumpTable, EntryTable countTable, out Counter callCounter) { callCounter = null; @@ -702,7 +704,7 @@ namespace ARMeilleure.Translation.PTC else if (relocEntry.Index == CountTableIndex) { // If we could not allocate an entry on the count table we dip. - if (!Counter.TryCreate(countTable, out Counter counter)) + if (!Counter.TryCreate(countTable, out Counter counter)) { return false; } @@ -745,7 +747,8 @@ namespace ARMeilleure.Translation.PTC return new UnwindInfo(pushEntries, prologueSize); } - private static TranslatedFunction FastTranslate(byte[] code, Counter callCounter, ulong guestSize, UnwindInfo unwindInfo, bool highCq) + private static TranslatedFunction FastTranslate(byte[] code, Counter callCounter, ulong guestSize, + UnwindInfo unwindInfo, bool highCq) { CompiledFunction cFunc = new CompiledFunction(code, unwindInfo); @@ -794,7 +797,8 @@ namespace ARMeilleure.Translation.PTC } } - internal static void MakeAndSaveTranslations(ConcurrentDictionary funcs, IMemoryManager memory, JumpTable jumpTable, EntryTable countTable) + internal static void MakeAndSaveTranslations(ConcurrentDictionary funcs, IMemoryManager memory, + JumpTable jumpTable, EntryTable countTable) { var profiledFuncsToTranslate = PtcProfiler.GetProfiledFuncsToTranslate(funcs); diff --git a/ARMeilleure/Translation/TranslatedFunction.cs b/ARMeilleure/Translation/TranslatedFunction.cs index c8adbe4cb..04dd769c1 100644 --- a/ARMeilleure/Translation/TranslatedFunction.cs +++ b/ARMeilleure/Translation/TranslatedFunction.cs @@ -8,12 +8,12 @@ namespace ARMeilleure.Translation { private readonly GuestFunction _func; // Ensure that this delegate will not be garbage collected. - public Counter CallCounter { get; } + public Counter CallCounter { get; } public ulong GuestSize { get; } public bool HighCq { get; } public IntPtr FuncPtr { get; } - public TranslatedFunction(GuestFunction func, Counter callCounter, ulong guestSize, bool highCq) + public TranslatedFunction(GuestFunction func, Counter callCounter, ulong guestSize, bool highCq) { _func = func; CallCounter = callCounter; diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 50d363cd8..f3ab15be0 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -37,7 +37,7 @@ namespace ARMeilleure.Translation private JumpTable _jumpTable; internal JumpTable JumpTable => _jumpTable; - internal EntryTable CountTable { get; } + internal EntryTable CountTable { get; } private volatile int _threadCount; @@ -59,7 +59,7 @@ namespace ARMeilleure.Translation _backgroundTranslatorEvent = new AutoResetEvent(false); _backgroundTranslatorLock = new ReaderWriterLock(); - CountTable = new EntryTable(capacity: 16 * 1024 * 1024); + CountTable = new EntryTable(capacity: 4 * 1024 * 1024); JitCache.Initialize(allocator); @@ -239,7 +239,7 @@ namespace ARMeilleure.Translation internal static TranslatedFunction Translate( IMemoryManager memory, JumpTable jumpTable, - EntryTable countTable, + EntryTable countTable, ulong address, ExecutionMode mode, bool highCq) @@ -256,7 +256,7 @@ namespace ARMeilleure.Translation Logger.StartPass(PassName.Translation); - Counter counter = null; + Counter counter = null; if (!context.HighCq) { @@ -415,29 +415,23 @@ namespace ARMeilleure.Translation return context.GetControlFlowGraph(); } - internal static void EmitRejitCheck(ArmEmitterContext context, out Counter counter) + internal static void EmitRejitCheck(ArmEmitterContext context, out Counter counter) { - if (!Counter.TryCreate(context.CountTable, out counter)) + if (!Counter.TryCreate(context.CountTable, out counter)) { return; } - Operand lblRejit = Label(); - Operand lblAdd = Label(); Operand lblEnd = Label(); Operand address = Const(ref counter.Value, Ptc.CountTableIndex); - Operand count = context.Load8(address); - context.BranchIf(lblAdd, count, Const(100), Comparison.LessUI); - context.BranchIf(lblRejit, count, Const(100), Comparison.Equal); - context.Branch(lblEnd); + Operand curCount = context.Load(OperandType.I32, address); + Operand count = context.Add(curCount, Const(1)); + context.Store(address, count); + context.BranchIf(lblEnd, curCount, Const(100), Comparison.NotEqual, BasicBlockFrequency.Cold); - context.MarkLabel(lblRejit, BasicBlockFrequency.Cold); context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.EnqueueForRejit)), Const(context.EntryAddress)); - context.MarkLabel(lblAdd, BasicBlockFrequency.Cold); - context.Store8(address, context.Add(count, Const(1))); - context.MarkLabel(lblEnd); }