about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-10-24 14:30:51 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-10-24 14:30:51 +0200
commit2e9bc93e1f1b989707941b8a1f43488d23f411c7 (patch)
tree7bc51484b4aca8985901da2e64b61e0fc2be5910 /src
parente2a993a4255e1d17a067727b959afce507c20eec (diff)
downloadbox64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.tar.gz
box64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.zip
[DYNAREC] Use customMalloc for internal dynarec stuff (fixed starbound)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c2
-rw-r--r--src/custommem.c34
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_pass0.h2
-rwxr-xr-xsrc/dynarec/dynablock.c37
-rwxr-xr-xsrc/dynarec/dynarec_native.c45
5 files changed, 80 insertions, 40 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 1610c4e8..e4fd522b 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -100,7 +100,7 @@ void relockMutex(int locks)
     relockCustommemMutex(locks);
     #define GO(A, B)                    \
         if(locks&(1<<B))                \
-            pthread_mutex_lock(&A);     \
+            pthread_mutex_trylock(&A);  \
 
     GO(my_context->mutex_once, 5)
     GO(my_context->mutex_once2, 6)
diff --git a/src/custommem.c b/src/custommem.c
index 9a34d2f6..e8abdd86 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -75,6 +75,7 @@ typedef struct blocklist_s {
     void*               block;
     size_t              maxfree;
     size_t              size;
+    void*               first;
 } blocklist_t;
 
 #define MMAPSIZE (256*1024)      // allocate 256kb sized blocks
@@ -125,6 +126,23 @@ static void* getFirstBlock(void* block, size_t maxsize, size_t* size, void* star
     return NULL;
 }
 
+static void* getNextFreeBlock(void* block)
+{
+    blockmark_t *m = (blockmark_t*)block;
+    while (m->next.fill) {
+         m = NEXT_BLOCK(m);
+    };
+    return m;
+}
+static void* getPrevFreeBlock(void* block)
+{
+    blockmark_t *m = (blockmark_t*)block;
+    do {
+         m = PREV_BLOCK(m);
+    } while (m->next.fill);
+    return m;
+}
+
 static size_t getMaxFreeBlock(void* block, size_t block_size, void* start)
 {
     // get start of block
@@ -271,11 +289,13 @@ void* customMalloc(size_t size)
     for(int i=0; i<n_blocks; ++i) {
         if(p_blocks[i].maxfree>=size) {
             size_t rsize = 0;
-            sub = getFirstBlock(p_blocks[i].block, size, &rsize, NULL);
+            sub = getFirstBlock(p_blocks[i].first, size, &rsize, NULL);
             if(sub) {
                 void* ret = allocBlock(p_blocks[i].block, sub, size, NULL);
+                if(sub==p_blocks[i].first)
+                    p_blocks[i].first = getNextFreeBlock(sub);
                 if(rsize==p_blocks[i].maxfree)
-                    p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL);
+                    p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first);
                 pthread_mutex_unlock(&mutex_blocks);
                 return ret;
             }
@@ -294,6 +314,7 @@ void* customMalloc(size_t size)
     void* p = box_calloc(1, allocsize);
     #endif
     p_blocks[i].block = p;
+    p_blocks[i].first = p;
     p_blocks[i].size = allocsize;
     // setup marks
     blockmark_t* m = (blockmark_t*)p;
@@ -329,7 +350,9 @@ void* customRealloc(void* p, size_t size)
          && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
             void* sub = (void*)(addr-sizeof(blockmark_t));
             if(expandBlock(p_blocks[i].block, sub, size)) {
-                p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL);
+                if(sub<p_blocks[i].first && p+size<p_blocks[i].first)
+                    p_blocks[i].first = getNextFreeBlock(sub);
+                p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, p_blocks[i].first);
                 pthread_mutex_unlock(&mutex_blocks);
                 return p;
             }
