mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 17:49:29 +01:00
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:
1 parent
675ad0acd6
commit
b03bbdbca3
3 files changed
+15
-1
No files matched your search
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user