Skip to content

Commit

Permalink
Merge pull request #1670 from FEX-Emu/skmp/processwide-code-invalidat…
Browse files Browse the repository at this point in the history
…ions

Core: context-wide guest code invalidations
  • Loading branch information
Stefanos Kornilios Mitsis Poiitidis authored May 3, 2022
2 parents 8e36f53 + 09be28a commit d810988
Show file tree
Hide file tree
Showing 19 changed files with 136 additions and 94 deletions.
8 changes: 5 additions & 3 deletions External/FEXCore/Source/Interface/Context/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,13 @@ namespace FEXCore::Context {
void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required);
void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required);

static void RemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP);
// Must be called from owning thread
static void RemoveThreadCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP);

// Wrapper which takes CpuStateFrame instead of InternalThreadState
static void RemoveCodeEntryFromJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) {
RemoveCodeEntry(Frame->Thread, GuestRIP);
// Must be called from owning thread
static void RemoveThreadCodeEntryFromJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) {
RemoveThreadCodeEntry(Frame->Thread, GuestRIP);
}

// Debugger interface
Expand Down
38 changes: 27 additions & 11 deletions External/FEXCore/Source/Interface/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ namespace FEXCore::Context {
: nullptr),
decltype(Entry.DebugData)(new Core::DebugData())
};
std::lock_guard<std::recursive_mutex> lk(Thread->LookupCache->WriteLock);
Thread->LocalIRCache.insert({Addr, std::move(Entry)});
};

Expand Down Expand Up @@ -626,6 +627,8 @@ namespace FEXCore::Context {
}

