Merge pull request #6505 from unknownbrackets/jit-minor

Keep track of ranges that have emuhack ops
This commit is contained in:
Henrik Rydgård 2014-07-06 01:31:44 +02:00
commit 3cb59eea61
6 changed files with 54 additions and 7 deletions

View File

@ -23,6 +23,7 @@
// locating performance issues.
#include <cstddef>
#include <algorithm>
#include "Common.h"
@ -124,6 +125,10 @@ void JitBlockCache::Clear() {
block_map_.clear();
proxyBlockIndices_.clear();
num_blocks_ = 0;
blockMemRanges_[JITBLOCK_RANGE_SCRATCH] = std::make_pair(0xFFFFFFFF, 0x00000000);
blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM] = std::make_pair(0xFFFFFFFF, 0x00000000);
blockMemRanges_[JITBLOCK_RANGE_RAMTOP] = std::make_pair(0xFFFFFFFF, 0x00000000);
}
void JitBlockCache::Reset() {
@ -198,6 +203,11 @@ void JitBlockCache::ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, cons
num_blocks_++; //commit the current block
}
static void ExpandRange(std::pair<u32, u32> &range, u32 newStart, u32 newEnd) {
range.first = std::min(range.first, newStart);
range.second = std::max(range.second, newEnd);
}
void JitBlockCache::FinalizeBlock(int block_num, bool block_link) {
JitBlock &b = blocks_[block_num];
@ -209,17 +219,31 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link) {
// Yeah, this'll work fine for PSP too I think.
u32 pAddr = b.originalAddress & 0x1FFFFFFF;
u32 latestExit = 0;
block_map_[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
if (block_link) {
for (int i = 0; i < MAX_JIT_BLOCK_EXITS; i++) {
if (b.exitAddress[i] != INVALID_EXIT)
if (b.exitAddress[i] != INVALID_EXIT) {
links_to_.insert(std::pair<u32, int>(b.exitAddress[i], block_num));
latestExit = std::max(latestExit, b.exitAddress[i]);
}
}
LinkBlock(block_num);
LinkBlockExits(block_num);
}
if (Memory::IsScratchpadAddress(b.originalAddress)) {
ExpandRange(blockMemRanges_[JITBLOCK_RANGE_SCRATCH], b.originalAddress, latestExit);
}
const u32 halfUserMemory = (PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()) / 2;
if (b.originalAddress < PSP_GetUserMemoryBase() + halfUserMemory) {
ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM], b.originalAddress, latestExit);
}
if (latestExit > PSP_GetUserMemoryBase() + halfUserMemory) {
ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMTOP], b.originalAddress, latestExit);
}
#if defined USE_OPROFILE && USE_OPROFILE
char buf[100];
sprintf(buf, "EmuCode%x", b.originalAddress);
@ -242,6 +266,15 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link) {
#endif
}
bool JitBlockCache::RangeMayHaveEmuHacks(u32 start, u32 end) const {
for (int i = 0; i < JITBLOCK_RANGE_COUNT; ++i) {
if (end >= blockMemRanges_[i].first && start <= blockMemRanges_[i].second) {
return true;
}
}
return false;
}
static int binary_search(JitBlock blocks_[], const u8 *baseoff, int imin, int imax) {
while (imin < imax) {
int imid = (imin + imax) / 2;

View File

@ -128,6 +128,8 @@ public:
MIPSOpcode GetOriginalFirstOp(int block_num);
bool RangeMayHaveEmuHacks(u32 start, u32 end) const;
// DOES NOT WORK CORRECTLY WITH JIT INLINING
void InvalidateICache(u32 address, const u32 length);
void DestroyBlock(int block_num, bool invalidate);
@ -155,6 +157,14 @@ private:
std::multimap<u32, int> links_to_;
std::map<std::pair<u32,u32>, u32> block_map_; // (end_addr, start_addr) -> number
enum {
JITBLOCK_RANGE_SCRATCH = 0,
JITBLOCK_RANGE_RAMBOTTOM = 1,
JITBLOCK_RANGE_RAMTOP = 2,
JITBLOCK_RANGE_COUNT = 3,
};
std::pair<u32, u32> blockMemRanges_[3];
enum {
MAX_NUM_BLOCKS = 65536*2
};

View File

@ -222,11 +222,6 @@ void Jit::InvalidateCache()
blocks.Clear();
}
void Jit::InvalidateCacheAt(u32 em_address, int length)
{
blocks.InvalidateICache(em_address, length);
}
void Jit::CompileDelaySlot(int flags, RegCacheState *state)
{
const u32 addr = js.compilerPC + 4;

View File

@ -169,7 +169,11 @@ public:
void ClearCache();
void InvalidateCache();
void InvalidateCacheAt(u32 em_address, int length = 4);
inline void InvalidateCacheAt(u32 em_address, int length = 4) {
if (blocks.RangeMayHaveEmuHacks(em_address, em_address + length)) {
blocks.InvalidateICache(em_address, length);
}
}
private:
void GetStateAndFlushAll(RegCacheState &state);

View File

@ -239,6 +239,7 @@ inline void Write_Float(float f, u32 address)
u8* GetPointer(const u32 address);
bool IsRAMAddress(const u32 address);
bool IsVRAMAddress(const u32 address);
bool IsScratchpadAddress(const u32 address);
inline const char* GetCharPointer(const u32 address) {
return (const char *)GetPointer(address);

View File

@ -159,6 +159,10 @@ bool IsVRAMAddress(const u32 address) {
return ((address & 0x3F800000) == 0x04000000);
}
bool IsScratchpadAddress(const u32 address) {
return (address & 0xBFFF0000) == 0x00010000;
}
u8 Read_U8(const u32 _Address)
{
u8 _var = 0;