Пример #1
0
        private static TranslatedFunction FastTranslate(byte[] code, UnwindInfo unwindInfo, bool highCq)
        {
            CompiledFunction cFunc = new CompiledFunction(code, unwindInfo);

            IntPtr codePtr = JitCache.Map(cFunc);

            GuestFunction gFunc = Marshal.GetDelegateForFunctionPointer <GuestFunction>(codePtr);

            TranslatedFunction tFunc = new TranslatedFunction(gFunc, highCq);

            return(tFunc);
        }
Пример #2
0
        public static ulong GetIndirectFunctionAddress(ulong address, ulong entryAddress)
        {
            TranslatedFunction function = _context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);
            ulong ptr = (ulong)function.GetPointer().ToInt64();

            if (function.HighCq)
            {
                // Rewrite the host function address in the table to point to the highCq function.
                Marshal.WriteInt64((IntPtr)entryAddress, 8, (long)ptr);
            }
            return(ptr);
        }
Пример #3
0
        private static TranslatedFunction FastTranslate(ReadOnlySpan <byte> code, ulong guestSize, UnwindInfo unwindInfo, bool highCq)
        {
            CompiledFunction cFunc = new CompiledFunction(code.ToArray(), unwindInfo);

            IntPtr codePtr = JitCache.Map(cFunc);

            GuestFunction gFunc = Marshal.GetDelegateForFunctionPointer <GuestFunction>(codePtr);

            TranslatedFunction tFunc = new TranslatedFunction(gFunc, guestSize, highCq);

            return(tFunc);
        }
Пример #4
0
        internal static void MakeAndSaveTranslations(ConcurrentDictionary <ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable)
        {
            var profiledFuncsToTranslate = PtcProfiler.GetProfiledFuncsToTranslate(funcs);

            if (profiledFuncsToTranslate.Count == 0)
            {
                return;
            }

            _translateCount = 0;

            ThreadPool.QueueUserWorkItem(TranslationLogger, profiledFuncsToTranslate.Count);

            int maxDegreeOfParallelism = (Environment.ProcessorCount * 3) / 4;

            Parallel.ForEach(profiledFuncsToTranslate, new ParallelOptions {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            }, (item, state) =>
            {
                ulong address = item.Key;

                Debug.Assert(PtcProfiler.IsAddressInStaticCodeRange(address));

                TranslatedFunction func = Translator.Translate(memory, jumpTable, address, item.Value.mode, item.Value.highCq);

                bool isAddressUnique = funcs.TryAdd(address, func);

                Debug.Assert(isAddressUnique, $"The address 0x{address:X16} is not unique.");

                if (func.HighCq)
                {
                    jumpTable.RegisterFunction(address, func);
                }

                Interlocked.Increment(ref _translateCount);

                if (State != PtcState.Enabled)
                {
                    state.Stop();
                }
            });

            _loggerEvent.Set();

            PtcJumpTable.Initialize(jumpTable);

            PtcJumpTable.ReadJumpTable(jumpTable);
            PtcJumpTable.ReadDynamicTable(jumpTable);

            ThreadPool.QueueUserWorkItem(PreSave);
        }
Пример #5
0
        public JITROMDelegate JITROM(Span <byte> ROM, SortedSet <UInt16> BreakPoints = null)
        {
            if (BreakPoints == null)
            {
                BreakPoints = new SortedSet <ushort>();
            }

            var exe = disasm.DisassembleProgram(ROM);

            JITContext ctx = new JITContext
            {
                BreakPoints = BreakPoints,
                Disasm      = exe
            };

            var(res, gen) = CreateMethod("JITROM", ctx);

            //Find all function calls
            Dictionary <UInt16, TranslatedFunction> Functions = exe.Entries.Where(x => !x.IsData && x.Instr.Value.Instruction == Instruction.CALL)
                                                                .Select(x => x.Instr.Value.Immediate16)
                                                                .Distinct()
                                                                .ToDictionary(x => x, x => (TranslatedFunction)null);

            //Function calls will get translated to their own method to use the runtime call stack
            foreach (var f in Functions.Keys.ToArray())
            {
                var(tmpMethod, TmpGen) = CreateMethod("method_" + f.ToString("X4"), ctx);

                Functions[f] = new TranslatedFunction
                {
                    Method    = tmpMethod,
                    Generator = TmpGen,
                    Info      = tmpMethod
                };
            }

            ctx.Functions = Functions;

            //As detecting where a funnction ends is not trivial we're just going to JIT all functions to the end of the rom, disgusting i know
            foreach (var f in Functions.Keys.Where(x => x >= Chip8State.ProgramStart))
            {
                JITBlock(Functions[f].Generator, ctx, (f - Chip8State.ProgramStart) / 2, exe.Entries.Length);
            }

            //Then JIT the whole ROM
            JITBlock(gen, ctx, 0, exe.Entries.Length);

            return((JITROMDelegate)res.CreateDelegate(typeof(JITROMDelegate)));
        }
