about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-01-23 10:01:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-01-23 10:01:11 +0100
commit89da530898fa08c23b59e3e3bf64f266f113e014 (patch)
treee38ddfff281f2d2144916be550b839081cbcd095 /src
parent2367e7df504dadd495abe095bd167cce67afb713 (diff)
downloadbox64-89da530898fa08c23b59e3e3bf64f266f113e014.tar.gz
box64-89da530898fa08c23b59e3e3bf64f266f113e014.zip
[DYNAREC] use an rbtree for dynablock size and max_db_size update
Diffstat (limited to 'src')
-rw-r--r--src/box64context.c10
-rw-r--r--src/dynarec/dynablock.c36
-rw-r--r--src/include/box64context.h2
-rw-r--r--src/include/rbtree.h1
-rw-r--r--src/tools/rbtree.c14
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) {