Some JIT cleanup

This commit is contained in:
Henrik Rydgard 2013-04-26 23:39:23 +02:00
parent f275607ae1
commit 8a904fe478
6 changed files with 51 additions and 99 deletions

View File

@ -169,7 +169,8 @@ void Jit::Compile(u32 em_address)
int block_num = blocks.AllocateBlock(em_address);
ArmJitBlock *b = blocks.GetBlock(block_num);
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b));
DoJit(em_address, b);
blocks.FinalizeBlock(block_num, jo.enableBlocklink);
// Drat. The VFPU hit an uneaten prefix at the end of a block.
if (js.startDefaultPrefix && js.MayHavePrefix())

View File

@ -160,10 +160,10 @@ int ArmJitBlockCache::AllocateBlock(u32 em_address)
return num_blocks - 1;
}
void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr)
void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link)
{
blockCodePointers[block_num] = code_ptr;
ArmJitBlock &b = blocks[block_num];
blockCodePointers[block_num] = b.normalEntry;
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
u32 opcode = MIPS_MAKE_EMUHACK(0, block_num);
@ -189,7 +189,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c
#if defined USE_OPROFILE && USE_OPROFILE
char buf[100];
sprintf(buf, "EmuCode%x", b.originalAddress);
const u8* blockStart = blockCodePointers[block_num];
const u8* blockStart = blocks[block_num].checkedEntry;
op_write_native_code(agent, buf, (uint64_t)blockStart,
blockStart, b.codeSize);
#endif
@ -201,7 +201,7 @@ void ArmJitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *c
jmethod.method_id = iJIT_GetNewMethodID();
jmethod.class_file_name = "";
jmethod.source_file_name = __FILE__;
jmethod.method_load_address = (void*)blockCodePointers[block_num];
jmethod.method_load_address = (void*)blocks[block_num].checkedEntry;
jmethod.method_size = b.codeSize;
jmethod.line_number_size = 0;
jmethod.method_name = b.blockName;
@ -246,29 +246,6 @@ u32 ArmJitBlockCache::GetOriginalFirstOp(int block_num)
return blocks[block_num].originalFirstOpcode;
}
CompiledCode ArmJitBlockCache::GetCompiledCodeFromBlock(int block_num)
{
return (CompiledCode)blockCodePointers[block_num];
}
std::string ArmJitBlockCache::GetCompiledDisassembly(int block_num)
{
/*
std::string buf;
const u8 *ptr = blockCodePointers[block_num];
while (ptr < blockCodePointers[block_num] + blocks[block_num].codeSize)
{
int len;
buf += std::string(disasmx86((unsigned char*)ptr, 0, &len)) + "\n";
ptr += len;
}*/
return "No ARM disassembler";
}
//Make sure to have as many blocks as possible compiled before calling this
//It's O(1), so it's fast :)
void ArmJitBlockCache::LinkBlockExits(int i)
{
ArmJitBlock &b = blocks[i];
@ -328,6 +305,10 @@ void ArmJitBlockCache::UnlinkBlock(int i)
}
}
u32 ArmJitBlockCache::GetEmuHackOpForBlock(int blockNum) const {
return (MIPS_EMUHACK_OPCODE | blockNum);
}
void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate)
{
if (block_num < 0 || block_num >= num_blocks)
@ -343,12 +324,14 @@ void ArmJitBlockCache::DestroyBlock(int block_num, bool invalidate)
return;
}
b.invalid = true;
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num))
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num))
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
UnlinkBlock(block_num);
b.normalEntry = 0;
// TODO: remove
blockCodePointers[block_num] = 0;
// Send anyone who tries to run this block back to the dispatcher.
// Not entirely ideal, but .. pretty good.
// I hope there's enough space...

View File

@ -30,17 +30,6 @@
// emulate CPU with unlimited instruction cache
// the only way to invalidate a region is the "icbi" instruction
#define JIT_ICACHE_SIZE 0x2000000
#define JIT_ICACHE_MASK 0x1ffffff
#define JIT_ICACHEEX_SIZE 0x4000000
#define JIT_ICACHEEX_MASK 0x3ffffff
#define JIT_ICACHE_EXRAM_BIT 0x10000000
#define JIT_ICACHE_VMEM_BIT 0x20000000
// this corresponds to opcode 5 which is invalid in PowerPC
#define JIT_ICACHE_INVALID_BYTE 0x14
#define JIT_ICACHE_INVALID_WORD 0x14141414
#define JIT_OPCODE 0xFFCCCCCC // yeah this ain't gonna work
struct ArmJitBlock
{
@ -85,7 +74,7 @@ public:
MAX_NUM_BLOCKS(0) { }
~ArmJitBlockCache();
int AllocateBlock(u32 em_address);
void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr);
void FinalizeBlock(int block_num, bool block_link);
void Clear();
void ClearSafe();
@ -110,18 +99,18 @@ public:
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
u32 GetOriginalFirstOp(int block_num);
CompiledCode GetCompiledCodeFromBlock(int block_num);
// DOES NOT WORK CORRECTLY WITH INLINING
void InvalidateICache(u32 address, const u32 length);
void DestroyBlock(int block_num, bool invalidate);
std::string GetCompiledDisassembly(int block_num);
// Not currently used
//void DestroyBlocksWithFlag(BlockFlag death_flag);
private:
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
void LinkBlockExits(int i);
void LinkBlock(int i);
void UnlinkBlock(int i);
u32 GetEmuHackOpForBlock(int blockNum) const;
MIPSState *mips;
const u8 **blockCodePointers;
ArmJitBlock *blocks;
@ -130,9 +119,4 @@ private:
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
int MAX_NUM_BLOCKS;
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
void LinkBlockExits(int i);
void LinkBlock(int i);
void UnlinkBlock(int i);
};