Пример #6
0
        public static ulong GetIndirectFunctionAddress(ulong address, ulong entryAddress)
        {
            TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode, hintRejit: true);

            ulong ptr = (ulong)function.FuncPtr.ToInt64();

            if (function.HighCq)
            {
                Debug.Assert(Context.Translator.JumpTable.CheckEntryFromAddressDynamicTable((IntPtr)entryAddress));

                // Rewrite the host function address in the table to point to the highCq function.
                Marshal.WriteInt64((IntPtr)entryAddress, 8, (long)ptr);
            }

            return(ptr);
        }
Пример #7
0
        public void RegisterFunction(ulong address, TranslatedFunction func)
        {
            Targets.AddOrUpdate(address, func, (key, oldFunc) => func);
            long funcPtr = func.FuncPtr.ToInt64();

            // Update all jump table entries that target this address.
            if (Dependants.TryGetValue(address, out List <int> myDependants))
            {
                lock (myDependants)
                {
                    foreach (int entry in myDependants)
                    {
                        IntPtr addr = GetEntryAddressJumpTable(entry);

                        Marshal.WriteInt64(addr, 8, funcPtr);
                    }
                }
            }
        }
        private bool ShouldOptOut(TranslatedFunction declaration)
        {
            switch (declaration.Name)
            {
            // Skip PushID(const char*) and prefer PushID(const char*, const char*)
            case "PushID":
            // Skip GetID(const char*) and prefer GetID(const char*, const char*)
            case "GetID":
                return(declaration.Parameters.Length == 1);

            // This function takes a string, but not one that's written by humans.
            // If we were to call this from C# we'd want to actually pass in a ReadOnlySpan<byte> or something.
            case "AddFontFromMemoryCompressedBase85TTF":
                return(true);

            // There is a UTF16 equivalent of this function, so it doesn't make sense to generate a wrapper
            case "AddInputCharactersUTF8":
                return(true);

            default:
                return(false);
            }
        }
Пример #9
0
        internal static void MakeAndSaveTranslations(
            ConcurrentDictionary <ulong, TranslatedFunction> funcs,
            IMemoryManager memory,
            JumpTable jumpTable,
            EntryTable <uint> countTable)
        {
            var profiledFuncsToTranslate = PtcProfiler.GetProfiledFuncsToTranslate(funcs);

            _translateCount      = 0;
            _translateTotalCount = profiledFuncsToTranslate.Count;

            int degreeOfParallelism = new DegreeOfParallelism(4d, 75d, 12.5d).GetDegreeOfParallelism(0, 32);

            if (_translateTotalCount == 0 || degreeOfParallelism == 0)
            {
                ResetCarriersIfNeeded();
                PtcJumpTable.ClearIfNeeded();

                GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

                return;
            }

            Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism}");

            PtcStateChanged?.Invoke(PtcLoadingState.Start, _translateCount, _translateTotalCount);

            using AutoResetEvent progressReportEvent = new AutoResetEvent(false);

            Thread progressReportThread = new Thread(ReportProgress)
            {
                Name         = "Ptc.ProgressReporter",
                Priority     = ThreadPriority.Lowest,
                IsBackground = true
            };

            progressReportThread.Start(progressReportEvent);

            void TranslateFuncs()
            {
                while (profiledFuncsToTranslate.TryDequeue(out var item))
                {
                    ulong address = item.address;

                    Debug.Assert(PtcProfiler.IsAddressInStaticCodeRange(address));

                    TranslatedFunction func = Translator.Translate(memory, jumpTable, countTable, address, item.funcProfile.Mode, item.funcProfile.HighCq);

                    bool isAddressUnique = funcs.TryAdd(address, func);

                    Debug.Assert(isAddressUnique, $"The address 0x{address:X16} is not unique.");

                    if (func.HighCq)
                    {
                        jumpTable.RegisterFunction(address, func);
                    }

                    Interlocked.Increment(ref _translateCount);

                    if (State != PtcState.Enabled)
                    {
                        break;
                    }
                }

                Translator.DisposePools();
            }

            List <Thread> threads = new List <Thread>();

            for (int i = 0; i < degreeOfParallelism; i++)
            {
                Thread thread = new Thread(TranslateFuncs);
                thread.IsBackground = true;

                threads.Add(thread);
            }

            threads.ForEach((thread) => thread.Start());
            threads.ForEach((thread) => thread.Join());

            threads.Clear();

            progressReportEvent.Set();
            progressReportThread.Join();

            PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);

            Logger.Info?.Print(LogClass.Ptc, $"{_translateCount} of {_translateTotalCount} functions translated | Thread count: {degreeOfParallelism}");

            PtcJumpTable.Initialize(jumpTable);

            PtcJumpTable.ReadJumpTable(jumpTable);
            PtcJumpTable.ReadDynamicTable(jumpTable);

            Thread preSaveThread = new Thread(PreSave);

            preSaveThread.IsBackground = true;
            preSaveThread.Start();
        }
