Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #404 from magumagu/jitcache-cleanup
JitCache cleanup
  • Loading branch information
Sonicadvance1 committed Jun 7, 2014
2 parents 7d12a31 + 282e9bd commit b778b43
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 31 deletions.
27 changes: 4 additions & 23 deletions Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
Expand Up @@ -109,31 +109,12 @@ using namespace Gen;
links_to.clear();
block_map.clear();

valid_block.clear();
valid_block.resize(VALID_BLOCK_MASK_SIZE, false);
valid_block.ClearAll();

num_blocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
}

void JitBaseBlockCache::ClearSafe()
{
memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE);
memset(iCacheEx, JIT_ICACHE_INVALID_BYTE, JIT_ICACHEEX_SIZE);
memset(iCacheVMEM, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE);
}

/*void JitBaseBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag)
{
for (int i = 0; i < num_blocks; i++)
{
if (blocks[i].flags & death_flag)
{
DestroyBlock(i, false);
}
}
}*/

void JitBaseBlockCache::Reset()
{
Shutdown();
Expand Down Expand Up @@ -183,7 +164,7 @@ using namespace Gen;
u32 pAddr = b.originalAddress & 0x1FFFFFFF;

for (u32 i = 0; i < (b.originalSize + 7) / 8; ++i)
valid_block[pAddr / 32 + i] = true;
valid_block.Set(pAddr / 32 + i);

block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
if (block_link)
Expand Down Expand Up @@ -353,10 +334,10 @@ using namespace Gen;
bool destroy_block = true;
if (length == 32)
{
if (!valid_block[pAddr / 32])
if (!valid_block.Test(pAddr / 32))
destroy_block = false;
else
valid_block[pAddr / 32] = false;
valid_block.Clear(pAddr / 32);
}

// destroy JIT blocks
Expand Down
43 changes: 37 additions & 6 deletions Source/Core/Core/PowerPC/JitCommon/JitCache.h
Expand Up @@ -6,6 +6,7 @@

#include <bitset>
#include <map>
#include <memory>
#include <vector>

#include "Core/PowerPC/Gekko.h"
Expand Down Expand Up @@ -63,6 +64,40 @@ struct JitBlock

typedef void (*CompiledCode)();

// This is essentially just an std::bitset, but Visual Studia 2013's
// implementation of std::bitset is slow.
class ValidBlockBitSet final
{
enum
{
VALID_BLOCK_MASK_SIZE = 0x20000000 / 32,
VALID_BLOCK_ALLOC_ELEMENTS = VALID_BLOCK_MASK_SIZE / 32
};
std::unique_ptr<u32[]> m_valid_block;

public:
ValidBlockBitSet()
{
m_valid_block.reset(new u32[VALID_BLOCK_ALLOC_ELEMENTS]);
ClearAll();
}
void Set(u32 bit)
{
m_valid_block[bit / 32] |= 1u << (bit % 32);
}
void Clear(u32 bit)
{
m_valid_block[bit / 32] &= ~(1u << (bit % 32));
}
void ClearAll()
{
memset(m_valid_block.get(), 0, sizeof(u32) * VALID_BLOCK_ALLOC_ELEMENTS);
}
bool Test(u32 bit)
{
return (m_valid_block[bit / 32] & (1u << (bit % 32))) != 0;
}
};

class JitBaseBlockCache
{
Expand All @@ -71,11 +106,11 @@ class JitBaseBlockCache
int num_blocks;
std::multimap<u32, int> links_to;
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
std::vector<bool> valid_block;
ValidBlockBitSet valid_block;

enum
{
MAX_NUM_BLOCKS = 65536*2,
VALID_BLOCK_MASK_SIZE = 0x20000000 / 32,
};

bool RangeIntersect(int s1, int e1, int s2, int e2) const;
Expand All @@ -95,7 +130,6 @@ class JitBaseBlockCache
void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr);

void Clear();
void ClearSafe();
void Init();
void Shutdown();
void Reset();
Expand All @@ -121,9 +155,6 @@ class JitBaseBlockCache
// DOES NOT WORK CORRECTLY WITH INLINING
void InvalidateICache(u32 address, const u32 length);
void DestroyBlock(int block_num, bool invalidate);

// Not currently used
//void DestroyBlocksWithFlag(BlockFlag death_flag);
};

// x86 BlockCache
Expand Down
8 changes: 6 additions & 2 deletions Source/Core/Core/PowerPC/JitInterface.cpp
Expand Up @@ -39,7 +39,7 @@ namespace JitInterface
void DoState(PointerWrap &p)
{
if (jit && p.GetMode() == PointerWrap::MODE_READ)
jit->GetBlockCache()->ClearSafe();
jit->GetBlockCache()->Clear();
}
CPUCoreBase *InitJitCore(int core)
{
Expand Down Expand Up @@ -199,8 +199,12 @@ namespace JitInterface
}
void ClearSafe()
{
// This clear is "safe" in the sense that it's okay to run from
// inside a JIT'ed block: it clears the instruction cache, but not
// the JIT'ed code.
// TODO: There's probably a better way to handle this situation.
if (jit)
jit->GetBlockCache()->ClearSafe();
jit->GetBlockCache()->Clear();
}

void InvalidateICache(u32 address, u32 size)
Expand Down

0 comments on commit b778b43

Please sign in to comment.