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); }
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); }
/// <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)); }
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); }