From 0bfab27b4601c633884e096fff06add64cf4bdf3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 4 Jan 2018 23:09:03 -0800 Subject: [PATCH 1/3] irjit: Calculate bloat statistics. At least based on IR for now. Can do something else later. memset() was causing a crash on the std::map. --- Core/MIPS/IR/IRJit.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 3c6b6a511d..87cd45a46a 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -234,9 +234,33 @@ JitBlockDebugInfo IRBlockCache::GetBlockDebugInfo(int blockNum) const { } void IRBlockCache::ComputeStats(BlockCacheStats &bcStats) const { - // TODO: Implement properly - memset(&bcStats, 0, sizeof(bcStats)); + double totalBloat = 0.0; + double maxBloat = 0.0; + double minBloat = 1000000000.0; + for (const auto &b : blocks_) { + double codeSize = (double)b.GetNumInstructions() * sizeof(IRInst); + if (codeSize == 0) + continue; + + u32 origAddr, mipsBytes; + b.GetRange(origAddr, mipsBytes); + double origSize = (double)mipsBytes; + double bloat = codeSize / origSize; + if (bloat < minBloat) { + minBloat = bloat; + bcStats.minBloatBlock = origAddr; + } + if (bloat > maxBloat) { + maxBloat = bloat; + bcStats.maxBloatBlock = origAddr; + } + totalBloat += bloat; + bcStats.bloatMap[bloat] = origAddr; + } bcStats.numBlocks = (int)blocks_.size(); + bcStats.minBloat = minBloat; + bcStats.maxBloat = maxBloat; + bcStats.avgBloat = totalBloat / (double)blocks_.size(); } int IRBlockCache::GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly) const { From 5b9b6daea850e2af59d771cbd6f0ef83c14b4ffe Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 4 Jan 2018 23:10:49 -0800 Subject: [PATCH 2/3] irjit: Enable more debug UI for block selection. --- UI/DevScreens.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 542a65a225..264ca0c562 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -748,7 +748,7 @@ UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { if (!MIPSComp::jit) { return UI::EVENT_DONE; } - JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); if (!blockCache) return UI::EVENT_DONE; u32 addr; @@ -815,7 +815,7 @@ UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { return UI::EVENT_DONE; } - JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); if (!blockCache) return UI::EVENT_DONE; @@ -859,7 +859,7 @@ void JitCompareScreen::OnRandomBlock(int flag) { if (!MIPSComp::jit) { return; } - JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); + JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); if (!blockCache) return; @@ -867,21 +867,25 @@ void JitCompareScreen::OnRandomBlock(int flag) { if (numBlocks > 0) { bool anyWanted = false; int tries = 0; - while (!anyWanted && tries < 10000) { + while (!anyWanted && tries < numBlocks) { currentBlock_ = rand() % numBlocks; - const JitBlock *b = blockCache->GetBlock(currentBlock_); - for (u32 addr = b->originalAddress; addr <= b->originalAddress + b->originalSize; addr += 4) { + JitBlockDebugInfo b = blockCache->GetBlockDebugInfo(currentBlock_); + u32 mipsBytes = (u32)b.origDisasm.size() * 4; + for (u32 addr = b.originalAddress; addr <= b.originalAddress + mipsBytes; addr += 4) { MIPSOpcode opcode = Memory::Read_Instruction(addr); if (MIPSGetInfo(opcode) & flag) { char temp[256]; MIPSDisAsm(opcode, addr, temp); - // INFO_LOG(HLE, "Stopping VFPU instruction: %s", temp); + // INFO_LOG(HLE, "Stopping at random instruction: %08x %s", addr, temp); anyWanted = true; break; } } tries++; } + + if (!anyWanted) + currentBlock_ = -1; } UpdateDisasm(); } From ccd562d934073c0a7086887ea7f14046258ed1e6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 4 Jan 2018 23:24:15 -0800 Subject: [PATCH 3/3] irjit: Add a safety check for block num overflow. In case a game is very frequently modifying some block. --- Core/MIPS/IR/IRJit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 87cd45a46a..4f11fde897 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -67,6 +67,12 @@ void IRJit::Compile(u32 em_address) { PROFILE_THIS_SCOPE("jitc"); int block_num = blocks_.AllocateBlock(em_address); + if ((block_num & ~MIPS_EMUHACK_VALUE_MASK) != 0) { + // Ran out of block numbers - need to reset. + ERROR_LOG(JIT, "Ran out of block numbers, clearing cache"); + ClearCache(); + block_num = blocks_.AllocateBlock(em_address); + } IRBlock *b = blocks_.GetBlock(block_num); std::vector instructions;