diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-03-12 14:39:07 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-03-12 14:39:07 +0100 |
| commit | 1af85c69a182fa6539c5690a3feebe9002fd9552 (patch) | |
| tree | f268bc9ca93813c953510c803293f07f71c42c04 /src/custommem.c | |
| parent | 3087ea0e6136fd1ed0c756e6ea316ce61678fb3a (diff) | |
| download | box64-1af85c69a182fa6539c5690a3feebe9002fd9552.tar.gz box64-1af85c69a182fa6539c5690a3feebe9002fd9552.zip | |
[DYNAREC] Introduced DYNAREC_DIRTY=2 and changed a profile to use it
Diffstat (limited to 'src/custommem.c')
| -rw-r--r-- | src/custommem.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/custommem.c b/src/custommem.c index 87d55778..f966c835 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -1446,6 +1446,47 @@ void unprotectDB(uintptr_t addr, size_t size, int mark) } UNLOCK_PROT(); } +// Add the NEVERCLEAN flag for an adress range, mark all block as dirty, and lift write protection if needed +void neverprotectDB(uintptr_t addr, size_t size, int mark) +{ + dynarec_log(LOG_DEBUG, "neverprotectDB %p -> %p (mark=%d)\n", (void*)addr, (void*)(addr+size-1), mark); + + uintptr_t cur = addr&~(box64_pagesize-1); + uintptr_t end = ALIGN(addr+size); + + LOCK_PROT(); + while(cur!=end) { + uint32_t prot = 0, oprot; + uintptr_t bend = 0; + if (!rb_get_end(memprot, cur, &prot, &bend)) { + if(bend>=end) break; + else { + cur = bend; + continue; + } + } + oprot = prot; + if(bend>end) + bend = end; + if(!(prot&PROT_NEVERPROT)) { + if(prot&PROT_DYNAREC) { + prot&=~PROT_DYN; + if(mark) + cleanDBFromAddressRange(cur, bend-cur, 0); + mprotect((void*)cur, bend-cur, prot); + } else if(prot&PROT_DYNAREC_R) { + if(mark) + cleanDBFromAddressRange(cur, bend-cur, 0); + prot &= ~PROT_DYN; + } + prot |= PROT_NEVERCLEAN; + } + if (prot != oprot) + rb_set(memprot, cur, bend, prot); + cur = bend; + } + UNLOCK_PROT(); +} int isprotectedDB(uintptr_t addr, size_t size) { @@ -1484,8 +1525,13 @@ 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); + if(BOX64ENV(dynarec_dirty)>1) { + dynarec_log(LOG_INFO, "Detecting a Hotpage at %p (%d), marking page as NEVERCLEAN\n", (void*)repeated_page, repeated_count); + neverprotectDB(repeated_page, box64_pagesize, 1); + } else { + dynarec_log(LOG_INFO, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count); + SetHotPage(repeated_page); + } repeated_count = 0; repeated_page = 0; } else { |