about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-10 19:00:47 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-10 19:00:47 +0200
commit51d9eb966db1ef22af0eaa5848556d74395bcf5d (patch)
tree305c551a6623e2d877a5a91528de17640c2279b2 /src
parent310d4016fa9632a575e2c3ba673206f29b76ae23 (diff)
downloadbox64-51d9eb966db1ef22af0eaa5848556d74395bcf5d.tar.gz
box64-51d9eb966db1ef22af0eaa5848556d74395bcf5d.zip
[DYNAREC] Speedup a bit DYNAREC_DIRTY=1
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c2
-rw-r--r--src/dynarec/dynablock.c33
-rw-r--r--src/dynarec/dynarec_native.c4
-rw-r--r--src/libtools/signals.c6
4 files changed, 28 insertions, 17 deletions
diff --git a/src/custommem.c b/src/custommem.c
index ef227b1b..ae6df5b0 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -1710,7 +1710,7 @@ static int hotpage_cnt = 0;
 static int repeated_count = 0;
 static uintptr_t repeated_page = 0;
 #define HOTPAGE_MARK 64
-#define HOTPAGE_DIRTY 2
+#define HOTPAGE_DIRTY 4
 void SetHotPage(uintptr_t addr)
 {
     hotpage = addr&~(box64_pagesize-1);
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 7eedfe10..561ab529 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -273,12 +273,15 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
 
 dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
 {
-    if(isInHotPage(addr))
+    int is_inhotpage = isInHotPage(addr);
+    if(is_inhotpage && !BOX64ENV(dynarec_dirty))
         return NULL;
     dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
     if(db && db->done && db->block && getNeedTest(addr)) {
         if (db->always_test) SchedYield(); // just calm down...
         uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
+        if(is_inhotpage && hash!=db->hash)
+            return NULL;    // will be handle when hotpage is over
         int need_lock = mutex_trylock(&my_context->mutex_dyndump);
         if(hash!=db->hash) {
             db->done = 0;   // invalidating the block
@@ -294,19 +297,23 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
             } else
                 FreeInvalidDynablock(old, need_lock);
         } else {
-            dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr);
-            if(db->always_test)
-                protectDB((uintptr_t)db->x64_addr, db->x64_size);
-            else {
-                #ifdef ARCH_NOP
-                if(db->callret_size) {
-                    // mark all callrets to UDF
-                    for(int i=0; i<db->callret_size; ++i)
-                        *(uint32_t*)(db->block+db->callrets[i].offs) = ARCH_NOP;
-                    ClearCache(db->block, db->size);
+            if(is_inhotpage) {
+                // log?
+            } else {
+                dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr);
+                if(db->always_test)
+                    protectDB((uintptr_t)db->x64_addr, db->x64_size);
+                else {
+                    #ifdef ARCH_NOP
+                    if(db->callret_size) {
+                        // mark all callrets to UDF
+                        for(int i=0; i<db->callret_size; ++i)
+                            *(uint32_t*)(db->block+db->callrets[i].offs) = ARCH_NOP;
+                        ClearCache(db->block, db->size);
+                    }
+                    #endif
+                    protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext);
                 }
-                #endif
-                protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext);
             }
         }
         if(!need_lock)
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 5478fc43..7574b124 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -605,6 +605,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
         dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock at %p as another one is going on\n", (void*)addr);
         return NULL;
     }
+    if(checkInHotPage(addr)) {
+        dynarec_log(LOG_DEBUG, "Not creating dynablock at %p as in a HotPage\n", (void*)addr);
+        return NULL;
+    }
     // protect the 1st page
     protectDB(addr, 1);
     // init the helper
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index c85c4401..aa44d308 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1790,9 +1790,9 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
         }
         // access error, unprotect the block (and mark them dirty)
         unprotectDB((uintptr_t)addr, 1, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
-        if(db) CheckHotPage((uintptr_t)addr);
-        int db_need_test = db?getNeedTest((uintptr_t)db->x64_addr):0;
-        if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || (db_need_test && !BOX64ENV(dynarec_dirty)))) {
+        CheckHotPage((uintptr_t)addr);
+        int db_need_test = (db && !BOX64ENV(dynarec_dirty))?getNeedTest((uintptr_t)db->x64_addr):0;
+        if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db_need_test)) {
             emu = getEmuSignal(emu, p, db);
             // dynablock got auto-dirty! need to get out of it!!!
             if(emu->jmpbuf) {