JitCache: Use std::array to back the arrays within it.

Cleans up some of the allocation process.
This commit is contained in:
Lioncash 2014-10-09 23:20:50 -04:00
parent 6eb2b6ef7a
commit 8b831c9483
5 changed files with 39 additions and 58 deletions

View File

@ -99,7 +99,7 @@ void Jit64AsmRoutineManager::Generate()
no_mem = J_CC(CC_NZ); no_mem = J_CC(CC_NZ);
} }
AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK)); AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK));
MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCache)); MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCache.data()));
MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0));
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii || SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || SConfig::GetInstance().m_LocalCoreStartupParameter.bTLBHack) if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii || SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || SConfig::GetInstance().m_LocalCoreStartupParameter.bTLBHack)
@ -112,7 +112,7 @@ void Jit64AsmRoutineManager::Generate()
TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_VMEM_BIT)); TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_VMEM_BIT));
FixupBranch no_vmem = J_CC(CC_Z); FixupBranch no_vmem = J_CC(CC_Z);
AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK)); AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK));
MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheVMEM)); MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheVMEM.data()));
MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0));
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) exit_vmem = J(); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) exit_vmem = J();
@ -123,7 +123,7 @@ void Jit64AsmRoutineManager::Generate()
TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_EXRAM_BIT)); TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_EXRAM_BIT));
FixupBranch no_exram = J_CC(CC_Z); FixupBranch no_exram = J_CC(CC_Z);
AND(32, R(RSCRATCH), Imm32(JIT_ICACHEEX_MASK)); AND(32, R(RSCRATCH), Imm32(JIT_ICACHEEX_MASK));
MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheEx)); MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheEx.data()));
MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0));
SetJumpTarget(no_exram); SetJumpTarget(no_exram);

View File

@ -116,7 +116,7 @@ void JitArmAsmRoutineManager::Generate()
Operand2 iCacheMask = Operand2(0xE, 2); // JIT_ICACHE_MASK Operand2 iCacheMask = Operand2(0xE, 2); // JIT_ICACHE_MASK
BIC(R12, R12, iCacheMask); // R12 contains PC & JIT_ICACHE_MASK here. BIC(R12, R12, iCacheMask); // R12 contains PC & JIT_ICACHE_MASK here.
MOVI2R(R14, (u32)jit->GetBlockCache()->iCache); MOVI2R(R14, (u32)jit->GetBlockCache()->iCache.data());
LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here
// R12 Confirmed this is the correct iCache Location loaded. // R12 Confirmed this is the correct iCache Location loaded.

View File

