MIPSTracer: don't index trace_info with stale block indices

flush_to_file() ends with clear(), but tracing stays on and the blocks
already compiled keep the index baked into their LogIRBlock instruction.
A second flush then indexed an emptied trace_info out of bounds.

Skip indices that no longer refer to anything and say so in the log, and
give the LogIRBlock placeholder an explicit invalid index so a block that
prepare_block failed to record doesn't dump block 0 instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5 committed 2026-09-19 10:02:54 -06:00
1 parent 675ad0acd6
commit b03bbdbca3
3 files changed
+15 -1

No files matched your search

+2 -1
View File
@@ -313,7 +313,8 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &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));
}
+10
View File
@@ -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);
+3
View File
@@ -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;