コード例 #1
0
ファイル: Ptc.cs プロジェクト: headassbtw/Ryujinx
        private static TranslatedFunction FastTranslate(byte[] code, ulong guestSize, 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, guestSize, highCq);

            return(tFunc);
        }
コード例 #2
0
        private static TranslatedFunction FastTranslate(ReadOnlySpan <byte> code, Counter callCounter, 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, callCounter, guestSize, highCq);

            return(tFunc);
        }
コード例 #3
0
        /// <summary>
        /// Maps the <see cref="CompiledFunction"/> onto the <see cref="JitCache"/> and returns a delegate of type
        /// <typeparamref name="T"/> pointing to the mapped function.
        /// </summary>
        /// <typeparam name="T">Type of delegate</typeparam>
        /// <returns>A delegate of type <typeparamref name="T"/> pointing to the mapped function</returns>
        public T Map <T>()
        {
            IntPtr codePtr = JitCache.Map(this);

            return(Marshal.GetDelegateForFunctionPointer <T>(codePtr));
        }
コード例 #4
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);
        }