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

View File

@ -1008,7 +1008,7 @@ void WifiWrite32(u32 addr, u32 val)
u32 WifiRead32(u32 addr) 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> template <typename T>