Disable partial JIT invalidation on unmap (#1991)

This commit is contained in:
gdkchan 2021-02-07 20:25:14 -03:00 committed by GitHub
parent 7016d95eb1
commit ee28ccebf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 29 deletions

View file

@ -33,5 +33,10 @@ namespace ARMeilleure.Translation
{ {
return !HighCq && Interlocked.Increment(ref _callCount) == MinCallsForRejit; return !HighCq && Interlocked.Increment(ref _callCount) == MinCallsForRejit;
} }
public void ResetCallCount()
{
Interlocked.Exchange(ref _callCount, 0);
}
} }
} }

View file

@ -390,33 +390,10 @@ namespace ARMeilleure.Translation
public void InvalidateJitCacheRegion(ulong address, ulong size) public void InvalidateJitCacheRegion(ulong address, ulong size)
{ {
static bool OverlapsWith(ulong funcAddress, ulong funcSize, ulong address, ulong size) // If rejit is running, stop it as it may be trying to rejit a function on the invalidated region.
{ ClearRejitQueue(allowRequeue: true);
return funcAddress < address + size && address < funcAddress + funcSize;
}
// Make a copy of all overlapping functions, as we can't otherwise // TODO: Completely remove functions overlapping the specified range from the cache.
// remove elements from the collection we are iterating.
// Doing that before clearing the rejit queue is fine, even
// if a function is translated after this, it would only replace
// a existing function, as rejit is only triggered on functions
// that were already executed before.
var toDelete = _funcs.Where(x => OverlapsWith(x.Key, x.Value.GuestSize, address, size)).ToArray();
if (toDelete.Length != 0)
{
// If rejit is running, stop it as it may be trying to rejit the functions we are
// supposed to remove.
ClearRejitQueue();
}
foreach (var kv in toDelete)
{
if (_funcs.TryRemove(kv.Key, out TranslatedFunction func))
{
EnqueueForDeletion(kv.Key, func);
}
}
} }
private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func) private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func)
@ -427,7 +404,7 @@ namespace ARMeilleure.Translation
private void ClearJitCache() private void ClearJitCache()
{ {
// Ensure no attempt will be made to compile new functions due to rejit. // Ensure no attempt will be made to compile new functions due to rejit.
ClearRejitQueue(); ClearRejitQueue(allowRequeue: false);
foreach (var kv in _funcs) foreach (var kv in _funcs)
{ {
@ -442,10 +419,25 @@ namespace ARMeilleure.Translation
} }
} }
private void ClearRejitQueue() private void ClearRejitQueue(bool allowRequeue)
{ {
_backgroundTranslatorLock.AcquireWriterLock(Timeout.Infinite); _backgroundTranslatorLock.AcquireWriterLock(Timeout.Infinite);
_backgroundStack.Clear();
if (allowRequeue)
{
while (_backgroundStack.TryPop(out var request))
{
if (_funcs.TryGetValue(request.Address, out var func))
{
func.ResetCallCount();
}
}
}
else
{
_backgroundStack.Clear();
}
_backgroundTranslatorLock.ReleaseWriterLock(); _backgroundTranslatorLock.ReleaseWriterLock();
} }
} }