mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Register quick call entries to speedup the aot/jit func call process (#2978)
In some scenarios there may be lots of callings to AOT/JIT functions from the host embedder, which expects good performance for the calling process, while in the current implementation, runtime calls the wasm_runtime_invoke_native to prepare the array of registers and stacks for the invokeNative assemble code, and the latter then puts the elements in the array to physical registers and native stacks and calls the AOT/JIT function, there may be many data copying and handlings which impact the performance. This PR registers some quick AOT/JIT entries for some simple wasm signatures, and let runtime call the entry to directly invoke the AOT/JIT function instead of calling wasm_runtime_invoke_native, which speedups the calling process. We may extend the mechanism next to allow the developer to register his quick AOT/JIT entries to speedup the calling process of invoking the AOT/JIT functions for some specific signatures.
This commit is contained in:
parent
6fa6d6d9a5
commit
7c7684819d
|
@ -449,7 +449,18 @@ if (WAMR_CONFIGUABLE_BOUNDS_CHECKS EQUAL 1)
|
|||
endif ()
|
||||
if (WAMR_BUILD_LINUX_PERF EQUAL 1)
|
||||
add_definitions (-DWASM_ENABLE_LINUX_PERF=1)
|
||||
message (" Enable linux perf support")
|
||||
message (" Linux perf support enabled")
|
||||
endif ()
|
||||
if (NOT DEFINED WAMR_BUILD_QUICK_AOT_ENTRY)
|
||||
# Enable quick aot/jit entries by default
|
||||
set (WAMR_BUILD_QUICK_AOT_ENTRY 1)
|
||||
endif ()
|
||||
if (WAMR_BUILD_QUICK_AOT_ENTRY EQUAL 1)
|
||||
add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=1)
|
||||
message (" Quick AOT/JIT entries enabled")
|
||||
else ()
|
||||
add_definitions (-DWASM_ENABLE_QUICK_AOT_ENTRY=0)
|
||||
message (" Quick AOT/JIT entries disabled")
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
|
|
|
@ -495,4 +495,11 @@
|
|||
#define WASM_ENABLE_LINUX_PERF 0
|
||||
#endif
|
||||
|
||||
/* Support registering quick AOT/JIT function entries of some func types
|
||||
to speedup the calling process of invoking the AOT/JIT functions of
|
||||
these types from the host embedder */
|
||||
#ifndef WASM_ENABLE_QUICK_AOT_ENTRY
|
||||
#define WASM_ENABLE_QUICK_AOT_ENTRY 1
|
||||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
|
|
@ -1202,6 +1202,11 @@ load_func_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
|||
|
||||
func_types[i]->param_cell_num = (uint16)param_cell_num;
|
||||
func_types[i]->ret_cell_num = (uint16)ret_cell_num;
|
||||
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
func_types[i]->quick_aot_entry =
|
||||
wasm_native_lookup_quick_aot_entry(func_types[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
*p_buf = buf;
|
||||
|
|
|
@ -1385,9 +1385,6 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
|
||||
uint32 page_size = os_getpagesize();
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
uint16 param_count = func_type->param_count;
|
||||
uint16 result_count = func_type->result_count;
|
||||
const uint8 *types = func_type->types;
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
int result;
|
||||
bool has_exception;
|
||||
|
@ -1426,28 +1423,22 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
|
||||
|
||||
if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
|
||||
/* Quick call with func_ptr if the function signature is simple */
|
||||
if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
|
||||
if (result_count == 0) {
|
||||
void (*NativeFunc)(WASMExecEnv *, uint32) =
|
||||
(void (*)(WASMExecEnv *, uint32))func_ptr;
|
||||
NativeFunc(exec_env, argv[0]);
|
||||
ret = aot_copy_exception(module_inst, NULL) ? false : true;
|
||||
}
|
||||
else if (result_count == 1
|
||||
&& types[param_count] == VALUE_TYPE_I32) {
|
||||
uint32 (*NativeFunc)(WASMExecEnv *, uint32) =
|
||||
(uint32(*)(WASMExecEnv *, uint32))func_ptr;
|
||||
argv_ret[0] = NativeFunc(exec_env, argv[0]);
|
||||
ret = aot_copy_exception(module_inst, NULL) ? false : true;
|
||||
}
|
||||
else {
|
||||
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||
signature, attachment, argv,
|
||||
argc, argv_ret);
|
||||
}
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
/* Quick call if the quick aot entry is registered */
|
||||
if (!signature && func_type->quick_aot_entry) {
|
||||
void (*invoke_native)(
|
||||
void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
|
||||
uint32 *argv_ret) = func_type->quick_aot_entry;
|
||||
invoke_native(func_ptr,
|
||||
func_type->result_count > 0
|
||||
? func_type->types[func_type->param_count]
|
||||
: VALUE_TYPE_VOID,
|
||||
exec_env, argv, argv_ret);
|
||||
ret = !aot_copy_exception(module_inst, NULL);
|
||||
}
|
||||
else {
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||
signature, attachment, argv, argc,
|
||||
argv_ret);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -104,6 +104,11 @@ wasm_native_init();
|
|||
void
|
||||
wasm_native_destroy();
|
||||
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
void *
|
||||
wasm_native_lookup_quick_aot_entry(const WASMType *func_type);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -129,6 +129,10 @@ typedef struct WASMType {
|
|||
/* Code block to call llvm jit functions of this
|
||||
kind of function type from fast jit jitted code */
|
||||
void *call_to_llvm_jit_from_fast_jit;
|
||||
#endif
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
/* Quick AOT/JIT entry of this func type */
|
||||
void *quick_aot_entry;
|
||||
#endif
|
||||
/* types of params and results */
|
||||
uint8 types[1];
|
||||
|
|
|
@ -4199,12 +4199,29 @@ llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
|||
ret = true;
|
||||
}
|
||||
else {
|
||||
ret = wasm_runtime_invoke_native(
|
||||
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL, NULL,
|
||||
argv, argc, argv);
|
||||
|
||||
if (ret)
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
/* Quick call if the quick jit entry is registered */
|
||||
if (func_type->quick_aot_entry) {
|
||||
void (*invoke_native)(
|
||||
void *func_ptr, uint8 ret_type, void *exec_env, uint32 *argv,
|
||||
uint32 *argv_ret) = func_type->quick_aot_entry;
|
||||
invoke_native(module_inst->func_ptrs[func_idx],
|
||||
func_type->result_count > 0
|
||||
? func_type->types[func_type->param_count]
|
||||
: VALUE_TYPE_VOID,
|
||||
exec_env, argv, argv);
|
||||
ret = !wasm_copy_exception(module_inst, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret = wasm_runtime_invoke_native(
|
||||
exec_env, module_inst->func_ptrs[func_idx], func_type, NULL,
|
||||
NULL, argv, argc, argv);
|
||||
|
||||
if (ret)
|
||||
ret = !wasm_copy_exception(module_inst, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
|
|
|
@ -641,6 +641,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
type->param_cell_num = (uint16)param_cell_num;
|
||||
type->ret_cell_num = (uint16)ret_cell_num;
|
||||
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
type->quick_aot_entry = wasm_native_lookup_quick_aot_entry(type);
|
||||
#endif
|
||||
|
||||
/* If there is already a same type created, use it instead */
|
||||
for (j = 0; j < i; j++) {
|
||||
if (wasm_type_equal(type, module->types[j])) {
|
||||
|
|
|
@ -418,6 +418,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
|||
type->param_cell_num = (uint16)param_cell_num;
|
||||
type->ret_cell_num = (uint16)ret_cell_num;
|
||||
|
||||
#if WASM_ENABLE_QUICK_AOT_ENTRY != 0
|
||||
type->quick_aot_entry = wasm_native_lookup_quick_aot_entry(type);
|
||||
#endif
|
||||
|
||||
/* If there is already a same type created, use it instead */
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (wasm_type_equal(type, module->types[j])) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user