Skip to content

Commit

Permalink
Refine AOT/JIT code call wasm-c-api import process (bytecodealliance#…
Browse files Browse the repository at this point in the history
…2982)

Allow to invoke the quick call entry wasm_runtime_quick_invoke_c_api_import to
call the wasm-c-api import functions to speedup the calling process, which reduces
the data copying.

Use `wamrc --invoke-c-api-import` to generate the optimized AOT code, and set
`jit_options->quick_invoke_c_api_import` true in wasm_engine_new when LLVM JIT
is enabled.
  • Loading branch information
wenyongh authored Jan 10, 2024
1 parent 7c76848 commit b21f17d
Show file tree
Hide file tree
Showing 20 changed files with 393 additions and 35 deletions.
1 change: 1 addition & 0 deletions core/iwasm/aot/aot_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ typedef struct {
REG_SYM(aot_enlarge_memory), \
REG_SYM(aot_set_exception), \
REG_SYM(aot_check_app_addr_and_convert),\
REG_SYM(wasm_runtime_quick_invoke_c_api_native),\
{ "memset", (void*)aot_memset }, \
{ "memmove", (void*)aot_memmove }, \
{ "memcpy", (void*)aot_memmove }, \
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ bh_static_assert(sizeof(AOTMemoryInstance) == 104);
bh_static_assert(offsetof(AOTTableInstance, elems) == 8);

bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);
bh_static_assert(offsetof(AOTModuleInstanceExtra, common.c_api_func_imports)
== sizeof(uint64));

bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3);

bh_static_assert(sizeof(wasm_val_t) == 16);
bh_static_assert(offsetof(wasm_val_t, of) == 8);

static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ wasm_engine_new_internal(wasm_config_t *config)
wasm_engine_t *engine = NULL;
/* init runtime */
RuntimeInitArgs init_args = { 0 };
#if WASM_ENABLE_JIT != 0
LLVMJITOptions *jit_options = wasm_runtime_get_llvm_jit_options();
#endif

#ifndef NDEBUG
bh_log_set_verbose_level(BH_LOG_LEVEL_VERBOSE);
Expand All @@ -394,6 +397,10 @@ wasm_engine_new_internal(wasm_config_t *config)
init_args.enable_linux_perf = config->enable_linux_perf;
init_args.segue_flags = config->segue_flags;

#if WASM_ENABLE_JIT != 0
jit_options->quick_invoke_c_api_import = true;
#endif

if (!wasm_runtime_full_init(&init_args)) {
LOG_DEBUG("wasm_runtime_full_init failed");
goto failed;
Expand Down
78 changes: 71 additions & 7 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ static JitCompOptions jit_options = { 0 };
#endif

#if WASM_ENABLE_JIT != 0
static LLVMJITOptions llvm_jit_options = { 3, 3, 0 };
/* opt_level: 3, size_level: 3, segue-flags: 0,
quick_invoke_c_api_import: false */
static LLVMJITOptions llvm_jit_options = { 3, 3, 0, false };
#endif

static RunningMode runtime_running_mode = Mode_Default;
Expand Down Expand Up @@ -638,10 +640,10 @@ wasm_runtime_get_default_running_mode(void)
}

#if WASM_ENABLE_JIT != 0
LLVMJITOptions
LLVMJITOptions *
wasm_runtime_get_llvm_jit_options(void)
{
return llvm_jit_options;
return &llvm_jit_options;
}
#endif

Expand Down Expand Up @@ -5675,7 +5677,7 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
wasm_val_t *params = params_buf, *results = results_buf;
wasm_trap_t *trap = NULL;
bool ret = false;
wasm_val_vec_t params_vec, results_vec;
wasm_val_vec_t params_vec = { 0 }, results_vec = { 0 };