@@ -355,7 +378,10 @@ void customFree(void* p)
         if ((addr>(uintptr_t)p_blocks[i].block) 
          && (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
             void* sub = (void*)(addr-sizeof(blockmark_t));
+            void* n = NEXT_BLOCK((blockmark_t*)sub);
             size_t newfree = freeBlock(p_blocks[i].block, sub, NULL);
+            if(sub<=p_blocks[i].first)
+                p_blocks[i].first = getPrevFreeBlock(n);
             if(p_blocks[i].maxfree < newfree) p_blocks[i].maxfree = newfree;
             pthread_mutex_unlock(&mutex_blocks);
             return;
@@ -1214,7 +1240,7 @@ void relockCustommemMutex(int locks)
 {
     #define GO(A, B)                    \
         if(locks&(1<<B))                \
-            pthread_mutex_lock(&A);     \
+            pthread_mutex_trylock(&A);  \
 
     GO(mutex_blocks, 0)
     GO(mutex_prot, 1)
diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h
index 26dcc9c7..23cbcc93 100755
--- a/src/dynarec/arm64/dynarec_arm64_pass0.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass0.h
@@ -23,7 +23,7 @@
 #define NEW_INST \
         ++dyn->size;                            \
         if(dyn->size+3>=dyn->cap) {             \
-                dyn->insts = (instruction_native_t*)box_realloc(dyn->insts, sizeof(instruction_native_t)*dyn->cap*2);\
+                dyn->insts = (instruction_native_t*)customRealloc(dyn->insts, sizeof(instruction_native_t)*dyn->cap*2);\
                 memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_native_t)*dyn->cap);   \
                 dyn->cap *= 2;                  \
         }                                       \
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 0e5e4aa0..f1b1b1f1 100755
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -43,13 +43,13 @@ dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int direct)
         printf_log(LOG_NONE, "Error, creating a NULL sized Dynablock\n");
         return NULL;
     }
-    dynablocklist_t* ret = (dynablocklist_t*)box_calloc(1, sizeof(dynablocklist_t));
+    dynablocklist_t* ret = (dynablocklist_t*)customCalloc(1, sizeof(dynablocklist_t));
     ret->text = text;
     ret->textsz = textsz;
     ret->minstart = text;
     ret->maxend = text+textsz-1;
     if(direct && textsz) {
-        ret->direct = (dynablock_t**)box_calloc(textsz, sizeof(dynablock_t*));
+        ret->direct = (dynablock_t**)customCalloc(textsz, sizeof(dynablock_t*));
         if(!ret->direct) {printf_log(LOG_NONE, "Warning, fail to create direct block for dynablock @%p\n", (void*)text);}
     }
     dynarec_log(LOG_DEBUG, "New Dynablocklist %p, from %p->%p\n", ret, (void*)text, (void*)(text+textsz));
@@ -85,10 +85,10 @@ void FreeDynablock(dynablock_t* db, int need_lock)
         if(!db->father) {
             dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->block, db->size);
             FreeDynarecMap(db, (uintptr_t)db->block, db->size);
-            box_free(db->sons);
-            box_free(db->instsize);
+            customFree(db->sons);
+            customFree(db->instsize);
         }
-        box_free(db);
+        customFree(db);
         if(need_lock)
             pthread_mutex_unlock(&my_context->mutex_dyndump);
     }
@@ -106,11 +106,11 @@ void FreeDynablockList(dynablocklist_t** dynablocks)
             if((*dynablocks)->direct[i] && !(*dynablocks)->direct[i]->father) 
                 FreeDynablock((*dynablocks)->direct[i], 1);
         }
-        box_free((*dynablocks)->direct);
+        customFree((*dynablocks)->direct);
     }
     (*dynablocks)->direct = NULL;
 
-    box_free(*dynablocks);
+    customFree(*dynablocks);
     *dynablocks = NULL;
 }
 
@@ -149,6 +149,17 @@ int IntervalIntersects(uintptr_t start1, uintptr_t end1, uintptr_t start2, uintp
     return 1;
 }
 
+static int MarkedDynablock(dynablock_t* db)
+{
+    if(db) {
+        if(db->father)
+            db = db->father;    // mark only father
+        if(db->need_test)
+            return 1; // already done
+    }
+    return 0;
+}
+
 void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
 {
     // Mark will try to find *any* blocks that intersect the range to mark
@@ -161,7 +172,7 @@ void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t
     dynablock_t *db;
     dynarec_log(LOG_DEBUG, "MarkDirectDynablock %p-%p .. startdb=%p, sizedb=%p\n", (void*)addr, (void*)addr+size-1, (void*)startdb, (void*)sizedb);
     for(uintptr_t i = 0; i<sizedb; ++i)
-        if((db=dynablocks->direct[i]))
+        if((db=dynablocks->direct[i]) && !MarkedDynablock(db))
             if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1))
                 MarkDynablock(db);
 }