Пример #10
0
        internal static void LoadTranslations(
            ConcurrentDictionary <ulong, TranslatedFunction> funcs,
            IMemoryManager memory,
            JumpTable jumpTable,
            EntryTable <uint> countTable)
        {
            if (AreCarriersEmpty())
            {
                return;
            }

            long infosStreamLength       = _infosStream.Length;
            long relocsStreamLength      = _relocsStream.Length;
            long unwindInfosStreamLength = _unwindInfosStream.Length;

            _infosStream.Seek(0L, SeekOrigin.Begin);
            _relocsStream.Seek(0L, SeekOrigin.Begin);
            _unwindInfosStream.Seek(0L, SeekOrigin.Begin);

            using (BinaryReader relocsReader = new(_relocsStream, EncodingCache.UTF8NoBOM, true))
                using (BinaryReader unwindInfosReader = new(_unwindInfosStream, EncodingCache.UTF8NoBOM, true))
                {
                    for (int index = 0; index < GetEntriesCount(); index++)
                    {
                        InfoEntry infoEntry = DeserializeStructure <InfoEntry>(_infosStream);

                        if (infoEntry.Stubbed)
                        {
                            SkipCode(index, infoEntry.CodeLength);
                            SkipReloc(infoEntry.RelocEntriesCount);
                            SkipUnwindInfo(unwindInfosReader);

                            continue;
                        }

                        bool isEntryChanged = infoEntry.Hash != ComputeHash(memory, infoEntry.Address, infoEntry.GuestSize);

                        if (isEntryChanged || (!infoEntry.HighCq && PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) && value.HighCq))
                        {
                            infoEntry.Stubbed    = true;
                            infoEntry.CodeLength = 0;
                            UpdateInfo(infoEntry);

                            StubCode(index);
                            StubReloc(infoEntry.RelocEntriesCount);
                            StubUnwindInfo(unwindInfosReader);

                            if (isEntryChanged)
                            {
                                PtcJumpTable.Clean(infoEntry.Address);

                                Logger.Info?.Print(LogClass.Ptc, $"Invalidated translated function (address: 0x{infoEntry.Address:X16})");
                            }

                            continue;
                        }

                        byte[] code = ReadCode(index, infoEntry.CodeLength);

                        Counter <uint> callCounter = null;

                        if (infoEntry.RelocEntriesCount != 0)
                        {
                            RelocEntry[] relocEntries = GetRelocEntries(relocsReader, infoEntry.RelocEntriesCount);

                            PatchCode(code, relocEntries, memory.PageTablePointer, jumpTable, countTable, out callCounter);
                        }

                        UnwindInfo unwindInfo = ReadUnwindInfo(unwindInfosReader);

                        TranslatedFunction func = FastTranslate(code, callCounter, infoEntry.GuestSize, unwindInfo, infoEntry.HighCq);

                        bool isAddressUnique = funcs.TryAdd(infoEntry.Address, func);

                        Debug.Assert(isAddressUnique, $"The address 0x{infoEntry.Address:X16} is not unique.");
                    }
                }

            if (_infosStream.Length != infosStreamLength || _infosStream.Position != infosStreamLength ||
                _relocsStream.Length != relocsStreamLength || _relocsStream.Position != relocsStreamLength ||
                _unwindInfosStream.Length != unwindInfosStreamLength || _unwindInfosStream.Position != unwindInfosStreamLength)
            {
                throw new Exception("The length of a memory stream has changed, or its position has not reached or has exceeded its end.");
            }

            jumpTable.Initialize(PtcJumpTable, funcs);

            PtcJumpTable.WriteJumpTable(jumpTable, funcs);
            PtcJumpTable.WriteDynamicTable(jumpTable);

            Logger.Info?.Print(LogClass.Ptc, $"{funcs.Count} translated functions loaded");
        }
