mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 12:46:14 +00:00
Add the fast-interp tail call support (#409)
And also fix one bug in loader for tail-call Signed-off-by: Xiaokang Qin <xiaokang.qxk@antgroup.com>
This commit is contained in:
parent
dc536538ad
commit
c83a5713f9
|
@ -35,6 +35,7 @@ iwasm VM core
|
|||
- [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory)
|
||||
- [Multi-value](https://github.com/WebAssembly/multi-value)
|
||||
- [wasm-c-api](https://github.com/WebAssembly/wasm-c-api)
|
||||
- [Tail-call](https://github.com/WebAssembly/tail-call)
|
||||
|
||||
### Performance and memory usage
|
||||
The WAMR performance, footprint and memory usage data are available at the [performance](../../wiki/Performance) wiki page.
|
||||
|
|
|
@ -1301,10 +1301,16 @@ recover_br_info:
|
|||
goto return_func;
|
||||
|
||||
HANDLE_OP (WASM_OP_CALL_INDIRECT):
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
|
||||
#endif
|
||||
{
|
||||
WASMType *cur_type, *cur_func_type;
|
||||
WASMTableInstance *cur_table_inst;
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
GET_OPCODE();
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
|
@ -1360,6 +1366,10 @@ recover_br_info:
|
|||
wasm_set_exception(module, "indirect call type mismatch");
|
||||
goto got_exception;
|
||||
}
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
|
||||
goto call_func_from_return_call;
|
||||
#endif
|
||||
goto call_func_from_interp;
|
||||
}
|
||||
|
||||
|
@ -3112,6 +3122,22 @@ recover_br_info:
|
|||
cur_func = module->functions + fidx;
|
||||
goto call_func_from_interp;
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL):
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
CHECK_SUSPEND_FLAGS();
|
||||
#endif
|
||||
fidx = read_uint32(frame_ip);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
if (fidx >= module->function_count) {
|
||||
wasm_set_exception(module, "unknown function");
|
||||
goto got_exception;
|
||||
}
|
||||
#endif
|
||||
cur_func = module->functions + fidx;
|
||||
goto call_func_from_return_call;
|
||||
#endif /* WASM_ENABLE_TAIL_CALL */
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES == 0
|
||||
default:
|
||||
wasm_set_exception(module, "unsupported opcode");
|
||||
|
@ -3125,8 +3151,10 @@ recover_br_info:
|
|||
HANDLE_OP (WASM_OP_UNUSED_0x08):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x09):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x0a):
|
||||
#if WASM_ENABLE_TAIL_CALL == 0
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL):
|
||||
HANDLE_OP (WASM_OP_RETURN_CALL_INDIRECT):
|
||||
#endif
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x14):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x15):
|
||||
HANDLE_OP (WASM_OP_UNUSED_0x16):
|
||||
|
@ -3169,6 +3197,40 @@ recover_br_info:
|
|||
FETCH_OPCODE_AND_DISPATCH ();
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_TAIL_CALL !=0
|
||||
call_func_from_return_call:
|
||||
{
|
||||
uint32 *lp_base;
|
||||
uint32 *lp;
|
||||
int i;
|
||||
|
||||
if (!(lp_base = lp = wasm_runtime_malloc(cur_func->param_cell_num * sizeof(uint32)))) {
|
||||
wasm_set_exception(module, "allocate memory failed");
|
||||
goto got_exception;
|
||||
}
|
||||
for (i = 0; i < cur_func->param_count; i++) {
|
||||
if (cur_func->param_types[i] == VALUE_TYPE_I64
|
||||
|| cur_func->param_types[i] == VALUE_TYPE_F64) {
|
||||
*(int64*)(lp) =
|
||||
GET_OPERAND(int64, (2 * (cur_func->param_count - i - 1)));
|
||||
lp += 2;
|
||||
}
|
||||
else {
|
||||
*(lp) = GET_OPERAND(int32, (2 * (cur_func->param_count - i - 1)));
|
||||
lp ++;
|
||||
}
|
||||
}
|
||||
frame->lp = frame->operand + cur_func->const_cell_num;
|
||||
bh_memcpy_s(frame->lp, (lp - lp_base) * sizeof(uint32),
|
||||
lp_base, (lp - lp_base) * sizeof(uint32));
|
||||
wasm_runtime_free(lp_base);
|
||||
FREE_FRAME(exec_env, frame);
|
||||
frame_ip += cur_func->param_count * sizeof(int16);
|
||||
wasm_exec_env_set_cur_frame(exec_env,
|
||||
(WASMRuntimeFrame *)prev_frame);
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
#endif /* WASM_ENABLE_TAIL_CALL */
|
||||
call_func_from_interp:
|
||||
/* Only do the copy when it's called from interpreter. */
|
||||
{
|
||||
|
|
|
@ -5970,6 +5970,9 @@ handle_op_block_and_loop:
|
|||
|
||||
read_leb_uint32(p, p_end, type_idx);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
#if WASM_ENABLE_TAIL_CALL != 0
|
||||
emit_byte(loader_ctx, opcode);
|
||||
#endif
|
||||
/* we need to emit func_idx before arguments */
|
||||
emit_uint32(loader_ctx, type_idx);
|
||||
#endif
|
||||
|
@ -6023,12 +6026,13 @@ handle_op_block_and_loop:
|
|||
}
|
||||
for (i = 0; i < func_type->result_count; i++) {
|
||||
type = func->func_type->types[func->func_type->param_count + i];
|
||||
if (func_type->types[func_type->param_count + i] != type)
|
||||
set_error_buf_v(error_buf, error_buf_size, "%s%s%s",
|
||||
"type mismatch: expect ",
|
||||
if (func_type->types[func_type->param_count + i] != type) {
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"%s%s%s", "type mismatch: expect ",
|
||||
type_str[type - VALUE_TYPE_F64],
|
||||
" but got other");
|
||||
goto fail;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
RESET_STACK();
|
||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||
|
|
|
@ -83,6 +83,9 @@ Currently we only profile the memory consumption of module, module_instance and
|
|||
- **WAMR_APP_THREAD_STACK_SIZE_MAX**=n, default to 8 MB (8388608) if not set
|
||||
> Note: the AOT boundary check with hardware trap mechanism might consume large stack since the OS may lazily grow the stack mapping as a guard page is hit, we may use this configuration to reduce the total stack usage, e.g. -DWAMR_APP_THREAD_STACK_SIZE_MAX=131072 (128 KB).
|
||||
|
||||
#### **Enable tail call feature**
|
||||
- **WAMR_BUILD_TAIL_CALL**=1/0, default to disable if not set
|
||||
|
||||
**Combination of configurations:**
|
||||
|
||||
We can combine the configurations. For example, if we want to disable interpreter, enable AOT and WASI, we can run command:
|
||||
|
|
Loading…
Reference in New Issue
Block a user