Skip to content

Commit b0b8843

Browse files
authored
Implement opcode atomic.wait and atomic.notify for Fast JIT (#1914)
1 parent cadf9d0 commit b0b8843

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

core/iwasm/fast-jit/fe/jit_emit_memory.c

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
135135
#ifndef OS_ENABLE_HW_BOUND_CHECK
136136
/* ---------- check ---------- */
137137
/* 1. shortcut if the memory size is 0 */
138-
if (0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
138+
if (cc->cur_wasm_module->memories != NULL
139+
&& 0 == cc->cur_wasm_module->memories[mem_idx].init_page_count) {
139140
JitReg module_inst, cur_page_count;
140141
uint32 cur_page_count_offset =
141142
(uint32)offsetof(WASMModuleInstance, global_table_data.bytes)
@@ -176,6 +177,18 @@ check_and_seek(JitCompContext *cc, JitReg addr, uint32 offset, uint32 bytes)
176177
return 0;
177178
}
178179

180+
#define CHECK_ALIGNMENT(maddr, memory_data, offset1) \
181+
do { \
182+
GEN_INSN(ADD, maddr, memory_data, offset1); \
183+
JitReg align_mask = NEW_CONST(I64, ((uint64)1 << align) - 1); \
184+
JitReg AND_res = jit_cc_new_reg_I64(cc); \
185+
GEN_INSN(AND, AND_res, maddr, align_mask); \
186+
GEN_INSN(CMP, cc->cmp_reg, AND_res, NEW_CONST(I64, 0)); \
187+
if (!jit_emit_exception(cc, EXCE_UNALIGNED_ATOMIC, JIT_OP_BNE, \
188+
cc->cmp_reg, NULL)) \
189+
goto fail; \
190+
} while (0)
191+
179192
bool
180193
jit_compile_op_i32_load(JitCompContext *cc, uint32 align, uint32 offset,
181194
uint32 bytes, bool sign, bool atomic)
@@ -779,13 +792,91 @@ bool
779792
jit_compile_op_atomic_wait(JitCompContext *cc, uint8 op_type, uint32 align,
780793
uint32 offset, uint32 bytes)
781794
{
795+
bh_assert(op_type == VALUE_TYPE_I32 || op_type == VALUE_TYPE_I64);
796+
797+
// Pop atomic.wait arguments
798+
JitReg timeout, expect, expect_64, addr;
799+
POP_I64(timeout);
800+
if (op_type == VALUE_TYPE_I32) {
801+
POP_I32(expect);
802+
expect_64 = jit_cc_new_reg_I64(cc);
803+
GEN_INSN(I32TOI64, expect_64, expect);
804+
}
805+
else {
806+
POP_I64(expect_64);
807+
}
808+
POP_I32(addr);
809+
810+
// Get referenced address and store it in `maddr`
811+
JitReg memory_data = get_memory_data_reg(cc->jit_frame, 0);
812+
JitReg offset1 = check_and_seek(cc, addr, offset, bytes);
813+
if (!offset1)
814+
goto fail;
815+
JitReg maddr = jit_cc_new_reg_I64(cc);
816+
CHECK_ALIGNMENT(maddr, memory_data, offset1);
817+
818+
// Prepare `wasm_runtime_atomic_wait` arguments
819+
JitReg res = jit_cc_new_reg_I32(cc);
820+
JitReg args[5] = { 0 };
821+
args[0] = get_module_inst_reg(cc->jit_frame);
822+
args[1] = maddr;
823+
args[2] = expect_64;
824+
args[3] = timeout;
825+
args[4] = NEW_CONST(I32, false);
826+
827+
if (!jit_emit_callnative(cc, wasm_runtime_atomic_wait, res, args,
828+
sizeof(args) / sizeof(args[0])))
829+
goto fail;
830+
831+
// Handle return code
832+
GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, -1));
833+
if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BEQ, cc->cmp_reg,
834+
NULL))
835+
goto fail;
836+
837+
PUSH_I32(res);
838+
return true;
839+
fail:
782840
return false;
783841
}
784842

785843
bool
786844
jit_compiler_op_atomic_notify(JitCompContext *cc, uint32 align, uint32 offset,
787845
uint32 bytes)
788846
{
847+
// Pop atomic.notify arguments
848+
JitReg notify_count, addr;
849+
POP_I32(notify_count);
850+
POP_I32(addr);
851+
852+
// Get referenced address and store it in `maddr`
853+
JitReg memory_data = get_memory_data_reg(cc->jit_frame, 0);
854+
JitReg offset1 = check_and_seek(cc, addr, offset, bytes);
855+
if (!offset1)
856+
goto fail;
857+
JitReg maddr = jit_cc_new_reg_I64(cc);
858+
CHECK_ALIGNMENT(maddr, memory_data, offset1);
859+
860+
// Prepare `wasm_runtime_atomic_notify` arguments
861+
JitReg res = jit_cc_new_reg_I32(cc);
862+
JitReg args[3] = { 0 };
863+
args[0] = get_module_inst_reg(cc->jit_frame);
864+
args[1] = maddr;
865+
args[2] = notify_count;
866+
867+
if (!jit_emit_callnative(cc, wasm_runtime_atomic_notify, res, args,
868+
sizeof(args) / sizeof(args[0])))
869+
goto fail;
870+
871+
// Handle return code
872+
GEN_INSN(CMP, cc->cmp_reg, res, NEW_CONST(I32, 0));
873+
if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BLTS, cc->cmp_reg,
874+
NULL))
875+
goto fail;
876+
877+
PUSH_I32(res);
878+
return true;
879+
fail:
789880
return false;
790881
}
791882
#endif

core/iwasm/fast-jit/jit_compiler.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,16 @@ jit_compiler_compile(WASMModule *module, uint32 func_idx)
157157
/* Apply compiler passes */
158158
if (!apply_compiler_passes(cc) || jit_get_last_error(cc)) {
159159
last_error = jit_get_last_error(cc);
160+
161+
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
162+
char *function_name = cc->cur_wasm_func->field_name;
163+
os_printf("fast jit compilation failed: %s (function_name=%s)\n",
164+
last_error ? last_error : "unknown error", function_name);
165+
#else
160166
os_printf("fast jit compilation failed: %s\n",
161167
last_error ? last_error : "unknown error");
168+
#endif
169+
162170
goto fail;
163171
}
164172

0 commit comments

Comments
 (0)