From 48eaa2286abfd02565175bc77866362023c0c93c Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Fri, 18 Oct 2024 15:15:33 +0800 Subject: [PATCH] Refine wasm/aot function instance lookup (#3865) Sort the module instance's export functions with the function name, and use binary search to lookup the wasm/aot function. --- core/iwasm/aot/aot_runtime.c | 20 +++++++++--- core/iwasm/common/wasm_c_api.c | 3 +- core/iwasm/common/wasm_runtime_common.c | 41 ++++++++++--------------- core/iwasm/interpreter/wasm_runtime.c | 30 +++++++++++++++--- 4 files changed, 57 insertions(+), 37 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 48b3b4b73..81e6aa1e8 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1379,6 +1379,15 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module, return true; } +static int +cmp_func_inst(const void *a, const void *b) +{ + const AOTFunctionInstance *func_inst1 = (const AOTFunctionInstance *)a; + const AOTFunctionInstance *func_inst2 = (const AOTFunctionInstance *)b; + + return strcmp(func_inst1->func_name, func_inst2->func_name); +} + static bool create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, char *error_buf, uint32 error_buf_size) @@ -1419,6 +1428,9 @@ create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module, export_func++; } } + + qsort(module_inst->export_functions, module_inst->export_func_count, + sizeof(AOTFunctionInstance), cmp_func_inst); } return true; @@ -2206,14 +2218,12 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst) AOTFunctionInstance * aot_lookup_function(const AOTModuleInstance *module_inst, const char *name) { - uint32 i; AOTFunctionInstance *export_funcs = (AOTFunctionInstance *)module_inst->export_functions; + AOTFunctionInstance key = { .func_name = (char *)name }; - for (i = 0; i < module_inst->export_func_count; i++) - if (!strcmp(export_funcs[i].func_name, name)) - return &export_funcs[i]; - return NULL; + return bsearch(&key, export_funcs, module_inst->export_func_count, + sizeof(AOTFunctionInstance), cmp_func_inst); } #ifdef OS_ENABLE_HW_BOUND_CHECK diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 01109658f..5c1e9efd3 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -3391,8 +3391,7 @@ wasm_func_call(const wasm_func_t *func, const wasm_val_vec_t *params, if (export->kind == EXPORT_KIND_FUNC) { if (export->index == func->func_idx_rt) { func_comm_rt = - (AOTFunctionInstance *)inst_aot->export_functions - + export_func_j; + aot_lookup_function(inst_aot, export->name); ((wasm_func_t *)func)->func_comm_rt = func_comm_rt; break; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 1c77b2e4d..fb16aa0f3 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -3908,23 +3908,18 @@ wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst) WASMFunctionInstanceCommon * wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst) { - uint32 i; - #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst; - WASMFunctionInstance *func; - for (i = 0; i < wasm_inst->export_func_count; i++) { - if (!strcmp(wasm_inst->export_functions[i].name, "_start")) { - func = wasm_inst->export_functions[i].function; - if (func->u.func->func_type->param_count != 0 - || func->u.func->func_type->result_count != 0) { - LOG_ERROR("Lookup wasi _start function failed: " - "invalid function type.\n"); - return NULL; - } - return (WASMFunctionInstanceCommon *)func; + WASMFunctionInstance *func = wasm_lookup_function(wasm_inst, "_start"); + if (func) { + if (func->u.func->func_type->param_count != 0 + || func->u.func->func_type->result_count != 0) { + LOG_ERROR("Lookup wasi _start function failed: " + "invalid function type.\n"); + return NULL; } + return (WASMFunctionInstanceCommon *)func; } return NULL; } @@ -3933,19 +3928,15 @@ wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst) #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst; - AOTFunctionInstance *export_funcs = - (AOTFunctionInstance *)aot_inst->export_functions; - for (i = 0; i < aot_inst->export_func_count; i++) { - if (!strcmp(export_funcs[i].func_name, "_start")) { - AOTFuncType *func_type = export_funcs[i].u.func.func_type; - if (func_type->param_count != 0 - || func_type->result_count != 0) { - LOG_ERROR("Lookup wasi _start function failed: " - "invalid function type.\n"); - return NULL; - } - return (WASMFunctionInstanceCommon *)&export_funcs[i]; + AOTFunctionInstance *func = aot_lookup_function(aot_inst, "_start"); + if (func) { + AOTFuncType *func_type = func->u.func.func_type; + if (func_type->param_count != 0 || func_type->result_count != 0) { + LOG_ERROR("Lookup wasi _start function failed: " + "invalid function type.\n"); + return NULL; } + return func; } return NULL; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index f6d5e1034..78900cb8a 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1367,6 +1367,17 @@ export_functions_deinstantiate(WASMExportFuncInstance *functions) wasm_runtime_free(functions); } +static int +cmp_export_func_inst(const void *a, const void *b) +{ + const WASMExportFuncInstance *export_func1 = + (const WASMExportFuncInstance *)a; + const WASMExportFuncInstance *export_func2 = + (const WASMExportFuncInstance *)b; + + return strcmp(export_func1->name, export_func2->name); +} + /** * Instantiate export functions in a module. */ @@ -1395,6 +1406,9 @@ export_functions_instantiate(const WASMModule *module, } bh_assert((uint32)(export_func - export_funcs) == export_func_count); + + qsort(export_funcs, export_func_count, sizeof(WASMExportFuncInstance), + cmp_export_func_inst); return export_funcs; } @@ -3420,11 +3434,17 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) WASMFunctionInstance * wasm_lookup_function(const WASMModuleInstance *module_inst, const char *name) { - uint32 i; - for (i = 0; i < module_inst->export_func_count; i++) - if (!strcmp(module_inst->export_functions[i].name, name)) - return module_inst->export_functions[i].function; - return NULL; + WASMExportFuncInstance key = { .name = (char *)name }; + WASMExportFuncInstance *export_func_inst; + + export_func_inst = bsearch( + &key, module_inst->export_functions, module_inst->export_func_count, + sizeof(WASMExportFuncInstance), cmp_export_func_inst); + + if (!export_func_inst) + return NULL; + + return export_func_inst->function; } WASMMemoryInstance *