Пример #11
0
        public static ulong GetFunctionAddress(ulong address)
        {
            TranslatedFunction function = _context.Translator.GetOrTranslate(address, GetContext().ExecutionMode);

            return((ulong)function.FuncPtr.ToInt64());
        }
Пример #12
0
        internal static void MakeAndSaveTranslations(ConcurrentDictionary <ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable)
        {
            var profiledFuncsToTranslate = PtcProfiler.GetProfiledFuncsToTranslate(funcs);

            if (profiledFuncsToTranslate.Count == 0)
            {
                return;
            }

            _translateCount = 0;

            ThreadPool.QueueUserWorkItem(TranslationLogger, profiledFuncsToTranslate.Count);

            void TranslateFuncs()
            {
                while (profiledFuncsToTranslate.TryDequeue(out var item))
                {
                    ulong address = item.address;

                    Debug.Assert(PtcProfiler.IsAddressInStaticCodeRange(address));

                    TranslatedFunction func = Translator.Translate(memory, jumpTable, address, item.mode, item.highCq);

                    bool isAddressUnique = funcs.TryAdd(address, func);

                    Debug.Assert(isAddressUnique, $"The address 0x{address:X16} is not unique.");

                    if (func.HighCq)
                    {
                        jumpTable.RegisterFunction(address, func);
                    }

                    Interlocked.Increment(ref _translateCount);

                    if (State != PtcState.Enabled)
                    {
                        break;
                    }
                }
            }

            int maxDegreeOfParallelism = (Environment.ProcessorCount * 3) / 4;

            List <Thread> threads = new List <Thread>();

            for (int i = 0; i < maxDegreeOfParallelism; i++)
            {
                Thread thread = new Thread(TranslateFuncs);
                thread.IsBackground = true;

                threads.Add(thread);
            }

            threads.ForEach((thread) => thread.Start());
            threads.ForEach((thread) => thread.Join());

            threads.Clear();

            Translator.ResetPools();

            _loggerEvent.Set();

            PtcJumpTable.Initialize(jumpTable);

            PtcJumpTable.ReadJumpTable(jumpTable);
            PtcJumpTable.ReadDynamicTable(jumpTable);

            ThreadPool.QueueUserWorkItem(PreSave);
        }
