Implement more intelligent out-of-memory algorithm.
This commit is contained in:
parent
bf392ffd3a
commit
ec18c8a2fb
8 changed files with 25 additions and 9 deletions
|
|
@ -290,6 +290,7 @@ void codegen_block_remove();
|
|||
void codegen_block_start_recompile(codeblock_t *block);
|
||||
void codegen_block_end_recompile(codeblock_t *block);
|
||||
void codegen_block_end();
|
||||
void codegen_delete_block(codeblock_t *block);
|
||||
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
void codegen_generate_seg_restore();
|
||||
void codegen_set_op32();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ typedef struct mem_block_t
|
|||
{
|
||||
uint32_t offset; /*Offset into mem_block_alloc*/
|
||||
uint32_t next;
|
||||
uint16_t code_block;
|
||||
} mem_block_t;
|
||||
|
||||
static mem_block_t mem_blocks[MEM_BLOCK_NR];
|
||||
|
|
@ -35,6 +36,7 @@ void codegen_allocator_init()
|
|||
for (c = 0; c < MEM_BLOCK_NR; c++)
|
||||
{
|
||||
mem_blocks[c].offset = c * MEM_BLOCK_SIZE;
|
||||
mem_blocks[c].code_block = BLOCK_INVALID;
|
||||
if (c < MEM_BLOCK_NR-1)
|
||||
mem_blocks[c].next = c+2;
|
||||
else
|
||||
|
|
@ -43,15 +45,19 @@ void codegen_allocator_init()
|
|||
mem_block_free_list = 1;
|
||||
}
|
||||
|
||||
mem_block_t *codegen_allocator_allocate(mem_block_t *parent)
|
||||
mem_block_t *codegen_allocator_allocate(mem_block_t *parent, int code_block)
|
||||
{
|
||||
mem_block_t *block;
|
||||
uint32_t block_nr;
|
||||
|
||||
while (!mem_block_free_list)
|
||||
{
|
||||
if (!codegen_purge_purgable_list())
|
||||
codegen_delete_random_block(1);
|
||||
/*Pick a random memory block and free the owning code block*/
|
||||
block_nr = rand() & MEM_BLOCK_MASK;
|
||||
block = &mem_blocks[block_nr];
|
||||
|
||||
if (block->code_block && block->code_block != code_block)
|
||||
codegen_delete_block(&codeblock[block->code_block]);
|
||||
}
|
||||
// fatal("codegen_allocator_allocate: free list empty!\n");
|
||||
|
||||
|
|
@ -60,6 +66,7 @@ mem_block_t *codegen_allocator_allocate(mem_block_t *parent)
|
|||
block = &mem_blocks[block_nr-1];
|
||||
mem_block_free_list = block->next;
|
||||
|
||||
block->code_block = code_block;
|
||||
if (parent)
|
||||
{
|
||||
/*Add to parent list*/
|
||||
|
|
@ -88,6 +95,7 @@ void codegen_allocator_free(mem_block_t *block)
|
|||
codegen_allocator_usage--;
|
||||
|
||||
block->next = mem_block_free_list;
|
||||
block->code_block = BLOCK_INVALID;
|
||||
mem_block_free_list = block_nr;
|
||||
block_nr = next_block_nr;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@
|
|||
#define MEM_BLOCK_NR 131072
|
||||
#endif
|
||||
|
||||
#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1)
|
||||
#define MEM_BLOCK_SIZE 0x3c0
|
||||
|
||||
void codegen_allocator_init();
|
||||
/*Allocate a mem_block_t, and the associated backing memory.
|
||||
If parent is non-NULL, then the new block will be added to the list in
|
||||
parent->next*/
|
||||
struct mem_block_t *codegen_allocator_allocate(struct mem_block_t *parent);
|
||||
struct mem_block_t *codegen_allocator_allocate(struct mem_block_t *parent, int code_block);
|
||||
/*Free a mem_block_t, and any subsequent blocks in the list at block->next*/
|
||||
void codegen_allocator_free(struct mem_block_t *block);
|
||||
/*Get a pointer to the backing memory associated with block*/
|
||||
|
|
|
|||
|
|
@ -300,6 +300,12 @@ static void delete_block(codeblock_t *block)
|
|||
block_free_list_add(block);
|
||||
}
|
||||
|
||||
void codegen_delete_block(codeblock_t *block)
|
||||
{
|
||||
if (block->pc != BLOCK_PC_INVALID)
|
||||
delete_block(block);
|
||||
}
|
||||
|
||||
void codegen_delete_random_block(int required_mem_block)
|
||||
{
|
||||
int block_nr = rand() & BLOCK_MASK;
|
||||
|
|
@ -419,7 +425,7 @@ void codegen_block_start_recompile(codeblock_t *block)
|
|||
if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED))
|
||||
fatal("Recompile to used block!\n");
|
||||
|
||||
block->head_mem_block = codegen_allocator_allocate(NULL);
|
||||
block->head_mem_block = codegen_allocator_allocate(NULL, block_current);
|
||||
block->data = codeblock_allocator_get_ptr(block->head_mem_block);
|
||||
|
||||
block->status = cpu_cur_status;
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ void codegen_backend_init()
|
|||
block_current = 0;
|
||||
block_pos = 0;
|
||||
block = &codeblock[block_current];
|
||||
codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL);
|
||||
codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current);
|
||||
codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block);
|
||||
block_write_data = codeblock[block_current].data;
|
||||
build_loadstore_routines(&codeblock[block_current]);
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ static inline void codegen_alloc_bytes(codeblock_t *block, int size)
|
|||
if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES))
|
||||
{
|
||||
/*Current block is full. Allocate a new block*/
|
||||
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block);
|
||||
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block));
|
||||
uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block);
|
||||
|
||||
/*Add a jump instruction to the new block*/
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2));
|
|||
block_current = 0;
|
||||
block_pos = 0;
|
||||
block = &codeblock[block_current];
|
||||
block->head_mem_block = codegen_allocator_allocate(NULL);
|
||||
block->head_mem_block = codegen_allocator_allocate(NULL, block_current);
|
||||
block->data = codeblock_allocator_get_ptr(block->head_mem_block);
|
||||
block_write_data = block->data;
|
||||
build_loadstore_routines(block);
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val)
|
|||
static void codegen_allocate_new_block(codeblock_t *block)
|
||||
{
|
||||
/*Current block is full. Allocate a new block*/
|
||||
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block);
|
||||
struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block));
|
||||
uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block);
|
||||
|
||||
/*Add a jump instruction to the new block*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue