diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-10-24 14:30:51 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-10-24 14:30:51 +0200 |
| commit | 2e9bc93e1f1b989707941b8a1f43488d23f411c7 (patch) | |
| tree | 7bc51484b4aca8985901da2e64b61e0fc2be5910 /src | |
| parent | e2a993a4255e1d17a067727b959afce507c20eec (diff) | |
| download | box64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.tar.gz box64-2e9bc93e1f1b989707941b8a1f43488d23f411c7.zip | |
[DYNAREC] Use customMalloc for internal dynarec stuff (fixed starbound)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 2 | ||||
| -rw-r--r-- | src/custommem.c | 34 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_pass0.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynablock.c | 37 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_native.c | 45 |
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; |