From 692ad43285a4182669254449d343066e2bdfe318 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 19 Feb 2023 23:55:18 +0100 Subject: [DYNAREC] Optimized FillBlock64 to avoid 3 for loop on all block instructions and a temporary malloc/free --- src/dynarec/arm64/dynarec_arm64_pass2.h | 12 ++++++++---- src/dynarec/arm64/dynarec_arm64_pass3.h | 9 +++++++-- src/dynarec/arm64/dynarec_arm64_private.h | 1 + src/dynarec/dynarec_native.c | 25 ++++--------------------- src/include/dynarec_native.h | 3 +++ 5 files changed, 23 insertions(+), 27 deletions(-) (limited to 'src') 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; ihelper.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; iinstsize = 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); -- cgit 1.4.1