Пример #13
0
        internal static void LoadTranslations(ConcurrentDictionary <ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable)
        {
            if ((int)_infosStream.Length == 0 ||
                (int)_codesStream.Length == 0 ||
                (int)_relocsStream.Length == 0 ||
                (int)_unwindInfosStream.Length == 0)
            {
                return;
            }

            Debug.Assert(funcs.Count == 0);

            _infosStream.Seek(0L, SeekOrigin.Begin);
            _codesStream.Seek(0L, SeekOrigin.Begin);
            _relocsStream.Seek(0L, SeekOrigin.Begin);
            _unwindInfosStream.Seek(0L, SeekOrigin.Begin);

            using (BinaryReader infosReader = new BinaryReader(_infosStream, EncodingCache.UTF8NoBOM, true))
                using (BinaryReader codesReader = new BinaryReader(_codesStream, EncodingCache.UTF8NoBOM, true))
                    using (BinaryReader relocsReader = new BinaryReader(_relocsStream, EncodingCache.UTF8NoBOM, true))
                        using (BinaryReader unwindInfosReader = new BinaryReader(_unwindInfosStream, EncodingCache.UTF8NoBOM, true))
                        {
                            for (int i = 0; i < GetInfosEntriesCount(); i++)
                            {
                                InfoEntry infoEntry = ReadInfo(infosReader);

                                if (infoEntry.Stubbed)
                                {
                                    SkipCode(infoEntry.CodeLen);
                                    SkipReloc(infoEntry.RelocEntriesCount);
                                    SkipUnwindInfo(unwindInfosReader);
                                }
                                else if (infoEntry.HighCq || !PtcProfiler.ProfiledFuncs.TryGetValue(infoEntry.Address, out var value) || !value.highCq)
                                {
                                    byte[] code = ReadCode(codesReader, infoEntry.CodeLen);

                                    if (infoEntry.RelocEntriesCount != 0)
                                    {
                                        RelocEntry[] relocEntries = GetRelocEntries(relocsReader, infoEntry.RelocEntriesCount);

                                        PatchCode(code, relocEntries, memory.PageTablePointer, jumpTable);
                                    }

                                    UnwindInfo unwindInfo = ReadUnwindInfo(unwindInfosReader);

                                    TranslatedFunction func = FastTranslate(code, infoEntry.GuestSize, unwindInfo, infoEntry.HighCq);

                                    bool isAddressUnique = funcs.TryAdd(infoEntry.Address, func);

                                    Debug.Assert(isAddressUnique, $"The address 0x{infoEntry.Address:X16} is not unique.");
                                }
                                else
                                {
                                    infoEntry.Stubbed = true;
                                    UpdateInfo(infoEntry);

                                    StubCode(infoEntry.CodeLen);
                                    StubReloc(infoEntry.RelocEntriesCount);
                                    StubUnwindInfo(unwindInfosReader);
                                }
                            }
                        }

            if (_infosStream.Position < _infosStream.Length ||
                _codesStream.Position < _codesStream.Length ||
                _relocsStream.Position < _relocsStream.Length ||
                _unwindInfosStream.Position < _unwindInfosStream.Length)
            {
                throw new Exception("Could not reach the end of one or more memory streams.");
            }

            jumpTable.Initialize(PtcJumpTable, funcs);

            PtcJumpTable.WriteJumpTable(jumpTable, funcs);
            PtcJumpTable.WriteDynamicTable(jumpTable);

            Logger.Info?.Print(LogClass.Ptc, $"{funcs.Count} translated functions loaded");
        }
Пример #14
0
        internal static void MakeAndSaveTranslations(ConcurrentDictionary <ulong, TranslatedFunction> funcs, IMemoryManager memory, JumpTable jumpTable)
        {
            if (PtcProfiler.ProfiledFuncs.Count == 0)
            {
                return;
            }

            _translateCount = 0;
            _rejitCount     = 0;

            ThreadPool.QueueUserWorkItem(TranslationLogger, (funcs.Count, PtcProfiler.ProfiledFuncs.Count));

            int maxDegreeOfParallelism = (Environment.ProcessorCount * 3) / 4;

            Parallel.ForEach(PtcProfiler.ProfiledFuncs, new ParallelOptions {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            }, (item, state) =>
            {
                ulong address = item.Key;

                Debug.Assert(PtcProfiler.IsAddressInStaticCodeRange(address));

                if (!funcs.ContainsKey(address))
                {
                    TranslatedFunction func = Translator.Translate(memory, jumpTable, address, item.Value.mode, item.Value.highCq);

                    funcs.TryAdd(address, func);

                    if (func.HighCq)
                    {
                        jumpTable.RegisterFunction(address, func);
                    }

                    Interlocked.Increment(ref _translateCount);
                }
                else if (item.Value.highCq && !funcs[address].HighCq)
                {
                    TranslatedFunction func = Translator.Translate(memory, jumpTable, address, item.Value.mode, highCq: true);

                    funcs[address] = func;

                    jumpTable.RegisterFunction(address, func);

                    Interlocked.Increment(ref _rejitCount);
                }

                if (State != PtcState.Enabled)
                {
                    state.Stop();
                }
            });

            _loggerEvent.Set();

            if (_translateCount != 0 || _rejitCount != 0)
            {
                PtcJumpTable.Initialize(jumpTable);

                PtcJumpTable.ReadJumpTable(jumpTable);
                PtcJumpTable.ReadDynamicTable(jumpTable);

                ThreadPool.QueueUserWorkItem(PreSave);
            }
        }
        // This transformation is an opt-out heuristic
        // It'd be not-ideal if it was wrong, but it's expected that the user will be smart enough to avoid calling the nonsense overload
        // In the long term we'll rely on a parameter being explicitly marked as a string once https://github.com/ocornut/imgui/pull/3038 is merged
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            // Opt out of specific functions that shouldn't get overloads
            if (ShouldOptOut(declaration))
            {
                return(declaration);
            }

            // Check if this function has a string parameter
            ImmutableArray <int> .Builder?stringParameters = null;
            bool firstParameterHasEnd = false;

            for (int i = 0; i < declaration.Parameters.Length; i++)
            {
                TranslatedParameter parameter = declaration.Parameters[i];

                // If the parameter is a `byte*`, it's a string parameter
                if (parameter.Type is PointerTypeReference {
                    Inner: CSharpBuiltinTypeReference cSharpPointee
                } && cSharpPointee == CSharpBuiltinType.Byte)
Пример #16
0
        private static ulong GetFunctionAddressWithHint(ulong address, bool hintRejit)
        {
            TranslatedFunction function = Context.Translator.GetOrTranslate(address, GetContext().ExecutionMode, hintRejit);

            return((ulong)function.FuncPtr.ToInt64());
        }
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            TransformationResult result = declaration;

            if (declaration.Name == "DebugCheckVersionAndDataLayout")
            {
                if (IMGUI_VERSION is not null)
                {
                    result.Add(IMGUI_VERSION);
                }

                if (IMGUI_VERSION_NUM is not null)
                {
                    result.Add(IMGUI_VERSION_NUM);
                }
            }

            return(result);
        }
