Optimize for multi-module support in AOT mode (#3563)

- Split the `aot_loader_resolve_function` into two functions to prevent
  redundant module lookups and loads
- Access pre-associated module instances from `import_func_module_insts`,
  avoiding unnecessary instance lookups and improving performance
This commit is contained in:
Xenia Lu 2024-06-26 09:56:01 +08:00 committed by GitHub
parent 867dbd8912
commit 6754b62195
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 78 additions and 31 deletions

View File

@ -591,15 +591,17 @@ str2uint64(const char *buf, uint64 *p_res);
#if WASM_ENABLE_MULTI_MODULE != 0
static void *
aot_loader_resolve_function(const char *module_name, const char *function_name,
aot_loader_resolve_function(const AOTModule *module, const char *function_name,
const AOTFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size);
static void *
aot_loader_resolve_function_ex(const char *module_name,
const char *function_name,
const AOTFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size)
{
WASMModuleCommon *module_reg;
void *function = NULL;
AOTExport *export = NULL;
AOTModule *module = NULL;
AOTFuncType *target_function_type = NULL;
module_reg = wasm_runtime_find_module_registered(module_name);
if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
@ -608,10 +610,23 @@ aot_loader_resolve_function(const char *module_name, const char *function_name,
set_error_buf(error_buf, error_buf_size, "unknown import");
return NULL;
}
return aot_loader_resolve_function((AOTModule *)module_reg, function_name,
expected_function_type, error_buf,
error_buf_size);
}
module = (AOTModule *)module_reg;
export = loader_find_export(module_reg, module_name, function_name,
EXPORT_KIND_FUNC, error_buf, error_buf_size);
static void *
aot_loader_resolve_function(const AOTModule *module, const char *function_name,
const AOTFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size)
{
void *function = NULL;
AOTExport *export = NULL;
AOTFuncType *target_function_type = NULL;
export = loader_find_export((WASMModuleCommon *)module, module->name,
function_name, EXPORT_KIND_FUNC, error_buf,
error_buf_size);
if (!export) {
return NULL;
}
@ -633,7 +648,7 @@ aot_loader_resolve_function(const char *module_name, const char *function_name,
if (!wasm_type_equal((WASMType *)expected_function_type,
(WASMType *)target_function_type, module->types,
module->type_count)) {
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
LOG_DEBUG("%s.%s failed the type check", module->name, function_name);
set_error_buf(error_buf, error_buf_size, "incompatible import type");
return NULL;
}
@ -2260,17 +2275,24 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
&import_funcs[i].signature, &import_funcs[i].attachment,
&import_funcs[i].call_conv_raw);
if (!linked_func) {
sub_module = NULL;
if (!wasm_runtime_is_built_in_module(module_name)) {
sub_module = (AOTModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)module, module_name, error_buf,
error_buf_size);
if (!sub_module) {
LOG_ERROR("failed to load sub module: %s", error_buf);
return false;
}
}
linked_func = aot_loader_resolve_function(
if (!sub_module)
linked_func = aot_loader_resolve_function_ex(
module_name, field_name, declare_func_type, error_buf,
error_buf_size);
else
linked_func = aot_loader_resolve_function(
sub_module, field_name, declare_func_type, error_buf,
error_buf_size);
}
import_funcs[i].func_ptr_linked = linked_func;
import_funcs[i].func_type = declare_func_type;

View File

@ -1640,6 +1640,16 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
#if WASM_ENABLE_MULTI_MODULE != 0
extra->sub_module_inst_list = &extra->sub_module_inst_list_head;
/* Allocate memory for import_func_module_insts*/
if (module->import_func_count > 0
&& !(extra->import_func_module_insts =
runtime_malloc((uint64)module->import_func_count
* sizeof(WASMModuleInstanceCommon *),
error_buf, error_buf_size))) {
goto fail;
}
ret = wasm_runtime_sub_module_instantiate(
(WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
@ -1980,6 +1990,8 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
#if WASM_ENABLE_MULTI_MODULE != 0
wasm_runtime_sub_module_deinstantiate(
(WASMModuleInstanceCommon *)module_inst);
if (extra->import_func_module_insts)
wasm_runtime_free(extra->import_func_module_insts);
#endif
if (module_inst->tables)
@ -2835,10 +2847,6 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
void *attachment;
char buf[96];
bool ret = false;
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list *sub_module_list_node = NULL;
const char *sub_inst_name = NULL;
#endif
bh_assert(func_idx < aot_module->import_func_count);
import_func = aot_module->import_funcs + func_idx;
@ -2863,20 +2871,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
else if (!import_func->call_conv_raw) {
signature = import_func->signature;
#if WASM_ENABLE_MULTI_MODULE != 0
sub_module_list_node =
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
sub_module_list_node = bh_list_first_elem(sub_module_list_node);
while (sub_module_list_node) {
sub_inst_name =
((AOTSubModInstNode *)sub_module_list_node)->module_name;
if (strcmp(sub_inst_name, import_func->module_name) == 0) {
exec_env = wasm_runtime_get_exec_env_singleton(
(WASMModuleInstanceCommon *)((AOTSubModInstNode *)
sub_module_list_node)
->module_inst);
break;
}
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
WASMModuleInstanceCommon *sub_inst = NULL;
if ((sub_inst = ((AOTModuleInstanceExtra *)module_inst->e)
->import_func_module_insts[func_idx])) {
exec_env = wasm_runtime_get_exec_env_singleton(sub_inst);
}
if (exec_env == NULL) {
wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,

View File

@ -109,6 +109,7 @@ typedef struct AOTModuleInstanceExtra {
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list sub_module_inst_list_head;
bh_list *sub_module_inst_list;
WASMModuleInstanceCommon **import_func_module_insts;
#endif
} AOTModuleInstanceExtra;

View File

@ -7325,6 +7325,32 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
(WASMModuleInstance *)sub_module_inst;
sub_module_inst_list_node->module_name =
sub_module_list_node->module_name;
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModuleInstance *aot_module_inst =
(AOTModuleInstance *)module_inst;
AOTModule *aot_module = (AOTModule *)module;
AOTModuleInstanceExtra *aot_extra =
(AOTModuleInstanceExtra *)aot_module_inst->e;
uint32 i;
AOTImportFunc *import_func;
for (i = 0; i < aot_module->import_func_count; i++) {
if (aot_extra->import_func_module_insts[i])
continue;
import_func = &aot_module->import_funcs[i];
if (strcmp(sub_module_inst_list_node->module_name,
import_func->module_name)
== 0) {
aot_extra->import_func_module_insts[i] =
(WASMModuleInstanceCommon *)
sub_module_inst_list_node->module_inst;
}
}
}
#endif
bh_list_status ret =
bh_list_insert(sub_module_inst_list, sub_module_inst_list_node);
bh_assert(BH_LIST_SUCCESS == ret);