use dictionary for jit cache, cleanup old functions in single passes

This commit is contained in:
emmaus 2019-12-27 22:28:57 +00:00 committed by emmauss
commit 3b68e7b459
2 changed files with 22 additions and 24 deletions

View file

@ -19,7 +19,7 @@ namespace ARMeilleure.Translation
private static JitCacheMemoryAllocator _allocator; private static JitCacheMemoryAllocator _allocator;
private static List<JitCacheEntry> _cacheEntries; private static Dictionary<int, JitCacheEntry> _cacheEntries;
private static object _lock; private static object _lock;
@ -41,7 +41,7 @@ namespace ARMeilleure.Translation
_allocator = new JitCacheMemoryAllocator(CacheSize, startOffset); _allocator = new JitCacheMemoryAllocator(CacheSize, startOffset);
_cacheEntries = new List<JitCacheEntry>(); _cacheEntries = new Dictionary<int, JitCacheEntry>();
_lock = new object(); _lock = new object();
} }
@ -101,7 +101,7 @@ namespace ARMeilleure.Translation
{ {
if (TryFind((int)offset, out JitCacheEntry entry)) if (TryFind((int)offset, out JitCacheEntry entry))
{ {
_cacheEntries.Remove(entry); _cacheEntries.Remove((int)offset, out entry);
int size = checked(entry.Size + (CodeAlignment - 1)) & ~(CodeAlignment - 1); int size = checked(entry.Size + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
@ -112,25 +112,18 @@ namespace ARMeilleure.Translation
private static void Add(JitCacheEntry entry) private static void Add(JitCacheEntry entry)
{ {
_cacheEntries.Add(entry); _cacheEntries.Add(entry.Offset, entry);
} }
public static bool TryFind(int offset, out JitCacheEntry entry) public static bool TryFind(int offset, out JitCacheEntry entry)
{ {
lock (_lock) lock (_lock)
{ {
foreach (JitCacheEntry cacheEntry in _cacheEntries) if(_cacheEntries.TryGetValue(offset, out entry))
{ {
int endOffset = cacheEntry.Offset + cacheEntry.Size;
if (offset >= cacheEntry.Offset && offset < endOffset)
{
entry = cacheEntry;
return true; return true;
} }
} }
}
entry = default(JitCacheEntry); entry = default(JitCacheEntry);

View file

@ -57,19 +57,24 @@ namespace ARMeilleure.Translation
return func; return func;
}); });
} }
else if (_oldFunctions.TryDequeue(out TranslatedFunction function)) else
{
Queue<TranslatedFunction> skippedFunctions = new Queue<TranslatedFunction>();
while (_oldFunctions.TryDequeue(out TranslatedFunction function))
{ {
if (Interlocked.CompareExchange(ref function.EntryCount, -1, 0) != 0) if (Interlocked.CompareExchange(ref function.EntryCount, -1, 0) != 0)
{ {
_oldFunctions.Enqueue(function); skippedFunctions.Enqueue(function);
} }
else else
{ {
JitCache.Free(function.Pointer); JitCache.Free(function.Pointer);
} }
} }
else
{ _oldFunctions = skippedFunctions;
_backgroundTranslatorEvent.WaitOne(); _backgroundTranslatorEvent.WaitOne();
} }
} }