diff options
author | gdkchan <gab.dark.100@gmail.com> | 2022-02-17 22:53:18 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-18 02:53:18 +0100 |
commit | 92d166ecb7e5b29a27bffd77754d8e592435ee6b (patch) | |
tree | 0c3d078c1487d6d596ed45deacca29c7d2d7d300 /ARMeilleure/Translation/Translator.cs | |
parent | 72e543e946610dc80e3d52290e4bea837097a070 (diff) |
Enable CPU JIT cache invalidation (#2965)1.1.44
* Enable CPU JIT cache invalidation
* Invalidate cache on IC IVAU
Diffstat (limited to 'ARMeilleure/Translation/Translator.cs')
-rw-r--r-- | ARMeilleure/Translation/Translator.cs | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 4962a846..611716e2 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -49,7 +49,7 @@ namespace ARMeilleure.Translation private readonly AutoResetEvent _backgroundTranslatorEvent; private readonly ReaderWriterLock _backgroundTranslatorLock; - internal ConcurrentDictionary<ulong, TranslatedFunction> Functions { get; } + internal TranslatorCache<TranslatedFunction> Functions { get; } internal AddressTable<ulong> FunctionTable { get; } internal EntryTable<uint> CountTable { get; } internal TranslatorStubs Stubs { get; } @@ -75,7 +75,7 @@ namespace ARMeilleure.Translation JitCache.Initialize(allocator); CountTable = new EntryTable<uint>(); - Functions = new ConcurrentDictionary<ulong, TranslatedFunction>(); + Functions = new TranslatorCache<TranslatedFunction>(); FunctionTable = new AddressTable<ulong>(for64Bits ? Levels64Bit : Levels32Bit); Stubs = new TranslatorStubs(this); @@ -93,12 +93,12 @@ namespace ARMeilleure.Translation { _backgroundTranslatorLock.AcquireReaderLock(Timeout.Infinite); - if (_backgroundStack.TryPop(out RejitRequest request) && + if (_backgroundStack.TryPop(out RejitRequest request) && _backgroundSet.TryRemove(request.Address, out _)) { TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true); - Functions.AddOrUpdate(request.Address, func, (key, oldFunc) => + Functions.AddOrUpdate(request.Address, func.GuestSize, func, (key, oldFunc) => { EnqueueForDeletion(key, oldFunc); return func; @@ -196,7 +196,7 @@ namespace ARMeilleure.Translation } } - public ulong ExecuteSingle(State.ExecutionContext context, ulong address) + private ulong ExecuteSingle(State.ExecutionContext context, ulong address) { TranslatedFunction func = GetOrTranslate(address, context.ExecutionMode); @@ -215,7 +215,7 @@ namespace ARMeilleure.Translation { func = Translate(address, mode, highCq: false); - TranslatedFunction oldFunc = Functions.GetOrAdd(address, func); + TranslatedFunction oldFunc = Functions.GetOrAdd(address, func.GuestSize, func); if (oldFunc != func) { @@ -471,7 +471,24 @@ namespace ARMeilleure.Translation // If rejit is running, stop it as it may be trying to rejit a function on the invalidated region. ClearRejitQueue(allowRequeue: true); - // TODO: Completely remove functions overlapping the specified range from the cache. + ulong[] overlapAddresses = Array.Empty<ulong>(); + + int overlapsCount = Functions.GetOverlaps(address, size, ref overlapAddresses); + + for (int index = 0; index < overlapsCount; index++) + { + ulong overlapAddress = overlapAddresses[index]; + + if (Functions.TryGetValue(overlapAddress, out TranslatedFunction overlap)) + { + Functions.Remove(overlapAddress); + Volatile.Write(ref FunctionTable.GetValue(overlapAddress), FunctionTable.Fill); + EnqueueForDeletion(overlapAddress, overlap); + } + } + + // TODO: Remove overlapping functions from the JitCache aswell. + // This should be done safely, with a mechanism to ensure the function is not being executed. } internal void EnqueueForRejit(ulong guestAddress, ExecutionMode mode) @@ -493,7 +510,9 @@ namespace ARMeilleure.Translation // Ensure no attempt will be made to compile new functions due to rejit. ClearRejitQueue(allowRequeue: false); - foreach (var func in Functions.Values) + List<TranslatedFunction> functions = Functions.AsList(); + + foreach (var func in functions) { JitCache.Unmap(func.FuncPtr); |