More code reorganization.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1605 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-12-20 12:10:59 +00:00
parent f0bb8f430a
commit 614dc1069e
16 changed files with 203 additions and 199 deletions

View File

@ -35,12 +35,6 @@
void Console_Submit(const char *cmd)
{
CASE1("jits")
{
#ifdef _M_X64
jit.PrintStats();
#endif
}
CASE1("r")
{
Core::StartTrace(false);
@ -57,7 +51,7 @@ void Console_Submit(const char *cmd)
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
if (addr!=0)
if (addr)
{
#ifdef LOGGING
u32 EA =
@ -75,7 +69,7 @@ void Console_Submit(const char *cmd)
TCHAR temp[256];
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
if (addr!=0)
if (addr)
{
g_symbolDB.PrintCalls(addr);
}
@ -89,7 +83,7 @@ void Console_Submit(const char *cmd)
TCHAR temp[256];
u32 addr;
sscanf(cmd, "%s %08x", temp, &addr);
if (addr!=0)
if (addr)
{
g_symbolDB.PrintCallers(addr);
}
@ -111,7 +105,7 @@ void Console_Submit(const char *cmd)
sscanf(cmd, "%s %08x %08x %s", temp, &start, &end, filename);
FILE *f = fopen(filename, "wb");
for (u32 i=start; i<end; i++)
for (u32 i = start; i < end; i++)
{
u8 b = Memory::ReadUnchecked_U8(i);
fputc(b,f);

View File

@ -28,6 +28,7 @@
#include "../HW/CPU.h"
#include "../Host.h"
#include "../PowerPC/SymbolDB.h"
#include "../PowerPC/Jit64/Jit.h"
#include "Debugger_BreakPoints.h"
CBreakPoints::TBreakPoints CBreakPoints::m_BreakPoints;
@ -90,7 +91,7 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address)
}
else
{
if ((*iter).StartAddress==address)
if ((*iter).StartAddress == address)
return &(*iter);
}
}
@ -99,16 +100,17 @@ TMemCheck *CBreakPoints::GetMemCheck(u32 address)
return 0;
}
void CBreakPoints::AddBreakPoint(u32 _iAddress, bool temp)
void CBreakPoints::AddBreakPoint(u32 em_address, bool temp)
{
if (!IsAddressBreakPoint(_iAddress)) // only add new addresses
if (!IsAddressBreakPoint(em_address)) // only add new addresses
{
TBreakPoint pt; // breakpoint settings
pt.bOn = true;
pt.bTemporary = temp;
pt.iAddress = _iAddress;
pt.iAddress = em_address;
m_BreakPoints.push_back(pt);
// jit.NotifyBreakpoint(em_address, true);
}
}
@ -121,11 +123,10 @@ void CBreakPoints::RemoveBreakPoint(u32 _iAddress)
if ((*iter).iAddress == _iAddress)
{
m_BreakPoints.erase(iter);
// jit.NotifyBreakpoint(em_address, false);
break;
}
}
Host_UpdateBreakPointView();
}
void CBreakPoints::ClearAllBreakPoints()

View File

@ -72,7 +72,7 @@ public:
static bool IsTempBreakPoint(u32 _iAddress);
// AddBreakPoint
static void AddBreakPoint(u32 _iAddress, bool temp=false);
static void AddBreakPoint(u32 em_address, bool temp=false);
// Remove Breakpoint
static void RemoveBreakPoint(u32 _iAddress);

View File

@ -757,9 +757,9 @@ bool AreMemoryBreakpointsActivated()
}
u32 Read_Instruction(const u32 _Address)
u32 Read_Instruction(const u32 em_address)
{
return jit.GetOriginalCode(_Address);
return jit.GetBlockCache()->GetOriginalCode(em_address);
}
u32 Read_Opcode(const u32 _Address)

View File

@ -340,7 +340,7 @@ void icbi(UGeckoInstruction _inst)
// VERY IMPORTANT when we start linking blocks
// There are a TON of these so hopefully we can make this mechanism
// fast in the JIT
jit.InvalidateCodeRange(address, 0x20);
jit.GetBlockCache()->InvalidateCodeRange(address, 0x20);
}
void lbzux(UGeckoInstruction _inst)

View File

