mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 00:45:28 +00:00
Implement opcode atomic.wait and atomic.notify for Fast JIT (#1914)
This commit is contained in:
parent
cadf9d0ad3
commit
b0b8843719
|
@ -135,7 +135,8 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
|
|||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||
/* ---------- check ---------- */
|
||||
/* 1. shortcut if the memory size is 0 */
|
||||
if (0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
|
||||
if (cc->cur_wasm_module->memories != NULL
|
||||
&& 0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
|
||||
JitReg module_inst, cur_page_count;
|
||||
uint32 cur_page_count_offset =
|
||||
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
|
||||
|
@ -176,6 +177,18 @@ fail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define CHECK_ALIGNMENT(maddr, memory_data, offset1) \
|
||||
do { \
|
||||
GEN_INSN(ADD, maddr, memory_data, offset1); \
|
||||
JitReg align_mask = NEW_CONST(I64, ((uint64)1 << align) - 1); \
|
||||
JitReg AND_res = jit_cc_new_reg_I64(cc); \
|
||||
GEN_INSN(AND, AND_res, maddr, align_mask); \
|
||||
GEN_INSN(CMP, cc->cmp_reg, AND_res, NEW_CONST(I64, 0)); \
|
||||
if (!jit_emit_exception(cc, EXCE_UNALIGNED_ATOMIC, JIT_OP_BNE, \
|
||||
cc->cmp_reg, NULL)) \
|
||||
goto fail; \
|
||||
} while (0)
|
||||
|
||||
bool
|
||||
jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset,
|
||||
uint32 bytes, bool sign, bool atomic)
|
||||
|
@ -779,6 +792,51 @@ bool
|
|||
jit_compile_op_atomic_wait(JitCompContext *cc, uint8 op_type, uint32 align,
|
||||
uint32 offset, uint32 bytes)
|
||||
{
|
||||
bh_assert(op_type == VALUE_TYPE_I32 || op_type == VALUE_TYPE_I64);
|
||||
|
||||
// Pop atomic.wait arguments
|
||||
JitReg timeout, expect, expect_64, addr;
|
||||
POP_I64(timeout);
|
||||
if (op_type == VALUE_TYPE_I32) {
|
||||
POP_I32(expect);
|
||||
expect_64 = jit_cc_new_reg_I64(cc);
|
||||
GEN_INSN(I32TOI64, expect_64, expect);
|
||||
}
|
||||
else {
|
||||
POP_I64(expect_64);
|
||||
}
|
||||
POP_I32(addr);
|
||||
|
||||
// Get referenced address and store it in `maddr`
|
||||
JitReg memory_data = get_memory_data_reg(cc->jit_frame, 0);
|
||||
JitReg offset1 = check_and_seek(cc, addr, offset, bytes);
|
||||
if (!offset1)
|
||||
goto fail;
|
||||
JitReg maddr = jit_cc_new_reg_I64(cc);
|
||||
CHECK_ALIGNMENT(maddr, memory_data, offset1);
|
||||
|
||||
// Prepare `wasm_runtime_atomic_wait` arguments
|
||||
JitReg res = jit_cc_new_reg_I32(cc);
|
||||
JitReg args[5] = { 0 };
|
||||
args[0] = get_module_inst_reg(cc->jit_frame);
|
||||
args[1] = maddr;
|
||||
args[2] = expect_64;
|
||||
args[3] = timeout;
|
||||
args[4] = NEW_CONST(I32, false);
|
||||
|
||||
if (!jit_emit_callnative(cc, wasm_runtime_atomic_wait, res, args,
|
||||
sizeof(args) / sizeof(args[0])))
|
||||
goto fail;
|
||||
|
||||
// Handle return code
|
||||
GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, -1));
|
||||
if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BEQ, cc->cmp_reg,
|
||||
NULL))
|
||||
goto fail;
|
||||
|
||||
PUSH_I32(res);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -786,6 +844,39 @@ bool
|
|||
jit_compiler_op_atomic_notify(JitCompContext *cc, uint32 align, uint32 offset,
|
||||
uint32 bytes)
|
||||
{
|
||||
// Pop atomic.notify arguments
|
||||
JitReg notify_count, addr;
|
||||
POP_I32(notify_count);
|
||||
POP_I32(addr);
|
||||
|
||||
// Get referenced address and store it in `maddr`
|
||||
JitReg memory_data = get_memory_data_reg(cc->jit_frame, 0);
|
||||
JitReg offset1 = check_and_seek(cc, addr, offset, bytes);
|
||||
if (!offset1)
|
||||
goto fail;
|
||||
JitReg maddr = jit_cc_new_reg_I64(cc);
|
||||
CHECK_ALIGNMENT(maddr, memory_data, offset1);
|
||||
|
||||
// Prepare `wasm_runtime_atomic_notify` arguments
|
||||
JitReg res = jit_cc_new_reg_I32(cc);
|
||||
JitReg args[3] = { 0 };
|
||||
args[0] = get_module_inst_reg(cc->jit_frame);
|
||||
args[1] = maddr;
|
||||
args[2] = notify_count;
|
||||
|
||||
if (!jit_emit_callnative(cc, wasm_runtime_atomic_notify, res, args,
|
||||
sizeof(args) / sizeof(args[0])))
|
||||
goto fail;
|
||||
|
||||
// Handle return code
|
||||
GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, 0));
|
||||
if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BLTS, cc->cmp_reg,
|
||||
NULL))
|
||||
goto fail;
|
||||
|
||||
PUSH_I32(res);
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -157,8 +157,16 @@ jit_compiler_compile(WASMModule *module, uint32 func_idx)
|
|||
/* Apply compiler passes */
|
||||
if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
|
||||
last_error = jit_get_last_error(cc);
|
||||
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
char *function_name = cc->cur_wasm_func->field_name;
|
||||
os_printf("fast jit compilation failed: %s (function_name=%s)\n",
|
||||
last_error ? last_error : "unknown error", function_name);
|
||||
#else
|
||||
os_printf("fast jit compilation failed: %s\n",
|
||||
last_error ? last_error : "unknown error");
|
||||
#endif
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user