From 3feb354186aa2227d496cfd220e8801f0658726f Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 16 Apr 2025 13:24:03 +0100 Subject: [PATCH] Frontend: Keep the associated thread object as a member Avoids an additional layer of indirection for callbacks. Passing them around deep into instruction decoding logic doesn't provide much benefit seeing as there will always be one frontend object per thread. --- FEXCore/Source/Interface/Core/Core.cpp | 9 ++------- FEXCore/Source/Interface/Core/Frontend.cpp | 19 +++++++++++-------- FEXCore/Source/Interface/Core/Frontend.h | 6 +++--- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 9685ac38b..153362039 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -412,7 +412,7 @@ void ContextImpl::InitializeCompiler(FEXCore::Core::InternalThreadState* Thread) Thread->OpDispatcher = fextl::make_unique(this); Thread->OpDispatcher->SetMultiblock(Config.Multiblock); Thread->LookupCache = fextl::make_unique(this); - Thread->FrontendDecoder = fextl::make_unique(this); + Thread->FrontendDecoder = fextl::make_unique(Thread); Thread->PassManager = fextl::make_unique(); Thread->CurrentFrame->Pointers.Common.L1Pointer = Thread->LookupCache->GetL1Pointer(); @@ -557,12 +557,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue bool HadDispatchError {false}; bool HadInvalidInst {false}; - Thread->FrontendDecoder->DecodeInstructionsAtEntry( - GuestCode, GuestRIP, MaxInst, [Thread](const fextl::set& BlockEntryPoints, uint64_t Start, uint64_t Length) { - if (Thread->LookupCache->AddBlockExecutableRange(BlockEntryPoints, Start, Length)) { - static_cast(Thread->CTX)->SyscallHandler->MarkGuestExecutableRange(Thread, Start, Length); - } - }); + Thread->FrontendDecoder->DecodeInstructionsAtEntry(GuestCode, GuestRIP, MaxInst); auto BlockInfo = Thread->FrontendDecoder->GetDecodedBlockInfo(); auto CodeBlocks = &BlockInfo->Blocks; diff --git a/FEXCore/Source/Interface/Core/Frontend.cpp b/FEXCore/Source/Interface/Core/Frontend.cpp index d9d997bb4..c54e2d1c2 100644 --- a/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/FEXCore/Source/Interface/Core/Frontend.cpp @@ -9,6 +9,7 @@ $end_info$ #include "Interface/Context/Context.h" #include "Interface/Core/Frontend.h" #include "Interface/Core/X86Tables/X86Tables.h" +#include "Interface/Core/LookupCache.h" #include #include @@ -21,6 +22,7 @@ $end_info$ #include #include #include +#include #include namespace FEXCore::Frontend { @@ -64,10 +66,11 @@ static uint32_t MapVEXToReg(uint8_t vvvv, bool HasXMM) { } } -Decoder::Decoder(FEXCore::Context::ContextImpl* ctx) - : CTX {ctx} - , OSABI {ctx->SyscallHandler ? ctx->SyscallHandler->GetOSABI() : FEXCore::HLE::SyscallOSABI::OS_UNKNOWN} - , PoolObject {ctx->FrontendAllocator, sizeof(FEXCore::X86Tables::DecodedInst) * DefaultDecodedBufferSize} {} +Decoder::Decoder(FEXCore::Core::InternalThreadState* Thread) + : Thread {Thread} + , CTX {static_cast(Thread->CTX)} + , OSABI {CTX->SyscallHandler ? CTX->SyscallHandler->GetOSABI() : FEXCore::HLE::SyscallOSABI::OS_UNKNOWN} + , PoolObject {CTX->FrontendAllocator, sizeof(FEXCore::X86Tables::DecodedInst) * DefaultDecodedBufferSize} {} uint8_t Decoder::ReadByte() { uint8_t Byte = InstStream[InstructionSize]; @@ -1122,9 +1125,7 @@ const uint8_t* Decoder::AdjustAddrForSpecialRegion(const uint8_t* _InstStream, u return _InstStream - EntryPoint + RIP; } -void Decoder::DecodeInstructionsAtEntry( - const uint8_t* _InstStream, uint64_t PC, uint64_t MaxInst, - std::function &BlockEntryPoints, uint64_t Start, uint64_t Length)> AddContainedCodePage) { +void Decoder::DecodeInstructionsAtEntry(const uint8_t* _InstStream, uint64_t PC, uint64_t MaxInst) { FEXCORE_PROFILE_SCOPED("DecodeInstructions"); BlockInfo.TotalInstructionCount = 0; BlockInfo.Blocks.clear(); @@ -1318,7 +1319,9 @@ void Decoder::DecodeInstructionsAtEntry( } for (auto CodePage : CodePages) { - AddContainedCodePage(BlockEntryPoints, CodePage, FEXCore::Utils::FEX_PAGE_SIZE); + if (Thread->LookupCache->AddBlockExecutableRange(BlockEntryPoints, CodePage, FEXCore::Utils::FEX_PAGE_SIZE)) { + CTX->SyscallHandler->MarkGuestExecutableRange(Thread, CodePage, FEXCore::Utils::FEX_PAGE_SIZE); + } } } diff --git a/FEXCore/Source/Interface/Core/Frontend.h b/FEXCore/Source/Interface/Core/Frontend.h index f1294bfd5..d17c98f0f 100644 --- a/FEXCore/Source/Interface/Core/Frontend.h +++ b/FEXCore/Source/Interface/Core/Frontend.h @@ -34,9 +34,8 @@ public: fextl::vector Blocks; }; - Decoder(FEXCore::Context::ContextImpl* ctx); - void DecodeInstructionsAtEntry(const uint8_t* InstStream, uint64_t PC, uint64_t MaxInst, - std::function& BlockEntryPoints, uint64_t Start, uint64_t Length)> AddContainedCodePage); + Decoder(FEXCore::Core::InternalThreadState* Thread); + void DecodeInstructionsAtEntry(const uint8_t* InstStream, uint64_t PC, uint64_t MaxInst); const DecodedBlockInformation* GetDecodedBlockInfo() const { return &BlockInfo; @@ -65,6 +64,7 @@ private: bool L; // VEX.L bit (if set then 256 bit operation, if unset then scalar or 128-bit operation) }; + FEXCore::Core::InternalThreadState* Thread; FEXCore::Context::ContextImpl* CTX; const FEXCore::HLE::SyscallOSABI OSABI {};