about summary refs log tree commit diff stats
path: root/src/dynarec/dynablock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/dynablock.c')
-rw-r--r--src/dynarec/dynablock.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index d5c95111..787a387c 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -1,6 +1,5 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <pthread.h>
 #include <errno.h>
 #include <setjmp.h>
 #include <sys/mman.h>
@@ -9,7 +8,6 @@
 #include "box64context.h"
 #include "dynarec.h"
 #include "emu/x64emu_private.h"
-#include "tools/bridge_private.h"
 #include "x64run.h"
 #include "x64emu.h"
 #include "box64stack.h"
@@ -184,7 +182,7 @@ void cancelFillBlock()
     return NULL if block is not found / cannot be created. 
     Don't create if create==0
 */
-static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, int need_lock)
+static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, int need_lock, int is32bits)
 {
     if(hasAlternate((void*)addr))
         return NULL;
@@ -212,18 +210,19 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
     block->x64_addr = (void*)addr;
     if(sigsetjmp(&dynarec_jmpbuf, 1)) {
         printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, cancelling\n", (void*)addr);
+        FreeDynablock(block, 0);
         if(need_lock)
             mutex_unlock(&my_context->mutex_dyndump);
         return NULL;
     }
-    void* ret = FillBlock64(block, filladdr);
+    void* ret = FillBlock64(block, filladdr, (addr==filladdr)?0:1, is32bits);
     if(!ret) {
         dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
         customFree(block);
         block = NULL;
     }
     // check size
-    if(block && (block->x64_size || (!block->x64_size && !block->done))) {
+    if(block) {
         int blocksz = block->x64_size;
         if(blocksz>my_context->max_db_size)
             my_context->max_db_size = blocksz;
@@ -245,9 +244,9 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
     return block;
 }
 
-dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create)
+dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
 {
-    dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1);
+    dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
     if(db && db->done && db->block && getNeedTest(addr)) {
         if(db->always_test)
             sched_yield();  // just calm down...
@@ -255,8 +254,10 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create)
             emu->test.test = 0;
             if(box64_dynarec_fastpage) {
                 uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size);
-                if(hash==db->hash)  // seems ok, run it without reprotecting it
+                if(hash==db->hash) { // seems ok, run it without reprotecting it
+                    setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext);
                     return db;
+                }
                 db->done = 0;   // invalidating the block, it's already not good
                 dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr);
                 // Free db, it's now invalid!
@@ -275,7 +276,7 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create)
             // Free db, it's now invalid!
             dynablock_t* old = InvalidDynablock(db, need_lock);
             // start again... (will create a new block)
-            db = internalDBGetBlock(emu, addr, addr, create, need_lock);
+            db = internalDBGetBlock(emu, addr, addr, create, need_lock, is32bits);
             if(db) {
                 if(db->previous)
                     FreeInvalidDynablock(db->previous, need_lock);
@@ -298,11 +299,11 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create)
     return db;
 }
 
-dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr)
+dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int is32bits)
 {
-    dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p\n", (void*)addr, (void*)filladdr);
+    dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p%s\n", (void*)addr, (void*)filladdr, is32bits?" 32bits":"");
     int create = 1;
-    dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1);
+    dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1, is32bits);
     if(db && db->done && db->block && getNeedTest(filladdr)) {
         if(db->always_test)
             sched_yield();  // just calm down...
@@ -314,7 +315,7 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr)
             // Free db, it's now invalid!
             dynablock_t* old = InvalidDynablock(db, need_lock);
             // start again... (will create a new block)
-            db = internalDBGetBlock(emu, addr, filladdr, create, need_lock);
+            db = internalDBGetBlock(emu, addr, filladdr, create, need_lock, is32bits);
             if(db) {
                 if(db->previous)
                     FreeInvalidDynablock(db->previous, need_lock);