diff --git a/FEXCore/Source/Interface/Context/Context.h b/FEXCore/Source/Interface/Context/Context.h index 88e630c31..8b59a8e1a 100644 --- a/FEXCore/Source/Interface/Context/Context.h +++ b/FEXCore/Source/Interface/Context/Context.h @@ -80,7 +80,7 @@ public: uint64_t ComputeCodeMapId(std::string_view Filename, int FD) override; bool SaveData(Core::InternalThreadState&, int TargetFD, const ExecutableFileSectionInfo&, uint64_t SerializedBaseAddress) override; - bool LoadData(Core::InternalThreadState&, std::byte* MappedCacheFile, const ExecutableFileSectionInfo&) override; + bool LoadData(Core::InternalThreadState*, std::byte* MappedCacheFile, const ExecutableFileSectionInfo&) override; /** * Performs expensive extra validation on the loaded code cache data. diff --git a/FEXCore/Source/Interface/Core/CodeCache.cpp b/FEXCore/Source/Interface/Core/CodeCache.cpp index 6a41f1350..2c3473dd3 100644 --- a/FEXCore/Source/Interface/Core/CodeCache.cpp +++ b/FEXCore/Source/Interface/Core/CodeCache.cpp @@ -329,7 +329,7 @@ bool CodeCache::SaveData(Core::InternalThreadState& Thread, int fd, const Execut return true; } -bool CodeCache::LoadData(Core::InternalThreadState& Thread, std::byte* MappedCacheFile, const ExecutableFileSectionInfo& BinarySection) { +bool CodeCache::LoadData(Core::InternalThreadState* Thread, std::byte* MappedCacheFile, const ExecutableFileSectionInfo& BinarySection) { if (!EnableCodeCaching) { return true; } @@ -417,10 +417,12 @@ bool CodeCache::LoadData(Core::InternalThreadState& Thread, std::byte* MappedCac // Prepare CodeBuffer: Page aligned and big enough to hold all cached data auto Lock = std::unique_lock {CTX.CodeBufferWriteMutex}; - if (auto Prev = Thread.CPUBackend->CheckCodeBufferUpdate()) { - Allocator::VirtualDontNeed(Thread.CallRetStackBase, FEXCore::Core::InternalThreadState::CALLRET_STACK_SIZE); - auto lk = Thread.LookupCache->AcquireWriteLock(); - Thread.LookupCache->ChangeGuestToHostMapping(*Prev, *CTX.GetLatest()->LookupCache, lk); + if (Thread) { + if (auto Prev = Thread->CPUBackend->CheckCodeBufferUpdate()) { + Allocator::VirtualDontNeed(Thread->CallRetStackBase, FEXCore::Core::InternalThreadState::CALLRET_STACK_SIZE); + auto lk = Thread->LookupCache->AcquireWriteLock(); + Thread->LookupCache->ChangeGuestToHostMapping(*Prev, *CTX.GetLatest()->LookupCache, lk); + } } auto CodeBuffer = CTX.GetLatest(); @@ -430,9 +432,13 @@ bool CodeCache::LoadData(Core::InternalThreadState& Thread, std::byte* MappedCac CTX.LatestOffset += Delta; while (CTX.LatestOffset + header.CodeBufferSize > CodeBuffer->Size - Utils::FEX_PAGE_SIZE) { - CTX.ClearCodeCache(&Thread); - CodeBuffer = CTX.GetLatest(); - LogMan::Msg::IFmt("Increased code buffer size to {} MiB for cache load", CodeBuffer->Size / 1024 / 1024); + if (Thread) { + CTX.ClearCodeCache(Thread); + CodeBuffer = CTX.GetLatest(); + LogMan::Msg::IFmt("Increased code buffer size to {} MiB for cache load", CodeBuffer->Size / 1024 / 1024); + } else { + ERROR_AND_DIE_FMT("Cannot extend codebuffer without thread!"); + } } // Read CodeBuffer data from file. Make sure the destination is page-aligned. @@ -475,7 +481,7 @@ bool CodeCache::LoadData(Core::InternalThreadState& Thread, std::byte* MappedCac MappedCacheFile += NumEntrypoints * sizeof(Entrypoints[0]); if (LookupCache.AddBlockExecutableRange(Entrypoints, CodePage, FEXCore::Utils::FEX_PAGE_SIZE, WriteLock)) { - CTX.SyscallHandler->MarkGuestExecutableRange(&Thread, CodePage, FEXCore::Utils::FEX_PAGE_SIZE); + CTX.SyscallHandler->MarkGuestExecutableRange(Thread, CodePage, FEXCore::Utils::FEX_PAGE_SIZE); } } } diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index a061a6e45..28219f924 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -723,7 +723,7 @@ ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState* Thread, uint64_t Gue ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestRIP, uint64_t MaxInst) { if (SourcecodeResolver && Config.GDBSymbols()) { - auto MappedSection = SyscallHandler->LookupExecutableFileSection(*Thread, GuestRIP); + auto MappedSection = SyscallHandler->LookupExecutableFileSection(Thread, GuestRIP); if (MappedSection) { MappedSection->FileInfo.SourcecodeMap = SourcecodeResolver->GenerateMap(MappedSection->FileInfo.Filename, CodeMap::GetBaseFilename(MappedSection->FileInfo, false)); @@ -804,7 +804,7 @@ uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_ if (Config.BlockJITNaming()) { auto FragmentBasePtr = CompiledCode.BlockBegin; - auto GuestRIPLookup = SyscallHandler->LookupExecutableFileSection(*Thread, GuestRIP); + auto GuestRIPLookup = SyscallHandler->LookupExecutableFileSection(Thread, GuestRIP); if (DebugData->Subblocks.size()) { for (auto& Subblock : DebugData->Subblocks) { @@ -827,7 +827,7 @@ uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_ } if (Config.LibraryJITNaming() || Config.GDBSymbols()) { - auto MappedSection = SyscallHandler->LookupExecutableFileSection(*Thread, GuestRIP); + auto MappedSection = SyscallHandler->LookupExecutableFileSection(Thread, GuestRIP); if (MappedSection) { if (Config.LibraryJITNaming()) { Symbols.RegisterNamedRegion(Thread->SymbolBuffer.get(), CodePtr, DebugData->HostCodeSize, MappedSection->FileInfo.Filename); @@ -866,7 +866,7 @@ uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_ } if (CodeMapWriter) { - auto Region = SyscallHandler->LookupExecutableFileSection(*Thread, GuestRIP); + auto Region = SyscallHandler->LookupExecutableFileSection(Thread, GuestRIP); if (Region && Region->FileStartVA != 0) { CodeMapWriter->AppendBlock(*Region, GuestRIP); } diff --git a/FEXCore/Source/Interface/Core/Frontend.cpp b/FEXCore/Source/Interface/Core/Frontend.cpp index 92ba1a49e..91b8566dd 100644 --- a/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/FEXCore/Source/Interface/Core/Frontend.cpp @@ -1352,7 +1352,7 @@ void Decoder::DecodeInstructionsAtEntry(FEXCore::Core::InternalThreadState* Thre if (CTX->GetCodeCache().IsGeneratingCache || EnableCodeCacheValidation) { // If generating cache, attempt to load section bounds and relocations - if (auto SectionInfo = CTX->SyscallHandler->LookupExecutableFileSection(*Thread, EntryPoint)) { + if (auto SectionInfo = CTX->SyscallHandler->LookupExecutableFileSection(Thread, EntryPoint)) { SectionMinAddress = SectionInfo->FileStartVA; SectionMaxAddress = SectionInfo->EndVA; Relocations = &SectionInfo->FileInfo.Relocations; diff --git a/FEXCore/include/FEXCore/Core/CodeCache.h b/FEXCore/include/FEXCore/Core/CodeCache.h index efb1f3d9e..fff72094c 100644 --- a/FEXCore/include/FEXCore/Core/CodeCache.h +++ b/FEXCore/include/FEXCore/Core/CodeCache.h @@ -190,7 +190,7 @@ public: * TODO: Optionally recompiles all contained code blocks at runtime for validation. * Returns false if the provided cache file is invalid, and true otherwise. */ - virtual bool LoadData(Core::InternalThreadState&, std::byte* MappedCacheFile, const ExecutableFileSectionInfo&) = 0; + virtual bool LoadData(Core::InternalThreadState*, std::byte* MappedCacheFile, const ExecutableFileSectionInfo&) = 0; /** * Bundles the current Core state (CodeBuffer, GuestToHostMapping, ...) to a code cache and writes it to the given file descriptor. diff --git a/FEXCore/include/FEXCore/HLE/SyscallHandler.h b/FEXCore/include/FEXCore/HLE/SyscallHandler.h index 712fda130..d1f4decd7 100644 --- a/FEXCore/include/FEXCore/HLE/SyscallHandler.h +++ b/FEXCore/include/FEXCore/HLE/SyscallHandler.h @@ -63,7 +63,7 @@ public: virtual void MarkOvercommitRange(uint64_t Start, uint64_t Length) {} virtual void UnmarkOvercommitRange(uint64_t Start, uint64_t Length) {} virtual ExecutableRangeInfo QueryGuestExecutableRange(FEXCore::Core::InternalThreadState* Thread, uint64_t Address) = 0; - virtual std::optional LookupExecutableFileSection(Core::InternalThreadState& Thread, uint64_t GuestAddr) = 0; + virtual std::optional LookupExecutableFileSection(Core::InternalThreadState* Thread, uint64_t GuestAddr) = 0; virtual void PreCompile() {} diff --git a/Source/Tools/CodeSizeValidation/Main.cpp b/Source/Tools/CodeSizeValidation/Main.cpp index 07380659d..a4d99b56e 100644 --- a/Source/Tools/CodeSizeValidation/Main.cpp +++ b/Source/Tools/CodeSizeValidation/Main.cpp @@ -449,7 +449,7 @@ public: // These are no-ops implementations of the SyscallHandler API std::optional - LookupExecutableFileSection(FEXCore::Core::InternalThreadState& Thread, uint64_t GuestAddr) override { + LookupExecutableFileSection(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestAddr) override { return std::nullopt; } diff --git a/Source/Tools/CommonTools/DummyHandlers.h b/Source/Tools/CommonTools/DummyHandlers.h index fd54d59e4..91666a525 100644 --- a/Source/Tools/CommonTools/DummyHandlers.h +++ b/Source/Tools/CommonTools/DummyHandlers.h @@ -17,7 +17,7 @@ public: } // These are no-ops implementations of the SyscallHandler API - std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState&, uint64_t) override { + std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState*, uint64_t) override { return std::nullopt; } diff --git a/Source/Tools/FEXOfflineCompiler/Main.cpp b/Source/Tools/FEXOfflineCompiler/Main.cpp index d90750792..e6d43b731 100644 --- a/Source/Tools/FEXOfflineCompiler/Main.cpp +++ b/Source/Tools/FEXOfflineCompiler/Main.cpp @@ -37,7 +37,7 @@ public: uintptr_t VAFileStart = 0; // These are no-ops implementations of the SyscallHandler API - std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState&, uint64_t Address) override { + std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState*, uint64_t Address) override { auto It = FileRanges.upper_bound(Address - VAFileStart); LOGMAN_THROW_A_FMT(It != FileRanges.begin(), "Could not find associated file mapping"); --It; @@ -180,7 +180,7 @@ GenerateSingleCache(const FEXCore::ExecutableFileInfo& Binary, fextl::setLookupExecutableFileSection(*Thread, SyscallHandler->VAFileStart).value(); + auto Entry = SyscallHandler->LookupExecutableFileSection(Thread, SyscallHandler->VAFileStart).value(); CTX->GetCodeCache().SaveData(*Thread, fd, Entry, 0 /* TODO: Use static base address information if available */); } std::filesystem::rename(FilenameNew.c_str(), Filename.c_str()); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h index efe798710..d044378c6 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h @@ -290,7 +290,7 @@ public: void MarkGuestExecutableRange(FEXCore::Core::InternalThreadState* Thread, uint64_t Start, uint64_t Length) override; void InvalidateGuestCodeRange(FEXCore::Core::InternalThreadState* Thread, uint64_t Start, uint64_t Length) override; std::optional - LookupExecutableFileSection(FEXCore::Core::InternalThreadState& Thread, uint64_t GuestAddr) final override; + LookupExecutableFileSection(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestAddr) final override; void TriggerPostStartupCodeCacheLoad(FEXCore::Core::InternalThreadState&); int OpenCodeMapFile() override; diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp index b4239a6d3..b13fc1ae2 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -178,8 +178,8 @@ static FEXCore::ExecutableFileSectionInfo BuildSectionInfo(const VMATracking::Ma } std::optional -SyscallHandler::LookupExecutableFileSection(FEXCore::Core::InternalThreadState& Thread, uint64_t GuestAddr) { - auto lk = FEXCore::GuardSignalDeferringSection(VMATracking.Mutex, &Thread); +SyscallHandler::LookupExecutableFileSection(FEXCore::Core::InternalThreadState* Thread, uint64_t GuestAddr) { + auto lk = FEXCore::GuardSignalDeferringSection(VMATracking.Mutex, Thread); auto EntryIt = VMATracking.FindVMAEntry(GuestAddr); if (EntryIt == VMATracking.VMAs.end() || !EntryIt->second.Resource || !EntryIt->second.Resource->MappedFile) { @@ -237,7 +237,7 @@ static void LoadCodeCache(FEXCore::Core::InternalThreadState& Thread, FEXCore::E auto CacheFileSize = buf.st_size; auto MappedCache = (std::byte*)FEXCore::Allocator::mmap(nullptr, CacheFileSize, PROT_READ, MAP_PRIVATE, CacheFD, 0); LOGMAN_THROW_A_FMT(MappedCache, "Failed to map code cache into memory"); - if (!Thread.CTX->GetCodeCache().LoadData(Thread, MappedCache, Section)) { + if (!Thread.CTX->GetCodeCache().LoadData(&Thread, MappedCache, Section)) { // TODO: Delete this cache file } FEXCore::Allocator::munmap(MappedCache, CacheFileSize); diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index c3110321a..c32ad7d7a 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -521,7 +521,7 @@ public: JumpSetStack(KiUserExceptionDispatcher, reinterpret_cast(&DispatchArgs)); } - std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState&, uint64_t) override { + std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState*, uint64_t Address) override { return std::nullopt; } diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 3b60257f9..752b771aa 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -454,7 +454,7 @@ public: return Ret; } - std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState&, uint64_t) override { + std::optional LookupExecutableFileSection(FEXCore::Core::InternalThreadState*, uint64_t Address) override { return std::nullopt; }