From dfd3d0ec932c327992764c5e2744fe9f0c0bff01 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 19 Jun 2021 11:15:53 +0200 Subject: [DYNAREC] Try to free dynablocks when no longer used --- src/custommem.c | 29 ++++++++++++++++++++++++++--- src/dynarec/dynablock.c | 48 ++++++++++++++++++++++++++---------------------- src/include/dynablock.h | 3 ++- 3 files changed, 54 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/custommem.c b/src/custommem.c index a3aa8358..151dad63 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -540,6 +540,14 @@ void addDBFromAddressRange(uintptr_t addr, size_t size) } } +static int dynmapempty(void** mem) +{ + for (int i=0; i<(1< %p %s\n", (void*)addr, (void*)(addr+size-1), destroy?"destroy":"mark"); @@ -552,9 +560,24 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy) if(dynmap123[idx3] && dynmap123[idx3][idx2]) { dynablocklist_t* dblist = dynmap123[idx3][idx2][idx1]; if(dblist) { - if(destroy) - FreeRangeDynablock(dblist, addr, size); - else + if(destroy) { + if(FreeRangeDynablock(dblist, addr, size)) { // dblist is empty, check if we can delete more... + 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)) + free(p2); + } + } + } + } + } + } else MarkRangeDynablock(dblist, addr, size); } } diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index d4a79156..a592b28f 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -165,10 +165,10 @@ void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t MarkDynablock(db); } -void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size) +int FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size) { if(!dynablocks) - return; + return 1; if(dynablocks->direct) { dynablock_t* db; @@ -176,34 +176,38 @@ void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s khint_t k; kh_dynablocks_t *blocks = kh_init(dynablocks); // copy in a temporary list - if(dynablocks->direct) { - uintptr_t startdb = dynablocks->text; - uintptr_t enddb = startdb + dynablocks->textsz; - uintptr_t start = addr; - uintptr_t end = addr+size; - if(startenddb) - end = enddb; - if(end>startdb && startdirect[i-startdb], 0); - if(db) { - if(db->father) - db = db->father; - if(db->parent==dynablocks) { - k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret); - kh_value(blocks, k) = db; - } + uintptr_t startdb = dynablocks->text; + uintptr_t enddb = startdb + dynablocks->textsz; + uintptr_t start = addr; + uintptr_t end = addr+size; + if(startenddb) + end = enddb; + if(end>startdb && startdirect[i-startdb], 0); + if(db) { + if(db->father) + db = db->father; + if(db->parent==dynablocks) { + k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret); + kh_value(blocks, k) = db; } } - } + } // purge the list kh_foreach_value(blocks, db, FreeDynablock(db); ); kh_destroy(dynablocks, blocks); + // check emptyness + for(uintptr_t i=0; itextsz; ++i) + if(dynablocks->direct[i]) + return 0; + return 1; } + return 1; } void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size) { diff --git a/src/include/dynablock.h b/src/include/dynablock.h index 76f1e5e0..618a3651 100755 --- a/src/include/dynablock.h +++ b/src/include/dynablock.h @@ -11,7 +11,8 @@ dynablocklist_t* NewDynablockList(uintptr_t text, int textsz, int direct); void FreeDynablockList(dynablocklist_t** dynablocks); void FreeDynablock(dynablock_t* db); void MarkDynablock(dynablock_t* db); -void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size); +//return 1 if Dynareblock is empty +int FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size); void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size); dynablock_t* FindDynablockFromNativeAddress(void* addr); // defined in box64context.h -- cgit 1.4.1