@@ -271,21 +282,21 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
     
     pthread_mutex_lock(&my_context->mutex_dyndump);
     if(!dynablocks->direct) {
-        dynablock_t** p = (dynablock_t**)box_calloc(dynablocks->textsz, sizeof(dynablock_t*));
+        dynablock_t** p = (dynablock_t**)customCalloc(dynablocks->textsz, sizeof(dynablock_t*));
         if(native_lock_storeifnull(&dynablocks->direct, p)!=p)
-            box_free(p);    // someone already create the direct array, too late...
+            customFree(p);    // someone already create the direct array, too late...
     }
 
     // create and add new block
     dynarec_log(LOG_VERBOSE, "Ask for DynaRec Block creation @%p\n", (void*)addr);
 
-    block = (dynablock_t*)box_calloc(1, sizeof(dynablock_t));
+    block = (dynablock_t*)customCalloc(1, sizeof(dynablock_t));
     block->parent = dynablocks; 
     dynablock_t* tmp = (dynablock_t*)native_lock_storeifnull(&dynablocks->direct[addr-dynablocks->text], block);
     if(tmp !=  block) {
         // a block appeard!
         pthread_mutex_unlock(&my_context->mutex_dyndump);
-        box_free(block);
+        customFree(block);
         *created = 0;
         return tmp;
     }
@@ -356,7 +367,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
             dynarec_log(LOG_INFO, "Warning, a wild block appeared at %p: %p\n", (void*)addr, old);
             // doing nothing else, the block has not be writen
         }
-        box_free(block);
+        customFree(block);
         block = NULL;
     }
     // check size
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index ee0195f8..c2a752b1 100755
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -73,8 +73,8 @@ void add_next(dynarec_native_t *dyn, uintptr_t addr) {
         }
     // add slots
     if(dyn->next_sz == dyn->next_cap) {
-        dyn->next_cap += 16;
-        dyn->next = (uintptr_t*)box_realloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
+        dyn->next_cap += 64;
+        dyn->next = (uintptr_t*)customRealloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
     }
     dyn->next[dyn->next_sz++] = addr;
 }
@@ -249,7 +249,7 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size,
         toadd = 1 + native_size/15;
     if((*size)+toadd>(*cap)) {
         *cap = (*size)+toadd;
-        insts = (instsize_t*)box_realloc(insts, (*cap)*sizeof(instsize_t));
+        insts = (instsize_t*)customRealloc(insts, (*cap)*sizeof(instsize_t));
     }
     while(toadd) {
         if(x64_size>15)
@@ -280,7 +280,7 @@ int Table64(dynarec_native_t *dyn, uint64_t val)
     if(idx==-1) {
         if(dyn->table64size == dyn->table64cap) {
             dyn->table64cap+=4;
-            dyn->table64 = (uint64_t*)box_realloc(dyn->table64, dyn->table64cap * sizeof(uint64_t));
+            dyn->table64 = (uint64_t*)customRealloc(dyn->table64, dyn->table64cap * sizeof(uint64_t));
         }
         idx = dyn->table64size++;
         dyn->table64[idx] = val;
@@ -308,7 +308,7 @@ static void fillPredecessors(dynarec_native_t* dyn)
             dyn->insts[i+1].pred_sz++;
         }
     }
-    dyn->predecessor = (int*)box_malloc(pred_sz*sizeof(int));
+    dyn->predecessor = (int*)customMalloc(pred_sz*sizeof(int));
     // fill pred pointer
     int* p = dyn->predecessor;
     for(int i=0; i<dyn->size; ++i) {
@@ -391,11 +391,11 @@ void CancelBlock64()
     current_helper = NULL;
     if(!helper)
         return;
-    box_free(helper->next);
-    box_free(helper->insts);
-    box_free(helper->table64);
-    box_free(helper->sons_x64);
-    box_free(helper->sons_native);
+    customFree(helper->next);
+    customFree(helper->insts);
+    customFree(helper->table64);
+    customFree(helper->sons_x64);
+    customFree(helper->sons_native);
     if(helper->dynablock && helper->dynablock->block)
         FreeDynarecMap(helper->dynablock, (uintptr_t)helper->dynablock->block, helper->dynablock->size);
 }
