about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-02-19 23:55:18 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-02-19 23:55:18 +0100
commit692ad43285a4182669254449d343066e2bdfe318 (patch)
tree3d71007654310f9beffd37b8882a0578c3b90855 /src
parentd06ff478d188eb4a077041e4b2b628f75ed9eaf8 (diff)
downloadbox64-692ad43285a4182669254449d343066e2bdfe318.tar.gz
box64-692ad43285a4182669254449d343066e2bdfe318.zip
[DYNAREC] Optimized FillBlock64 to avoid 3 for loop on all block instructions and a temporary malloc/free
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_pass2.h12
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_pass3.h9
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_private.h1
-rwxr-xr-xsrc/dynarec/dynarec_native.c25
-rwxr-xr-xsrc/include/dynarec_native.h3
5 files changed, 23 insertions, 27 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_pass2.h b/src/dynarec/arm64/dynarec_arm64_pass2.h
index 29d5f01a..edc43ae5 100755
--- a/src/dynarec/arm64/dynarec_arm64_pass2.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass2.h
@@ -1,14 +1,18 @@
 #define INIT        dyn->native_size = 0
-#define FINI        if(ninst) {dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);}
+#define FINI                                                                                            \
+        if(ninst) {                                                                                     \
+                dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);     \
+                dyn->insts_size += 1+((dyn->insts[ninst].x64.size>dyn->insts[ninst].size)?dyn->insts[ninst].x64.size:dyn->insts[ninst].size)/15; \
+        }
 
 #define MESSAGE(A, ...)  
 #define EMIT(A)     dyn->insts[ninst].size+=4; dyn->native_size+=4
 #define NEW_INST                                                                                        \
         if(ninst) {                                                                                     \
                 dyn->insts[ninst].address = (dyn->insts[ninst-1].address+dyn->insts[ninst-1].size);     \
-                if(ninst && isInstClean(dyn, ninst)) {                                                  \
-                        if(dyn->last_ip!=ip) dyn->last_ip = 0;                                          \
-                }                                                                                       \
+                if(isInstClean(dyn, ninst) && dyn->last_ip!=ip)                                         \
+                        dyn->last_ip = 0;                                                               \
+                dyn->insts_size += 1+((dyn->insts[ninst-1].x64.size>dyn->insts[ninst-1].size)?dyn->insts[ninst-1].x64.size:dyn->insts[ninst-1].size)/15; \
         }
 #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size; 
 #define INST_NAME(name) 
diff --git a/src/dynarec/arm64/dynarec_arm64_pass3.h b/src/dynarec/arm64/dynarec_arm64_pass3.h
index 13b2b323..ae79c11f 100755
--- a/src/dynarec/arm64/dynarec_arm64_pass3.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass3.h
@@ -1,5 +1,8 @@
 #define INIT    
-#define FINI
+#define FINI        \
+    if(ninst)       \
+        addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst].x64.size, dyn->insts[ninst].size/4); \
+    addInst(dyn->instsize, &dyn->insts_size, 0, 0);
 #define EMIT(A)     \
     if(box64_dynarec_dump) {dynarec_log(LOG_NONE, "\t%08x\t%s\n", (uint32_t)(A), arm64_print(A, (uintptr_t)dyn->block));} \
     *(uint32_t*)(dyn->block) = (uint32_t)(A);       \
@@ -10,7 +13,9 @@
 #define NEW_INST        \
     if(ninst && isInstClean(dyn, ninst)) {                      \
         if(dyn->last_ip!=ip) dyn->last_ip = 0;                  \
-    }
+    }                                                           \
+    if(ninst)                                                   \
+        addInst(dyn->instsize, &dyn->insts_size, dyn->insts[ninst-1].x64.size, dyn->insts[ninst-1].size/4);
 #define INST_EPILOG     
 #define INST_NAME(name) \
     if(box64_dynarec_dump) {\
diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h
index 6abdf829..1b194e97 100755
--- a/src/dynarec/arm64/dynarec_arm64_private.h
+++ b/src/dynarec/arm64/dynarec_arm64_private.h
@@ -103,6 +103,7 @@ typedef struct dynarec_arm_s {
     int*                predecessor;// single array of all predecessor
     dynablock_t*        dynablock;
     instsize_t*         instsize;
+    size_t              insts_size; // size of the instruction size array (calculated)
     uint8_t             smread;    // for strongmem model emulation
     uint8_t             smwrite;    // for strongmem model emulation
 } dynarec_arm_t;
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index f8d29b61..c3f01ff2 100755
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -240,7 +240,7 @@ int is_instructions(dynarec_native_t *dyn, uintptr_t addr, int n)
     return (i==n)?1:0;
 }
 
-instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size, int native_size)
+void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size)
 {
     // x64 instruction is <16 bytes
     int toadd;
@@ -248,10 +248,6 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size,
         toadd = 1 + x64_size/15;
     else
         toadd = 1 + native_size/15;
-    if((*size)+toadd>(*cap)) {
-        *cap = (*size)+toadd;
-        insts = (instsize_t*)customRealloc(insts, (*cap)*sizeof(instsize_t));
-    }
     while(toadd) {
         if(x64_size>15)
             insts[*size].x64 = 15;    
@@ -266,7 +262,6 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size,
         ++(*size);
         --toadd;
     }
-    return insts;
 }
 
 // add a value to table64 (if needed) and gives back the imm19 to use in LDR_literal
@@ -391,7 +386,6 @@ void CancelBlock64(int need_lock)
     }
     customFree(helper->next);
     customFree(helper->insts);
-    customFree(helper->instsize);
     customFree(helper->predecessor);
     customFree(helper->table64);
     if(helper->dynablock && helper->dynablock->actual_block)
@@ -522,18 +516,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     // pass 2, instruction size
     native_pass2(&helper, addr);
     // keep size of instructions for signal handling
-    size_t insts_rsize = 0;
-    {
-        size_t insts_size = 0;
-        size_t cap = 1;
-        for(int i=0; i<helper.size; ++i)
-            cap += 1 + ((helper.insts[i].x64.size>helper.insts[i].size)?helper.insts[i].x64.size:helper.insts[i].size)/15;
-        helper.instsize = (instsize_t*)customCalloc(cap, sizeof(instsize_t));
-        for(int i=0; i<helper.size; ++i)
-            helper.instsize = addInst(helper.instsize, &insts_size, &cap, helper.insts[i].x64.size, helper.insts[i].size/4);
-        helper.instsize = addInst(helper.instsize, &insts_size, &cap, 0, 0);    // add a "end of block" mark, just in case
-        insts_rsize = insts_size*sizeof(instsize_t);
-    }
+    size_t insts_rsize = (helper.insts_size+2)*sizeof(instsize_t);
     insts_rsize = (insts_rsize+7)&~7;   // round the size...
     // ok, now allocate mapped memory, with executable flag on
     size_t sz = sizeof(void*) + helper.native_size + helper.table64size*sizeof(uint64_t) + 4*sizeof(void*) + insts_rsize;
@@ -550,6 +533,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
     helper.block = p;
     helper.native_start = (uintptr_t)p;
     helper.tablestart = helper.native_start + helper.native_size;
+    helper.insts_size = 0;  // reset
+    helper.instsize = (instsize_t*)instsize;
     *(dynablock_t**)actual_p = block;
     // pass 3, emit (log emit native opcode)
     if(box64_dynarec_dump) {
@@ -581,14 +566,12 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
         memcpy((void*)helper.tablestart, helper.table64, helper.table64size*8);
     }
     // keep size of instructions for signal handling
-    memcpy(instsize, helper.instsize, insts_rsize);
     block->instsize = instsize;
     // ok, free the helper now
     customFree(helper.insts);
     helper.insts = NULL;
     customFree(helper.table64);
     helper.table64 = NULL;
-    customFree(helper.instsize);
     helper.instsize = NULL;
     customFree(helper.predecessor);
     helper.predecessor = NULL;
diff --git a/src/include/dynarec_native.h b/src/include/dynarec_native.h
index 9fe26323..eff5a6bf 100755
--- a/src/include/dynarec_native.h
+++ b/src/include/dynarec_native.h
@@ -3,6 +3,9 @@
 
 typedef struct dynablock_s dynablock_t;
 typedef struct x64emu_s x64emu_t;
+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);
 void* FillBlock64(dynablock_t* block, uintptr_t addr);