about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/dynarec_arm64_pass0.h6
-rw-r--r--src/dynarec/dynarec_native.c57
-rw-r--r--src/dynarec/dynarec_native_pass.c7
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h4
-rw-r--r--src/dynarec/la64/dynarec_la64_pass0.h6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass0.h6
-rw-r--r--src/include/dynarec_native.h2
8 files changed, 42 insertions, 50 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_pass0.h b/src/dynarec/arm64/dynarec_arm64_pass0.h
index 812986a0..a335c6c5 100644
--- a/src/dynarec/arm64/dynarec_arm64_pass0.h
+++ b/src/dynarec/arm64/dynarec_arm64_pass0.h
@@ -22,11 +22,7 @@
 #define SET_HASCALLRET()    dyn->insts[ninst].x64.has_callret = 1
 #define NEW_INST \
         ++dyn->size;                            \
-        if(dyn->size+3>=dyn->cap) {             \
-                dyn->insts = (instruction_native_t*)dynaRealloc(dyn->insts, sizeof(instruction_native_t)*dyn->cap*2);\
-                memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_native_t)*dyn->cap);   \
-                dyn->cap *= 2;                  \
-        }                                       \
+        memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t));     \
         dyn->insts[ninst].x64.addr = ip;        \
         dyn->n.combined1 = dyn->n.combined2 = 0;\
         dyn->n.swapped = 0; dyn->n.barrier = 0; \
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 600d23d1..84e5d3dc 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -72,8 +72,7 @@ void add_next(dynarec_native_t *dyn, uintptr_t addr) {
         }
     // add slots
     if(dyn->next_sz == dyn->next_cap) {
-        dyn->next_cap += 64;
-        dyn->next = (uintptr_t*)dynaRealloc(dyn->next, dyn->next_cap*sizeof(uintptr_t));
+        printf_log(LOG_NONE, "Warning, overallocating next\n");
     }
     dyn->next[dyn->next_sz++] = addr;
 }
@@ -97,8 +96,7 @@ uintptr_t get_closest_next(dynarec_native_t *dyn, uintptr_t addr) {
 void add_jump(dynarec_native_t *dyn, int ninst) {
     // add slots
     if(dyn->jmp_sz == dyn->jmp_cap) {
-        dyn->jmp_cap += 64;
-        dyn->jmps = (int*)dynaRealloc(dyn->jmps, dyn->jmp_cap*sizeof(int));
+        printf_log(LOG_NONE, "Warning, overallocating jmps\n");
     }
     dyn->jmps[dyn->jmp_sz++] = ninst;
 }
@@ -289,15 +287,10 @@ int Table64(dynarec_native_t *dyn, uint64_t val, int pass)
             idx = i;
     // not found, add it
     if(idx==-1) {
-        if(dyn->table64size == dyn->table64cap) {
-            dyn->table64cap+=16;
-            if(pass<3)  // do not resize on pass3, it's not the same type of memory anymore
-                dyn->table64 = (uint64_t*)dynaRealloc(dyn->table64, dyn->table64cap * sizeof(uint64_t));
-        }
         idx = dyn->table64size++;
         if(idx < dyn->table64cap)
             dyn->table64[idx] = val;
-        else
+        else if(pass==3)
             printf_log(LOG_NONE, "Warning, table64 bigger than expected %d vs %d\n", idx, dyn->table64cap);
     }
     // calculate offset
@@ -305,7 +298,7 @@ int Table64(dynarec_native_t *dyn, uint64_t val, int pass)
     return delta;
 }
 
-static void fillPredecessors(dynarec_native_t* dyn)
+static int sizePredecessors(dynarec_native_t* dyn)
 {
     int pred_sz = 1;    // to be safe
     // compute total size of predecessor to allocate the array
@@ -330,8 +323,10 @@ static void fillPredecessors(dynarec_native_t* dyn)
             dyn->insts[i+1].pred_sz++;
         }
     }