void Context::ClearCodeCache(FEXCore::Core::InternalThreadState *Thread, bool AlsoClearIRCache) {
std::lock_guard<std::recursive_mutex> lk(Thread->LookupCache->WriteLock);

Thread->LookupCache->ClearCache();
Thread->CPUBackend->ClearCache();

Expand Down Expand Up @@ -738,7 +741,7 @@ namespace FEXCore::Context {
Thread->OpDispatcher->SetTrueJumpTarget(InvalidateCodeCond, CodeWasChangedBlock);

Thread->OpDispatcher->SetCurrentCodeBlock(CodeWasChangedBlock);
Thread->OpDispatcher->_RemoveCodeEntry();
Thread->OpDispatcher->_RemoveThreadCodeEntry();
Thread->OpDispatcher->_ExitFunction(Thread->OpDispatcher->_EntrypointOffset(Block.Entry + BlockInstructionsLength - GuestRIP, GPRSize));

auto NextOpBlock = Thread->OpDispatcher->CreateNewCodeBlockAfter(CurrentBlock);
Expand Down Expand Up @@ -847,6 +850,7 @@ namespace FEXCore::Context {
uint64_t StartAddr {};
uint64_t Length {};

std::lock_guard<std::recursive_mutex> lk(Thread->LookupCache->WriteLock);
// Do we already have this in the IR cache?
auto LocalEntry = Thread->LocalIRCache.find(GuestRIP);

Expand Down Expand Up @@ -1033,21 +1037,32 @@ namespace FEXCore::Context {
}
}

void FlushCodeRange(FEXCore::Core::InternalThreadState *Thread, uint64_t Start, uint64_t Length) {
static void InvalidateGuestThreadCodeRange(FEXCore::Core::InternalThreadState *Thread, uint64_t Start, uint64_t Length) {
std::lock_guard<std::recursive_mutex> lk(Thread->LookupCache->WriteLock);

if (Thread->CTX->Config.SMCChecks == FEXCore::Config::CONFIG_SMC_MMAN) {
auto lower = Thread->LookupCache->CodePages.lower_bound(Start >> 12);
auto upper = Thread->LookupCache->CodePages.upper_bound((Start + Length) >> 12);
auto lower = Thread->LookupCache->CodePages.lower_bound(Start >> 12);
auto upper = Thread->LookupCache->CodePages.upper_bound((Start + Length - 1) >> 12);

for (auto it = lower; it != upper; it++) {
for (auto Address: it->second)
Context::RemoveCodeEntry(Thread, Address);
it->second.clear();
for (auto it = lower; it != upper; it++) {
for (auto Address: it->second) {
Context::RemoveThreadCodeEntry(Thread, Address);
}
it->second.clear();
}
}

void Context::RemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) {
void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length) {
std::lock_guard<std::mutex> lk(CTX->ThreadCreationMutex);
for (auto &Thread : CTX->Threads) {
if (Thread->RunningEvents.Running.load()) {
InvalidateGuestThreadCodeRange(Thread, Start, Length);
}
}
}

void Context::RemoveThreadCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) {
std::lock_guard<std::recursive_mutex> lk(Thread->LookupCache->WriteLock);

Thread->LocalIRCache.erase(GuestRIP);
Thread->LookupCache->Erase(GuestRIP);
}
Expand All @@ -1058,7 +1073,7 @@ namespace FEXCore::Context {
Thread->CurrentFrame->State.rip = RIP;

// Erase the RIP from all the storage backings if it exists
RemoveCodeEntry(Thread, RIP);
RemoveThreadCodeEntry(Thread, RIP);

// We don't care if compilation passes or not
CompileBlock(Thread->CurrentFrame, RIP);
Expand All @@ -1075,6 +1090,7 @@ namespace FEXCore::Context {
}

bool Context::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) {
std::lock_guard<std::recursive_mutex> lk(ParentThread->LookupCache->WriteLock);
auto it = ParentThread->LocalIRCache.find(RIP);
if (it == ParentThread->LocalIRCache.end()) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ DEF_OP(ValidateCode) {
}
}

DEF_OP(RemoveCodeEntry) {
Data->State->CTX->RemoveCodeEntry(Data->State, Data->CurrentEntry);
DEF_OP(RemoveThreadCodeEntry) {
Data->State->CTX->RemoveThreadCodeEntry(Data->State, Data->CurrentEntry);
}

DEF_OP(CPUID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ constexpr OpHandlerArray InterpreterOpHandlers = [] {
REGISTER_OP(INLINESYSCALL, InlineSyscall);
REGISTER_OP(THUNK, Thunk);
REGISTER_OP(VALIDATECODE, ValidateCode);
REGISTER_OP(REMOVECODEENTRY, RemoveCodeEntry);
REGISTER_OP(REMOVETHREADCODEENTRY, RemoveThreadCodeEntry);
REGISTER_OP(CPUID, CPUID);

// Conversion ops
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace FEXCore::CPU {
DEF_OP(InlineSyscall);
DEF_OP(Thunk);
DEF_OP(ValidateCode);
DEF_OP(RemoveCodeEntry);
DEF_OP(RemoveThreadCodeEntry);
DEF_OP(CPUID);

///< Conversion ops
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ DEF_OP(ValidateCode) {
}
}

DEF_OP(RemoveCodeEntry) {
DEF_OP(RemoveThreadCodeEntry) {
// Arguments are passed as follows:
// X0: Thread
// X1: RIP
Expand All @@ -452,7 +452,7 @@ DEF_OP(RemoveCodeEntry) {
mov(x0, STATE);
LoadConstant(x1, Entry);

ldr(x2, MemOperand(STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.AArch64.RemoveCodeEntryFromJIT)));
ldr(x2, MemOperand(STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.AArch64.RemoveThreadCodeEntryFromJIT)));
SpillStaticRegs();
blr(x2);
FillStaticRegs();
Expand Down Expand Up @@ -500,7 +500,7 @@ void Arm64JITCore::RegisterBranchHandlers() {
REGISTER_OP(INLINESYSCALL, InlineSyscall);
REGISTER_OP(THUNK, Thunk);
REGISTER_OP(VALIDATECODE, ValidateCode);
REGISTER_OP(REMOVECODEENTRY, RemoveCodeEntry);
REGISTER_OP(REMOVETHREADCODEENTRY, RemoveThreadCodeEntry);
REGISTER_OP(CPUID, CPUID);
#undef REGISTER_OP
}
Expand Down
2 changes: 1 addition & 1 deletion External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern
Pointers.LREM = reinterpret_cast<uint64_t>(LREM);
Pointers.PrintValue = reinterpret_cast<uint64_t>(PrintValue);
Pointers.PrintVectorValue = reinterpret_cast<uint64_t>(PrintVectorValue);
Pointers.RemoveCodeEntryFromJIT = reinterpret_cast<uintptr_t>(&Context::Context::RemoveCodeEntryFromJit);
Pointers.RemoveThreadCodeEntryFromJIT = reinterpret_cast<uintptr_t>(&Context::Context::RemoveThreadCodeEntryFromJit);
Pointers.CPUIDObj = reinterpret_cast<uint64_t>(&CTX->CPUID);

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class Arm64JITCore final : public CPUBackend, public Arm64Emitter {
DEF_OP(InlineSyscall);
DEF_OP(Thunk);
DEF_OP(ValidateCode);
DEF_OP(RemoveCodeEntry);
DEF_OP(RemoveThreadCodeEntry);
DEF_OP(CPUID);

///< Conversion ops
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ DEF_OP(ValidateCode) {
}
}

DEF_OP(RemoveCodeEntry) {
DEF_OP(RemoveThreadCodeEntry) {
auto NumPush = RA64.size();

for (auto &Reg : RA64)
Expand All @@ -272,7 +272,7 @@ DEF_OP(RemoveCodeEntry) {
mov(rax, Entry); // imm64 move
mov(rsi, rax);

call(qword [STATE + offsetof(FEXCore::Core::CpuStateFrame, Pointers.X86.RemoveCodeEntryFromJIT)]);
call(qword [STATE + offsetof(FEXCore::Core::CpuStateFrame, Pointers.X86.RemoveThreadCodeEntryFromJIT)]);

if (NumPush & 1)
add(rsp, 8); // Align
Expand Down Expand Up @@ -330,7 +330,7 @@ void X86JITCore::RegisterBranchHandlers() {
REGISTER_OP(SYSCALL, Syscall);
REGISTER_OP(THUNK, Thunk);
REGISTER_OP(VALIDATECODE, ValidateCode);
REGISTER_OP(REMOVECODEENTRY, RemoveCodeEntry);
REGISTER_OP(REMOVETHREADCODEENTRY, RemoveThreadCodeEntry);
REGISTER_OP(CPUID, CPUID);
#undef REGISTER_OP
}
Expand Down
2 changes: 1 addition & 1 deletion External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh
// Process specific
Pointers.PrintValue = reinterpret_cast<uint64_t>(PrintValue);
Pointers.PrintVectorValue = reinterpret_cast<uint64_t>(PrintVectorValue);
Pointers.RemoveCodeEntryFromJIT = reinterpret_cast<uintptr_t>(&Context::Context::RemoveCodeEntryFromJit);
Pointers.RemoveThreadCodeEntryFromJIT = reinterpret_cast<uintptr_t>(&Context::Context::RemoveThreadCodeEntryFromJit);
Pointers.CPUIDObj = reinterpret_cast<uint64_t>(&CTX->CPUID);

{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator {
DEF_OP(Syscall);
DEF_OP(Thunk);
DEF_OP(ValidateCode);
DEF_OP(RemoveCodeEntry);
DEF_OP(RemoveThreadCodeEntry);
DEF_OP(CPUID);

///< Conversion ops
Expand Down
3 changes: 3 additions & 0 deletions External/FEXCore/Source/Interface/Core/LookupCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,16 @@ void LookupCache::HintUsedRange(uint64_t Address, uint64_t Size) {
}

void LookupCache::ClearL2Cache() {
std::lock_guard<std::recursive_mutex> lk(WriteLock);
// Clear out the page memory
madvise(reinterpret_cast<void*>(PagePointer), ctx->Config.VirtualMemSize / 4096 * 8, MADV_DONTNEED);
madvise(reinterpret_cast<void*>(PageMemory), CODE_SIZE, MADV_DONTNEED);
AllocateOffset = 0;
}

void LookupCache::ClearCache() {
std::lock_guard<std::recursive_mutex> lk(WriteLock);

// Clear L1
madvise(reinterpret_cast<void*>(L1Pointer), L1_SIZE, MADV_DONTNEED);
// Clear L2
Expand Down
Loading

0 comments on commit d810988

Please sign in to comment.