diff --git a/FEXCore/Source/Interface/Core/Core.cpp b/FEXCore/Source/Interface/Core/Core.cpp index 6df445e5e..4f832f200 100644 --- a/FEXCore/Source/Interface/Core/Core.cpp +++ b/FEXCore/Source/Interface/Core/Core.cpp @@ -773,8 +773,9 @@ ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalT } uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame* Frame, uint64_t GuestRIP, uint64_t MaxInst) { - FEXCORE_PROFILE_SCOPED("CompileBlock"); auto Thread = Frame->Thread; + FEXCORE_PROFILE_SCOPED("CompileBlock"); + FEXCORE_PROFILE_ACCUMULATION(Thread, AccumulatedJITTime); // Invalidate might take a unique lock on this, to guarantee that during invalidation no code gets compiled auto lk = GuardSignalDeferringSection(CodeInvalidationMutex, Thread); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp index 2c332fe5c..959f49983 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp @@ -59,6 +59,7 @@ static FEX::HLE::ThreadStateObject* GetThreadFromAltStack(const stack_t& alt_sta static void SignalHandlerThunk(int Signal, siginfo_t* Info, void* UContext) { ucontext_t* _context = (ucontext_t*)UContext; auto ThreadObject = GetThreadFromAltStack(_context->uc_stack); + FEXCORE_PROFILE_ACCUMULATION(ThreadObject->Thread, AccumulatedSignalTime); ThreadObject->SignalInfo.Delegator->HandleSignal(ThreadObject, Signal, Info, UContext); } @@ -916,6 +917,7 @@ SignalDelegator::SignalDelegator(FEXCore::Context::Context* _CTX, const std::str return false; } + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSIGBUSCount, 1); const auto Delegator = FEX::HLE::ThreadManager::GetStateObjectFromFEXCoreThread(Thread)->SignalInfo.Delegator; const auto Result = FEXCore::ArchHelpers::Arm64::HandleUnalignedAccess(Thread, Delegator->GetUnalignedHandlerType(), PC, ArchHelpers::Context::GetArmGPRs(ucontext)); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp index b81242d95..8edfa70c4 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -97,6 +97,7 @@ bool SyscallHandler::HandleSegfault(FEXCore::Core::InternalThreadState* Thread, }); } + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSMCCount, 1); return true; } } diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index 07c299734..1b57b96cd 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -256,12 +256,14 @@ struct alignas(16) KiUserExceptionDispatcherStackLayout { }; static bool HandleUnalignedAccess(ARM64_NT_CONTEXT& Context) { - if (!CTX->IsAddressInCodeBuffer(GetCPUArea().ThreadState(), Context.Pc)) { + auto Thread = GetCPUArea().ThreadState(); + if (!CTX->IsAddressInCodeBuffer(Thread, Context.Pc)) { return false; } - const auto Result = FEXCore::ArchHelpers::Arm64::HandleUnalignedAccess(GetCPUArea().ThreadState(), - HandlerConfig->GetUnalignedHandlerType(), Context.Pc, &Context.X0); + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSIGBUSCount, 1); + const auto Result = + FEXCore::ArchHelpers::Arm64::HandleUnalignedAccess(Thread, HandlerConfig->GetUnalignedHandlerType(), Context.Pc, &Context.X0); if (!Result.first) { return false; } @@ -591,19 +593,22 @@ public: // Returns true if exception dispatch should be halted and the execution context restored to NativeContext bool ResetToConsistentStateImpl(EXCEPTION_RECORD* Exception, CONTEXT* GuestContext, ARM64_NT_CONTEXT* NativeContext) { const auto CPUArea = GetCPUArea(); + auto Thread = CPUArea.ThreadState(); + FEXCORE_PROFILE_ACCUMULATION(Thread, AccumulatedSignalTime); LogMan::Msg::DFmt("Exception: Code: {:X} Address: {:X}", Exception->ExceptionCode, reinterpret_cast(Exception->ExceptionAddress)); - if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && CPUArea.ThreadState() && InvalidationTracker) { + if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && Thread && InvalidationTracker) { const auto FaultAddress = static_cast(Exception->ExceptionInformation[1]); std::scoped_lock Lock(ThreadCreationMutex); if (InvalidationTracker->HandleRWXAccessViolation(FaultAddress)) { - if (CTX->IsAddressInCodeBuffer(CPUArea.ThreadState(), NativeContext->Pc) && !CTX->IsCurrentBlockSingleInst(CPUArea.ThreadState()) && - CTX->IsAddressInCurrentBlock(CPUArea.ThreadState(), FaultAddress, 8)) { + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSMCCount, 1); + if (CTX->IsAddressInCodeBuffer(Thread, NativeContext->Pc) && !CTX->IsCurrentBlockSingleInst(CPUArea.ThreadState()) && + CTX->IsAddressInCurrentBlock(Thread, FaultAddress, 8)) { // If we are not patching ourself (single inst block case) and patching the current block, this is inline SMC. Reconstruct the current context (before the SMC write) then single step the write to reduce it to regular SMC. - Exception::ReconstructThreadState(CPUArea.ThreadState(), *NativeContext); + Exception::ReconstructThreadState(Thread, *NativeContext); LogMan::Msg::DFmt("Handled inline self-modifying code: pc: {:X} rip: {:X} fault: {:X}", NativeContext->Pc, - CPUArea.ThreadState()->CurrentFrame->State.rip, FaultAddress); + Thread->CurrentFrame->State.rip, FaultAddress); NativeContext->Pc = CPUArea.DispatcherLoopTopEnterECFillSRA(); NativeContext->Sp = CPUArea.EmulatorStackBase(); NativeContext->X10 = 1; // Set ENTRY_FILL_SRA_SINGLE_INST_REG to force a single step diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 75ef7ac5f..8815e404a 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -520,6 +520,8 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { return; } + auto* OldThreadState = TLS.ThreadState(); + THREAD_BASIC_INFORMATION Info; if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { return; @@ -531,7 +533,7 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { Threads.erase(ThreadTID); } - CTX->DestroyThread(TLS.ThreadState()); + CTX->DestroyThread(OldThreadState); if (ThreadTID == GetCurrentThreadId()) { FEX::Windows::DeinitCRTThread(); } @@ -687,6 +689,7 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) { auto* Context = Ptrs->ContextRecord; auto* Exception = Ptrs->ExceptionRecord; auto Thread = GetTLS().ThreadState(); + FEXCORE_PROFILE_ACCUMULATION(Thread, AccumulatedSignalTime); if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { const auto FaultAddress = static_cast(Exception->ExceptionInformation[1]); @@ -702,6 +705,7 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) { if (Thread) { std::scoped_lock Lock(ThreadCreationMutex); + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSMCCount, 1); if (InvalidationTracker->HandleRWXAccessViolation(FaultAddress)) { LogMan::Msg::DFmt("Handled self-modifying code: pc: {:X} fault: {:X}", Context->Pc, FaultAddress); return true; @@ -713,6 +717,7 @@ bool BTCpuResetToConsistentStateImpl(EXCEPTION_POINTERS* Ptrs) { return false; } + FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSIGBUSCount, 1); if (Exception->ExceptionCode == EXCEPTION_DATATYPE_MISALIGNMENT && Context::HandleUnalignedAccess(Context)) { LogMan::Msg::DFmt("Handled unaligned atomic: new pc: {:X}", Context->Pc); return true;