Пример #1
0
        public Translator(IJitMemoryAllocator allocator, IMemoryManager memory)
        {
            _memory = memory;

            _funcs = new ConcurrentDictionary <ulong, TranslatedFunction>();

            _backgroundStack = new ConcurrentStack <RejitRequest>();

            _backgroundTranslatorEvent = new AutoResetEvent(false);

            _jumpTable = new JumpTable(allocator);

            JitCache.Initialize(allocator);

            DirectCallStubs.InitializeStubs();

            if (Ptc.State == PtcState.Enabled)
            {
                Ptc.LoadTranslations(_funcs, memory.PageTablePointer, _jumpTable);
            }
        }
Пример #2
0
        public void Execute(State.ExecutionContext context, ulong address)
        {
            if (Interlocked.Increment(ref _threadCount) == 1)
            {
                IsReadyForTranslation.WaitOne();

                Debug.Assert(_jumpTable == null);
                _jumpTable = new JumpTable(_allocator);

                if (Ptc.State == PtcState.Enabled)
                {
                    Debug.Assert(_funcs.Count == 0);
                    Ptc.LoadTranslations(_funcs, _memory, _jumpTable);
                    Ptc.MakeAndSaveTranslations(_funcs, _memory, _jumpTable);
                }

                PtcProfiler.Start();

                Ptc.Disable();

                // Simple heuristic, should be user configurable in future. (1 for 4 core/ht or less, 2 for 6 core+ht etc).
                // All threads are normal priority except from the last, which just fills as much of the last core as the os lets it with a low priority.
                // If we only have one rejit thread, it should be normal priority as highCq code is performance critical.
                // TODO: Use physical cores rather than logical. This only really makes sense for processors with hyperthreading. Requires OS specific code.
                int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3);
                int threadCount          = Math.Min(4, unboundedThreadCount);

                for (int i = 0; i < threadCount; i++)
                {
                    bool last = i != 0 && i == unboundedThreadCount - 1;

                    Thread backgroundTranslatorThread = new Thread(TranslateStackedSubs)
                    {
                        Name     = "CPU.BackgroundTranslatorThread." + i,
                        Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal
                    };

                    backgroundTranslatorThread.Start();
                }
            }

            Statistics.InitializeTimer();

            NativeInterface.RegisterThread(context, _memory, this);

            do
            {
                address = ExecuteSingle(context, address);
            }while (context.Running && address != 0);

            NativeInterface.UnregisterThread();

            if (Interlocked.Decrement(ref _threadCount) == 0)
            {
                _backgroundTranslatorEvent.Set();

                ClearJitCache();

                DisposePools();

                _jumpTable.Dispose();
                _jumpTable = null;

                GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
            }
        }