From 2007c25177e0bbc5488f949caa4940da3a155206 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 20:29:48 +0000 Subject: [PATCH] Start reducing size of codeblock_t structure. Re-arrange all variables needed to run a block to fit in a single cache line. --- src/386_dynarec.c | 9 ++++---- src/codegen.h | 45 +++++++++++++++++++-------------------- src/codegen_backend.c | 14 ++++++------ src/codegen_backend_x86.c | 24 ++++++++++++++++++++- src/ibm.h | 10 ++++----- 5 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/386_dynarec.c b/src/386_dynarec.c index bdb1aa7..eb727b0 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -19,7 +19,7 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -uint32_t cpu_cur_status = 0; +uint16_t cpu_cur_status = 0; int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -663,16 +663,15 @@ void exec386_dynarec(int cycs) valid_block = 0; } } - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) { /*FPU top-of-stack does not match the value this block was compiled with, re-compile using dynamic top-of-stack*/ - block->flags &= ~CODEBLOCK_STATIC_TOP; - block->was_recompiled = 0; + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); } } - if (valid_block && block->was_recompiled) + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) { void (*code)() = (void *)&block->data[BLOCK_START]; diff --git a/src/codegen.h b/src/codegen.h index b212cbe..f9d357c 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -37,10 +37,19 @@ typedef struct codeblock_t { + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint16_t ins; + uint8_t TOP; + uint32_t endpc; + uint8_t *data; + uint64_t page_mask, page_mask2; uint64_t *dirty_mask, *dirty_mask2; - uint64_t cmp; - + /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -50,21 +59,6 @@ typedef struct codeblock_t /*Pointers for codeblock tree, used to search for blocks when hash lookup fails.*/ struct codeblock_t *parent, *left, *right; - - int pnt; - int ins; - - int was_recompiled; - int TOP; - - uint32_t pc; - uint32_t _cs; - uint32_t endpc; - uint32_t phys, phys_2; - uint32_t status; - uint32_t flags; - - uint8_t *data; } codeblock_t; uint8_t *codeblock_data; @@ -73,6 +67,8 @@ uint8_t *codeblock_data; #define CODEBLOCK_HAS_FPU 1 /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 +/*Code block has been compiled*/ +#define CODEBLOCK_WAS_RECOMPILED 4 #define BLOCK_PC_INVALID 0xffffffff @@ -83,13 +79,14 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) while (block) { - if (a == block->cmp) + uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); + if (a == block_cmp) { if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) break; } - if (a < block->cmp) + if (a < block_cmp) block = block->left; else block = block->right; @@ -102,8 +99,7 @@ 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; @@ -112,17 +108,20 @@ static inline void codeblock_tree_add(codeblock_t *new_block) else { codeblock_t *old_block = NULL; + uint64_t old_block_cmp; while (block) { old_block = block; - if (a < old_block->cmp) + old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); + + if (a < old_block_cmp) block = block->left; else block = block->right; } - if (a < old_block->cmp) + if (a < old_block_cmp) old_block->left = new_block; else old_block->right = new_block; diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 482e1e9..a24b7a5 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -277,7 +277,6 @@ void codegen_block_init(uint32_t phys_addr) block->ins = 0; block->pc = cs + cpu_state.pc; block->_cs = cs; - block->pnt = block_current; block->phys = phys_addr; block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; block->dirty_mask2 = NULL; @@ -287,8 +286,6 @@ void codegen_block_init(uint32_t phys_addr) block->flags = CODEBLOCK_STATIC_TOP; block->status = cpu_cur_status; - block->was_recompiled = 0; - recomp_page = block->phys & ~0xfff; codeblock_tree_add(block); @@ -301,6 +298,11 @@ ir_data_t *codegen_get_ir_data() return ir_data; } +static int get_block_nr(codeblock_t *block) +{ + return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); +} + void codegen_block_start_recompile(codeblock_t *block) { page_t *page = &pages[block->phys >> 12]; @@ -309,9 +311,9 @@ void codegen_block_start_recompile(codeblock_t *block) mem_flush_write_page(block->phys, cs+cpu_state.pc); block_num = HASH(block->phys); - block_current = block->pnt; + block_current = get_block_nr(block);//block->pnt; - if (block->pc != cs + cpu_state.pc || block->was_recompiled) + if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) fatal("Recompile to used block!\n"); block->status = cpu_cur_status; @@ -342,7 +344,7 @@ void codegen_block_start_recompile(codeblock_t *block) cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; block->TOP = cpu_state.TOP & 7; - block->was_recompiled = 1; + block->flags |= CODEBLOCK_WAS_RECOMPILED; codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); diff --git a/src/codegen_backend_x86.c b/src/codegen_backend_x86.c index 675d9fe..0fd6104 100644 --- a/src/codegen_backend_x86.c +++ b/src/codegen_backend_x86.c @@ -1,5 +1,6 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#include #include "ibm.h" #include "codegen.h" #include "codegen_backend.h" @@ -260,7 +261,28 @@ void codegen_backend_init() long pagesize = sysconf(_SC_PAGESIZE); long pagemask = ~(pagesize - 1); #endif - +pclog("sizeof(codeblock_t)=%i\n", sizeof(codeblock_t)); +pclog(" offsetof(codeblock_t, pc)=%i\n", offsetof(codeblock_t, pc)); +pclog(" offsetof(codeblock_t, _cs)=%i\n", offsetof(codeblock_t, _cs)); +pclog(" offsetof(codeblock_t, phys)=%i\n", offsetof(codeblock_t, phys)); +pclog(" offsetof(codeblock_t, phys_2)=%i\n", offsetof(codeblock_t, phys_2)); +pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status)); +pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags)); +pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins)); +pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP)); +pclog(" offsetof(codeblock_t, endpc)=%i\n", offsetof(codeblock_t, endpc)); +pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data)); +pclog(" offsetof(codeblock_t, page_mask=%i\n", offsetof(codeblock_t, page_mask)); +pclog(" offsetof(codeblock_t, page_mask2=%i\n", offsetof(codeblock_t, page_mask2)); +pclog(" offsetof(codeblock_t, dirty_mask=%i\n", offsetof(codeblock_t, dirty_mask)); +pclog(" offsetof(codeblock_t, dirty_mask2=%i\n", offsetof(codeblock_t, dirty_mask2)); +pclog(" offsetof(codeblock_t, prev=%i\n", offsetof(codeblock_t, prev)); +pclog(" offsetof(codeblock_t, next=%i\n", offsetof(codeblock_t, next)); +pclog(" offsetof(codeblock_t, prev_2=%i\n", offsetof(codeblock_t, prev_2)); +pclog(" offsetof(codeblock_t, next_2=%i\n", offsetof(codeblock_t, next_2)); +pclog(" offsetof(codeblock_t, parent=%i\n", offsetof(codeblock_t, parent)); +pclog(" offsetof(codeblock_t, left=%i\n", offsetof(codeblock_t, left)); +pclog(" offsetof(codeblock_t, right=%i\n", offsetof(codeblock_t, right)); codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); #if defined WIN32 || defined _WIN32 || defined _WIN32 codeblock_data = VirtualAlloc(NULL, (BLOCK_SIZE+1) * BLOCK_DATA_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); diff --git a/src/ibm.h b/src/ibm.h index e6488e4..2221e8c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -194,7 +194,7 @@ struct #define cycles cpu_state._cycles -extern uint32_t cpu_cur_status; +extern uint16_t cpu_cur_status; /*The flags below must match in both cpu_cur_status and block->status for a block to be valid*/ @@ -202,13 +202,13 @@ extern uint32_t cpu_cur_status; #define CPU_STATUS_STACK32 (1 << 1) #define CPU_STATUS_PMODE (1 << 2) #define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_FLAGS 0xffff +#define CPU_STATUS_FLAGS 0xff /*If the flags below are set in cpu_cur_status, they must be set in block->status. Otherwise they are ignored*/ -#define CPU_STATUS_NOTFLATDS (1 << 16) -#define CPU_STATUS_NOTFLATSS (1 << 17) -#define CPU_STATUS_MASK 0xffff0000 +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_MASK 0xff00 #define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0];