if (func_type->param_count > 16) {
if (!(params =
Expand Down Expand Up @@ -5703,12 +5705,10 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
params_vec.data = params;
params_vec.num_elems = func_type->param_count;
params_vec.size = func_type->param_count;
params_vec.size_of_elem = sizeof(wasm_val_t);

results_vec.data = results;
results_vec.num_elems = 0;
results_vec.size = func_type->result_count;
results_vec.size_of_elem = sizeof(wasm_val_t);

if (!with_env) {
wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
Expand Down Expand Up @@ -5744,7 +5744,6 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
wasm_runtime_set_exception(module_inst, "unsupported result type");
goto fail;
}
results_vec.num_elems = func_type->result_count;
ret = true;

fail:
Expand All @@ -5755,6 +5754,71 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
return ret;
}

bool
wasm_runtime_quick_invoke_c_api_native(WASMModuleInstanceCommon *inst_comm,
CApiFuncImport *c_api_import,
wasm_val_t *params, uint32 param_count,
wasm_val_t *results, uint32 result_count)
{
WASMModuleInstance *module_inst = (WASMModuleInstance *)inst_comm;
void *func_ptr = c_api_import->func_ptr_linked;
bool with_env_arg = c_api_import->with_env_arg, ret = true;
wasm_val_vec_t params_vec = { 0 }, results_vec = { 0 };
wasm_trap_t *trap = NULL;

params_vec.data = params;
params_vec.num_elems = param_count;
params_vec.size = param_count;

results_vec.data = results;
results_vec.num_elems = 0;
results_vec.size = result_count;

if (!func_ptr) {
wasm_set_exception_with_id(module_inst, EXCE_CALL_UNLINKED_IMPORT_FUNC);
ret = false;
goto fail;
}

if (!with_env_arg) {
wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
trap = callback(&params_vec, &results_vec);
}
else {
void *wasm_c_api_env = c_api_import->env_arg;
wasm_func_callback_with_env_t callback =
(wasm_func_callback_with_env_t)func_ptr;
trap = callback(wasm_c_api_env, &params_vec, &results_vec);
}

if (trap) {
if (trap->message->data) {
/* since trap->message->data does not end with '\0' */
char trap_message[108] = { 0 };
uint32 max_size_to_copy = (uint32)sizeof(trap_message) - 1;
uint32 size_to_copy = (trap->message->size < max_size_to_copy)
? (uint32)trap->message->size
: max_size_to_copy;
bh_memcpy_s(trap_message, (uint32)sizeof(trap_message),
trap->message->data, size_to_copy);
wasm_set_exception(module_inst, trap_message);
}
else {
wasm_set_exception(module_inst,
"native function throw unknown exception");
}
wasm_trap_delete(trap);
ret = false;
}

fail:
#ifdef OS_ENABLE_HW_BOUND_CHECK
if (!ret)
wasm_runtime_access_exce_check_guard_page();
#endif
return ret;
}

void
wasm_runtime_show_app_heap_corrupted_prompt()
{
Expand Down
13 changes: 12 additions & 1 deletion core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ typedef struct LLVMJITOptions {
uint32 opt_level;
uint32 size_level;
uint32 segue_flags;
bool quick_invoke_c_api_import;
} LLVMJITOptions;
#endif

Expand Down Expand Up @@ -476,7 +477,7 @@ wasm_runtime_get_default_running_mode(void);

#if WASM_ENABLE_JIT != 0
/* Internal API */
LLVMJITOptions
LLVMJITOptions *
wasm_runtime_get_llvm_jit_options(void);
#endif

Expand Down Expand Up @@ -1079,6 +1080,16 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
uint32 argc, uint32 *argv, bool with_env,
void *wasm_c_api_env);

struct CApiFuncImport;
/* A quick version of wasm_runtime_invoke_c_api_native to directly invoke
wasm-c-api import function from jitted code to improve performance */
bool
wasm_runtime_quick_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
struct CApiFuncImport *c_api_import,
wasm_val_t *params, uint32 param_count,
wasm_val_t *results,
uint32 result_count);

void
wasm_runtime_show_app_heap_corrupted_prompt();

Expand Down
Loading

0 comments on commit b21f17d

Please sign in to comment.