View File

@ -220,7 +220,8 @@ void Jit::Compile(u32 em_address)
int block_num = blocks.AllocateBlock(em_address);
JitBlock *b = blocks.GetBlock(block_num);
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, b));
DoJit(em_address, b);
blocks.FinalizeBlock(block_num, jo.enableBlocklink);
// Drat. The VFPU hit an uneaten prefix at the end of a block.
if (js.startDefaultPrefix && js.MayHavePrefix())

View File

@ -173,10 +173,10 @@ int JitBlockCache::AllocateBlock(u32 em_address)
return num_blocks - 1;
}
void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr)
void JitBlockCache::FinalizeBlock(int block_num, bool block_link)
{
blockCodePointers[block_num] = code_ptr;
JitBlock &b = blocks[block_num];
blockCodePointers[block_num] = b.normalEntry;
b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress);
u32 opcode = MIPS_MAKE_EMUHACK(0, block_num);
@ -202,9 +202,8 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code
#if defined USE_OPROFILE && USE_OPROFILE
char buf[100];
sprintf(buf, "EmuCode%x", b.originalAddress);
const u8* blockStart = blockCodePointers[block_num];
op_write_native_code(agent, buf, (uint64_t)blockStart,
blockStart, b.codeSize);
const u8* blockStart = blocks[block_num].checkedEntry;
op_write_native_code(agent, buf, (uint64_t)blockStart, blockStart, b.codeSize);
#endif
#ifdef USE_VTUNE
@ -214,7 +213,7 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code
jmethod.method_id = iJIT_GetNewMethodID();
jmethod.class_file_name = "";
jmethod.source_file_name = __FILE__;
jmethod.method_load_address = (void*)blockCodePointers[block_num];
jmethod.method_load_address = (void*)blocks[block_num].checkedEntry;
jmethod.method_size = b.codeSize;
jmethod.line_number_size = 0;
jmethod.method_name = b.blockName;
@ -259,19 +258,6 @@ u32 JitBlockCache::GetOriginalFirstOp(int block_num)
return blocks[block_num].originalFirstOpcode;
}
CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int block_num)
{
return (CompiledCode)blockCodePointers[block_num];
}
//Block linker
//Make sure to have as many blocks as possible compiled before calling this
//It's O(N), so it's fast :)
//Can be faster by doing a queue for blocks to link up, and only process those
//Should probably be done
void JitBlockCache::LinkBlockExits(int i)
{
JitBlock &b = blocks[i];
@ -330,6 +316,10 @@ void JitBlockCache::UnlinkBlock(int i)
}
}
u32 JitBlockCache::GetEmuHackOpForBlock(int blockNum) {
return (MIPS_EMUHACK_OPCODE | blockNum);
}
void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
{
if (block_num < 0 || block_num >= num_blocks)
@ -345,7 +335,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
return;
}
b.invalid = true;
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == (MIPS_EMUHACK_OPCODE | block_num))
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == GetEmuHackOpForBlock(block_num))
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
UnlinkBlock(block_num);
@ -356,13 +346,6 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
XEmitter emit((u8 *)b.checkedEntry);
emit.MOV(32, M(&mips->pc), Imm32(b.originalAddress));
emit.JMP(MIPSComp::jit->Asm().dispatcher, true);
// this is not needed really
/*
emit.SetCodePtr((u8 *)blockCodePointers[blocknum]);
emit.MOV(32, M(&PC), Imm32(b.originalAddress));
emit.JMP(asm_routines.dispatcher, true);
*/
}
void JitBlockCache::InvalidateICache(u32 address, const u32 length)

View File

@ -79,20 +79,6 @@ typedef void (*CompiledCode)();
class JitBlockCache
{
MIPSState *mips;
const u8 **blockCodePointers;
JitBlock *blocks;
int num_blocks;
std::multimap<u32, int> links_to;
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
int MAX_NUM_BLOCKS;
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
void LinkBlockExits(int i);
void LinkBlock(int i);
void UnlinkBlock(int i);
public:
JitBlockCache(MIPSState *mips_) :
mips(mips_), blockCodePointers(0), blocks(0), num_blocks(0),
@ -100,7 +86,7 @@ public:
~JitBlockCache();
int AllocateBlock(u32 em_address);
void FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr);
void FinalizeBlock(int block_num, bool block_link);
void Clear();
void Init();
@ -124,12 +110,26 @@ public:
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
u32 GetOriginalFirstOp(int block_num);
CompiledCode GetCompiledCodeFromBlock(int block_num);
// DOES NOT WORK CORRECTLY WITH JIT INLINING
void InvalidateICache(u32 address, const u32 length);
void DestroyBlock(int block_num, bool invalidate);
// Not currently used
//void DestroyBlocksWithFlag(BlockFlag death_flag);
private:
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
void LinkBlockExits(int i);
void LinkBlock(int i);
void UnlinkBlock(int i);
u32 GetEmuHackOpForBlock(int block_num);
MIPSState *mips;
const u8 **blockCodePointers;
JitBlock *blocks;
int num_blocks;
std::multimap<u32, int> links_to;
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
int MAX_NUM_BLOCKS;
};