about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-06-21 10:49:42 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-06-21 10:49:42 +0200
commitbcd504eb055af1a13d69dbb3cbe0c7f00654d468 (patch)
tree5596bc8aa2537cc55d9370722173e877e62afc40 /src
parent7057b7f92962c6971fbd617cb9e78c7251a1c403 (diff)
downloadbox64-bcd504eb055af1a13d69dbb3cbe0c7f00654d468.tar.gz
box64-bcd504eb055af1a13d69dbb3cbe0c7f00654d468.zip
Various change to try improve stability on JIT'd program (like mono for Terraria, with moderate success)
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c41
-rwxr-xr-xsrc/dynarec/dynablock.c7
-rwxr-xr-xsrc/dynarec/dynarec_arm64.c4
3 files changed, 19 insertions, 33 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 151dad63..e1413157 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -561,20 +561,22 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy)
             dynablocklist_t* dblist = dynmap123[idx3][idx2][idx1];
             if(dblist) {
                 if(destroy) {
-                    if(FreeRangeDynablock(dblist, addr, size)) {    // dblist is empty, check if we can delete more...
+                    if(FreeRangeDynablock(dblist, addr, size) && 0) {    // dblist is empty, check if we can delete more...
+                        // disabling this for now. It seems to cause random crash in Terraria
                         if(!arm64_lock_storeifref(&dynmap123[idx3][idx2][idx1], NULL, dblist)) {
-                            free(dblist);
                             dynablocklist_t** p = dynmap123[idx3][idx2];
                             if(dynmapempty((void**)p)) {
                                 if(!arm64_lock_storeifref(&dynmap123[idx3][idx2], NULL, p)) {
-                                    free(p);
                                     dynablocklist_t*** p2 = dynmap123[idx3];
                                     if(dynmapempty((void**)p2)) {
-                                        if(!arm64_lock_storeifref(&dynmap123[idx3], NULL, p2))
+                                        if(!arm64_lock_storeifref(&dynmap123[idx3], NULL, p2)) {
                                             free(p2);
+                                        }
                                     }
+                                    free(p);
                                 }
                             }
+                            FreeDynablockList(&dblist);
                         }
                     }
                 } else
@@ -690,15 +692,13 @@ uintptr_t getJumpTableAddress64(uintptr_t addr)
     return (uintptr_t)&box64_jmptbl3[idx3][idx2][idx1][idx0];
 }
 
-// Remove the Write flag from an adress range, so DB can be executed
-// no log, as it can be executed inside a signal handler
-void protectDB(uintptr_t addr, size_t size)
+// Remove the Write flag from an adress range, so DB can be executed safely
+void protectDBnolock(uintptr_t addr, uintptr_t size)
 {
     dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
     uintptr_t idx = (addr>>MEMPROT_SHIFT);
     uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
     int ret;
-    pthread_mutex_lock(&mutex_prot);
     for (uintptr_t i=idx; i<=end; ++i) {
         const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
         khint_t k = kh_put(memprot, memprot, key, &ret);
@@ -714,30 +714,13 @@ void protectDB(uintptr_t addr, size_t size)
         if(!(prot&PROT_DYNAREC))
             mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~(PROT_WRITE|PROT_CUSTOM));
     }
-    pthread_mutex_unlock(&mutex_prot);
 }
 
-void protectDBnolock(uintptr_t addr, uintptr_t size)
+void protectDB(uintptr_t addr, size_t size)
 {
-    dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
-    uintptr_t idx = (addr>>MEMPROT_SHIFT);
-    uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
-    int ret;
-    for (uintptr_t i=idx; i<=end; ++i) {
-        const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
-        khint_t k = kh_put(memprot, memprot, key, &ret);
-        if(ret) {
-            uint8_t *m = (uint8_t*)calloc(1, MEMPROT_SIZE);
-            kh_value(memprot, k) = m;
-        }
-        const uintptr_t ii = i&(MEMPROT_SIZE-1);
-        uint8_t prot = kh_value(memprot, k)[ii];
-        if(!prot)
-            prot = PROT_READ | PROT_WRITE;    // comes from malloc & co, so should not be able to execute
-        kh_value(memprot, k)[ii] = prot|PROT_DYNAREC;
-        if(!(prot&PROT_DYNAREC))
-            mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~(PROT_WRITE|PROT_CUSTOM));
-    }
+    pthread_mutex_lock(&mutex_prot);
+    protectDBnolock(addr, size);
+    pthread_mutex_unlock(&mutex_prot);
 }
 
 void lockDB()
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index a592b28f..5df4979d 100755
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -337,7 +337,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
         void* old = (void*)arm64_lock_storeifref(&dynablocks->direct[addr-dynablocks->text], 0, block);
         if(old!=block && old) {// put it back in place, strange things are happening here!
             dynarec_log(LOG_INFO, "Warning, a wild block appeared at %p: %p\n", (void*)addr, old);
-            // doing nothing else, the block as not be writen
+            // doing nothing else, the block has not be writen
         }
         free(block);
         block = NULL;
@@ -362,8 +362,11 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
         protectDBnolock((uintptr_t)block->x64_addr, block->x64_size);
         // fill-in jumptable
         addJumpTableIfDefault64(block->x64_addr, block->block);
-        for(int i=0; i<block->sons_size; ++i)
+        for(int i=0; i<block->sons_size; ++i) {
             addJumpTableIfDefault64(block->sons[i]->x64_addr, block->sons[i]->block);
+            block->sons[i]->done = 1;
+        }
+        block->done = 1;
         unlockDB();
     }
 
diff --git a/src/dynarec/dynarec_arm64.c b/src/dynarec/dynarec_arm64.c
index 63652c6b..c4f4dd6a 100755
--- a/src/dynarec/dynarec_arm64.c
+++ b/src/dynarec/dynarec_arm64.c
@@ -474,7 +474,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
                 if(!son->x64_size) {printf_log(LOG_NONE, "Warning, son with null x64 size! (@%p / ARM=%p)", son->x64_addr, son->block);}
                 son->father = block;
                 son->size = sz + son->block - block->block; // update size count, for debugging
-                son->done = 1;
+                //son->done = 1;
                 if(!son->parent)
                     son->parent = block->parent;
                 sons[sons_size] = son;
@@ -489,6 +489,6 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     }
     free(helper.sons_x64);
     free(helper.sons_arm);
-    block->done = 1;
+    //block->done = 1;
     return (void*)block;
 }