jit: Lock around changes to the jit pointer.

This commit is contained in:
Unknown W. Brackets 2021-11-27 16:11:51 -08:00
parent 0c6c2fb47a
commit b8ab7f39df
17 changed files with 87 additions and 33 deletions

View file

@ -633,23 +633,25 @@ bool CBreakPoints::HasMemChecks()
return !memChecks_.empty(); return !memChecks_.empty();
} }
void CBreakPoints::Update(u32 addr) void CBreakPoints::Update(u32 addr) {
{ if (MIPSComp::jit) {
if (MIPSComp::jit)
{
bool resume = false; bool resume = false;
if (Core_IsStepping() == false) if (Core_IsStepping() == false) {
{
Core_EnableStepping(true, "cpu.breakpoint.update", addr); Core_EnableStepping(true, "cpu.breakpoint.update", addr);
Core_WaitInactive(200); Core_WaitInactive(200);
resume = true; resume = true;
} }
// In case this is a delay slot, clear the previous instruction too. {
if (addr != 0) std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit->InvalidateCacheAt(addr - 4, 8); if (MIPSComp::jit) {
else // In case this is a delay slot, clear the previous instruction too.
MIPSComp::jit->ClearCache(); if (addr != 0)
MIPSComp::jit->InvalidateCacheAt(addr - 4, 8);
else
MIPSComp::jit->ClearCache();
}
}
if (resume) if (resume)
Core_EnableStepping(false); Core_EnableStepping(false);

View file

@ -17,6 +17,7 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <mutex>
#include "Common/Data/Encoding/Base64.h" #include "Common/Data/Encoding/Base64.h"
#include "Common/StringUtils.h" #include "Common/StringUtils.h"
#include "Core/Core.h" #include "Core/Core.h"
@ -67,6 +68,7 @@ static AutoDisabledReplacements LockMemoryAndCPU(uint32_t addr, bool keepReplace
result.saved = true; result.saved = true;
// Okay, save so we can restore later. // Okay, save so we can restore later.
result.replacements = SaveAndClearReplacements(); result.replacements = SaveAndClearReplacements();
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) if (MIPSComp::jit)
result.emuhacks = MIPSComp::jit->SaveAndClearEmuHackOps(); result.emuhacks = MIPSComp::jit->SaveAndClearEmuHackOps();
} }
@ -75,6 +77,7 @@ static AutoDisabledReplacements LockMemoryAndCPU(uint32_t addr, bool keepReplace
AutoDisabledReplacements::~AutoDisabledReplacements() { AutoDisabledReplacements::~AutoDisabledReplacements() {
if (saved) { if (saved) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) if (MIPSComp::jit)
MIPSComp::jit->RestoreSavedEmuHackOps(emuhacks); MIPSComp::jit->RestoreSavedEmuHackOps(emuhacks);
RestoreSavedReplacements(replacements); RestoreSavedReplacements(replacements);

View file

@ -1476,6 +1476,7 @@ void __KernelLoadContext(PSPThreadContext *ctx, bool vfpuEnabled) {
} }
memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other));
// Not locking here, we assume the jit isn't switched during execution.
if (MIPSComp::jit) { if (MIPSComp::jit) {
// When thread switching, we must update the rounding mode if cached in the jit. // When thread switching, we must update the rounding mode if cached in the jit.
MIPSComp::jit->UpdateFCR31(); MIPSComp::jit->UpdateFCR31();

View file

@ -17,6 +17,7 @@
#include "ppsspp_config.h" #include "ppsspp_config.h"
#include <cstdlib> #include <cstdlib>
#include <mutex>
#include "ext/disarm.h" #include "ext/disarm.h"
#include "ext/udis86/udis86.h" #include "ext/udis86/udis86.h"
@ -46,6 +47,8 @@
namespace MIPSComp { namespace MIPSComp {
JitInterface *jit; JitInterface *jit;
std::recursive_mutex jitLock;
void JitAt() { void JitAt() {
jit->Compile(currentMIPS->pc); jit->Compile(currentMIPS->pc);
} }
@ -135,6 +138,7 @@ std::string AddAddress(const std::string &buf, uint64_t addr) {
#if PPSSPP_ARCH(ARM64) || defined(DISASM_ALL) #if PPSSPP_ARCH(ARM64) || defined(DISASM_ALL)
static bool Arm64SymbolCallback(char *buffer, int bufsize, uint8_t *address) { static bool Arm64SymbolCallback(char *buffer, int bufsize, uint8_t *address) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) { if (MIPSComp::jit) {
std::string name; std::string name;
if (MIPSComp::jit->DescribeCodePtr(address, name)) { if (MIPSComp::jit->DescribeCodePtr(address, name)) {
@ -196,7 +200,7 @@ std::vector<std::string> DisassembleArm64(const u8 *data, int size) {
const char *ppsspp_resolver(struct ud*, const char *ppsspp_resolver(struct ud*,
uint64_t addr, uint64_t addr,
int64_t *offset) { int64_t *offset) {
// For some reason these two don't seem to trigger.. // For some reason these don't seem to trigger..
if (addr >= (uint64_t)(&currentMIPS->r[0]) && addr < (uint64_t)&currentMIPS->r[32]) { if (addr >= (uint64_t)(&currentMIPS->r[0]) && addr < (uint64_t)&currentMIPS->r[32]) {
*offset = addr - (uint64_t)(&currentMIPS->r[0]); *offset = addr - (uint64_t)(&currentMIPS->r[0]);
return "mips.r"; return "mips.r";
@ -226,7 +230,9 @@ const char *ppsspp_resolver(struct ud*,
// UGLY HACK because the API is terrible // UGLY HACK because the API is terrible
static char buf[128]; static char buf[128];
std::string str; std::string str;
if (MIPSComp::jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) {
*offset = 0; *offset = 0;
truncate_cpy(buf, sizeof(buf), str.c_str()); truncate_cpy(buf, sizeof(buf), str.c_str());
return buf; return buf;

View file

@ -17,8 +17,9 @@
#pragma once #pragma once
#include <vector> #include <mutex>
#include <string> #include <string>
#include <vector>
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -154,6 +155,7 @@ namespace MIPSComp {
typedef int (MIPSFrontendInterface::*MIPSReplaceFunc)(); typedef int (MIPSFrontendInterface::*MIPSReplaceFunc)();
extern JitInterface *jit; extern JitInterface *jit;
extern std::recursive_mutex jitLock;
void DoDummyJitState(PointerWrap &p); void DoDummyJitState(PointerWrap &p);

View file

@ -17,6 +17,7 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <mutex>
#include "Common/Math/math_util.h" #include "Common/Math/math_util.h"
@ -163,6 +164,7 @@ MIPSState::~MIPSState() {
} }
void MIPSState::Shutdown() { void MIPSState::Shutdown() {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::JitInterface *oldjit = MIPSComp::jit; MIPSComp::JitInterface *oldjit = MIPSComp::jit;
if (oldjit) { if (oldjit) {
MIPSComp::jit = nullptr; MIPSComp::jit = nullptr;
@ -210,6 +212,7 @@ void MIPSState::Init() {
// Initialize the VFPU random number generator with .. something? // Initialize the VFPU random number generator with .. something?
rng.Init(0x1337); rng.Init(0x1337);
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (PSP_CoreParameter().cpuCore == CPUCore::JIT) { if (PSP_CoreParameter().cpuCore == CPUCore::JIT) {
MIPSComp::jit = MIPSComp::CreateNativeJit(this); MIPSComp::jit = MIPSComp::CreateNativeJit(this);
} else if (PSP_CoreParameter().cpuCore == CPUCore::IR_JIT) { } else if (PSP_CoreParameter().cpuCore == CPUCore::IR_JIT) {
@ -230,31 +233,41 @@ void MIPSState::UpdateCore(CPUCore desired) {
PSP_CoreParameter().cpuCore = desired; PSP_CoreParameter().cpuCore = desired;
MIPSComp::JitInterface *oldjit = MIPSComp::jit; MIPSComp::JitInterface *oldjit = MIPSComp::jit;
MIPSComp::JitInterface *newjit = nullptr;
switch (PSP_CoreParameter().cpuCore) { switch (PSP_CoreParameter().cpuCore) {
case CPUCore::JIT: case CPUCore::JIT:
INFO_LOG(CPU, "Switching to JIT"); INFO_LOG(CPU, "Switching to JIT");
if (oldjit) { if (oldjit) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit = nullptr; MIPSComp::jit = nullptr;
delete oldjit; delete oldjit;
} }
MIPSComp::jit = MIPSComp::CreateNativeJit(this); newjit = MIPSComp::CreateNativeJit(this);
break; break;
case CPUCore::IR_JIT: case CPUCore::IR_JIT:
INFO_LOG(CPU, "Switching to IRJIT"); INFO_LOG(CPU, "Switching to IRJIT");
if (oldjit) { if (oldjit) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit = nullptr; MIPSComp::jit = nullptr;
delete oldjit; delete oldjit;
} }
MIPSComp::jit = new MIPSComp::IRJit(this); newjit = new MIPSComp::IRJit(this);
break; break;
case CPUCore::INTERPRETER: case CPUCore::INTERPRETER:
INFO_LOG(CPU, "Switching to interpreter"); INFO_LOG(CPU, "Switching to interpreter");
MIPSComp::jit = nullptr; if (oldjit) {
delete oldjit; std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit = nullptr;
delete oldjit;
}
break; break;
} }
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit = newjit;
} }
void MIPSState::DoState(PointerWrap &p) { void MIPSState::DoState(PointerWrap &p) {
@ -265,6 +278,7 @@ void MIPSState::DoState(PointerWrap &p) {
// Reset the jit if we're loading. // Reset the jit if we're loading.
if (p.mode == p.MODE_READ) if (p.mode == p.MODE_READ)
Reset(); Reset();
// Assume we're not saving state during a CPU core reset, so no lock.
if (MIPSComp::jit) if (MIPSComp::jit)
MIPSComp::jit->DoState(p); MIPSComp::jit->DoState(p);
else else
@ -332,11 +346,13 @@ int MIPSState::RunLoopUntil(u64 globalTicks) {
void MIPSState::InvalidateICache(u32 address, int length) { void MIPSState::InvalidateICache(u32 address, int length) {
// Only really applies to jit. // Only really applies to jit.
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) if (MIPSComp::jit)
MIPSComp::jit->InvalidateCacheAt(address, length); MIPSComp::jit->InvalidateCacheAt(address, length);
} }
void MIPSState::ClearJitCache() { void MIPSState::ClearJitCache() {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) if (MIPSComp::jit)
MIPSComp::jit->ClearCache(); MIPSComp::jit->ClearCache();
} }

View file

@ -917,6 +917,7 @@ skip:
void PrecompileFunction(u32 startAddr, u32 length) { void PrecompileFunction(u32 startAddr, u32 length) {
// Direct calls to this ignore the bPreloadFunctions flag, since it's just for stubs. // Direct calls to this ignore the bPreloadFunctions flag, since it's just for stubs.
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) { if (MIPSComp::jit) {
MIPSComp::jit->CompileFunction(startAddr, length); MIPSComp::jit->CompileFunction(startAddr, length);
} }

View file

@ -38,6 +38,7 @@ public:
Memory::Memcpy((u32)address, data, (u32)length, "Debugger"); Memory::Memcpy((u32)address, data, (u32)length, "Debugger");
// In case this is a delay slot or combined instruction, clear cache above it too. // In case this is a delay slot or combined instruction, clear cache above it too.
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) if (MIPSComp::jit)
MIPSComp::jit->InvalidateCacheAt((u32)(address - 4),(int)length+4); MIPSComp::jit->InvalidateCacheAt((u32)(address - 4),(int)length+4);

View file

@ -105,7 +105,8 @@ namespace MIPSInt
switch (func) { switch (func) {
// Icache // Icache
case 8: case 8:
// Invalidate the instruction cache at this address // Invalidate the instruction cache at this address.
// We assume the CPU won't be reset during this, so no locking.
if (MIPSComp::jit) { if (MIPSComp::jit) {
MIPSComp::jit->InvalidateCacheAt(addr, 0x40); MIPSComp::jit->InvalidateCacheAt(addr, 0x40);
} }
@ -515,6 +516,7 @@ namespace MIPSInt
if (fs == 31) { if (fs == 31) {
currentMIPS->fcr31 = value & 0x0181FFFF; currentMIPS->fcr31 = value & 0x0181FFFF;
currentMIPS->fpcond = (value >> 23) & 1; currentMIPS->fpcond = (value >> 23) & 1;
// Don't bother locking, assuming the CPU can't be reset now anyway.
if (MIPSComp::jit) { if (MIPSComp::jit) {
// In case of DISABLE, we need to tell jit we updated FCR31. // In case of DISABLE, we need to tell jit we updated FCR31.
MIPSComp::jit->UpdateFCR31(); MIPSComp::jit->UpdateFCR31();

View file

@ -19,6 +19,7 @@
#include <cstdint> #include <cstdint>
#include <unordered_set> #include <unordered_set>
#include <mutex>
#include "Common/MachineContext.h" #include "Common/MachineContext.h"
@ -89,6 +90,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
SContext *context = (SContext *)ctx; SContext *context = (SContext *)ctx;
const uint8_t *codePtr = (uint8_t *)(context->CTX_PC); const uint8_t *codePtr = (uint8_t *)(context->CTX_PC);
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
// We set this later if we think it can be resumed from. // We set this later if we think it can be resumed from.
g_lastCrashAddress = nullptr; g_lastCrashAddress = nullptr;

View file

@ -413,6 +413,7 @@ __forceinline static Opcode Read_Instruction(u32 address, bool resolveReplacemen
return inst; return inst;
} }
// No mutex on jit access here, but we assume the caller has locked, if necessary.
if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) { if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
inst = MIPSComp::jit->GetOriginalOp(inst); inst = MIPSComp::jit->GetOriginalOp(inst);
if (resolveReplacements && MIPS_IS_REPLACEMENT(inst)) { if (resolveReplacements && MIPS_IS_REPLACEMENT(inst)) {
@ -461,6 +462,7 @@ Opcode ReadUnchecked_Instruction(u32 address, bool resolveReplacements)
Opcode Read_Opcode_JIT(u32 address) Opcode Read_Opcode_JIT(u32 address)
{ {
Opcode inst = Opcode(Read_U32(address)); Opcode inst = Opcode(Read_U32(address));
// No mutex around jit access here, but we assume caller has if necessary.
if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) { if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
return MIPSComp::jit->GetOriginalOp(inst); return MIPSComp::jit->GetOriginalOp(inst);
} else { } else {

View file

@ -303,15 +303,19 @@ namespace SaveState
// Memory is a bit tricky when jit is enabled, since there's emuhacks in it. // Memory is a bit tricky when jit is enabled, since there's emuhacks in it.
auto savedReplacements = SaveAndClearReplacements(); auto savedReplacements = SaveAndClearReplacements();
if (MIPSComp::jit && p.mode == p.MODE_WRITE) if (MIPSComp::jit && p.mode == p.MODE_WRITE) {
{ std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
std::vector<u32> savedBlocks; if (MIPSComp::jit) {
savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps(); std::vector<u32> savedBlocks;
savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps();
Memory::DoState(p);
MIPSComp::jit->RestoreSavedEmuHackOps(savedBlocks);
} else {
Memory::DoState(p);
}
} else {
Memory::DoState(p); Memory::DoState(p);
MIPSComp::jit->RestoreSavedEmuHackOps(savedBlocks);
} }
else
Memory::DoState(p);
RestoreSavedReplacements(savedReplacements); RestoreSavedReplacements(savedReplacements);
MemoryStick_DoState(p); MemoryStick_DoState(p);

View file

@ -136,6 +136,7 @@ void CwCheatScreen::onFinish(DialogResult result) {
if (result != DR_BACK) // This only works for BACK here. if (result != DR_BACK) // This only works for BACK here.
return; return;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) { if (MIPSComp::jit) {
MIPSComp::jit->ClearCache(); MIPSComp::jit->ClearCache();
} }
@ -167,6 +168,7 @@ UI::EventReturn CwCheatScreen::OnAddCheat(UI::EventParams &params) {
UI::EventReturn CwCheatScreen::OnEditCheatFile(UI::EventParams &params) { UI::EventReturn CwCheatScreen::OnEditCheatFile(UI::EventParams &params) {
g_Config.bReloadCheats = true; g_Config.bReloadCheats = true;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) { if (MIPSComp::jit) {
MIPSComp::jit->ClearCache(); MIPSComp::jit->ClearCache();
} }

View file

@ -910,6 +910,7 @@ void JitCompareScreen::UpdateDisasm() {
} }
UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }
@ -929,6 +930,7 @@ UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) {
} }
UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) { UI::EventReturn JitCompareScreen::OnShowStats(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }
@ -976,6 +978,7 @@ UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) {
} }
UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }
@ -994,6 +997,7 @@ UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
} }
UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) { UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }
@ -1021,6 +1025,7 @@ UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) {
} }
void JitCompareScreen::OnRandomBlock(int flag) { void JitCompareScreen::OnRandomBlock(int flag) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return; return;
} }
@ -1056,6 +1061,7 @@ void JitCompareScreen::OnRandomBlock(int flag) {
} }
UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) { UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) { if (!MIPSComp::jit) {
return UI::EVENT_DONE; return UI::EVENT_DONE;
} }

View file

@ -376,13 +376,13 @@ void DrawGameBackground(UIContext &dc, const Path &gamePath, float x, float y, f
void HandleCommonMessages(const char *message, const char *value, ScreenManager *manager, Screen *activeScreen) { void HandleCommonMessages(const char *message, const char *value, ScreenManager *manager, Screen *activeScreen) {
bool isActiveScreen = manager->topScreen() == activeScreen; bool isActiveScreen = manager->topScreen() == activeScreen;
if (!strcmp(message, "clear jit")) { if (!strcmp(message, "clear jit") && PSP_IsInited()) {
if (MIPSComp::jit && PSP_IsInited()) { if (MIPSComp::jit) {
MIPSComp::jit->ClearCache(); std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
} if (MIPSComp::jit)
if (PSP_IsInited()) { MIPSComp::jit->ClearCache();
currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore);
} }
currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore);
} else if (!strcmp(message, "control mapping") && isActiveScreen && activeScreen->tag() != "control mapping") { } else if (!strcmp(message, "control mapping") && isActiveScreen && activeScreen->tag() != "control mapping") {
UpdateUIState(UISTATE_MENU); UpdateUIState(UISTATE_MENU);
manager->push(new ControlMappingScreen()); manager->push(new ControlMappingScreen());

View file

@ -1,5 +1,6 @@
#include <algorithm> #include <algorithm>
#include <cstdio> #include <cstdio>
#include <mutex>
#include "Common/Data/Encoding/Utf8.h" #include "Common/Data/Encoding/Utf8.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/HLE/ReplaceTables.h" #include "Core/HLE/ReplaceTables.h"
@ -102,6 +103,7 @@ INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam,
fwrite(Memory::GetPointer(bp->start), 1, bp->size, output); fwrite(Memory::GetPointer(bp->start), 1, bp->size, output);
} else { } else {
auto savedReplacements = SaveAndClearReplacements(); auto savedReplacements = SaveAndClearReplacements();
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) { if (MIPSComp::jit) {
auto savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps(); auto savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps();
fwrite(Memory::GetPointer(bp->start), 1, bp->size, output); fwrite(Memory::GetPointer(bp->start), 1, bp->size, output);

View file

@ -895,6 +895,7 @@ namespace MainWindow
const u8 *ptr = (const u8 *)info->addr; const u8 *ptr = (const u8 *)info->addr;
std::string name; std::string name;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) { if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) {
swprintf_s(info->name, L"Jit::%S", name.c_str()); swprintf_s(info->name, L"Jit::%S", name.c_str());
return TRUE; return TRUE;