diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-01-23 10:01:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-01-23 10:01:11 +0100 |
| commit | 89da530898fa08c23b59e3e3bf64f266f113e014 (patch) | |
| tree | e38ddfff281f2d2144916be550b839081cbcd095 | |
| parent | 2367e7df504dadd495abe095bd167cce67afb713 (diff) | |
| download | box64-89da530898fa08c23b59e3e3bf64f266f113e014.tar.gz box64-89da530898fa08c23b59e3e3bf64f266f113e014.zip | |
[DYNAREC] use an rbtree for dynablock size and max_db_size update
| -rw-r--r-- | src/box64context.c | 10 | ||||
| -rw-r--r-- | src/dynarec/dynablock.c | 36 | ||||
| -rw-r--r-- | src/include/box64context.h | 2 | ||||
| -rw-r--r-- | src/include/rbtree.h | 1 | ||||
| -rw-r--r-- | src/tools/rbtree.c | 14 |
5 files changed, 59 insertions, 4 deletions
diff --git a/src/box64context.c b/src/box64context.c index b302b777..679ee108 100644 --- a/src/box64context.c +++ b/src/box64context.c @@ -21,6 +21,7 @@ #include "signals.h" #include "rcfile.h" #include "gltools.h" +#include "rbtree.h" EXPORTDYN void initAllHelpers(box64context_t* context) @@ -264,6 +265,10 @@ box64context_t *NewBox64Context(int argc) context->globdata = NewMapSymbols(); initAllHelpers(context); + + #ifdef DYNAREC + context->db_sizes = init_rbtree(); + #endif return context; } @@ -359,6 +364,11 @@ void FreeBox64Context(box64context_t** context) FreeMapSymbols(&ctx->globdata); +#ifdef DYNAREC + //dynarec_log(LOG_INFO, "BOX64 Dynarec at exit: Max DB=%d, righter=%d\n", ctx->max_db_size, rb_get_righter(ctx->db_sizes)); + delete_rbtree(ctx->db_sizes); +#endif + finiAllHelpers(ctx); #ifdef DYNAREC diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index c5fa1dc5..fda14912 100644 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -25,6 +25,7 @@ #include "custommem.h" #include "khash.h" +#include "rbtree.h" uint32_t X31_hash_code(void* addr, int len) { @@ -47,6 +48,18 @@ dynablock_t* InvalidDynablock(dynablock_t* db, int need_lock) mutex_lock(&my_context->mutex_dyndump); db->done = 0; db->gone = 1; + int db_size = db->x64_size; + if(db_size && my_context) { + uint32_t n = rb_get(my_context->db_sizes, db_size); + if(n>1) + rb_set(my_context->db_sizes, db_size, db_size+1, n-1); + else + rb_unset(my_context->db_sizes, db_size, db_size+1); + if(db_size == my_context->max_db_size) { + my_context->max_db_size = rb_get_righter(my_context->db_sizes); + dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size); + } + } if(need_lock) mutex_unlock(&my_context->mutex_dyndump); } @@ -81,6 +94,18 @@ void FreeDynablock(dynablock_t* db, int need_lock) dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size); db->done = 0; db->gone = 1; + int db_size = db->x64_size; + if(db_size && my_context) { + uint32_t n = rb_get(my_context->db_sizes, db_size); + if(n>1) + rb_set(my_context->db_sizes, db_size, db_size+1, n-1); + else + rb_unset(my_context->db_sizes, db_size, db_size+1); + if(db_size == my_context->max_db_size) { + my_context->max_db_size = rb_get_righter(my_context->db_sizes); + dynarec_log(LOG_INFO, "BOX64 Dynarec: lower max_db=%d\n", my_context->max_db_size); + } + } if(db->previous) FreeInvalidDynablock(db->previous, 0); FreeDynarecMap((uintptr_t)db->actual_block); @@ -219,17 +244,20 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t } // check size if(block) { - int blocksz = block->x64_size; - if(blocksz>my_context->max_db_size) - my_context->max_db_size = blocksz; // fill-in jumptable if(!addJumpTableIfDefault64(block->x64_addr, block->dirty?block->jmpnext:block->block)) { FreeDynablock(block, 0); block = getDB(addr); MarkDynablock(block); // just in case... } else { - if(block->x64_size) + if(block->x64_size) { + if(block->x64_size>my_context->max_db_size) { + my_context->max_db_size = block->x64_size; + dynarec_log(LOG_INFO, "BOX64 Dynarec: higher max_db=%d\n", my_context->max_db_size); + } block->done = 1; // don't validate the block if the size is null, but keep the block + rb_set(my_context->db_sizes, block->x64_size, block->x64_size+1, rb_get(my_context->db_sizes, block->x64_size)+1); + } } } if(need_lock) diff --git a/src/include/box64context.h b/src/include/box64context.h index 96442038..da09bc49 100644 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -27,6 +27,7 @@ typedef struct kh_mapsymbols_s kh_mapsymbols_t; typedef struct library_s library_t; typedef struct linkmap_s linkmap_t; typedef struct kh_threadstack_s kh_threadstack_t; +typedef struct rbtree rbtree; typedef struct atfork_fnc_s { uintptr_t prepare; uintptr_t parent; @@ -154,6 +155,7 @@ typedef struct box64context_s { pthread_mutex_t mutex_bridge; #endif uintptr_t max_db_size; // the biggest (in x86_64 instructions bytes) built dynablock + rbtree* db_sizes; int trace_dynarec; pthread_mutex_t mutex_lock; // this is for the Test interpreter #ifdef __riscv diff --git a/src/include/rbtree.h b/src/include/rbtree.h index 82695d8c..c210d55d 100644 --- a/src/include/rbtree.h +++ b/src/include/rbtree.h @@ -12,6 +12,7 @@ uint32_t rb_get(rbtree *tree, uintptr_t addr); int rb_get_end(rbtree* tree, uintptr_t addr, uint32_t* val, uintptr_t* end); int rb_set(rbtree *tree, uintptr_t start, uintptr_t end, uint32_t data); int rb_unset(rbtree *tree, uintptr_t start, uintptr_t end); +uintptr_t rb_get_righter(rbtree *tree); void print_rbtree(const rbtree *tree); diff --git a/src/tools/rbtree.c b/src/tools/rbtree.c index 1fa08b71..a7e4daf1 100644 --- a/src/tools/rbtree.c +++ b/src/tools/rbtree.c @@ -782,6 +782,20 @@ dynarec_log(LOG_DEBUG, "rb_unset(tree, 0x%lX, 0x%lX);\n", start, end); return 0; } +uintptr_t rb_get_righter(rbtree* tree) +{ +dynarec_log(LOG_DEBUG, "rb_get_righter(tree);\n"); + if (!tree->root) return 0; + + rbnode *node = tree->root; + while (node) { + if(!node->right) + return node->start; + node = node->right; + } + return 0; +} + #include <stdio.h> void print_rbnode(const rbnode *node, unsigned depth, uintptr_t minstart, uintptr_t maxend, unsigned *bdepth) { if (!node) { |