@ -196,20 +196,28 @@ namespace CPUCompare
trampolines.Init();
AllocCodeSpace(CODE_SIZE);
InitCache();
blocks.Init();
asm_routines.Init();
}
void Jit64::Shutdown()
{
FreeCodeSpace();
ShutdownCache();
blocks.Shutdown();
trampolines.Shutdown();
asm_routines.Shutdown();
}
void Jit64::WriteCallInterpreter(UGeckoInstruction _inst)
void Jit64::EnterFastRun()
{
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
pExecAddr();
//Will return when PowerPC::state changes
}
void Jit64::WriteCallInterpreter(UGeckoInstruction inst)
{
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
@ -218,8 +226,14 @@ namespace CPUCompare
MOV(32, M(&PC), Imm32(js.compilerPC));
MOV(32, M(&NPC), Imm32(js.compilerPC + 4));
}
Interpreter::_interpreterInstruction instr = GetInterpreterOp(_inst);
ABI_CallFunctionC((void*)instr, _inst.hex);
Interpreter::_interpreterInstruction instr = GetInterpreterOp(inst);
ABI_CallFunctionC((void*)instr, inst.hex);
}
void Jit64::unknown_instruction(UGeckoInstruction inst)
{
// CCPU::Break();
PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex);
}
void Jit64::Default(UGeckoInstruction _inst)
@ -286,11 +300,11 @@ namespace CPUCompare
b->exitPtrs[exit_num] = GetWritableCodePtr();
// Link opportunity!
int block = GetBlockNumberFromAddress(destination);
int block = blocks.GetBlockNumberFromAddress(destination);
if (block >= 0 && jo.enableBlocklink)
{
// It exists! Joy of joy!
JMP(GetBlock(block)->checkedEntry, true);
JMP(blocks.GetBlock(block)->checkedEntry, true);
b->linkStatus[exit_num] = true;
}
else
@ -323,6 +337,21 @@ namespace CPUCompare
MOV(32, M(&PC), Imm32(js.compilerPC + 4));
JMP(asm_routines.testExceptions, true);
}
const u8 *Jit64::Jit(u32 em_address)
{
if (GetSpaceLeft() < 0x10000 || blocks.IsFull())
{
LOG(DYNA_REC, "JIT cache full - clearing.")
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
{
PanicAlert("What? JIT cache still full - clearing.");
}
ClearCache();
}
return blocks.Jit(em_address);
}
const u8* Jit64::DoJit(u32 emaddress, JitBlock &b)
{

View File

@ -71,37 +71,7 @@ public:
class Jit64 : public Gen::XCodeBlock
{
public:
// TODO(ector) - optimize this struct for size
struct JitBlock
{
u32 exitAddress[2]; // 0xFFFFFFFF == unknown
u8 *exitPtrs[2]; // to be able to rewrite the exit jump
bool linkStatus[2];
u32 originalAddress;
u32 originalFirstOpcode; //to be able to restore
u32 codeSize;
u32 originalSize;
int runCount; // for profiling.
#ifdef _WIN32
// we don't really need to save start and stop
// TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;)
LARGE_INTEGER ticStart; // for profiling - time.
LARGE_INTEGER ticStop; // for profiling - time.
LARGE_INTEGER ticCounter; // for profiling - time.
#endif
const u8 *checkedEntry;
bool invalid;
int flags;
};
private:
enum BlockFlag
{
BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8,
BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80,
};
struct JitState
{
u32 compilerPC;
@ -139,20 +109,14 @@ private:
bool accurateSinglePrecision;
};
JitBlockCache blocks;
TrampolineCache trampolines;
GPRRegCache gpr;
FPURegCache fpr;
u8 **blockCodePointers;
std::multimap<u32, int> links_to;
JitBlock *blocks;
int numBlocks;
public:
typedef void (*CompiledCode)();
Jit64() {blocks.SetJit(this);}
~Jit64() {}
JitState js;
JitOptions jo;
@ -162,40 +126,24 @@ public:
void Init();
void Shutdown();
void PrintStats();
// Jit!
const u8* Jit(u32 emaddress);
const u8 *Jit(u32 emAddress); // calls blocks.Jit, which in turn calls DoJit below after setting up a block.
const u8* DoJit(u32 emaddress, JitBlock &b);
JitBlockCache *GetBlockCache() { return &blocks; }
void ClearCache()
{
blocks.Clear();
trampolines.ClearCodeSpace();
}
// Run!
void EnterFastRun();
const u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
// Code Cache
u32 GetOriginalCode(u32 address);
JitBlock *GetBlock(int no);
void InvalidateCodeRange(u32 address, u32 length);
int GetBlockNumberFromAddress(u32 address);
CompiledCode GetCompiledCode(u32 address);
CompiledCode GetCompiledCodeFromBlock(int blockNumber);
int GetCodeSize();
int GetNumBlocks();
u8 **GetCodePointers();
void DestroyBlocksWithFlag(BlockFlag death_flag);
void LinkBlocks();
void LinkBlockExits(int i);
void LinkBlock(int i);
void ClearCache();
void InitCache();
void ShutdownCache();
void ResetCache();
void DestroyBlock(int blocknum, bool invalidate);
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
#define JIT_OPCODE 0
// Utilities for use by opcodes

View File

@ -169,10 +169,8 @@ void AsmRoutineManager::Generate()
ABI_PushAllCalleeSavedRegsAndAdjustStack();
if (!jit.GetCodePointers() || !Memory::base)
PanicAlert("Memory::base and jit.GetCodePointers() must return valid values");
MOV(64, R(RBX), Imm64((u64)Memory::base));
MOV(64, R(R15), Imm64((u64)jit.GetCodePointers())); //It's below 2GB so 32 bits are good enough
MOV(64, R(R15), Imm64((u64)jit.GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough
const u8 *outerLoop = GetCodePtr();
CALL((void *)&CoreTiming::Advance);

View File

@ -204,7 +204,7 @@ const u8 *Jit64::BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *
if (info.instructionSize < 3)
PanicAlert("instruction too small");
// We entered here with a BSWAP-ed EAX. We'll have to swap it back.
ctx->Rax = Common::swap32(ctx->Rax);
ctx->Rax = Common::swap32((u32)ctx->Rax);
return codePtr - 2;
}
return 0;

View File

@ -24,8 +24,6 @@
//#define OPROFILE_REPORT
#include <map>
#include "Common.h"
#include "../../Core.h"
#include "MemoryUtil.h"
@ -50,31 +48,23 @@
#include <opagent.h>
#endif
using namespace Gen;
#ifdef OPROFILE_REPORT
op_agent_t agent;
#endif
using namespace Gen;
#define INVALID_EXIT 0xFFFFFFFF
enum
bool JitBlockCache::IsFull() const
{
TRAMPOLINE_SIZE = 1024*1024,
};
int MAX_NUM_BLOCKS = 65536*2;
void Jit64::PrintStats()
{
LOG(DYNA_REC, "JIT Statistics =======================");
LOG(DYNA_REC, "Number of blocks currently: %i", numBlocks);
LOG(DYNA_REC, "======================================");
return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
}
void Jit64::InitCache()
void JitBlockCache::Init()
{
MAX_NUM_BLOCKS = 65536*2;
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
{
MAX_NUM_BLOCKS = 65536*8;
@ -86,10 +76,10 @@ using namespace Gen;
blocks = new JitBlock[MAX_NUM_BLOCKS];
blockCodePointers = new u8*[MAX_NUM_BLOCKS];
ClearCache();
Clear();
}
void Jit64::ShutdownCache()
void JitBlockCache::Shutdown()
{
delete [] blocks;
delete [] blockCodePointers;
@ -103,7 +93,7 @@ using namespace Gen;
// This clears the JIT cache. It's called from JitCache.cpp when the JIT cache
// is full and when saving and loading states.
void Jit64::ClearCache()
void JitBlockCache::Clear()
{
Core::DisplayMessage("Cleared code cache.", 3000);
// Is destroying the blocks really necessary?
@ -114,11 +104,9 @@ using namespace Gen;
links_to.clear();
numBlocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
trampolines.ClearCodeSpace();
}
void Jit64::DestroyBlocksWithFlag(BlockFlag death_flag)
void JitBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag)
{
for (int i = 0; i < numBlocks; i++)
{
@ -129,23 +117,23 @@ using namespace Gen;
}
}
void Jit64::ResetCache()
void JitBlockCache::Reset()
{
ShutdownCache();
InitCache();
Shutdown();
Init();
}
Jit64::JitBlock *Jit64::GetBlock(int no)
JitBlock *JitBlockCache::GetBlock(int no)
{
return &blocks[no];
}
int Jit64::GetNumBlocks()
int JitBlockCache::GetNumBlocks() const
{
return numBlocks;
}
bool Jit64::RangeIntersect(int s1, int e1, int s2, int e2) const
bool JitBlockCache::RangeIntersect(int s1, int e1, int s2, int e2) const
{
// check if any endpoint is inside the other range
if ( (s1 >= s2 && s1 <= e2) ||
@ -162,18 +150,8 @@ using namespace Gen;
return jit.Jit(emAddress);
}
const u8 *Jit64::Jit(u32 emAddress)
const u8 *JitBlockCache::Jit(u32 emAddress)
{
if (GetSpaceLeft() < 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1)
{
LOG(DYNA_REC, "JIT cache full - clearing.")
if (Core::g_CoreStartupParameter.bJITUnlimitedCache)
{
PanicAlert("What? JIT cache still full - clearing.");
}
ClearCache();
}
JitBlock &b = blocks[numBlocks];
b.invalid = false;
b.originalAddress = emAddress;
@ -185,10 +163,10 @@ using namespace Gen;
b.linkStatus[0] = false;
b.linkStatus[1] = false;
blockCodePointers[numBlocks] = (u8*)DoJit(emAddress, b); //cast away const
blockCodePointers[numBlocks] = (u8*)jit->DoJit(emAddress, b); //cast away const
Memory::WriteUnchecked_U32((JIT_OPCODE << 26) | numBlocks, emAddress);
if (jo.enableBlocklink) {
if (jit->jo.enableBlocklink) {
for (int i = 0; i < 2; i++) {
if (b.exitAddress[i] != INVALID_EXIT) {
links_to.insert(std::pair<u32, int>(b.exitAddress[i], numBlocks));
@ -211,26 +189,12 @@ using namespace Gen;
return 0;
}
void Jit64::unknown_instruction(UGeckoInstruction _inst)
{
// CCPU::Break();
PanicAlert("unknown_instruction Jit64 - Fix me ;)");
_dbg_assert_(DYNA_REC, 0);
}
u8 **Jit64::GetCodePointers()
u8 **JitBlockCache::GetCodePointers()
{
return blockCodePointers;
}
void Jit64::EnterFastRun()
{
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
pExecAddr();
//Will return when PowerPC::state changes
}
int Jit64::GetBlockNumberFromAddress(u32 addr)
int JitBlockCache::GetBlockNumberFromAddress(u32 addr)
{
if (!blocks)
return -1;
@ -256,7 +220,7 @@ using namespace Gen;
}
}
u32 Jit64::GetOriginalCode(u32 address)
u32 JitBlockCache::GetOriginalCode(u32 address)
{
int num = GetBlockNumberFromAddress(address);
if (num == -1)
@ -265,7 +229,7 @@ using namespace Gen;
return blocks[num].originalFirstOpcode;
}
Jit64::CompiledCode Jit64::GetCompiledCode(u32 address)
CompiledCode JitBlockCache::GetCompiledCode(u32 address)
{
int num = GetBlockNumberFromAddress(address);
if (num == -1)
@ -274,7 +238,7 @@ using namespace Gen;
return (CompiledCode)blockCodePointers[num];
}
Jit64::CompiledCode Jit64::GetCompiledCodeFromBlock(int blockNumber)
CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int blockNumber)
{
return (CompiledCode)blockCodePointers[blockNumber];
}
@ -285,7 +249,7 @@ using namespace Gen;
//Can be faster by doing a queue for blocks to link up, and only process those
//Should probably be done
void Jit64::LinkBlockExits(int i)
void JitBlockCache::LinkBlockExits(int i)
{
JitBlock &b = blocks[i];
if (b.invalid)
@ -310,10 +274,10 @@ using namespace Gen;
using namespace std;
void Jit64::LinkBlock(int i)
void JitBlockCache::LinkBlock(int i)
{
LinkBlockExits(i);
Jit64::JitBlock &b = blocks[i];
JitBlock &b = blocks[i];
std::map<u32, int>::iterator iter;
pair<multimap<u32, int>::iterator, multimap<u32, int>::iterator> ppp;
// equal_range(b) returns pair<iterator,iterator> representing the range
@ -327,10 +291,10 @@ using namespace Gen;
}
}
void Jit64::DestroyBlock(int blocknum, bool invalidate)
void JitBlockCache::DestroyBlock(int blocknum, bool invalidate)
{
u32 codebytes = (JIT_OPCODE << 26) | blocknum; //generate from i
Jit64::JitBlock &b = blocks[blocknum];
JitBlock &b = blocks[blocknum];
b.invalid = 1;
if (codebytes == Memory::ReadFast32(b.originalAddress))
{
@ -363,9 +327,9 @@ using namespace Gen;
}
void Jit64::InvalidateCodeRange(u32 address, u32 length)
void JitBlockCache::InvalidateCodeRange(u32 address, u32 length)
{
if (!jo.enableBlocklink)
if (!jit->jo.enableBlocklink)
return;
return;
//This is slow but should be safe (zelda needs it for block linking)

View File

@ -17,8 +17,87 @@
#ifndef _JITCACHE_H
#define _JITCACHE_H
#include <map>
#include "../Gekko.h"
// Will soon introduce the JitBlockCache class here.
#ifdef _WIN32
#include <windows.h>
#endif
enum BlockFlag
{
BLOCK_USE_GQR0 = 0x1, BLOCK_USE_GQR1 = 0x2, BLOCK_USE_GQR2 = 0x4, BLOCK_USE_GQR3 = 0x8,
BLOCK_USE_GQR4 = 0x10, BLOCK_USE_GQR5 = 0x20, BLOCK_USE_GQR6 = 0x40, BLOCK_USE_GQR7 = 0x80,
};
// TODO(ector) - optimize this struct for size
struct JitBlock
{
u32 exitAddress[2]; // 0xFFFFFFFF == unknown
u8 *exitPtrs[2]; // to be able to rewrite the exit jump
bool linkStatus[2];
u32 originalAddress;
u32 originalFirstOpcode; //to be able to restore
u32 codeSize;
u32 originalSize;
int runCount; // for profiling.
#ifdef _WIN32
// we don't really need to save start and stop
// TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;)
LARGE_INTEGER ticStart; // for profiling - time.
LARGE_INTEGER ticStop; // for profiling - time.
LARGE_INTEGER ticCounter; // for profiling - time.
#endif
const u8 *checkedEntry;
bool invalid;
int flags;
};
class Jit64;
typedef void (*CompiledCode)();
class JitBlockCache
{
Jit64 *jit;
u8 **blockCodePointers;
JitBlock *blocks;
int numBlocks;
std::multimap<u32, int> links_to;
int MAX_NUM_BLOCKS;
public:
JitBlockCache() {}
void SetJit(Jit64 *jit_) { jit = jit_; }
const u8* Jit(u32 emaddress);
void Clear();
void Init();
void Shutdown();
void Reset();
bool IsFull() const;
// Code Cache
u32 GetOriginalCode(u32 address);
JitBlock *GetBlock(int no);
void InvalidateCodeRange(u32 address, u32 length);
int GetBlockNumberFromAddress(u32 address);
CompiledCode GetCompiledCode(u32 address);
CompiledCode GetCompiledCodeFromBlock(int blockNumber);
int GetNumBlocks() const;
u8 **GetCodePointers();
void DestroyBlocksWithFlag(BlockFlag death_flag);
void LinkBlocks();
void LinkBlockExits(int i);
void LinkBlock(int i);
void DestroyBlock(int blocknum, bool invalidate);
bool RangeIntersect(int s1, int e1, int s2, int e2) const;
};
#endif

View File

@ -131,18 +131,6 @@
}
}
/*
if (js.next_inst.OPCD == 16) { // bcx
if (!js.next_inst.LK && (js.next_inst.BO & BO_DONT_DECREMENT_FLAG))
{
// it's clear there's plenty of opportunity.
//PanicAlert("merge");
}
}
*/
// unsigned
void Jit64::cmpXX(UGeckoInstruction inst)
{
// USES_CR

View File

@ -41,16 +41,16 @@ struct BlockStat
void WriteProfileResults(const char *filename) {
std::vector<BlockStat> stats;
stats.reserve(jit.GetNumBlocks());
stats.reserve(jit.GetBlockCache()->GetNumBlocks());
u64 cost_sum = 0;
#ifdef _WIN32
u64 timecost_sum = 0;
LARGE_INTEGER countsPerSec;
QueryPerformanceFrequency(&countsPerSec);
#endif
for (int i = 0; i < jit.GetNumBlocks(); i++)
for (int i = 0; i < jit.GetBlockCache()->GetNumBlocks(); i++)
{
const Jit64::JitBlock *block = jit.GetBlock(i);
const JitBlock *block = jit.GetBlockCache()->GetBlock(i);
u64 cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more.
#ifdef _WIN32
u64 timecost = block->ticCounter.QuadPart; // Indeed ;)
@ -73,8 +73,9 @@ void WriteProfileResults(const char *filename) {
fprintf(f, "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
for (unsigned int i = 0; i < stats.size(); i++)
{
const Jit64::JitBlock *block = jit.GetBlock(stats[i].blockNum);
if (block) {
const JitBlock *block = jit.GetBlockCache()->GetBlock(stats[i].blockNum);
if (block)
{
std::string name = g_symbolDB.GetDescription(block->originalAddress);
double percent = 100.0 * (double)stats[i].cost / (double)cost_sum;
#ifdef _WIN32
@ -90,4 +91,4 @@ void WriteProfileResults(const char *filename) {
fclose(f);
}
}
} // namespace

View File

@ -97,7 +97,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
p.SetMode(PointerWrap::MODE_WRITE);
DoState(p);
if(bCompressed) {
if (bCompressed) {
fwrite(&sz, sizeof(int), 1, f);
} else {
int zero = 0;
@ -105,7 +105,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
}
if(bCompressed) {
if (bCompressed) {
if (lzo_init() != LZO_E_OK)
PanicAlert("Internal LZO Error - lzo_init() failed");
else {
@ -163,15 +163,15 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
bCompressedState = (sz != 0);
if(bCompressedState) {
if (bCompressedState) {
if (lzo_init() != LZO_E_OK)
PanicAlert("Internal LZO Error - lzo_init() failed");
else {
lzo_uint i = 0;
buffer = new u8[sz];
for(;;) {
if(fread(&cur_len, 1, sizeof(int), f) == 0)
for (;;) {
if (fread(&cur_len, 1, sizeof(int), f) == 0)
break;
fread(out, 1, cur_len, f);
@ -216,7 +216,8 @@ void State_Shutdown()
// nothing to do, here for consistency.
}
std::string MakeStateFilename(int state_number) {
std::string MakeStateFilename(int state_number)
{
return StringFromFormat(FULL_STATESAVES_DIR "%s.s%02i", Core::GetStartupParameter().GetUniqueID().c_str(), state_number);
}

View File

@ -496,7 +496,9 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
// creates the SCoreStartupParameter as a game is loaded
GetMenuBar()->Check(event.GetId(),!event.IsChecked());
wxMessageBox(_T("Please start a game before changing mode."));
} else {
}
else
{
if (Core::GetState() != Core::CORE_RUN)
{
switch (event.GetId())
@ -504,9 +506,8 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
case IDM_JITUNLIMITED:
Core::g_CoreStartupParameter.bJITUnlimitedCache = event.IsChecked();
jit.ClearCache(); // allow InitCache() even after the game has started
jit.InitCache();
GetMenuBar()->Enable(event.GetId(),!event.IsChecked());
break;
return; // avoid a second jit.ClearCache
case IDM_JITOFF:
Core::g_CoreStartupParameter.bJITOff = event.IsChecked(); break;
case IDM_JITLSOFF:
@ -531,15 +532,15 @@ void CCodeWindow::OnJITOff(wxCommandEvent& event)
Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked(); break;
}
jit.ClearCache();
} else {
}
else
{
//event.Skip(); // this doesn't work
GetMenuBar()->Check(event.GetId(),!event.IsChecked());
wxMessageBox(_T("Please pause the emulator before changing mode."));
}
}
}
// ==============
void CCodeWindow::OnJitMenu(wxCommandEvent& event)
{

View File

@ -138,16 +138,16 @@ void CJitWindow::Compare(u32 em_address)
disassembler x64disasm;
x64disasm.set_syntax_intel();
int block_num = jit.GetBlockNumberFromAddress(em_address);
int block_num = jit.GetBlockCache()->GetBlockNumberFromAddress(em_address);
if (block_num < 0)
{
for (int i = 0; i < 500; i++) {
block_num = jit.GetBlockNumberFromAddress(em_address - 4 * i);
block_num = jit.GetBlockCache()->GetBlockNumberFromAddress(em_address - 4 * i);
if (block_num >= 0)
break;
}
if (block_num >= 0) {
Jit64::JitBlock *block = jit.GetBlock(block_num);
JitBlock *block = jit.GetBlockCache()->GetBlock(block_num);
if (!(block->originalAddress <= em_address && block->originalSize + block->originalAddress >= em_address))
block_num = -1;
}
@ -158,13 +158,13 @@ void CJitWindow::Compare(u32 em_address)
return;
}
}
Jit64::JitBlock *block = jit.GetBlock(block_num);
JitBlock *block = jit.GetBlockCache()->GetBlock(block_num);
// 800031f0
// == Fill in x86 box
memset(xDis, 0, 65536);
const u8 *code = (const u8 *)jit.GetCompiledCodeFromBlock(block_num);
const u8 *code = (const u8 *)jit.GetBlockCache()->GetCompiledCodeFromBlock(block_num);
u64 disasmPtr = (u64)code;
int size = block->codeSize;
const u8 *end = code + size;