about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c4
-rw-r--r--src/dynarec/dynablock.c12
-rw-r--r--src/dynarec/dynarec_native.c16
-rw-r--r--src/include/custommem.h2
-rw-r--r--src/include/dynarec_native.h2
5 files changed, 19 insertions, 17 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 256dd528..f23ec5d5 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -1064,6 +1064,7 @@ typedef struct mmaplist_s {
     blocklist_t**   chunks;
     int             cap;
     int             size;
+    int             has_new;
 } mmaplist_t;
 
 mmaplist_t* NewMmaplist()
@@ -1124,7 +1125,7 @@ dynablock_t* FindDynablockFromNativeAddress(void* p)
 #ifdef TRACE_MEMSTAT
 static uint64_t dynarec_allocated = 0;
 #endif
-uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size)
+uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size, int is_new)
 {
     if(!size)
         return 0;
@@ -1136,6 +1137,7 @@ uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size)
         list = mmaplist;
     if(!list)
         list = mmaplist = NewMmaplist();
+    if(is_new) list->has_new = 1;
     // check if there is space in current open ones
     int idx = 0;
     uintptr_t sz = size + 2*sizeof(blockmark_t);
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 45a2b4f9..b5a81020 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -185,7 +185,7 @@ void cancelFillBlock()
     return NULL if block is not found / cannot be created. 
     Don't create if create==0
 */
-static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, int need_lock, int is32bits)
+static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, int need_lock, int is32bits, int is_new)
 {
     if (hasAlternate((void*)filladdr))
         return NULL;
@@ -225,7 +225,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
             mutex_unlock(&my_context->mutex_dyndump);
         return NULL;
     }
-    block = FillBlock64(filladdr, (addr==filladdr)?0:1, is32bits, MAX_INSTS);
+    block = FillBlock64(filladdr, (addr==filladdr)?0:1, is32bits, MAX_INSTS, is_new);
     if(!block) {
         dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
     }
@@ -260,7 +260,7 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
     int is_inhotpage = isInHotPage(addr);
     if(is_inhotpage && !BOX64ENV(dynarec_dirty))
         return NULL;
-    dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits);
+    dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits, 1);
     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);
@@ -273,7 +273,7 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
             // Free db, it's now invalid!
             dynablock_t* old = InvalidDynablock(db, need_lock);
             // start again... (will create a new block)
