Implement GC (Garbage Collection) feature for interpreter, AOT and LLVM-JIT (#3125)

Implement the GC (Garbage Collection) feature for interpreter mode,
AOT mode and LLVM-JIT mode, and support most features of the latest
spec proposal, and also enable the stringref feature.

Use `cmake -DWAMR_BUILD_GC=1/0` to enable/disable the feature,
and `wamrc --enable-gc` to generate the AOT file with GC supported.

And update the AOT file version from 2 to 3 since there are many AOT
ABI breaks, including the changes of AOT file format, the changes of
AOT module/memory instance layouts, the AOT runtime APIs for the
AOT code to invoke and so on.
This commit is contained in:
Wenyong Huang
2024-02-06 20:47:11 +08:00
committed by GitHub
parent 5931aaacbe
commit 16a4d71b34
98 changed files with 33469 additions and 3159 deletions

View File

@ -396,8 +396,9 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
#endif
#if WASM_ENABLE_PERF_PROFILING != 0
/* time_end = os_time_get_boot_us() */
if (!jit_emit_callnative(cc, os_time_get_boot_us, time_end, NULL, 0)) {
/* time_end = os_time_thread_cputime_us() */
if (!jit_emit_callnative(cc, os_time_thread_cputime_us, time_end, NULL,
0)) {
return false;
}
/* time_start = cur_frame->time_started */
@ -449,9 +450,9 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
}
/* Free stack space of the current frame:
exec_env->wasm_stack.s.top = cur_frame */
exec_env->wasm_stack.top = cur_frame */
GEN_INSN(STPTR, cc->fp_reg, cc->exec_env_reg,
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.top)));
/* Set the prev_frame as the current frame:
exec_env->cur_frame = prev_frame */
GEN_INSN(STPTR, prev_frame, cc->exec_env_reg,

View File

@ -499,7 +499,9 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
if (UINTPTR_MAX == UINT64_MAX) {
offset_i32 = jit_cc_new_reg_I32(cc);
offset = jit_cc_new_reg_I64(cc);
GEN_INSN(SHL, offset_i32, elem_idx, NEW_CONST(I32, 2));
/* Calculate offset by pointer size (elem_idx *
* sizeof(table_elem_type_t)) */
GEN_INSN(SHL, offset_i32, elem_idx, NEW_CONST(I32, 3));
GEN_INSN(I32TOI64, offset, offset_i32);
}
else {

View File

@ -46,7 +46,8 @@ jit_compile_op_table_get(JitCompContext *cc, uint32 tbl_idx)
GEN_INSN(I32TOI64, elem_idx_long, elem_idx);
offset = jit_cc_new_reg_I64(cc);
GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32)));
GEN_INSN(MUL, offset, elem_idx_long,
NEW_CONST(I64, sizeof(table_elem_type_t)));
res = jit_cc_new_reg_I32(cc);
tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx);
@ -77,7 +78,8 @@ jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx)
GEN_INSN(I32TOI64, elem_idx_long, elem_idx);
offset = jit_cc_new_reg_I64(cc);
GEN_INSN(MUL, offset, elem_idx_long, NEW_CONST(I64, sizeof(uint32)));
GEN_INSN(MUL, offset, elem_idx_long,
NEW_CONST(I64, sizeof(table_elem_type_t)));
tbl_elems = get_table_elems_reg(cc->jit_frame, tbl_idx);
GEN_INSN(STI32, elem_val, tbl_elems, offset);
@ -92,14 +94,15 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 seg_idx,
uint32 dst_offset, uint32 len, uint32 src_offset)
{
WASMTableInstance *tbl;
uint32 tbl_sz;
WASMTableSeg *tbl_seg = inst->module->table_segments + seg_idx;
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
InitializerExpression *tbl_seg_init_values = NULL, *init_values;
uint32 tbl_sz, tbl_seg_len = 0, i;
table_elem_type_t *addr;
if (!bh_bitmap_get_bit(inst->e->common.elem_dropped, seg_idx)) {
/* table segment isn't dropped */
tbl_seg_elems = tbl_seg->func_indexes;
tbl_seg_len = tbl_seg->function_count;
tbl_seg_init_values = tbl_seg->init_values;
tbl_seg_len = tbl_seg->value_count;
}
if (offset_len_out_of_bounds(src_offset, len, tbl_seg_len))
@ -113,10 +116,13 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 seg_idx,
if (!len)
return 0;
bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
+ dst_offset * sizeof(uint32),
(uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
tbl_seg_elems + src_offset, (uint32)(len * sizeof(uint32)));
addr =
(table_elem_type_t *)((uint8 *)tbl + offsetof(WASMTableInstance, elems)
+ dst_offset * sizeof(table_elem_type_t));
init_values = tbl_seg_init_values + src_offset;
for (i = 0; i < len; i++) {
addr[i] = (table_elem_type_t)(uintptr_t)init_values[+i].u.ref_index;
}
return 0;
out_of_bounds:
@ -175,12 +181,13 @@ wasm_copy_table(WASMModuleInstance *inst, uint32 src_tbl_idx,
if (offset_len_out_of_bounds(src_offset, len, src_tbl_sz))
goto out_of_bounds;
bh_memmove_s((uint8 *)dst_tbl + offsetof(WASMTableInstance, elems)
+ dst_offset * sizeof(uint32),
(uint32)((dst_tbl_sz - dst_offset) * sizeof(uint32)),
(uint8 *)src_tbl + offsetof(WASMTableInstance, elems)
+ src_offset * sizeof(uint32),
(uint32)(len * sizeof(uint32)));
bh_memmove_s(
(uint8 *)dst_tbl + offsetof(WASMTableInstance, elems)
+ dst_offset * sizeof(table_elem_type_t),
(uint32)((dst_tbl_sz - dst_offset) * sizeof(table_elem_type_t)),
(uint8 *)src_tbl + offsetof(WASMTableInstance, elems)
+ src_offset * sizeof(table_elem_type_t),
(uint32)(len * sizeof(table_elem_type_t)));
return 0;
out_of_bounds:
@ -272,7 +279,7 @@ fail:
static int
wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst_offset,
uint32 val, uint32 len)
uintptr_t val, uint32 len)
{
WASMTableInstance *tbl;
uint32 tbl_sz;