From 4610f451e99610043461401f4c9acd3de408a02d Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 19 Feb 2023 14:50:01 +0100 Subject: Improved convertion to/from 80bits double, and added BOX64_X87_NO80BITS to not handle them --- src/include/debug.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/include') diff --git a/src/include/debug.h b/src/include/debug.h index 7251c728..06ec0d8c 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -47,6 +47,7 @@ extern uint64_t start_cnt; extern int box64_nosandbox; extern int box64_dummy_crashhandler; extern int box64_sse_flushto0; +extern int box64_x87_no80bits; extern int allow_missing_libs; extern int box64_mapclean; extern int box64_prefer_wrapped; -- cgit 1.4.1 From d06ff478d188eb4a077041e4b2b628f75ed9eaf8 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sun, 19 Feb 2023 23:54:00 +0100 Subject: [DYNAREC] Introduced BOX64_DYNAREC_FASTPAGE to use an alternate way to handle HotPages (faster but crashy) --- docs/USAGE.md | 7 ++++++- src/dynarec/dynablock.c | 15 +++++++++++++-- src/include/debug.h | 1 + src/main.c | 10 ++++++++++ src/tools/rcfile.c | 8 +++++--- 5 files changed, 35 insertions(+), 6 deletions(-) (limited to 'src/include') diff --git a/docs/USAGE.md b/docs/USAGE.md index 17fadb61..92913438 100755 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -175,7 +175,12 @@ Optimisation of CALL/RET opcodes (not compatible with jit/dynarec/smc) #### BOX64_DYNAREC_HOTPAGE * Handling of HotPage (Page beeing both executed and writen) * 0 : Don't track hotpage -* 1-255 : Trak HotPage, and disable execution of a page beeing writen for N attempts (default is 16) +* 1-255 : Track HotPage, and disable execution of a page beeing writen for N attempts (default is 16) + +#### BOX64_DYNAREC_FASTPAGE * +Will use a faster handling of HotPage (Page beeing both executed and writen) +* 0 : use regular hotpage (Default) +* 1 : Use faster hotpage, taking the risk of running obsolete JIT code (might be faster, but more prone to crash) #### BOX64_DYNAREC_BLEEDING_EDGE * Detect MonoBleedingEdge and apply conservative settings diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index 6ff5e53c..9529a91c 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -205,8 +205,19 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create) dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1); if(db && db->done && db->block && db->need_test) { if(AreaInHotPage((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr + db->x64_size - 1)) { - dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, (void*)addr); - return NULL; + if(box64_dynarec_fastpage) { + uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); + if(hash==db->hash) // seems ok, run it without reprotecting it + return db; + db->done = 0; // invalidating the block, it's already not good + dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr); + // Free db, it's now invalid! + FreeDynablock(db, 1); + return NULL; // not building a new one, it's still a hotpage + } else { + dynarec_log(LOG_INFO, "Not running block %p from %p:%p with for %p because it's in a hotpage\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, (void*)addr); + return NULL; + } } uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); if(mutex_trylock(&my_context->mutex_dyndump)) { diff --git a/src/include/debug.h b/src/include/debug.h index 06ec0d8c..b9729787 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -23,6 +23,7 @@ extern int box64_dynarec_safeflags; extern int box64_dynarec_callret; extern int box64_dynarec_bleeding_edge; extern int box64_dynarec_hotpage; +extern int box64_dynarec_fastpage; extern int box64_dynarec_wait; #ifdef ARM64 extern int arm64_asimd; diff --git a/src/main.c b/src/main.c index b8ee9f4b..55a18473 100755 --- a/src/main.c +++ b/src/main.c @@ -57,6 +57,7 @@ int box64_dynarec_fastround = 1; int box64_dynarec_safeflags = 1; int box64_dynarec_callret = 0; int box64_dynarec_hotpage = 16; +int box64_dynarec_fastpage = 0; int box64_dynarec_bleeding_edge = 1; int box64_dynarec_wait = 1; uintptr_t box64_nodynarec_start = 0; @@ -563,6 +564,15 @@ void LoadLogEnv() else printf_log(LOG_INFO, "Dynarec will not tag HotPage\n"); } + p = getenv("BOX64_DYNAREC_FASTPAGE"); + if(p) { + if(strlen(p)==1) { + if(p[0]>='0' && p[0]<='1') + box64_dynarec_fastpage = p[0]-'0'; + } + if(box64_dynarec_fastpage) + printf_log(LOG_INFO, "Dynarec will use Fast HotPage\n"); + } p = getenv("BOX64_NODYNAREC"); if(p) { if (strchr(p,'-')) { diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index e3789a20..60e1a1e5 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -112,7 +112,8 @@ ENTRYINT(BOX64_DYNAREC_SAFEFLAGS, box64_dynarec_safeflags, 0, 2, 2) \ ENTRYBOOL(BOX64_DYNAREC_CALLRET, box64_dynarec_callret) \ ENTRYBOOL(BOX64_DYNAREC_BLEEDING_EDGE, box64_dynarec_bleeding_edge) \ ENTRYINT(BOX64_DYNAREC_HOTPAGE, box64_dynarec_hotpage, 0, 255, 8) \ -ENTRYBOOL(box64_dynarec_wait, box64_dynarec_wait) \ +ENTRYBOOL(BOX64_DYNAREC_FASTPAGE, box64_dynarec_fastpage) \ +ENTRYBOOL(BOX64_DYNAREC_WAIT, box64_dynarec_wait) \ ENTRYSTRING_(BOX64_NODYNAREC, box64_nodynarec) \ #else @@ -129,7 +130,8 @@ IGNORE(BOX64_DYNAREC_SAFEFLAGS) \ IGNORE(BOX64_DYNAREC_CALLRET) \ IGNORE(BOX64_DYNAREC_BLEEDING_EDGE) \ IGNORE(BOX64_DYNAREC_HOTPAGE) \ -IGNORE(BOX64_DYNAREC_wait) \ +IGNORE(BOX64_DYNAREC_FASTPAGE) \ +IGNORE(BOX64_DYNAREC_WAIT) \ IGNORE(BOX64_NODYNAREC) \ #endif @@ -354,7 +356,7 @@ void LoadRCFile(const char* filename) if(0) ; SUPER() else if(len && current_name) { - printf_log(LOG_INFO, "Warning, unsupported %s=%s for [%s] in %s", key, val, current_name, filename); + printf_log(LOG_INFO, "Warning, unsupported %s=%s for [%s] in %s\n", key, val, current_name, filename); } #undef ENTRYBOOL #undef CENTRYBOOL -- cgit 1.4.1 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/include') 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