Start reducing size of codeblock_t structure.

Re-arrange all variables needed to run a block to fit in a single cache line.
This commit is contained in:
SarahW 2018-11-28 20:29:48 +00:00
commit 2007c25177
5 changed files with 62 additions and 40 deletions

View file

@ -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];

View file

@ -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;

View file

@ -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);

View file

@ -1,5 +1,6 @@
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include <stddef.h>
#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);

View file

@ -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];