-    int alloc_size = pred_sz;
-    dyn->predecessor = (int*)dynaMalloc(pred_sz*sizeof(int));
+    return pred_sz;
+}
+static void fillPredecessors(dynarec_native_t* dyn)
+{
     // fill pred pointer
     int* p = dyn->predecessor;
     for(int i=0; i<dyn->size; ++i) {
@@ -406,12 +401,6 @@ void CancelBlock64(int need_lock)
     dynarec_native_t* helper = (dynarec_native_t*)current_helper;
     current_helper = NULL;
     if(helper) {
-        dynaFree(helper->next);
-        dynaFree(helper->jmps);
-        dynaFree(helper->insts);
-        dynaFree(helper->predecessor);
-        if(helper->table64 && (helper->table64!=(uint64_t*)helper->tablestart))
-            dynaFree(helper->table64);
         if(helper->dynablock && helper->dynablock->actual_block) {
             FreeDynarecMap((uintptr_t)helper->dynablock->actual_block);
             helper->dynablock->actual_block = NULL;
@@ -449,6 +438,12 @@ void* CreateEmptyBlock(dynablock_t* block, uintptr_t addr) {
     return block;
 }
 
+static int static_jmps[MAX_INSTS+2];
+static uintptr_t static_next[MAX_INSTS+2];
+static uint64_t static_table64[(MAX_INSTS+3)/4];
+static instruction_native_t static_insts[MAX_INSTS+2] = {0};
+// TODO: ninst could be a uint16_t instead of an int, that could same some temp. memory
+
 void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bits) {
     /*
         A Block must have this layout:
@@ -458,7 +453,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
         A ..    A+8*n   : Table64: n 64bits values
         B ..    B+7     : dynablock_t* : self (as part of JmpNext, that simulate another block)
         B+8 ..  B+15    : 2 Native code for jmpnext (or jmp epilog in case of empty block)
-        B+16 .. B+23    : jmpnext (or jmp_epilog) address
+        B+16 .. B+23    : jmpnext (or jmp_epilog) address. jumpnext is used when the block needs testing
         B+24 .. B+31    : empty (in case an architecture needs more than 2 opcodes)
         B+32 .. B+32+sz : instsize (compressed array with each instruction length on x64 and native side)
 
@@ -479,8 +474,14 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
     helper.dynablock = block;
     helper.start = addr;
     uintptr_t start = addr;
-    helper.cap = 128;
-    helper.insts = (instruction_native_t*)dynaCalloc(helper.cap, sizeof(instruction_native_t));
+    helper.cap = MAX_INSTS;
+    helper.insts = static_insts;
+    helper.jmps = static_jmps;
+    helper.jmp_cap = MAX_INSTS;
+    helper.next = static_next;
+    helper.next_cap = MAX_INSTS;
+    helper.table64 = static_table64;
+    helper.table64cap = sizeof(static_table64)/sizeof(uint64_t);
     // pass 0, addresses, x64 jump addresses, overall size of the block
     uintptr_t end = native_pass0(&helper, addr, alternate, is32bits);
     if(helper.abort) {
@@ -550,13 +551,13 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
         }
     }
     // no need for next and jmps anymore
-    dynaFree(helper.next);
     helper.next_sz = helper.next_cap = 0;
     helper.next = NULL;
-    dynaFree(helper.jmps);
     helper.jmp_sz = helper.jmp_cap = 0;
     helper.jmps = NULL;
     // fill predecessors with the jump address
+    int alloc_size = sizePredecessors(&helper);
+    helper.predecessor = (int*)alloca(alloc_size*sizeof(int));
     fillPredecessors(&helper);
 
     int pos = helper.size;
@@ -612,7 +613,6 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
     helper.instsize = (instsize_t*)instsize;
     *(dynablock_t**)actual_p = block;
     helper.table64cap = helper.table64size;
-    dynaFree(helper.table64);
     helper.table64 = (uint64_t*)helper.tablestart;
     // pass 3, emit (log emit native opcode)
     if(box64_dynarec_dump) {
@@ -634,12 +634,8 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
     }
     // keep size of instructions for signal handling
     block->instsize = instsize;
-    // ok, free the helper now
-    dynaFree(helper.insts);
-    helper.insts = NULL;
     helper.table64 = NULL;
     helper.instsize = NULL;
-    dynaFree(helper.predecessor);
     helper.predecessor = NULL;
     block->size = sz;
     block->isize = helper.size;
@@ -676,6 +672,9 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
         CancelBlock64(0);
         return NULL;
     }
+    // ok, free the helper now
+    //dynaFree(helper.insts);
+    helper.insts = NULL;
     if(insts_rsize/sizeof(instsize_t)<helper.insts_size) {
         printf_log(LOG_NONE, "BOX64: Warning, insts_size difference in block between pass2 (%zu) and pass3 (%zu), allocated: %zu\n", oldinstsize, helper.insts_size, insts_rsize/sizeof(instsize_t));
     }
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index 471e2c98..8c609da1 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -71,7 +71,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
         // This test is here to prevent things like TABLE64 to be out of range
         // native_size is not exact at this point, but it should be larger, not smaller, and not by a huge margin anyway
         // so it's good enough to avoid overflow in relative to PC data fectching
-        if(dyn->native_size >= MAXBLOCK_SIZE) {
+        if((dyn->native_size >= MAXBLOCK_SIZE) || (ninst >= MAX_INSTS)) {
             need_epilog = 1;
             break;
         }
@@ -98,8 +98,11 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
                 }
             }
             reset_n = -1;
-        } else if(ninst && (dyn->insts[ninst].pred_sz>1 || (dyn->insts[ninst].pred_sz==1 && dyn->insts[ninst].pred[0]!=ninst-1)))
+        } 
+        #if STEP > 0
+        else if(ninst && (dyn->insts[ninst].pred_sz>1 || (dyn->insts[ninst].pred_sz==1 && dyn->insts[ninst].pred[0]!=ninst-1)))
             dyn->last_ip = 0;   // reset IP if some jump are coming here
+        #endif
         fpu_propagate_stack(dyn, ninst);
         NEW_INST;
         #if STEP == 0
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index a2503932..b1cb2fc0 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -403,8 +403,8 @@
 #define ARCH_INIT()
 
 #if STEP < 2
-#define GETIP(A)
-#define GETIP_(A)
+#define GETIP(A) TABLE64(0, 0)
+#define GETIP_(A) TABLE64(0, 0)
 #else
 // put value in the Table64 even if not using it for now to avoid difference between Step2 and Step3. Needs to be optimized later...
 #define GETIP(A)                                     \
diff --git a/src/dynarec/la64/dynarec_la64_pass0.h b/src/dynarec/la64/dynarec_la64_pass0.h
index af2c29ba..5b3ce706 100644
--- a/src/dynarec/la64/dynarec_la64_pass0.h
+++ b/src/dynarec/la64/dynarec_la64_pass0.h
@@ -25,11 +25,7 @@
 #define SET_HASCALLRET() dyn->insts[ninst].x64.has_callret = 1
 #define NEW_INST                                                                                                  \
     ++dyn->size;                                                                                                  \
-    if (dyn->size + 3 >= dyn->cap) {                                                                              \
-        dyn->insts = (instruction_native_t*)dynaRealloc(dyn->insts, sizeof(instruction_native_t) * dyn->cap * 2); \
-        memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_native_t) * dyn->cap);                                \
-        dyn->cap *= 2;                                                                                            \
-    }                                                                                                             \
+    memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t));                                                  \
     dyn->insts[ninst].x64.addr = ip;                                                                              \
     dyn->insts[ninst].f_entry = dyn->f;                                                                           \
     if (ninst) { dyn->insts[ninst - 1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst - 1].x64.addr; }
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index bb2572ad..1f2f43c5 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -1002,8 +1002,8 @@
 
 
 #if STEP < 2
-#define GETIP(A)
-#define GETIP_(A)
+#define GETIP(A) TABLE64(0, 0)
+#define GETIP_(A) TABLE64(0, 0)
 #else
 // put value in the Table64 even if not using it for now to avoid difference between Step2 and Step3. Needs to be optimized later...
 #define GETIP(A)                                     \
diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h
index 13d4f115..0def2bed 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass0.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass0.h
@@ -22,11 +22,7 @@
 #define SET_HASCALLRET()    dyn->insts[ninst].x64.has_callret = 1
 #define NEW_INST \
         ++dyn->size;                            \
-        if(dyn->size+3>=dyn->cap) {             \
-                dyn->insts = (instruction_native_t*)dynaRealloc(dyn->insts, sizeof(instruction_native_t)*dyn->cap*2);\
-                memset(&dyn->insts[dyn->cap], 0, sizeof(instruction_native_t)*dyn->cap);   \
-                dyn->cap *= 2;                  \
-        }                                       \
+        memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t));     \
         dyn->insts[ninst].x64.addr = ip;        \
         dyn->e.combined1 = dyn->e.combined2 = 0;\
         dyn->e.swapped = 0; dyn->e.barrier = 0; \
diff --git a/src/include/dynarec_native.h b/src/include/dynarec_native.h
index 05bfc3b5..c61eb375 100644
--- a/src/include/dynarec_native.h
+++ b/src/include/dynarec_native.h
@@ -18,6 +18,8 @@ typedef struct instsize_s instsize_t;
 #define dynaFree box_free
 #endif
 
+#define MAX_INSTS   8190
+
 void addInst(instsize_t* insts, size_t* size, int x64_size, int native_size);
 
 void CancelBlock64(int need_lock);