jit-ir: Restore emuhacks before saving state.

Let's just ask jit to do this, not its block cache directly.
This commit is contained in:
Unknown W. Brackets committed 2016-05-14 08:59:44 -07:00
1 parent b74df87db0
commit e37777648e
9 files changed
+73 -9

No files matched your search

+3
View File
@@ -170,6 +170,9 @@ public:
JitBlockCache *GetBlockCache() override { return &blocks; }
std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks.RestoreSavedEmuHackOps(saved); }
void ClearCache() override;
void InvalidateCache() override;
void InvalidateCacheAt(u32 em_address, int length = 4) override;
+3
View File
@@ -171,6 +171,9 @@ public:
JitBlockCache *GetBlockCache() { return &blocks; }
std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks.RestoreSavedEmuHackOps(saved); }
void ClearCache();
void InvalidateCache();
void InvalidateCacheAt(u32 em_address, int length = 4);
+44
View File
@@ -159,6 +159,50 @@ void IRBlockCache::InvalidateICache(u32 addess, u32 length) {
// TODO
}
std::vector<u32> IRBlockCache::SaveAndClearEmuHackOps() {
std::vector<u32> result;
result.resize(size_);
for (int number = 0; number < size_; ++number) {
IRBlock &b = blocks_[number];
if (b.IsValid() && b.RestoreOriginalFirstOp(number)) {
result[number] = number;
} else {
result[number] = 0;
}
}
return result;
}
void IRBlockCache::RestoreSavedEmuHackOps(std::vector<u32> saved) {
if (size_ != (int)saved.size()) {
ERROR_LOG(JIT, "RestoreSavedEmuHackOps: Wrong saved block size.");
return;
}
for (int number = 0; number < size_; ++number) {
IRBlock &b = blocks_[number];
// Only if we restored it, write it back.
if (b.IsValid() && saved[number] != 0 && b.HasOriginalFirstOp()) {
b.Finalize(number);
}
}
}
bool IRBlock::HasOriginalFirstOp() {
return Memory::ReadUnchecked_U32(origAddr_) == origFirstOpcode_.encoding;
}
bool IRBlock::RestoreOriginalFirstOp(int number) {
const u32 emuhack = MIPS_EMUHACK_OPCODE | number;
if (Memory::ReadUnchecked_U32(origAddr_) == emuhack) {
Memory::Write_Opcode_JIT(origAddr_, origFirstOpcode_);
return true;
}
return false;
}
void IRBlock::Finalize(int number) {
origFirstOpcode_ = Memory::Read_Opcode_JIT(origAddr_);
MIPSOpcode opcode = MIPSOpcode(MIPS_EMUHACK_OPCODE | number);
+10
View File
@@ -97,6 +97,9 @@ public:
const u32 *GetConstants() const { return const_; }
int GetNumInstructions() const { return numInstructions_; }
MIPSOpcode GetOriginalFirstOp() const { return origFirstOpcode_; }
bool HasOriginalFirstOp();
bool RestoreOriginalFirstOp(int number);
bool IsValid() const { return origAddr_ != 0; }
void Finalize(int number);
void Destroy(int number);
@@ -127,6 +130,10 @@ public:
return nullptr;
}
}
std::vector<u32> SaveAndClearEmuHackOps();
void RestoreSavedEmuHackOps(std::vector<u32> saved);
private:
int size_;
std::vector<IRBlock> blocks_;
@@ -151,6 +158,9 @@ public:
JitBlockCache *GetBlockCache() override { return nullptr; }
MIPSOpcode GetOriginalOp(MIPSOpcode op) override;
std::vector<u32> SaveAndClearEmuHackOps() override { return blocks_.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks_.RestoreSavedEmuHackOps(saved); }
void ClearCache();
void InvalidateCache();
void InvalidateCacheAt(u32 em_address, int length = 4);
+5
View File
@@ -132,6 +132,11 @@ namespace MIPSComp {
virtual void ClearCache() = 0;
virtual MIPSOpcode GetOriginalOp(MIPSOpcode op) = 0;
// No jit operations may be run between these calls.
// Meant to be used to make memory safe for savestates, memcpy, etc.
virtual std::vector<u32> SaveAndClearEmuHackOps() = 0;
virtual void RestoreSavedEmuHackOps(std::vector<u32> saved) = 0;
// Block linking. This may need to work differently for whole-function JITs and stuff
// like that.
virtual void LinkBlock(u8 *exitPoint, const u8 *entryPoint) = 0;
+3
View File
@@ -131,6 +131,9 @@ public:
JitBlockCache *GetBlockCache() { return &blocks; }
std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks.RestoreSavedEmuHackOps(saved); }
void ClearCache();
void InvalidateCache();
void InvalidateCacheAt(u32 em_address, int length = 4);
+3
View File
@@ -163,6 +163,9 @@ public:
JitBlockCache *GetBlockCache() { return &blocks; }
MIPSOpcode GetOriginalOp(MIPSOpcode op) override;
std::vector<u32> SaveAndClearEmuHackOps() override { return blocks.SaveAndClearEmuHackOps(); }
void RestoreSavedEmuHackOps(std::vector<u32> saved) override { blocks.RestoreSavedEmuHackOps(saved); }
void ClearCache();
void InvalidateCache() override;
void InvalidateCacheAt(u32 em_address, int length = 4) {
-2
View File
@@ -425,8 +425,6 @@ __forceinline static Opcode Read_Instruction(u32 address, bool resolveReplacemen
}
if (MIPS_IS_RUNBLOCK(inst.encoding) && MIPSComp::jit) {
JitBlockCache *bc = MIPSComp::jit->GetBlockCache();
inst = MIPSComp::jit->GetOriginalOp(inst);
if (resolveReplacements && MIPS_IS_REPLACEMENT(inst)) {
u32 op;
+2 -7
View File
@@ -233,15 +233,10 @@ namespace SaveState
auto savedReplacements = SaveAndClearReplacements();
if (MIPSComp::jit && p.mode == p.MODE_WRITE)
{
auto blockCache = MIPSComp::jit->GetBlockCache();
std::vector<u32> savedBlocks;
if (blockCache) {
savedBlocks = blockCache->SaveAndClearEmuHackOps();
}
savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps();
Memory::DoState(p);
if (blockCache) {
blockCache->RestoreSavedEmuHackOps(savedBlocks);
}
MIPSComp::jit->RestoreSavedEmuHackOps(savedBlocks);
}
else
Memory::DoState(p);