Implement spu_runtime::reset

To handle JIT: Out Of Memory error.
This commit is contained in:
Nekotekina 2019-03-18 23:01:16 +03:00
parent 1880a17f79
commit 4b381fbbb1
7 changed files with 332 additions and 92 deletions

View file

@ -46,35 +46,20 @@ void spu_recompiler::init()
}
}
spu_function_t spu_recompiler::compile(std::vector<u32>&& func_rv)
bool spu_recompiler::compile(u64 last_reset_count, const std::vector<u32>& func)
{
init();
const auto fn_location = m_spurt->find(last_reset_count, func);
std::unique_lock lock(m_spurt->m_mutex);
// Try to find existing function, register new one if necessary
const auto fn_info = m_spurt->m_map.emplace(std::move(func_rv), nullptr);
auto& fn_location = fn_info.first->second;
if (!fn_location && !fn_info.second)
if (fn_location == spu_runtime::g_dispatcher)
{
// Wait if already in progress
while (!fn_location)
{
m_spurt->m_cond.wait(lock);
}
return true;
}
if (fn_location)
if (!fn_location)
{
return fn_location;
return false;
}
auto& func = fn_info.first->first;
lock.unlock();
using namespace asmjit;
SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode);
@ -833,12 +818,20 @@ spu_function_t spu_recompiler::compile(std::vector<u32>&& func_rv)
// Compile and get function address
spu_function_t fn;
if (m_asmrt.add(&fn, &code))
if (auto err = m_asmrt.add(&fn, &code))
{
if (err == asmjit::ErrorCode::kErrorNoVirtualMemory)
{
return false;
}
LOG_FATAL(SPU, "Failed to build a function");
}
m_spurt->add(*fn_info.first, fn);
if (!m_spurt->add(last_reset_count, fn_location, fn))
{
return false;
}
if (g_cfg.core.spu_debug)
{
@ -848,7 +841,7 @@ spu_function_t spu_recompiler::compile(std::vector<u32>&& func_rv)
log += "\n\n\n";
// Append log file
fs::file(m_spurt->m_cache_path + "spu.log", fs::write + fs::append).write(log);
fs::file(m_spurt->get_cache_path() + "spu.log", fs::write + fs::append).write(log);
}
if (m_cache && g_cfg.core.spu_cache)
@ -856,7 +849,7 @@ spu_function_t spu_recompiler::compile(std::vector<u32>&& func_rv)
m_cache->add(func);
}
return fn;
return true;
}
spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register
@ -947,11 +940,21 @@ void spu_recompiler::branch_fixed(u32 target)
return;
}
const auto ppptr = m_spurt->make_branch_patchpoint(target);
c->mov(SPU_OFF_32(pc), target);
c->xor_(qw0->r32(), qw0->r32());
c->cmp(SPU_OFF_32(state), 0);
c->jnz(label_stop);
c->jmp(imm_ptr(m_spurt->make_branch_patchpoint(target)));
if (ppptr)
{
c->jmp(imm_ptr(ppptr));
}
else
{
c->ret();
}
}
void spu_recompiler::branch_indirect(spu_opcode_t op, bool jt, bool ret)