@ -31,7 +31,7 @@ void JitArm64AsmRoutineManager::Generate()
LDR(INDEX_UNSIGNED, W28, X29, PPCSTATE_OFF(pc)); // Load the current PC into W28 LDR(INDEX_UNSIGNED, W28, X29, PPCSTATE_OFF(pc)); // Load the current PC into W28
BFM(W28, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK BFM(W28, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK
MOVI2R(X27, (u64)jit->GetBlockCache()->iCache); MOVI2R(X27, (u64)jit->GetBlockCache()->iCache.data());
LDR(W27, X27, X28); LDR(W27, X27, X28);
FixupBranch JitBlock = TBNZ(W27, 7); // Test the 7th bit FixupBranch JitBlock = TBNZ(W27, 7); // Test the 7th bit

View File

@ -41,47 +41,27 @@ using namespace Gen;
void JitBaseBlockCache::Init() void JitBaseBlockCache::Init()
{ {
if (m_initialized)
{
PanicAlert("JitBaseBlockCache::Init() - iCache is already initialized");
return;
}
#if defined USE_OPROFILE && USE_OPROFILE #if defined USE_OPROFILE && USE_OPROFILE
agent = op_open_agent(); agent = op_open_agent();
#endif #endif
blocks = new JitBlock[MAX_NUM_BLOCKS]; iCache.fill(JIT_ICACHE_INVALID_BYTE);
blockCodePointers = new const u8*[MAX_NUM_BLOCKS]; iCacheEx.fill(JIT_ICACHE_INVALID_BYTE);
if (iCache == nullptr && iCacheEx == nullptr && iCacheVMEM == nullptr) iCacheVMEM.fill(JIT_ICACHE_INVALID_BYTE);
{
iCache = new u8[JIT_ICACHE_SIZE];
iCacheEx = new u8[JIT_ICACHEEX_SIZE];
iCacheVMEM = new u8[JIT_ICACHE_SIZE];
}
else
{
PanicAlert("JitBaseBlockCache::Init() - iCache is already initialized");
}
if (iCache == nullptr || iCacheEx == nullptr || iCacheVMEM == nullptr)
{
PanicAlert("JitBaseBlockCache::Init() - unable to allocate iCache");
}
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);
Clear(); Clear();
m_initialized = true;
} }
void JitBaseBlockCache::Shutdown() void JitBaseBlockCache::Shutdown()
{ {
delete[] blocks;
delete[] blockCodePointers;
if (iCache != nullptr)
delete[] iCache;
iCache = nullptr;
if (iCacheEx != nullptr)
delete[] iCacheEx;
iCacheEx = nullptr;
if (iCacheVMEM != nullptr)
delete[] iCacheVMEM;
iCacheVMEM = nullptr;
blocks = nullptr;
blockCodePointers = nullptr;
num_blocks = 0; num_blocks = 0;
m_initialized = false;
#if defined USE_OPROFILE && USE_OPROFILE #if defined USE_OPROFILE && USE_OPROFILE
op_close_agent(agent); op_close_agent(agent);
#endif #endif
@ -112,7 +92,7 @@ using namespace Gen;
valid_block.ClearAll(); valid_block.ClearAll();
num_blocks = 0; num_blocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); blockCodePointers.fill(nullptr);
} }
void JitBaseBlockCache::Reset() void JitBaseBlockCache::Reset()
@ -203,31 +183,31 @@ using namespace Gen;
const u8 **JitBaseBlockCache::GetCodePointers() const u8 **JitBaseBlockCache::GetCodePointers()
{ {
return blockCodePointers; return blockCodePointers.data();
} }
u32* JitBaseBlockCache::GetICachePtr(u32 addr) u32* JitBaseBlockCache::GetICachePtr(u32 addr)
{ {
if (addr & JIT_ICACHE_VMEM_BIT) if (addr & JIT_ICACHE_VMEM_BIT)
return (u32*)(jit->GetBlockCache()->iCacheVMEM + (addr & JIT_ICACHE_MASK)); return (u32*)(&jit->GetBlockCache()->iCacheVMEM[addr & JIT_ICACHE_MASK]);
else if (addr & JIT_ICACHE_EXRAM_BIT) else if (addr & JIT_ICACHE_EXRAM_BIT)
return (u32*)(jit->GetBlockCache()->iCacheEx + (addr & JIT_ICACHEEX_MASK)); return (u32*)(&jit->GetBlockCache()->iCacheEx[addr & JIT_ICACHEEX_MASK]);
else else
return (u32*)(jit->GetBlockCache()->iCache + (addr & JIT_ICACHE_MASK)); return (u32*)(&jit->GetBlockCache()->iCache[addr & JIT_ICACHE_MASK]);
} }
int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr) int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr)
{ {
if (!blocks) u32 inst = *GetICachePtr(addr);
return -1;
u32 inst;
inst = *GetICachePtr(addr);
if (inst & 0xfc000000) // definitely not a JIT block if (inst & 0xfc000000) // definitely not a JIT block
return -1; return -1;
if ((int)inst >= num_blocks) if ((int)inst >= num_blocks)
return -1; return -1;
if (blocks[inst].originalAddress != addr) if (blocks[inst].originalAddress != addr)
return -1; return -1;
return inst; return inst;
} }

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array>
#include <bitset> #include <bitset>
#include <map> #include <map>
#include <memory> #include <memory>
@ -106,17 +107,19 @@ public:
class JitBaseBlockCache class JitBaseBlockCache
{ {
const u8 **blockCodePointers; enum
JitBlock *blocks; {
MAX_NUM_BLOCKS = 65536 * 2,
};
std::array<const u8*, MAX_NUM_BLOCKS> blockCodePointers;
std::array<JitBlock, MAX_NUM_BLOCKS> blocks;
int num_blocks; int num_blocks;
std::multimap<u32, int> links_to; std::multimap<u32, int> links_to;
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
ValidBlockBitSet valid_block; ValidBlockBitSet valid_block;
enum bool m_initialized;
{
MAX_NUM_BLOCKS = 65536*2,
};
bool RangeIntersect(int s1, int e1, int s2, int e2) const; bool RangeIntersect(int s1, int e1, int s2, int e2) const;
void LinkBlockExits(int i); void LinkBlockExits(int i);
@ -128,9 +131,7 @@ class JitBaseBlockCache
virtual void WriteDestroyBlock(const u8* location, u32 address) = 0; virtual void WriteDestroyBlock(const u8* location, u32 address) = 0;
public: public:
JitBaseBlockCache() : JitBaseBlockCache() : num_blocks(0), m_initialized(false)
blockCodePointers(nullptr), blocks(nullptr), num_blocks(0),
iCache(nullptr), iCacheEx(nullptr), iCacheVMEM(nullptr)
{ {
} }
@ -148,9 +149,9 @@ public:
JitBlock *GetBlock(int block_num); JitBlock *GetBlock(int block_num);
int GetNumBlocks() const; int GetNumBlocks() const;
const u8 **GetCodePointers(); const u8 **GetCodePointers();
u8 *iCache; std::array<u8, JIT_ICACHE_SIZE> iCache;
u8 *iCacheEx; std::array<u8, JIT_ICACHEEX_SIZE> iCacheEx;
u8 *iCacheVMEM; std::array<u8, JIT_ICACHE_SIZE> iCacheVMEM;
u32* GetICachePtr(u32 addr); u32* GetICachePtr(u32 addr);