From a694420d11ef74e4f0bf473be2b6f64635bc89c7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 4 Feb 2019 18:26:05 -0300 Subject: Implement speculative translation on the CPU (#515) * Implement speculative translation on the cpu, and change the way how branches to unknown or untranslated addresses works * Port t0opt changes and other cleanups * Change namespace from translation related classes to ChocolArm64.Translation, other minor tweaks * Fix typo * Translate higher quality code for indirect jumps aswell, and on some cases that were missed when lower quality (tier 0) code was available * Remove debug print * Remove direct argument passing optimization, and enable tail calls for BR instructions * Call delegates directly with Callvirt rather than calling Execute, do not emit calls for tier 0 code * Remove unused property * Rename argument on ArmSubroutine delegate --- ChocolArm64/Translation/TranslatorQueue.cs | 83 ++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 ChocolArm64/Translation/TranslatorQueue.cs (limited to 'ChocolArm64/Translation/TranslatorQueue.cs') diff --git a/ChocolArm64/Translation/TranslatorQueue.cs b/ChocolArm64/Translation/TranslatorQueue.cs new file mode 100644 index 00000000..89d665bf --- /dev/null +++ b/ChocolArm64/Translation/TranslatorQueue.cs @@ -0,0 +1,83 @@ +using System.Collections.Concurrent; +using System.Threading; + +namespace ChocolArm64.Translation +{ + class TranslatorQueue + { + //This is the maximum number of functions to be translated that the queue can hold. + //The value may need some tuning to find the sweet spot. + private const int MaxQueueSize = 1024; + + private ConcurrentStack[] _translationQueue; + + private ManualResetEvent _queueDataReceivedEvent; + + private bool _signaled; + + public TranslatorQueue() + { + _translationQueue = new ConcurrentStack[(int)TranslationTier.Count]; + + for (int prio = 0; prio < _translationQueue.Length; prio++) + { + _translationQueue[prio] = new ConcurrentStack(); + } + + _queueDataReceivedEvent = new ManualResetEvent(false); + } + + public void Enqueue(TranslatorQueueItem item) + { + ConcurrentStack queue = _translationQueue[(int)item.Tier]; + + if (queue.Count >= MaxQueueSize) + { + queue.TryPop(out _); + } + + queue.Push(item); + + _queueDataReceivedEvent.Set(); + } + + public bool TryDequeue(out TranslatorQueueItem item) + { + for (int prio = 0; prio < _translationQueue.Length; prio++) + { + if (_translationQueue[prio].TryPop(out item)) + { + return true; + } + } + + item = default(TranslatorQueueItem); + + return false; + } + + public void WaitForItems() + { + _queueDataReceivedEvent.WaitOne(); + + lock (_queueDataReceivedEvent) + { + if (!_signaled) + { + _queueDataReceivedEvent.Reset(); + } + } + } + + public void ForceSignal() + { + lock (_queueDataReceivedEvent) + { + _signaled = true; + + _queueDataReceivedEvent.Set(); + _queueDataReceivedEvent.Close(); + } + } + } +} \ No newline at end of file -- cgit v1.2.3