about summary refs log tree commit diff stats
path: root/src/custommem.c
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-03-12 14:39:07 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-03-12 14:39:07 +0100
commit1af85c69a182fa6539c5690a3feebe9002fd9552 (patch)
treef268bc9ca93813c953510c803293f07f71c42c04 /src/custommem.c
parent3087ea0e6136fd1ed0c756e6ea316ce61678fb3a (diff)
downloadbox64-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.c50
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 {