| 707 | } |
| 708 | |
| 709 | ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestRIP, uint64_t MaxInst) { |
| 710 | if (SourcecodeResolver && Config.GDBSymbols()) { |
| 711 | auto AOTIRCacheEntry = SyscallHandler->LookupAOTIRCacheEntry(Thread, GuestRIP); |
| 712 | if (AOTIRCacheEntry.Entry) { |
| 713 | AOTIRCacheEntry.Entry->SourcecodeMap = SourcecodeResolver->GenerateMap(AOTIRCacheEntry.Entry->Filename, AOTIRCacheEntry.Entry->FileId); |
| 714 | } |
| 715 | } |
| 716 | |
| 717 | // Generate IR + Meta Info |
| 718 | auto [IRView, TotalInstructions, TotalInstructionsLength, StartAddr, Length, NeedsAddGuestCodeRanges] = |
| 719 | GenerateIR(Thread, GuestRIP, Config.GDBSymbols(), MaxInst); |
| 720 | if (!IRView) { |
| 721 | return {{}, nullptr, 0, 0, false}; |
| 722 | } |
| 723 | |
| 724 | // Attempt to get the CPU backend to compile this code |
| 725 | // Re-check if another thread raced us in compiling this block. |
| 726 | // We could lock CodeBufferWriteMutex earlier to prevent this from happening, |
| 727 | // but this would increase lock contention. Redundant frontend runs aren't |
| 728 | // as expensive and are easily reverted. |
| 729 | if (MaxInst != 1) { |
| 730 | if (auto Block = Thread->LookupCache->FindBlock(GuestRIP)) { |
| 731 | Thread->OpDispatcher->DelayedDisownBuffer(); |
| 732 | return {.CompiledCode = {.BlockBegin = reinterpret_cast<uint8_t*>(Block), .EntryPoints = {{GuestRIP, reinterpret_cast<uint8_t*>(Block)}}}, |
| 733 | .DebugData = nullptr, |
| 734 | .StartAddr = 0, |
| 735 | .Length = 0, |
| 736 | .NeedsAddGuestCodeRanges = false}; |
| 737 | } |
| 738 | } |
| 739 | |
| 740 | auto DebugData = fextl::make_unique<FEXCore::Core::DebugData>(); |
| 741 | |
| 742 | // If the trap flag is set we generate single instruction blocks that each check to generate a single step exception. |
| 743 | bool TFSet = Thread->CurrentFrame->State.flags[X86State::RFLAG_TF_RAW_LOC]; |
| 744 | |
| 745 | auto CompiledCode = Thread->CPUBackend->CompileCode(GuestRIP, Length, TotalInstructions == 1, &*IRView, DebugData.get(), TFSet); |
| 746 | |
| 747 | // Release the IR |
| 748 | Thread->OpDispatcher->DelayedDisownBuffer(); |
| 749 | |
| 750 | return { |
| 751 | .CompiledCode = std::move(CompiledCode), |
| 752 | .DebugData = std::move(DebugData), |
| 753 | .StartAddr = StartAddr, |
| 754 | .Length = Length, |
| 755 | .NeedsAddGuestCodeRanges = NeedsAddGuestCodeRanges, |
| 756 | }; |
| 757 | } |
| 758 | |
| 759 | uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_t GuestRIP, uint64_t MaxInst) { |
| 760 | auto Thread = Frame->Thread; |
nothing calls this directly
no test coverage detected