From 427b7d06b5ab6d2b06784a9d283eaf836a04c27e Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 20 Jan 2024 11:11:28 -0300 Subject: Implement a new JIT for Arm devices (#6057) * Implement a new JIT for Arm devices * Auto-format * Make a lot of Assembler members read-only * More read-only * Fix more warnings * ObjectDisposedException.ThrowIf * New JIT cache for platforms that enforce W^X, currently unused * Remove unused using * Fix assert * Pass memory manager type around * Safe memory manager mode support + other improvements * Actual safe memory manager mode masking support * PR feedback --- src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs | 96 +++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs (limited to 'src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs') diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs new file mode 100644 index 00000000..60e13de9 --- /dev/null +++ b/src/Ryujinx.Cpu/LightningJit/TranslatorCache.cs @@ -0,0 +1,96 @@ +using ARMeilleure.Translation; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx.Cpu.LightningJit +{ + internal class TranslatorCache + { + private readonly IntervalTree _tree; + private readonly ReaderWriterLockSlim _treeLock; + + public int Count => _tree.Count; + + public TranslatorCache() + { + _tree = new IntervalTree(); + _treeLock = new ReaderWriterLockSlim(); + } + + public bool TryAdd(ulong address, ulong size, T value) + { + return AddOrUpdate(address, size, value, null); + } + + public bool AddOrUpdate(ulong address, ulong size, T value, Func updateFactoryCallback) + { + _treeLock.EnterWriteLock(); + bool result = _tree.AddOrUpdate(address, address + size, value, updateFactoryCallback); + _treeLock.ExitWriteLock(); + + return result; + } + + public T GetOrAdd(ulong address, ulong size, T value) + { + _treeLock.EnterWriteLock(); + value = _tree.GetOrAdd(address, address + size, value); + _treeLock.ExitWriteLock(); + + return value; + } + + public bool Remove(ulong address) + { + _treeLock.EnterWriteLock(); + bool removed = _tree.Remove(address) != 0; + _treeLock.ExitWriteLock(); + + return removed; + } + + public void Clear() + { + _treeLock.EnterWriteLock(); + _tree.Clear(); + _treeLock.ExitWriteLock(); + } + + public bool ContainsKey(ulong address) + { + _treeLock.EnterReadLock(); + bool result = _tree.ContainsKey(address); + _treeLock.ExitReadLock(); + + return result; + } + + public bool TryGetValue(ulong address, out T value) + { + _treeLock.EnterReadLock(); + bool result = _tree.TryGet(address, out value); + _treeLock.ExitReadLock(); + + return result; + } + + public int GetOverlaps(ulong address, ulong size, ref ulong[] overlaps) + { + _treeLock.EnterReadLock(); + int count = _tree.Get(address, address + size, ref overlaps); + _treeLock.ExitReadLock(); + + return count; + } + + public List AsList() + { + _treeLock.EnterReadLock(); + List list = _tree.AsList(); + _treeLock.ExitReadLock(); + + return list; + } + } +} -- cgit v1.2.3