use unordered map for JIT RestoreCandidates

also fix WifiRead32?
This commit is contained in:
RSDuck 2020-08-14 23:38:47 +02:00
parent 4cefff2528
commit 4299ef5f06
2 changed files with 33 additions and 122 deletions

View File

@ -38,6 +38,14 @@ namespace ARMJIT
Compiler* JITCompiler;
std::unordered_map<u32, JitBlock*> JitBlocks9;
std::unordered_map<u32, JitBlock*> JitBlocks7;
std::unordered_map<u32, JitBlock*> RestoreCandidates;
TinyVector<u32> InvalidLiterals;
AddressRange CodeIndexITCM[ITCMPhysicalSize / 512];
AddressRange CodeIndexMainRAM[NDS::MainRAMMaxSize / 512];
AddressRange CodeIndexSWRAM[NDS::SharedWRAMSize / 512];
@ -52,9 +60,6 @@ AddressRange CodeIndexNWRAM_A[DSi::NWRAMSize / 512];
AddressRange CodeIndexNWRAM_B[DSi::NWRAMSize / 512];
AddressRange CodeIndexNWRAM_C[DSi::NWRAMSize / 512];
std::unordered_map<u32, JitBlock*> JitBlocks9;
std::unordered_map<u32, JitBlock*> JitBlocks7;
u64 FastBlockLookupITCM[ITCMPhysicalSize / 2];
u64 FastBlockLookupMainRAM[NDS::MainRAMMaxSize / 2];
u64 FastBlockLookupSWRAM[NDS::SharedWRAMSize / 2];
@ -146,8 +151,6 @@ u32 LocaliseCodeAddress(u32 num, u32 addr)
return 0;
}
TinyVector<u32> InvalidLiterals;
template <typename T, int ConsoleType>
T SlowRead9(u32 addr, ARMv5* cpu)
{
@ -286,97 +289,6 @@ void SlowBlockTransfer7(u32 addr, u64* data, u32 num)
INSTANTIATE_SLOWMEM(0)
INSTANTIATE_SLOWMEM(1)
template <typename K, typename V, int Size, V InvalidValue>
struct UnreliableHashTable
{
struct Bucket
{
K KeyA, KeyB;
V ValA, ValB;
};
Bucket Table[Size];
void Reset()
{
for (int i = 0; i < Size; i++)
{
Table[i].ValA = Table[i].ValB = InvalidValue;
}
}
UnreliableHashTable()
{
Reset();
}
V Insert(K key, V value)
{
u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1);
Bucket* bucket = &Table[slot];
if (bucket->ValA == value || bucket->ValB == value)
{
return InvalidValue;
}
else if (bucket->ValA == InvalidValue)
{
bucket->KeyA = key;
bucket->ValA = value;
}
else if (bucket->ValB == InvalidValue)
{
bucket->KeyB = key;
bucket->ValB = value;
}
else
{
V prevVal = bucket->ValB;
bucket->KeyB = bucket->KeyA;
bucket->ValB = bucket->ValA;
bucket->KeyA = key;
bucket->ValA = value;
return prevVal;
}
return InvalidValue;
}
void Remove(K key)
{
u32 slot = XXH3_64bits(&key, sizeof(K)) & (Size - 1);
Bucket* bucket = &Table[slot];
if (bucket->KeyA == key && bucket->ValA != InvalidValue)
{
bucket->ValA = InvalidValue;
if (bucket->ValB != InvalidValue)
{
bucket->KeyA = bucket->KeyB;
bucket->ValA = bucket->ValB;
bucket->ValB = InvalidValue;
}
}
if (bucket->KeyB == key && bucket->ValB != InvalidValue)
bucket->ValB = InvalidValue;
}
V LookUp(K addr)
{
u32 slot = XXH3_64bits(&addr, 4) & (Size - 1);
Bucket* bucket = &Table[slot];
if (bucket->ValA != InvalidValue && bucket->KeyA == addr)
return bucket->ValA;
if (bucket->ValB != InvalidValue && bucket->KeyB == addr)
return bucket->ValB;
return InvalidValue;
}
};
UnreliableHashTable<u32, JitBlock*, 0x800, nullptr> RestoreCandidates;
void Init()
{
JITCompiler = new Compiler();
@ -622,6 +534,20 @@ InterpreterFunc InterpretTHUMB[ARMInstrInfo::tk_Count] =
};
#undef F
void RetireJitBlock(JitBlock* block)
{
auto it = RestoreCandidates.find(block->InstrHash);
if (it != RestoreCandidates.end())
{
delete it->second;
it->second = block;
}
else
{
RestoreCandidates[block->InstrHash] = block;
}
}
void CompileBlock(ARM* cpu)
{
bool thumb = cpu->CPSR & 0x20;
@ -659,10 +585,7 @@ void CompileBlock(ARM* cpu)
}
// some memory has been remapped
JitBlock* prevBlock = RestoreCandidates.Insert(existingBlockIt->second->InstrHash, existingBlockIt->second);
if (prevBlock)
delete prevBlock;
RetireJitBlock(existingBlockIt->second);
map.erase(existingBlockIt);
}
@ -906,11 +829,13 @@ void CompileBlock(ARM* cpu)
u32 literalHash = (u32)XXH3_64bits(literalValues, numLiterals * 4);
u32 instrHash = (u32)XXH3_64bits(instrValues, i * 4);
JitBlock* prevBlock = RestoreCandidates.LookUp(instrHash);
auto prevBlockIt = RestoreCandidates.find(instrHash);
JitBlock* prevBlock = NULL;
bool mayRestore = true;
if (prevBlock)
if (prevBlockIt != RestoreCandidates.end())
{
RestoreCandidates.Remove(instrHash);
prevBlock = prevBlockIt->second;
RestoreCandidates.erase(prevBlockIt);
mayRestore = prevBlock->StartAddr == blockAddr && prevBlock->LiteralHash == literalHash;
@ -932,7 +857,6 @@ void CompileBlock(ARM* cpu)
else
{
mayRestore = false;
prevBlock = NULL;
}
JitBlock* block;
@ -1078,9 +1002,7 @@ void InvalidateByAddr(u32 localAddr)
if (!literalInvalidation)
{
JitBlock* prevBlock = RestoreCandidates.Insert(block->InstrHash, block);
if (prevBlock)
delete prevBlock;
RetireJitBlock(block);
}
else
{
@ -1166,20 +1088,9 @@ void ResetBlockCache()
InvalidLiterals.Clear();
for (int i = 0; i < ARMJIT_Memory::memregions_Count; i++)
memset(FastBlockLookupRegions[i], 0xFF, CodeRegionSizes[i] * sizeof(u64) / 2);
RestoreCandidates.Reset();
for (int i = 0; i < sizeof(RestoreCandidates.Table)/sizeof(RestoreCandidates.Table[0]); i++)
{
if (RestoreCandidates.Table[i].ValA)
{
delete RestoreCandidates.Table[i].ValA;
RestoreCandidates.Table[i].ValA = NULL;
}
if (RestoreCandidates.Table[i].ValA)
{
delete RestoreCandidates.Table[i].ValB;
RestoreCandidates.Table[i].ValB = NULL;
}
}
for (auto it = RestoreCandidates.begin(); it != RestoreCandidates.end(); it++)
delete it->second;
RestoreCandidates.clear();
for (auto it : JitBlocks9)
{
JitBlock* block = it.second;

View File

@ -1008,7 +1008,7 @@ void WifiWrite32(u32 addr, u32 val)
u32 WifiRead32(u32 addr)
{
return Wifi::Read(addr) | (Wifi::Read(addr + 2) << 16);
return (u32)Wifi::Read(addr) | ((u32)Wifi::Read(addr + 2) << 16);
}
template <typename T>