From a174a88c4977c9ed9f3b9f6a366e1324215701af Mon Sep 17 00:00:00 2001 From: SarahW Date: Tue, 8 Nov 2016 21:30:48 +0000 Subject: [PATCH] Codeblock tree now includes both physical and virtual addresses into key. Fixes performance issues with Windows 3.1. --- src/386_dynarec.c | 2 +- src/codegen.h | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 11d0815..dbc4fa2 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1309,7 +1309,7 @@ void exec386_dynarec(int cycs) 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); + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && diff --git a/src/codegen.h b/src/codegen.h index 3f3f38d..c70094e 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -59,6 +59,8 @@ typedef struct codeblock_t uint32_t flags; int TOP; + uint64_t cmp; + uint8_t data[2048]; } codeblock_t; @@ -67,15 +69,16 @@ typedef struct codeblock_t /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 -static inline codeblock_t *codeblock_tree_find(uint32_t phys) +static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) { codeblock_t *block = pages[phys >> 12].head; + uint64_t a = _cs | ((uint64_t)phys << 32); while (block) { - if (phys == block->phys) + if (a == block->cmp) break; - else if (phys < block->phys) + else if (a < block->cmp) block = block->left; else block = block->right; @@ -87,7 +90,9 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys) static inline void codeblock_tree_add(codeblock_t *new_block) { codeblock_t *block = pages[new_block->phys >> 12].head; - + uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); + new_block->cmp = a; + if (!block) { pages[new_block->phys >> 12].head = new_block; @@ -96,17 +101,17 @@ static inline void codeblock_tree_add(codeblock_t *new_block) else { codeblock_t *old_block = NULL; + while (block) { old_block = block; - - if (new_block->phys < old_block->phys) + if (a < old_block->cmp) block = block->left; else block = block->right; } - if (new_block->phys < old_block->phys) + if (a < old_block->cmp) old_block->left = new_block; else old_block->right = new_block;