diff options
Diffstat (limited to 'src/dynarec/dynablock.c')
| -rw-r--r-- | src/dynarec/dynablock.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index b5a81020..b804eff2 100644 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -85,14 +85,15 @@ void FreeInvalidDynablock(dynablock_t* db, int need_lock) } } -void FreeDynablock(dynablock_t* db, int need_lock) +void FreeDynablock(dynablock_t* db, int need_lock, int need_remove) { if(db) { if(db->gone) return; // already in the process of deletion! dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x64=%p:%p already gone=%d\n", db, db->block, db->x64_addr, db->x64_addr+db->x64_size-1, db->gone); // remove jumptable without waiting - setJumpTableDefault64(db->x64_addr); + if(need_remove) + setJumpTableDefault64(db->x64_addr); if(need_lock) mutex_lock(&my_context->mutex_dyndump); dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->actual_block, db->size); @@ -168,7 +169,7 @@ int FreeRangeDynablock(dynablock_t* db, uintptr_t addr, uintptr_t size) int need_lock = my_context?1:0; if(IntervalIntersects((uintptr_t)db->x64_addr, (uintptr_t)db->x64_addr+db->x64_size-1, addr, addr+size+1)) { - FreeDynablock(db, need_lock); + FreeDynablock(db, need_lock, 1); return 0; } return 1; @@ -233,7 +234,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t if(block) { // fill-in jumptable if(!addJumpTableIfDefault64(block->x64_addr, block->dirty?block->jmpnext:block->block)) { - FreeDynablock(block, 0); + FreeDynablock(block, 0, 0); block = getDB(addr); MarkDynablock(block); // just in case... } else { @@ -261,9 +262,9 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits) if(is_inhotpage && !BOX64ENV(dynarec_dirty)) return NULL; dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1, is32bits, 1); - if(db && db->done && db->block && getNeedTest(addr)) { + if(db && db->done && db->block && (db->dirty || getNeedTest(addr))) { if (db->always_test) SchedYield(); // just calm down... - uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); + uint32_t hash = db->dirty?(~db->hash):X31_hash_code(db->x64_addr, db->x64_size); if(is_inhotpage && hash!=db->hash) return NULL; // will be handle when hotpage is over int need_lock = mutex_trylock(&my_context->mutex_dyndump); @@ -313,10 +314,10 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p%s\n", (void*)addr, (void*)filladdr, is32bits?" 32bits":""); int create = 1; dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, 1, is32bits, 1); - if(db && db->done && db->block && getNeedTest(filladdr)) { + if(db && db->done && db->block && (db->dirty || getNeedTest(filladdr))) { if (db->always_test) SchedYield(); // just calm down... int need_lock = mutex_trylock(&my_context->mutex_dyndump); - uint32_t hash = X31_hash_code(db->x64_addr, db->x64_size); + uint32_t hash = db->dirty?(~db->hash):X31_hash_code(db->x64_addr, db->x64_size); if(hash!=db->hash) { db->done = 0; // invalidating the block dynarec_log(LOG_DEBUG, "Invalidating alt block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size, hash, db->hash, (void*)addr); |