If recompiler block hash table points to wrong block, then walk tree to find correct block instead of recompiling. Speedups of 10-20% on games that were seeing hash aliasing, eg Quake III, System Shock 2, UltraHLE etc
This commit is contained in:
parent
c9111b22a2
commit
36bb949126
4 changed files with 169 additions and 2 deletions
|
|
@ -1292,7 +1292,7 @@ void exec386_dynarec(int cycs)
|
|||
int valid_block = 0;
|
||||
trap = 0;
|
||||
|
||||
if (block)
|
||||
if (block && !abrt)
|
||||
{
|
||||
page_t *page = &pages[phys_addr >> 12];
|
||||
|
||||
|
|
@ -1301,7 +1301,23 @@ void exec386_dynarec(int cycs)
|
|||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + pc) && (block->_cs == cs) &&
|
||||
(block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32);
|
||||
|
||||
if (!valid_block)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
|
||||
if (page->code_present_mask & mask)
|
||||
{
|
||||
/*Walk page tree to see if we find the correct block*/
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr);
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + pc) && (new_block->_cs == cs) &&
|
||||
(new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32);
|
||||
if (valid_block)
|
||||
block = new_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (valid_block && (block->page_mask & page->dirty_mask))
|
||||
{
|
||||
codegen_check_flush(page, page->dirty_mask, phys_addr);
|
||||
|
|
@ -1337,6 +1353,7 @@ void exec386_dynarec(int cycs)
|
|||
{
|
||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||
|
||||
codeblock_hash[hash] = block;
|
||||
// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc);
|
||||
|
||||
inrecomp=1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue