[DYNAREC] Speedup a bit DYNAREC_DIRTY=1

This commit is contained in:
ptitSeb 2025-04-10 19:00:47 +02:00
parent 310d4016fa
commit 51d9eb966d
5 changed files with 51 additions and 21 deletions

View File

@ -1710,7 +1710,7 @@ static int hotpage_cnt = 0;
static int repeated_count = 0; static int repeated_count = 0;
static uintptr_t repeated_page = 0; static uintptr_t repeated_page = 0;
#define HOTPAGE_MARK 64 #define HOTPAGE_MARK 64
#define HOTPAGE_DIRTY 2 #define HOTPAGE_DIRTY 4
void SetHotPage(uintptr_t addr) void SetHotPage(uintptr_t addr)
{ {
hotpage = addr&~(box64_pagesize-1); hotpage = addr&~(box64_pagesize-1);

View File

@ -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) 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; return NULL;
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits); dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
if(db && db->done && db->block && getNeedTest(addr)) { if(db && db->done && db->block && getNeedTest(addr)) {
if (db->always_test) SchedYield(); // just calm down... if (db->always_test) SchedYield(); // just calm down...
uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); 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); int need_lock = mutex_trylock(&my_context->mutex_dyndump);
if(hash!=db->hash) { if(hash!=db->hash) {
db->done = 0; // invalidating the block db->done = 0; // invalidating the block
@ -294,19 +297,23 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
} else } else
FreeInvalidDynablock(old, need_lock); FreeInvalidDynablock(old, need_lock);
} else { } 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(is_inhotpage) {
if(db->always_test) // log?
protectDB((uintptr_t)db->x64_addr, db->x64_size); } else {
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);
#ifdef ARCH_NOP if(db->always_test)
if(db->callret_size) { protectDB((uintptr_t)db->x64_addr, db->x64_size);
// mark all callrets to UDF else {
for(int i=0; i<db->callret_size; ++i) #ifdef ARCH_NOP
*(uint32_t*)(db->block+db->callrets[i].offs) = ARCH_NOP; if(db->callret_size) {
ClearCache(db->block, db->size); // mark all callrets to UDF
for(int i=0; i<db->callret_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) if(!need_lock)

View File

@ -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); dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock at %p as another one is going on\n", (void*)addr);
return NULL; 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 // protect the 1st page
protectDB(addr, 1); protectDB(addr, 1);
// init the helper // init the helper

View File

@ -1790,9 +1790,9 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
} }
// access error, unprotect the block (and mark them dirty) // 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 unprotectDB((uintptr_t)addr, 1, 1); // unprotect 1 byte... But then, the whole page will be unprotected
if(db) CheckHotPage((uintptr_t)addr); CheckHotPage((uintptr_t)addr);
int db_need_test = db?getNeedTest((uintptr_t)db->x64_addr):0; 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 && !BOX64ENV(dynarec_dirty)))) { if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db_need_test)) {
emu = getEmuSignal(emu, p, db); emu = getEmuSignal(emu, p, db);
// dynablock got auto-dirty! need to get out of it!!! // dynablock got auto-dirty! need to get out of it!!!
if(emu->jmpbuf) { if(emu->jmpbuf) {

View File

@ -55,7 +55,9 @@ BOX64_DYNAREC_SAFEFLAGS=0
[3dSen.x86_64] [3dSen.x86_64]
BOX64_DYNAREC_BLEEDING_EDGE=0 # avoid the use of STRONGMEM for much better performances BOX64_DYNAREC_BLEEDING_EDGE=0 # avoid the use of STRONGMEM for much better performances
BOX64_DYNAREC_SAFEFLAGS=0 BOX64_DYNAREC_SAFEFLAGS=0
BOX64_DYNAREC_STRONGMEM=1
BOX64_DYNAREC_BIGBLOCK=2 BOX64_DYNAREC_BIGBLOCK=2
BOX64_DYNAREC_DIRTY=1
BOX64_DYNAREC_FORWARD=1024 BOX64_DYNAREC_FORWARD=1024
BOX64_DYNAREC_CALLRET=1 BOX64_DYNAREC_CALLRET=1
BOX64_MAXCPU=4 # surprisingly, having too much cpu core slow down things.4 is more than enough here 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_DYNAREC_CALLRET=1
BOX64_MAXCPU=4 # surprisingly, having too much cpu core slow down things.4 is more than enough here 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] [chrome]
BOX64_MALLOC_HACK=2 BOX64_MALLOC_HACK=2
@ -465,7 +483,7 @@ BOX64_DYNAREC_BIGBLOCK=0
BOX64_DYNAREC_SAFEFLAGS=2 BOX64_DYNAREC_SAFEFLAGS=2
BOX64_DYNAREC_STRONGMEM=1 BOX64_DYNAREC_STRONGMEM=1
BOX64_DYNAREC_BIGBLOCK=3 BOX64_DYNAREC_BIGBLOCK=3
BOX64_DYNAREC_CALLRET=2 BOX64_DYNAREC_CALLRET=0
BOX64_SSE_FLUSHTO0=1 BOX64_SSE_FLUSHTO0=1
BOX64_DYNAREC_DIRTY=1 BOX64_DYNAREC_DIRTY=1
@ -584,11 +602,13 @@ BOX64_DYNAREC_DIRTY=0
[EAappInstaller.exe] [EAappInstaller.exe]
BOX64_DYNAREC_SAFEFLAGS=2 BOX64_DYNAREC_SAFEFLAGS=2
BOX64_DYNAREC_DIRTY=1
BOX64_DYNAREC_BIGBLOCK=3
[NeedForSpeedHeat.exe] [NeedForSpeedHeat.exe]
BOX64_DYNAREC_BIGBLOCK=3 BOX64_DYNAREC_BIGBLOCK=3
BOX64_DYNAREC_SAFEFLAGS=2 BOX64_DYNAREC_SAFEFLAGS=2
BOX64_DYNAREC_DIRTY=2 BOX64_DYNAREC_DIRTY=1
BOX64_DYNAREC_CALLRET=1 BOX64_DYNAREC_CALLRET=1
BOX64_DYNAREC_FASTNAN=0 BOX64_DYNAREC_FASTNAN=0
@ -613,9 +633,8 @@ BOX64_DYNAREC_PAUSE=3
[RockstarService.exe] [RockstarService.exe]
BOX64_DYNAREC_STRONGMEM=1 BOX64_DYNAREC_STRONGMEM=1
BOX64_DYNAREC_FASTNAN=0
BOX64_DYNAREC_FASTROUND=0
BOX64_DYNAREC_SAFEFLAGS=2 BOX64_DYNAREC_SAFEFLAGS=2
BOX64_DYNAREC_BIGBLOCK=3
BOX64_DYNAREC_DIRTY=1 BOX64_DYNAREC_DIRTY=1
[SocialClubHelper.exe] [SocialClubHelper.exe]