diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index 08667325f1..d98b49dbc5 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -313,7 +313,8 @@ void IRFrontend::DoJit(u32 em_address, std::vector &instructions, u32 &m instructions.reserve(block_instructions.size() + 2); // +2 for Downcount and LogIRBlock // The first instruction is "Downcount" instructions.push_back(block_instructions.front()); - instructions.push_back({ IROp::LogIRBlock, {0}, 0, 0, 0 }); + // prepare_block() fills in the constant, unless it fails to record the block. + instructions.push_back({ IROp::LogIRBlock, {0}, 0, 0, INVALID_TRACE_INDEX }); std::copy(block_instructions.begin() + 1, block_instructions.end(), std::back_inserter(instructions)); } diff --git a/Core/MIPS/MIPSTracer.cpp b/Core/MIPS/MIPSTracer.cpp index 27e62892a0..a04d00c2ff 100644 --- a/Core/MIPS/MIPSTracer.cpp +++ b/Core/MIPS/MIPSTracer.cpp @@ -113,10 +113,20 @@ bool MIPSTracer::flush_to_file() { return false; } auto trace = executed_blocks.get_content(); + int skipped = 0; for (auto index : trace) { + // Blocks compiled before an earlier flush (or before a clear) still carry their old index, + // which no longer refers to anything. Clearing the jit cache gets rid of them for good. + if (index >= trace_info.size()) { + skipped++; + continue; + } auto& block_info = trace_info[index]; flush_block_to_file(block_info); } + if (skipped != 0) { + WARN_LOG(Log::JIT, "Skipped %d stale block(s) in the trace, clear the jit cache to avoid this", skipped); + } INFO_LOG(Log::JIT, "Trace flushed, closing the file..."); fclose(output); diff --git a/Core/MIPS/MIPSTracer.h b/Core/MIPS/MIPSTracer.h index d9c873323d..6741929c7c 100644 --- a/Core/MIPS/MIPSTracer.h +++ b/Core/MIPS/MIPSTracer.h @@ -29,6 +29,9 @@ #include "Common/Data/Collections/CyclicBuffer.h" +// Stored in the LogIRBlock instruction's constant field for a block the tracer never recorded. +constexpr u32 INVALID_TRACE_INDEX = 0xFFFFFFFF; + struct TraceBlockInfo { u32 virt_address; u32 storage_index;