mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
asmjit: Minimal locking when reading, also only lock when actually writing to the db
This commit is contained in:
parent
f69121116a
commit
78f09d7645
@ -12,9 +12,24 @@ std::shared_ptr<spu_function_t> SPUDatabase::find(const be_t<u32>* 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)
|
||||
{
|
||||
return func;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,23 +58,27 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
|
||||
// Key for multimap
|
||||
const u64 key = entry | u64{ ls[entry / 4] } << 32;
|
||||
const be_t<u32>* base = ls + entry / 4;
|
||||
const u32 block_sz = max_limit - entry;
|
||||
|
||||
{
|
||||
reader_lock lock(m_mutex);
|
||||
//reader_lock lock(m_mutex);
|
||||
|
||||
// Try to find existing function in the database
|
||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
||||
if (auto func = find(base, key, block_sz))
|
||||
{
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
||||
writer_lock lock(m_mutex);
|
||||
|
||||
// Double-check
|
||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
||||
{
|
||||
return func;
|
||||
writer_lock lock(m_mutex);
|
||||
|
||||
// Double-check
|
||||
if (auto func = find(base, key, block_sz))
|
||||
{
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize block entries with the function entry point
|
||||
@ -81,11 +100,15 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
|
||||
const auto type = s_spu_itype.decode(op.opcode);
|
||||
|
||||
// Find existing function
|
||||
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
||||
{
|
||||
limit = pos;
|
||||
break;
|
||||
//reader_lock lock(m_mutex);
|
||||
|
||||
// Find existing function
|
||||
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
||||
{
|
||||
limit = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional analysis at the beginning of the block
|
||||
@ -311,8 +334,23 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||
// Set whether the function can reset stack
|
||||
func->does_reset_stack = ila_sp_pos < limit;
|
||||
|
||||
// Add function to the database
|
||||
m_db.emplace(key, func);
|
||||
// Lock here just before we write to the db
|
||||
// Its is unlikely that the second check will pass anyway so we delay this step since compiling functions is very fast
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
LOG_SUCCESS(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user