diff --git a/rpcs3/Emu/Cell/SPUAnalyser.cpp b/rpcs3/Emu/Cell/SPUAnalyser.cpp index d370d9f7a8..16609af0f0 100644 --- a/rpcs3/Emu/Cell/SPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/SPUAnalyser.cpp @@ -12,24 +12,9 @@ std::shared_ptr SPUDatabase::find(const be_t* data, u64 key const auto& func = found.first->second; // Compare binary data explicitly (TODO: optimize) - //if (LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0) + if (LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0) { - const auto dwords = (u32*)(func->data.data()); - const auto cast_data = (u32*)(data); - const auto limit = std::min(max_size, func->size) >> 2; - - bool failed = false; - for (u32 dword = 0; dword < limit; dword++) - { - if (dwords[dword] != cast_data[dword]) - { - failed = true; - break; - } - } - - if (!failed) - return func; + return func; } } @@ -339,15 +324,6 @@ std::shared_ptr SPUDatabase::analyse(const be_t* ls, u32 en { writer_lock lock(m_mutex); - if (0)//funcs_length != m_db.size()) - { - // Double-check if something new has been written before we got here - if (auto func = find(base, key, block_sz)) - { - return func; - } - } - // Add function to the database m_db.emplace(key, func); } diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 0712dcc2cf..ed52c5c24e 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -22,8 +22,23 @@ void spu_recompiler_base::enter(SPUThread& spu) // Get SPU LS pointer const auto _ls = vm::ps3::_ptr(spu.offset); - // Always validate (TODO) - const auto func = spu.spu_db->analyse(_ls, spu.pc); + // Search if cached data matches + bool found = false; + auto func = spu.compiled_cache[spu.pc / 4]; + + if (func) + { + const be_t* base = _ls + spu.pc / 4; + if (std::memcmp(base, func->data.data(), func->size) == 0) + found = true; + } + + // Check shared db if we dont have a match + if (!found) + { + func = spu.spu_db->analyse(_ls, spu.pc); + spu.compiled_cache[spu.pc / 4] = func; + } // Reset callstack if necessary if ((func->does_reset_stack && spu.recursion_level) || spu.recursion_level >= 128) @@ -32,6 +47,7 @@ void spu_recompiler_base::enter(SPUThread& spu) return; } + // Compile if needed if (!func->compiled) { if (!spu.spu_rec) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index d20c5d1240..9bd485f14f 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -582,6 +582,7 @@ public: std::exception_ptr pending_exception; + std::array, 65536> compiled_cache; std::shared_ptr spu_db; std::shared_ptr spu_rec; u32 recursion_level = 0;