diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-12-23 12:48:35 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-12-23 12:48:35 +0100 |
| commit | 48db75961ee8784acd93278f841ddf80a9796949 (patch) | |
| tree | c222eadaebbf9386f1916c9f83fdccdd42ac7214 /src | |
| parent | da0820ce0a07356ed53fd7175a65375775c87811 (diff) | |
| download | box64-48db75961ee8784acd93278f841ddf80a9796949.tar.gz box64-48db75961ee8784acd93278f841ddf80a9796949.zip | |
[DYNAREC] Some light rework of the hotpage handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 25 | ||||
| -rw-r--r-- | src/libtools/signals.c | 14 |
2 files changed, 22 insertions, 17 deletions
diff --git a/src/custommem.c b/src/custommem.c index ec45500a..1b8da942 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -1482,20 +1482,37 @@ int isprotectedDB(uintptr_t addr, size_t size) return 1; } -uintptr_t hotpage = 0; -int hotpage_cnt = 0; +static uintptr_t hotpage = 0; +static int hotpage_cnt = 0; +static int repeated_count = 0; +static uintptr_t repeated_page = 0; #define HOTPAGE_MARK 64 void SetHotPage(uintptr_t addr) { hotpage = addr&~(box64_pagesize-1); hotpage_cnt = HOTPAGE_MARK; } +void CheckHotPage(uintptr_t addr) +{ + uintptr_t page = (uintptr_t)addr&~(box64_pagesize-1); + if(repeated_count==1 && repeated_page==page) { + dynarec_log(LOG_DEBUG, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count); + SetHotPage(repeated_page); + repeated_count = 0; + repeated_page = 0; + } else { + repeated_count = 1; + repeated_page = page; + } +} int isInHotPage(uintptr_t addr) { if(!hotpage_cnt) return 0; - --hotpage_cnt; - return (addr>=hotpage) && (addr<hotpage+box64_pagesize); + int ret = (addr>=hotpage) && (addr<hotpage+box64_pagesize); + if(ret) + --hotpage_cnt; + return ret; } int checkInHotPage(uintptr_t addr) { diff --git a/src/libtools/signals.c b/src/libtools/signals.c index d7120842..4abf8a4f 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -1478,21 +1478,9 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx) // check if SMC inside block db = FindDynablockFromNativeAddress(pc); db_searched = 1; - static uintptr_t repeated_page = 0; - dynarec_log(LOG_DEBUG, "SIGSEGV with Access error on %p for %p , db=%p(%p), prot=0x%hhx (old page=%p)\n", pc, addr, db, db?((void*)db->x64_addr):NULL, prot, (void*)repeated_page); - static int repeated_count = 0; - if(repeated_page == ((uintptr_t)addr&~(box64_pagesize-1))) { - ++repeated_count; // Access eoor multiple time on same page, disable dynarec on this page a few time... - if(repeated_count>1) { - dynarec_log(LOG_DEBUG, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count); - SetHotPage(repeated_page); - } - } else { - repeated_page = (uintptr_t)addr&~(box64_pagesize-1); - repeated_count = 0; - } // 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)) { emu = getEmuSignal(emu, p, db); |