From 51d9eb966db1ef22af0eaa5848556d74395bcf5d Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 10 Apr 2025 19:00:47 +0200 Subject: [PATCH] [DYNAREC] Speedup a bit DYNAREC_DIRTY=1 --- src/custommem.c | 2 +- src/dynarec/dynablock.c | 33 ++++++++++++++++++++------------- src/dynarec/dynarec_native.c | 4 ++++ src/libtools/signals.c | 6 +++--- system/box64.box64rc | 27 +++++++++++++++++++++++---- 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/custommem.c b/src/custommem.c index ef227b1bf..ae6df5b0c 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -1710,7 +1710,7 @@ static int hotpage_cnt = 0; static int repeated_count = 0; static uintptr_t repeated_page = 0; #define HOTPAGE_MARK 64 -#define HOTPAGE_DIRTY 2 +#define HOTPAGE_DIRTY 4 void SetHotPage(uintptr_t addr) { hotpage = addr&~(box64_pagesize-1); diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index 7eedfe107..561ab529b 100644 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -273,12 +273,15 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits) { - if(isInHotPage(addr)) + int is_inhotpage = isInHotPage(addr); + if(is_inhotpage && !BOX64ENV(dynarec_dirty)) return NULL; dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits); if(db && db->done && db->block && getNeedTest(addr)) { if (db->always_test) SchedYield(); // just calm down... uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); + if(is_inhotpage && hash!=db->hash) + return NULL; // will be handle when hotpage is over int need_lock = mutex_trylock(&my_context->mutex_dyndump); if(hash!=db->hash) { db->done = 0; // invalidating the block @@ -294,19 +297,23 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits) } else FreeInvalidDynablock(old, need_lock); } else { - dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr); - if(db->always_test) - protectDB((uintptr_t)db->x64_addr, db->x64_size); - else { - #ifdef ARCH_NOP - if(db->callret_size) { - // mark all callrets to UDF - for(int i=0; icallret_size; ++i) - *(uint32_t*)(db->block+db->callrets[i].offs) = ARCH_NOP; - ClearCache(db->block, db->size); + if(is_inhotpage) { + // log? + } else { + dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr); + if(db->always_test) + protectDB((uintptr_t)db->x64_addr, db->x64_size); + else { + #ifdef ARCH_NOP + if(db->callret_size) { + // mark all callrets to UDF + for(int i=0; icallret_size; ++i) + *(uint32_t*)(db->block+db->callrets[i].offs) = ARCH_NOP; + ClearCache(db->block, db->size); + } + #endif + protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext); } - #endif - protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext); } } if(!need_lock) diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c index 5478fc437..7574b124f 100644 --- a/src/dynarec/dynarec_native.c +++ b/src/dynarec/dynarec_native.c @@ -605,6 +605,10 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock at %p as another one is going on\n", (void*)addr); return NULL; } + if(checkInHotPage(addr)) { + dynarec_log(LOG_DEBUG, "Not creating dynablock at %p as in a HotPage\n", (void*)addr); + return NULL; + } // protect the 1st page protectDB(addr, 1); // init the helper diff --git a/src/libtools/signals.c b/src/libtools/signals.c index c85c4401d..aa44d308f 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -1790,9 +1790,9 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx) } // access error, unprotect the block (and mark them dirty) unprotectDB((uintptr_t)addr, 1, 1); // unprotect 1 byte... But then, the whole page will be unprotected - if(db) CheckHotPage((uintptr_t)addr); - int db_need_test = db?getNeedTest((uintptr_t)db->x64_addr):0; - if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || (db_need_test && !BOX64ENV(dynarec_dirty)))) { + CheckHotPage((uintptr_t)addr); + int db_need_test = (db && !BOX64ENV(dynarec_dirty))?getNeedTest((uintptr_t)db->x64_addr):0; + if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db_need_test)) { emu = getEmuSignal(emu, p, db); // dynablock got auto-dirty! need to get out of it!!! if(emu->jmpbuf) { diff --git a/system/box64.box64rc b/system/box64.box64rc index 3d47fdebc..3f6d70aff 100644 --- a/system/box64.box64rc +++ b/system/box64.box64rc @@ -55,7 +55,9 @@ BOX64_DYNAREC_SAFEFLAGS=0 [3dSen.x86_64] BOX64_DYNAREC_BLEEDING_EDGE=0 # avoid the use of STRONGMEM for much better performances BOX64_DYNAREC_SAFEFLAGS=0 +BOX64_DYNAREC_STRONGMEM=1 BOX64_DYNAREC_BIGBLOCK=2 +BOX64_DYNAREC_DIRTY=1 BOX64_DYNAREC_FORWARD=1024 BOX64_DYNAREC_CALLRET=1 BOX64_MAXCPU=4 # surprisingly, having too much cpu core slow down things.4 is more than enough here @@ -114,6 +116,22 @@ BOX64_DYNAREC_FORWARD=1024 BOX64_DYNAREC_CALLRET=1 BOX64_MAXCPU=4 # surprisingly, having too much cpu core slow down things.4 is more than enough here +[Broforce-838.x86_64] +BOX64_DYNAREC_SAFEFLAGS=0 +BOX64_DYNAREC_BIGBLOCK=2 +BOX64_DYNAREC_FORWARD=1024 +BOX64_DYNAREC_STRONGMEM=1 +BOX64_DYNAREC_CALLRET=1 +BOX64_MAXCPU=4 # surprisingly, having too much cpu core slow down things.4 is more than enough here +BOX64_DYNAREC_DIRTY=1 + +[Celeste.bin.x86_64] +BOX64_DYNAREC_SAFEFLAGS=0 +BOX64_DYNAREC_BIGBLOCK=3 +BOX64_DYNAREC_STRONGMEM=1 +BOX64_DYNAREC_CALLRET=1 +BOX64_DYNAREC_DIRTY=1 + [chrome] BOX64_MALLOC_HACK=2 @@ -465,7 +483,7 @@ BOX64_DYNAREC_BIGBLOCK=0 BOX64_DYNAREC_SAFEFLAGS=2 BOX64_DYNAREC_STRONGMEM=1 BOX64_DYNAREC_BIGBLOCK=3 -BOX64_DYNAREC_CALLRET=2 +BOX64_DYNAREC_CALLRET=0 BOX64_SSE_FLUSHTO0=1 BOX64_DYNAREC_DIRTY=1 @@ -584,11 +602,13 @@ BOX64_DYNAREC_DIRTY=0 [EAappInstaller.exe] BOX64_DYNAREC_SAFEFLAGS=2 +BOX64_DYNAREC_DIRTY=1 +BOX64_DYNAREC_BIGBLOCK=3 [NeedForSpeedHeat.exe] BOX64_DYNAREC_BIGBLOCK=3 BOX64_DYNAREC_SAFEFLAGS=2 -BOX64_DYNAREC_DIRTY=2 +BOX64_DYNAREC_DIRTY=1 BOX64_DYNAREC_CALLRET=1 BOX64_DYNAREC_FASTNAN=0 @@ -613,9 +633,8 @@ BOX64_DYNAREC_PAUSE=3 [RockstarService.exe] BOX64_DYNAREC_STRONGMEM=1 -BOX64_DYNAREC_FASTNAN=0 -BOX64_DYNAREC_FASTROUND=0 BOX64_DYNAREC_SAFEFLAGS=2 +BOX64_DYNAREC_BIGBLOCK=3 BOX64_DYNAREC_DIRTY=1 [SocialClubHelper.exe]