diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-02-19 23:55:18 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-02-19 23:55:18 +0100 |
| commit | 692ad43285a4182669254449d343066e2bdfe318 (patch) | |
| tree | 3d71007654310f9beffd37b8882a0578c3b90855 /src | |
| parent | d06ff478d188eb4a077041e4b2b628f75ed9eaf8 (diff) | |
| download | box64-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-x | src/dynarec/arm64/dynarec_arm64_pass2.h | 12 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_pass3.h | 9 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_private.h | 1 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_native.c | 25 | ||||
| -rwxr-xr-x | src/include/dynarec_native.h | 3 |
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); |