diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index c26a5d116..19ac4f33d 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -595,7 +595,7 @@ NTSTATUS ProcessInit() { CTX->InitCore(); Exception::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); - ImageTracker.emplace(*CTX); + ImageTracker.emplace(*CTX, false); auto MainModule = reinterpret_cast<__TEB*>(NtCurrentTeb())->Peb->ImageBaseAddress; HandleImageMap(reinterpret_cast(MainModule), true); diff --git a/Source/Windows/Common/ImageTracker.cpp b/Source/Windows/Common/ImageTracker.cpp index 35f9eaaf8..8131ccbb8 100644 --- a/Source/Windows/Common/ImageTracker.cpp +++ b/Source/Windows/Common/ImageTracker.cpp @@ -75,9 +75,10 @@ static void LoadImageVolatileMetadata(fextl::set& VolatileInstructions } } -ImageTracker::ImageTracker(FEXCore::Context::Context& CTX) +ImageTracker::ImageTracker(FEXCore::Context::Context& CTX, bool IsGeneratingCache) : CTX {CTX} - , ExtendedMetaData {FEX::VolatileMetadata::ParseExtendedVolatileMetadata(ExtendedVolatileMetadataConfig())} {} + , ExtendedMetaData {FEX::VolatileMetadata::ParseExtendedVolatileMetadata(ExtendedVolatileMetadataConfig())} + , IsGeneratingCache {IsGeneratingCache} {} ImageTracker::MappedImageInfo::MappedImageInfo(std::string_view Path, uint64_t Address, ArchImageNtHeaders* Nt, fextl::unordered_map Relocations) @@ -108,6 +109,25 @@ FEXCore::ExecutableFileSectionInfo ImageTracker::HandleImageMap(std::string_view auto ID = FEXCore::CodeMap::GetBaseFilename(ImageInfo->Info, false); LogMan::Msg::DFmt("Load module {} ({}): {:X}", ModuleName, ID, Address); + if (FEXCore::Config::Get_ENABLECODECACHINGWIP() && !IsGeneratingCache) { + if (MainImage) { + LARGE_INTEGER Time; + NtQuerySystemTime(&Time); + const auto CodeMapDir = fmt::format("{}codemap\\new\\", FEX::Config::GetCacheDirectory()); + std::error_code ec; + if (!std::filesystem::exists(CodeMapDir, ec)) { + std::filesystem::create_directories(CodeMapDir, ec); + } + if (!ec) { + ActiveCodeMapPath = fmt::format("{}{}.{}.bin", CodeMapDir, ID, Time.QuadPart); + + auto Writer = fextl::make_unique(*this, false); + Writer->AppendSetMainExecutable(ImageInfo->Info); + CTX.SetCodeMapWriter(std::move(Writer)); + } + } + } + uint64_t EndAddress = Address + Nt->OptionalHeader.SizeOfImage; fextl::set VolatileInstructions {}; FEXCore::IntervalList VolatileValidRanges {}; @@ -140,4 +160,11 @@ std::optional ImageTracker::LookupExecutable } return std::prev(It)->second.SectionInfo; } + +int ImageTracker::OpenCodeMapFile() { + if (ActiveCodeMapPath.empty()) { + return -1; + } + return _sopen(ActiveCodeMapPath.c_str(), O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, _SH_DENYRW, 0644); +} } // namespace FEX::Windows diff --git a/Source/Windows/Common/ImageTracker.h b/Source/Windows/Common/ImageTracker.h index f54efbe1a..e377f055a 100644 --- a/Source/Windows/Common/ImageTracker.h +++ b/Source/Windows/Common/ImageTracker.h @@ -36,14 +36,16 @@ FEXCore::CodeMapFileId ComputeCodeMapId(std::string_view FileName, uint32_t Time /** * @brief Tracks mapped PE code images and handles their volatile metadata */ -class ImageTracker { +class ImageTracker : public FEXCore::CodeMapOpener { public: - ImageTracker(FEXCore::Context::Context& CTX); + ImageTracker(FEXCore::Context::Context& CTX, bool IsGeneratingCache); FEXCore::ExecutableFileSectionInfo HandleImageMap(std::string_view Path, uint64_t Address, bool MainImage); void HandleImageUnmap(uint64_t Address, uint64_t Size); std::optional LookupExecutableFileSection(uint64_t Address); + int OpenCodeMapFile() override; + private: struct MappedImageInfo { FEXCore::ExecutableFileInfo Info; @@ -60,6 +62,9 @@ private: std::shared_mutex ImagesLock; std::map MappedImages; + + std::string ActiveCodeMapPath; + bool IsGeneratingCache; }; } // namespace FEX::Windows diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 5be957143..dfd015582 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -513,7 +513,7 @@ void BTCpuProcessInit() { CTX->InitCore(); Context::HandlerConfig.emplace(*CTX); InvalidationTracker.emplace(*CTX, Threads); - ImageTracker.emplace(*CTX); + ImageTracker.emplace(*CTX, false); auto MainModule = reinterpret_cast<__TEB*>(NtCurrentTeb())->Peb->ImageBaseAddress; HandleImageMap(reinterpret_cast(MainModule), true);