tcg/wasm32: compile pure store TBs, keep mixed store-helper TBs TCI
This commit is contained in:
@@ -6684,17 +6684,12 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
||||
}
|
||||
*(uint32_t *)wasm_blob_ptr_base = s->code_ptr - wasm_blob_ptr_base - 4;
|
||||
|
||||
{
|
||||
static __thread int dumped_store, dumped_load;
|
||||
if (wasm_dump_pc_hi && pc_start >= wasm_dump_pc_lo && pc_start < wasm_dump_pc_hi) {
|
||||
uint32_t mod_len = *(uint32_t *)wasm_blob_ptr_base;
|
||||
const uint8_t *mod = wasm_blob_ptr_base + 4;
|
||||
if (wasm_tb_had_store && !dumped_store) {
|
||||
dumped_store = 1;
|
||||
wasm_dump_module(mod, mod_len, "store");
|
||||
} else if (wasm_tb_had_load && !wasm_tb_had_store && !dumped_load) {
|
||||
dumped_load = 1;
|
||||
wasm_dump_module(mod, mod_len, "load");
|
||||
}
|
||||
char dump_name[32];
|
||||
snprintf(dump_name, sizeof(dump_name), "pc-%08llx", (unsigned long long)pc_start);
|
||||
wasm_dump_module(mod, mod_len, dump_name);
|
||||
}
|
||||
|
||||
size_base = (uint32_t*)s->code_ptr;
|
||||
|
||||
+22
-3
@@ -45,14 +45,19 @@ EMSCRIPTEN_KEEPALIVE int wasm_instantiated_tb_count(void)
|
||||
}
|
||||
|
||||
EM_JS(void, wasm_dump_module_js, (int ptr, int len, int name), {
|
||||
const bytes = Uint8Array.from(HEAP8.subarray(ptr, ptr + len));
|
||||
const dumpName = UTF8ToString(name);
|
||||
try {
|
||||
const fs = require('fs');
|
||||
const bytes = Uint8Array.from(HEAP8.subarray(ptr, ptr + len));
|
||||
const fname = '/tmp/tbdump-' + UTF8ToString(name) + '.wasm';
|
||||
const fname = '/tmp/tbdump-' + dumpName + '.wasm';
|
||||
fs.writeFileSync(fname, bytes);
|
||||
out('WASM_DUMP wrote ' + fname + ' (' + len + ' bytes)');
|
||||
} catch (e) {
|
||||
/* Browser has no require('fs'); dump is a node-only analysis aid. */
|
||||
let hex = '';
|
||||
for (let i = 0; i < bytes.length; i++) hex += bytes[i].toString(16).padStart(2, '0');
|
||||
out('WASM_DUMP_HEX_BEGIN ' + dumpName + ' ' + len);
|
||||
for (let i = 0; i < hex.length; i += 2048) out('WASM_DUMP_HEX ' + dumpName + ' ' + hex.slice(i, i + 2048));
|
||||
out('WASM_DUMP_HEX_END ' + dumpName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1365,8 +1370,11 @@ static __thread uint8_t *diff_fulltlb_c[NB_MMU_MODES];
|
||||
int wasm_diff_mode;
|
||||
int wasm_stateflush_enabled;
|
||||
int wasm_tlb_guard_enabled;
|
||||
uint64_t wasm_dump_pc_lo;
|
||||
uint64_t wasm_dump_pc_hi;
|
||||
int wasm_store_tci_disabled;
|
||||
int wasm_store_tci_hash;
|
||||
int wasm_store_helper_tci;
|
||||
int wasm_store_bisect_on;
|
||||
int wasm_store_bisect_width;
|
||||
uint64_t wasm_store_pc_lo;
|
||||
@@ -1394,6 +1402,11 @@ EMSCRIPTEN_KEEPALIVE void wasm_set_store_tci_hash(int mode)
|
||||
wasm_store_tci_hash = mode;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void wasm_set_store_helper_tci(void)
|
||||
{
|
||||
wasm_store_helper_tci = 1;
|
||||
}
|
||||
|
||||
/* E15 bisection: compile a store TB only when (hash(pc) & mask) == val, else
|
||||
* TCI. Runtime-settable so the culprit set can be binary-searched with no
|
||||
* rebuild. */
|
||||
@@ -1433,6 +1446,12 @@ EMSCRIPTEN_KEEPALIVE void wasm_tlb_guard_enable(void)
|
||||
wasm_tlb_guard_enabled = 1;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void wasm_set_dump_pc_window(uint32_t lo, uint32_t hi)
|
||||
{
|
||||
wasm_dump_pc_lo = lo;
|
||||
wasm_dump_pc_hi = hi;
|
||||
}
|
||||
|
||||
int wasm_diff_on(void)
|
||||
{
|
||||
return wasm_diff_enabled;
|
||||
|
||||
@@ -58,16 +58,21 @@ extern __thread uint64_t wasm_cur_tb_pc;
|
||||
extern int wasm_diff_mode;
|
||||
extern int wasm_store_tci_disabled;
|
||||
extern int wasm_store_tci_hash;
|
||||
extern int wasm_store_helper_tci;
|
||||
extern int wasm_store_bisect_on;
|
||||
extern int wasm_store_bisect_width;
|
||||
extern uint64_t wasm_store_pc_lo;
|
||||
extern uint64_t wasm_store_pc_hi;
|
||||
extern uint64_t wasm_dump_pc_lo;
|
||||
extern uint64_t wasm_dump_pc_hi;
|
||||
extern uint32_t wasm_store_bisect_mask;
|
||||
extern uint32_t wasm_store_bisect_val;
|
||||
void wasm_disable_store_tci(void);
|
||||
void wasm_set_store_tci_hash(int mode);
|
||||
void wasm_set_store_helper_tci(void);
|
||||
void wasm_set_store_bisect(int width, uint32_t mask, uint32_t val);
|
||||
void wasm_set_store_pc_window(uint32_t lo, uint32_t hi);
|
||||
void wasm_set_dump_pc_window(uint32_t lo, uint32_t hi);
|
||||
void wasm_diff_enable(void);
|
||||
void wasm_diff_enable2(void);
|
||||
int wasm_diff_on(void);
|
||||
|
||||
@@ -3399,10 +3399,8 @@ static void tcg_out_qemu_st(TCGContext *s, TCGOpcode opc, const TCGArg *args, bo
|
||||
wasm_tb_had_store = true;
|
||||
tcg_tci_out_qemu_ldst(s, opc, args);
|
||||
tcg_wasm_out_qemu_st(s, args, is_64);
|
||||
/* ponytail: Store TBs Stay TCI - All-compiled stores still reproduce the 0x4201e210 panic.
|
||||
* The narrower 32-bit-only fallback passed reader-open but hit an app-init watchdog in benchmark,
|
||||
* so keep the upstream blanket fallback until the cross-width bug is fully fixed. */
|
||||
bool store_tci = !wasm_store_tci_disabled;
|
||||
/* ponytail: Mixed Store TBs Stay TCI - Pure store TBs are safe, but a store+load/helper TB in uzlib corrupts the vCPU TLB arrays when compiled. */
|
||||
bool store_tci = !wasm_store_tci_disabled && (wasm_tb_had_load || wasm_tb_had_helper);
|
||||
if (s->gen_tb && (wasm_store_tci_hash || wasm_store_bisect_on)) {
|
||||
uint64_t pc = s->gen_tb->pc;
|
||||
uint32_t h = (uint32_t)((pc * 0x9e3779b97f4a7c15ull) >> 33);
|
||||
@@ -3427,6 +3425,9 @@ static void tcg_out_qemu_st(TCGContext *s, TCGOpcode opc, const TCGArg *args, bo
|
||||
store_tci = ((h & 1) == (uint32_t)(wasm_store_tci_hash - 1));
|
||||
}
|
||||
}
|
||||
if (wasm_store_helper_tci && (wasm_tb_had_helper || wasm_tb_had_load)) {
|
||||
store_tci = true;
|
||||
}
|
||||
if (wasm_diff_mode != 2 && store_tci) {
|
||||
wasm_tci_only_tb = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user