-            db = internalDBGetBlock(emu, addr, addr, create, need_lock, is32bits);
+            db = internalDBGetBlock(emu, addr, addr, create, need_lock, is32bits, 0);
             if(db) {
                 if(db->previous)
                     FreeInvalidDynablock(db->previous, need_lock);
@@ -312,7 +312,7 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr,
 {
     dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p%s\n", (void*)addr, (void*)filladdr, is32bits?" 32bits":"");
     int create = 1;
-    dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1, is32bits);
+    dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1, is32bits, 1);
     if(db && db->done && db->block && getNeedTest(filladdr)) {
         if (db->always_test) SchedYield(); // just calm down...
         int need_lock = mutex_trylock(&my_context->mutex_dyndump);
@@ -323,7 +323,7 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr,
             // Free db, it's now invalid!
             dynablock_t* old = InvalidDynablock(db, need_lock);
             // start again... (will create a new block)
-            db = internalDBGetBlock(emu, addr, filladdr, create, need_lock, is32bits);
+            db = internalDBGetBlock(emu, addr, filladdr, create, need_lock, is32bits, 0);
             if(db) {
                 if(db->previous)
                     FreeInvalidDynablock(db->previous, need_lock);
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 6d777805..bba18978 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -567,9 +567,9 @@ uintptr_t native_pass1(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
 uintptr_t native_pass2(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits, int inst_max);
 uintptr_t native_pass3(dynarec_native_t* dyn, uintptr_t addr, int alternate, int is32bits, int inst_max);
 
-dynablock_t* CreateEmptyBlock(uintptr_t addr, int is32bits) {
+dynablock_t* CreateEmptyBlock(uintptr_t addr, int is32bits, int is_new) {
     size_t sz = 4*sizeof(void*) + sizeof(dynablock_t);
-    void* actual_p = (void*)AllocDynarecMap(addr, sz);
+    void* actual_p = (void*)AllocDynarecMap(addr, sz, is_new);
     void* p = actual_p + sizeof(void*);
     if(actual_p==NULL) {
         dynarec_log(LOG_INFO, "AllocDynarecMap(%p, %zu) failed, canceling block\n", (void*)addr, sz);
@@ -595,7 +595,7 @@ dynablock_t* CreateEmptyBlock(uintptr_t addr, int is32bits) {
     return block;
 }
 
-dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_max) {
+dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_max, int is_new) {
     /*
         A Block must have this layout:
 
@@ -612,7 +612,7 @@ dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_m
     */
     if(addr>=BOX64ENV(nodynarec_start) && addr<BOX64ENV(nodynarec_end)) {
         dynarec_log(LOG_INFO, "Create empty block in no-dynarec zone\n");
-        return CreateEmptyBlock(addr, is32bits);
+        return CreateEmptyBlock(addr, is32bits, is_new);
     }
     if(current_helper) {
         dynarec_log(LOG_DEBUG, "Canceling dynarec FillBlock at %p as another one is going on\n", (void*)addr);
@@ -660,7 +660,7 @@ dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_m
     if(!helper.size) {
         dynarec_log(LOG_INFO, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
         CancelBlock64(0);
-        return CreateEmptyBlock(addr, is32bits);
+        return CreateEmptyBlock(addr, is32bits, is_new);
     }
     if(!isprotectedDB(addr, 1)) {
         dynarec_log(LOG_INFO, "Warning, write on current page on pass0, aborting dynablock creation (%p)\n", (void*)addr);
@@ -762,7 +762,7 @@ dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_m
         // NULL block after removing dead code, how is that possible?
         dynarec_log(LOG_INFO, "Warning, null-sized dynarec block after trimming dead code (%p)\n", (void*)addr);
         CancelBlock64(0);
-        return CreateEmptyBlock(addr, is32bits);
+        return CreateEmptyBlock(addr, is32bits, is_new);
     }
     updateYmm0s(&helper, 0, 0);
     UPDATE_SPECIFICS(&helper);
@@ -818,7 +818,7 @@ dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_m
         --imax;
         if(dyn->need_dump || BOX64ENV(dynarec_log))dynarec_log(LOG_NONE, "Dynablock oversized, with %zu (max=%zd), recomputing cutting at %d from %d\n", native_size, MAXBLOCK_SIZE, imax, helper.size);
         CancelBlock64(0);
-        return FillBlock64(addr, alternate, is32bits, imax);
+        return FillBlock64(addr, alternate, is32bits, imax, is_new);
     }
     size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
     insts_rsize = (insts_rsize+7)&~7;   // round the size...
@@ -828,7 +828,7 @@ dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_m
     // ok, now allocate mapped memory, with executable flag on
     size_t sz = sizeof(void*) + native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize + arch_size + callret_size + sizeof(dynablock_t) + reloc_size;
     //           dynablock_t*     block (arm insts)            table64               jmpnext code       instsize     arch         callrets          dynablock           relocs
-    void* actual_p = (void*)AllocDynarecMap(addr, sz);
+    void* actual_p = (void*)AllocDynarecMap(addr, sz, is_new);
     void* p = (void*)(((uintptr_t)actual_p) + sizeof(void*));
     void* tablestart = p + native_size;
     void* next = tablestart + helper.table64size*sizeof(uint64_t);
diff --git a/src/include/custommem.h b/src/include/custommem.h
index 1ff4bdcc..17acc1e9 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -33,7 +33,7 @@ size_t customGetUsableSize(void* p);
 typedef struct dynablock_s dynablock_t;
 typedef struct mmaplist_s mmaplist_t;
 // custom protection flag to mark Page that are Write protected for Dynarec purpose
-uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size);
+uintptr_t AllocDynarecMap(uintptr_t x64_addr, size_t size, int is_new);
 void FreeDynarecMap(uintptr_t addr);
 mmaplist_t* NewMmaplist();
 void DelMmaplist(mmaplist_t* list);
diff --git a/src/include/dynarec_native.h b/src/include/dynarec_native.h
index 74e0e05a..c5bca0a4 100644
--- a/src/include/dynarec_native.h
+++ b/src/include/dynarec_native.h
@@ -24,6 +24,6 @@ typedef struct instsize_s instsize_t;
 void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size);
 
 void CancelBlock64(int need_lock);
-dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_max);
+dynablock_t* FillBlock64(uintptr_t addr, int alternate, int is32bits, int inst_max, int is_new);
 
 #endif //__DYNAREC_ARM_H_