@@ -423,11 +423,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     helper.start = addr;
     uintptr_t start = addr;
     helper.cap = 64; // needs epilog handling
-    helper.insts = (instruction_native_t*)box_calloc(helper.cap, sizeof(instruction_native_t));
+    helper.insts = (instruction_native_t*)customCalloc(helper.cap, sizeof(instruction_native_t));
     // pass 0, addresses, x64 jump addresses, overall size of the block
     uintptr_t end = native_pass0(&helper, addr);
     // no need for next anymore
-    box_free(helper.next);
+    customFree(helper.next);
     helper.next_sz = helper.next_cap = 0;
     helper.next = NULL;
     // basic checks
@@ -548,9 +548,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     helper.native_start = (uintptr_t)p;
     helper.tablestart = helper.native_start + helper.native_size;
     if(helper.sons_size) {
-        helper.sons_x64 = (uintptr_t*)box_calloc(helper.sons_size, sizeof(uintptr_t));
-        helper.sons_native = (void**)box_calloc(helper.sons_size, sizeof(void*));
+        helper.sons_x64 = (uintptr_t*)customCalloc(helper.sons_size, sizeof(uintptr_t));
+        helper.sons_native = (void**)customCalloc(helper.sons_size, sizeof(void*));
     }
+    int pass2_sons_size = helper.sons_size;
     // pass 3, emit (log emit native opcode)
     if(box64_dynarec_dump) {
         dynarec_log(LOG_NONE, "%s%04d|Emitting %zu bytes for %u x64 bytes", (box64_dynarec_dump>1)?"\e[01;36m":"", GetTID(), helper.native_size, helper.isize); 
@@ -588,15 +589,15 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
         for(int i=0; i<helper.size; ++i)
             cap += 1 + ((helper.insts[i].x64.size>helper.insts[i].size)?helper.insts[i].x64.size:helper.insts[i].size)/15;
         size_t size = 0;
-        block->instsize = (instsize_t*)box_calloc(cap, sizeof(instsize_t));
+        block->instsize = (instsize_t*)customCalloc(cap, sizeof(instsize_t));
         for(int i=0; i<helper.size; ++i)
             block->instsize = addInst(block->instsize, &size, &cap, helper.insts[i].x64.size, helper.insts[i].size/4);
         block->instsize = addInst(block->instsize, &size, &cap, 0, 0);    // add a "end of block" mark, just in case
     }
     // ok, free the helper now
-    box_free(helper.insts);
+    customFree(helper.insts);
     helper.insts = NULL;
-    box_free(helper.table64);
+    customFree(helper.table64);
     helper.table64 = NULL;
     block->size = sz;
     block->isize = helper.size;
@@ -620,8 +621,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     // fill sons if any
     dynablock_t** sons = NULL;
     int sons_size = 0;
+    if(pass2_sons_size != helper.sons_size)
+        dynarec_log(LOG_NONE, "Warning, sons size difference bitween pass2:%d and pass3:%d\n", pass2_sons_size, helper.sons_size);
     if(helper.sons_size) {
-        sons = (dynablock_t**)box_calloc(helper.sons_size, sizeof(dynablock_t*));
+        sons = (dynablock_t**)customCalloc(helper.sons_size, sizeof(dynablock_t*));
         for (int i=0; i<helper.sons_size; ++i) {
             int created = 1;
             dynablock_t *son = AddNewDynablock(block->parent, helper.sons_x64[i], &created);
@@ -643,11 +646,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
             block->sons = sons;
             block->sons_size = sons_size;
         } else
-            box_free(sons);
+            customFree(sons);
     }
-    box_free(helper.sons_x64);
+    customFree(helper.sons_x64);
     helper.sons_x64 = NULL;
-    box_free(helper.sons_native);
+    customFree(helper.sons_native);
     helper.sons_native = NULL;
     current_helper = NULL;
     //block->done = 1;