Пример #18
0
        public static bool TryFastTranslateDyn(
            Translator translator,
            ulong address,
            ulong funcSize,
            bool highCq,
            ref TtcInfo ttcInfoRef,
            out TranslatedFunction translatedFuncDyn)
        {
            ttcInfoRef        = null;
            translatedFuncDyn = null;

            if (!Translator.OverlapsWith(address, funcSize, Translator.StaticCodeStart, Translator.StaticCodeSize) && (highCq || funcSize > MinFuncSizeDyn))
            {
                Hash128 preHash = translator.ComputeHash(address, funcSize);
                Hash128 hash    = highCq ? ~preHash : preHash;

                if (!translator.TtcInfos.TryGetValue(hash, out TtcInfo ttcInfoOut))
                {
                    TtcInfo ttcInfoNew = new TtcInfo();

                    ttcInfoNew.IsBusy = true;

                    ttcInfoNew.LastGuestAddress = address;
                    ttcInfoNew.GuestSize        = funcSize;

                    if (translator.TtcInfos.TryAdd(hash, ttcInfoNew))
                    {
                        ttcInfoRef = ttcInfoNew;
                    }
                    else
                    {
                        ttcInfoNew.Dispose();
                    }
                }
                else
                {
                    lock (ttcInfoOut)
                    {
                        if (!ttcInfoOut.IsBusy)
                        {
                            ttcInfoOut.IsBusy = true;

                            ttcInfoOut.LastGuestAddress = address;

                            if (ttcInfoOut.RelocEntriesCount != 0)
                            {
                                RelocEntry[] relocEntries = Ptc.GetRelocEntries(ttcInfoOut.RelocStream, ttcInfoOut.RelocEntriesCount, reloadStream: true);

                                JitCache.ModifyMapped(ttcInfoOut.TranslatedFunc.FuncPtr, ttcInfoOut.HostSize, (code) => PatchCodeDyn(translator, code, relocEntries, address));
                            }

                            if (ttcInfoOut.TranslatedFunc.CallCounter != null && Volatile.Read(ref ttcInfoOut.TranslatedFunc.CallCounter.Value) > Translator.MinsCallForRejit)
                            {
                                Volatile.Write(ref ttcInfoOut.TranslatedFunc.CallCounter.Value, Translator.MinsCallForRejit);
                            }

                            translatedFuncDyn = ttcInfoOut.TranslatedFunc;

                            Logger.Debug?.Print(LogClass.Ttc,
                                                $"Fast translated dynamic function 0x{preHash} " +
                                                $"(HighCq: {highCq}{(!highCq ? $" [CallCounter: {ttcInfoOut.TranslatedFunc.CallCounter.Value}]" : string.Empty)}, HostSize: {ttcInfoOut.HostSize}) " +
                                                $"| DynFuncs: {translator.TtcInfos.Count}.");

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
        {
            // Private/protected functions are always stripped
            if (declaration.Accessibility is AccessModifier.Private or AccessModifier.Protected)
            {
                return(null);
            }

            // Check if any parents are private/protected
            foreach (TranslatedDeclaration parent in context.Parents)
            {
                if (parent.Accessibility is AccessModifier.Private or AccessModifier.Protected)
                {
                    return(null);
                }
            }

            return(base.TransformFunction(context, declaration));
        }
Пример #20
0
 protected override TransformationResult TransformFunction(TransformationContext context, TranslatedFunction declaration)
 => declaration with