mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-13 05:01:13 +00:00
Refine LLVM JIT function call process (#2925)
- Don't allocate the implicit/unused frame when calling the LLVM JIT function - Don't set exec_env's thread handle and stack boundary in the recursive calling from host, since they have been set in the first time calling - Fix frame not freed in llvm_jit_call_func_bytecode
This commit is contained in:
parent
d818672f62
commit
3637f2df79
|
@ -4109,7 +4109,7 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
||||||
uint32 result_count = func_type->result_count;
|
uint32 result_count = func_type->result_count;
|
||||||
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
||||||
uint32 func_idx = (uint32)(function - module_inst->e->functions);
|
uint32 func_idx = (uint32)(function - module_inst->e->functions);
|
||||||
bool ret;
|
bool ret = false;
|
||||||
|
|
||||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||||
if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
|
if (!llvm_jit_alloc_frame(exec_env, function - module_inst->e->functions)) {
|
||||||
|
@ -4137,7 +4137,8 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
||||||
if (size > UINT32_MAX
|
if (size > UINT32_MAX
|
||||||
|| !(argv1 = wasm_runtime_malloc((uint32)size))) {
|
|| !(argv1 = wasm_runtime_malloc((uint32)size))) {
|
||||||
wasm_set_exception(module_inst, "allocate memory failed");
|
wasm_set_exception(module_inst, "allocate memory failed");
|
||||||
return false;
|
ret = false;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4161,7 +4162,7 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (argv1 != argv1_buf)
|
if (argv1 != argv1_buf)
|
||||||
wasm_runtime_free(argv1);
|
wasm_runtime_free(argv1);
|
||||||
return ret;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get extra result values */
|
/* Get extra result values */
|
||||||
|
@ -4195,15 +4196,24 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
||||||
|
|
||||||
if (argv1 != argv1_buf)
|
if (argv1 != argv1_buf)
|
||||||
wasm_runtime_free(argv1);
|
wasm_runtime_free(argv1);
|
||||||
return true;
|
ret = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = wasm_runtime_invoke_native(
|
ret = wasm_runtime_invoke_native(
|
||||||
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
|
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
|
||||||
argv, argc, argv);
|
argv, argc, argv);
|
||||||
|
|
||||||
return ret && !wasm_copy_exception(module_inst, NULL) ? true : false;
|
if (ret)
|
||||||
|
ret = !wasm_copy_exception(module_inst, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
|
||||||
|
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||||
|
llvm_jit_free_frame(exec_env);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_JIT != 0 */
|
#endif /* end of WASM_ENABLE_JIT != 0 */
|
||||||
|
|
||||||
|
@ -4212,16 +4222,11 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
WASMFunctionInstance *function, uint32 argc,
|
WASMFunctionInstance *function, uint32 argc,
|
||||||
uint32 argv[])
|
uint32 argv[])
|
||||||
{
|
{
|
||||||
WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
|
WASMRuntimeFrame *frame = NULL, *prev_frame, *outs_area;
|
||||||
WASMInterpFrame *frame, *outs_area;
|
RunningMode running_mode =
|
||||||
|
wasm_runtime_get_running_mode((WASMModuleInstanceCommon *)module_inst);
|
||||||
/* Allocate sufficient cells for all kinds of return values. */
|
/* Allocate sufficient cells for all kinds of return values. */
|
||||||
unsigned all_cell_num =
|
bool alloc_frame = true;
|
||||||
function->ret_cell_num > 2 ? function->ret_cell_num : 2;
|
|
||||||
/* This frame won't be used by JITed code, so only allocate interp
|
|
||||||
frame here. */
|
|
||||||
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
|
|
||||||
unsigned i;
|
|
||||||
bool copy_argv_from_frame = true;
|
|
||||||
|
|
||||||
if (argc < function->param_cell_num) {
|
if (argc < function->param_cell_num) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
@ -4244,6 +4249,36 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!function->is_import_func) {
|
||||||
|
/* No need to alloc frame when calling LLVM JIT function */
|
||||||
|
#if WASM_ENABLE_JIT != 0
|
||||||
|
if (running_mode == Mode_LLVM_JIT) {
|
||||||
|
alloc_frame = false;
|
||||||
|
}
|
||||||
|
#if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_FAST_JIT != 0
|
||||||
|
else if (running_mode == Mode_Multi_Tier_JIT) {
|
||||||
|
/* Tier-up from Fast JIT to LLVM JIT, call llvm jit function
|
||||||
|
if it is compiled, else call fast jit function */
|
||||||
|
uint32 func_idx = (uint32)(function - module_inst->e->functions);
|
||||||
|
if (module_inst->module->func_ptrs_compiled
|
||||||
|
[func_idx - module_inst->module->import_function_count]) {
|
||||||
|
alloc_frame = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alloc_frame) {
|
||||||
|
unsigned all_cell_num =
|
||||||
|
function->ret_cell_num > 2 ? function->ret_cell_num : 2;
|
||||||
|
unsigned frame_size;
|
||||||
|
|
||||||
|
prev_frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||||
|
/* This frame won't be used by JITed code, so only allocate interp
|
||||||
|
frame here. */
|
||||||
|
frame_size = wasm_interp_interp_frame_size(all_cell_num);
|
||||||
|
|
||||||
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame)))
|
if (!(frame = ALLOC_FRAME(exec_env, frame_size, prev_frame)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -4263,6 +4298,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
word_copy(outs_area->lp, argv, argc);
|
word_copy(outs_area->lp, argv, argc);
|
||||||
|
|
||||||
wasm_exec_env_set_cur_frame(exec_env, frame);
|
wasm_exec_env_set_cur_frame(exec_env, frame);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(os_writegsbase)
|
#if defined(os_writegsbase)
|
||||||
{
|
{
|
||||||
|
@ -4288,9 +4324,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RunningMode running_mode =
|
|
||||||
wasm_runtime_get_running_mode((wasm_module_inst_t)module_inst);
|
|
||||||
|
|
||||||
if (running_mode == Mode_Interp) {
|
if (running_mode == Mode_Interp) {
|
||||||
wasm_interp_call_func_bytecode(module_inst, exec_env, function,
|
wasm_interp_call_func_bytecode(module_inst, exec_env, function,
|
||||||
frame);
|
frame);
|
||||||
|
@ -4304,9 +4337,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
else if (running_mode == Mode_LLVM_JIT) {
|
else if (running_mode == Mode_LLVM_JIT) {
|
||||||
llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
|
llvm_jit_call_func_bytecode(module_inst, exec_env, function, argc,
|
||||||
argv);
|
argv);
|
||||||
/* For llvm jit, the results have been stored in argv,
|
|
||||||
no need to copy them from stack frame again */
|
|
||||||
copy_argv_from_frame = false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_FAST_JIT != 0 \
|
#if WASM_ENABLE_LAZY_JIT != 0 && WASM_ENABLE_FAST_JIT != 0 \
|
||||||
|
@ -4319,9 +4349,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
[func_idx - module_inst->module->import_function_count]) {
|
[func_idx - module_inst->module->import_function_count]) {
|
||||||
llvm_jit_call_func_bytecode(module_inst, exec_env, function,
|
llvm_jit_call_func_bytecode(module_inst, exec_env, function,
|
||||||
argc, argv);
|
argc, argv);
|
||||||
/* For llvm jit, the results have been stored in argv,
|
|
||||||
no need to copy them from stack frame again */
|
|
||||||
copy_argv_from_frame = false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fast_jit_call_func_bytecode(module_inst, exec_env, function,
|
fast_jit_call_func_bytecode(module_inst, exec_env, function,
|
||||||
|
@ -4342,7 +4369,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
|
|
||||||
/* Output the return value to the caller */
|
/* Output the return value to the caller */
|
||||||
if (!wasm_copy_exception(module_inst, NULL)) {
|
if (!wasm_copy_exception(module_inst, NULL)) {
|
||||||
if (copy_argv_from_frame) {
|
if (alloc_frame) {
|
||||||
|
uint32 i;
|
||||||
for (i = 0; i < function->ret_cell_num; i++) {
|
for (i = 0; i < function->ret_cell_num; i++) {
|
||||||
argv[i] = *(frame->sp + i - function->ret_cell_num);
|
argv[i] = *(frame->sp + i - function->ret_cell_num);
|
||||||
}
|
}
|
||||||
|
@ -4356,6 +4384,8 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alloc_frame) {
|
||||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||||
FREE_FRAME(exec_env, frame);
|
FREE_FRAME(exec_env, frame);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2271,7 +2271,6 @@ wasm_lookup_table(const WASMModuleInstance *module_inst, const char *name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
#ifdef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
|
||||||
static void
|
static void
|
||||||
call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
|
call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
|
||||||
WASMExecEnv *exec_env,
|
WASMExecEnv *exec_env,
|
||||||
|
@ -2301,19 +2300,26 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exec_env_tls && (exec_env_tls != exec_env)) {
|
if (!exec_env_tls) {
|
||||||
wasm_set_exception(module_inst, "invalid exec env");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!os_thread_signal_inited()) {
|
if (!os_thread_signal_inited()) {
|
||||||
wasm_set_exception(module_inst, "thread signal env not inited");
|
wasm_set_exception(module_inst, "thread signal env not inited");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
|
/* Set thread handle and stack boundary if they haven't been set */
|
||||||
|
wasm_exec_env_set_thread_info(exec_env);
|
||||||
|
|
||||||
wasm_runtime_set_exec_env_tls(exec_env);
|
wasm_runtime_set_exec_env_tls(exec_env);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (exec_env_tls != exec_env) {
|
||||||
|
wasm_set_exception(module_inst, "invalid exec env");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
|
||||||
|
|
||||||
if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
|
if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
|
||||||
#ifndef BH_PLATFORM_WINDOWS
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
|
wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
|
||||||
|
@ -2323,7 +2329,7 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
|
||||||
} __except (wasm_copy_exception(module_inst, NULL)
|
} __except (wasm_copy_exception(module_inst, NULL)
|
||||||
? EXCEPTION_EXECUTE_HANDLER
|
? EXCEPTION_EXECUTE_HANDLER
|
||||||
: EXCEPTION_CONTINUE_SEARCH) {
|
: EXCEPTION_CONTINUE_SEARCH) {
|
||||||
/* exception was thrown in wasm_exception_handler */
|
/* Exception was thrown in wasm_exception_handler */
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
has_exception = wasm_copy_exception(module_inst, exception);
|
has_exception = wasm_copy_exception(module_inst, exception);
|
||||||
|
@ -2377,10 +2383,15 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
|
||||||
WASMModuleInstance *module_inst =
|
WASMModuleInstance *module_inst =
|
||||||
(WASMModuleInstance *)exec_env->module_inst;
|
(WASMModuleInstance *)exec_env->module_inst;
|
||||||
|
|
||||||
/* set thread handle and stack boundary */
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
|
/* Set thread handle and stack boundary */
|
||||||
wasm_exec_env_set_thread_info(exec_env);
|
wasm_exec_env_set_thread_info(exec_env);
|
||||||
|
#else
|
||||||
|
/* Set thread info in call_wasm_with_hw_bound_check when
|
||||||
|
hw bound check is enabled */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set exec env so it can be later retrieved from instance */
|
/* Set exec env so it can be later retrieved from instance */
|
||||||
module_inst->e->common.cur_exec_env = exec_env;
|
module_inst->e->common.cur_exec_env = exec_env;
|
||||||
|
|
||||||
interp_call_wasm(module_inst, exec_env, function, argc, argv);
|
interp_call_wasm(module_inst, exec_env, function, argc, argv);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user