Normalize wasm types (#1378)

Normalize wasm types, for the two wasm types, if their parameter types
and result types are the same, we only save one copy, so as to reduce
the footprint and simplify the type comparison in opcode CALL_INDIRECT.

And fix issue in interpreter globals_instantiate, and remove used codes.
This commit is contained in:
FromLiQg
2022-08-18 17:52:02 +08:00
committed by GitHub
parent 9cf7b88bad
commit 88bb4f3c81
8 changed files with 75 additions and 35 deletions

View File

@ -122,6 +122,7 @@ typedef struct WASMType {
uint16 result_count;
uint16 param_cell_num;
uint16 ret_cell_num;
uint16 ref_count;
/* types of params and results */
uint8 types[1];
} WASMType;
@ -612,6 +613,9 @@ wasm_value_type_cell_num_outside(uint8 value_type)
inline static bool
wasm_type_equal(const WASMType *type1, const WASMType *type2)
{
if (type1 == type2) {
return true;
}
return (type1->param_count == type2->param_count
&& type1->result_count == type2->result_count
&& memcmp(type1->types, type2->types,

View File

@ -1391,7 +1391,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
tbl_inst = wasm_get_table_inst(module, tbl_idx);
val = POP_I32();
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
if ((uint32)val >= tbl_inst->cur_size) {
wasm_set_exception(module, "undefined element");
goto got_exception;
}
@ -1419,10 +1419,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
if (cur_type != cur_func_type) {
wasm_set_exception(module, "indirect call type mismatch");
goto got_exception;
}
#if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;

View File

@ -1316,7 +1316,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
val = GET_OPERAND(uint32, I32, 0);
frame_ip += 2;
if (val < 0 || val >= (int32)tbl_inst->cur_size) {
if ((uint32)val >= tbl_inst->cur_size) {
wasm_set_exception(module, "undefined element");
goto got_exception;
}
@ -1344,10 +1344,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
cur_func_type = cur_func->u.func_import->func_type;
else
cur_func_type = cur_func->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
if (cur_type != cur_func_type) {
wasm_set_exception(module, "indirect call type mismatch");
goto got_exception;
}
#if WASM_ENABLE_TAIL_CALL != 0
if (opcode == WASM_OP_RETURN_CALL_INDIRECT)
goto call_func_from_return_call;

View File

@ -415,6 +415,19 @@ const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
return node->str;
}
static void
destroy_wasm_type(WASMType *type)
{
if (type->ref_count > 1) {
/* The type is referenced by other types
of current wasm module */
type->ref_count--;
return;
}
wasm_runtime_free(type);
}
static bool
load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, char *error_buf,
@ -582,6 +595,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
}
/* Resolve param types and result types */
type->ref_count = 1;
type->param_count = (uint16)param_count;
type->result_count = (uint16)result_count;
for (j = 0; j < param_count; j++) {
@ -611,6 +625,21 @@ 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 there is already a same type created, use it instead */
for (j = 0; j < i; j++) {
if (wasm_type_equal(type, module->types[j])) {
if (module->types[j]->ref_count == UINT16_MAX) {
set_error_buf(error_buf, error_buf_size,
"wasm type's ref count too large");
return false;
}
destroy_wasm_type(type);
module->types[i] = module->types[j];
module->types[j]->ref_count++;
break;
}
}
}
}
@ -3729,7 +3758,7 @@ wasm_loader_unload(WASMModule *module)
if (module->types) {
for (i = 0; i < module->type_count; i++) {
if (module->types[i])
wasm_runtime_free(module->types[i]);
destroy_wasm_type(module->types[i]);
}
wasm_runtime_free(module->types);
}

View File

@ -248,6 +248,19 @@ const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module,
return node->str;
}
static void
destroy_wasm_type(WASMType *type)
{
if (type->ref_count > 1) {
/* The type is referenced by other types
of current wasm module */
type->ref_count--;
return;
}
wasm_runtime_free(type);
}
static bool
load_init_expr(const uint8 **p_buf, const uint8 *buf_end,
InitializerExpression *init_expr, uint8 type, char *error_buf,
@ -372,6 +385,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
}
/* Resolve param types and result types */
type->ref_count = 1;
type->param_count = (uint16)param_count;
type->result_count = (uint16)result_count;
for (j = 0; j < param_count; j++) {
@ -394,6 +408,17 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
&& ret_cell_num <= UINT16_MAX);
type->param_cell_num = (uint16)param_cell_num;
type->ret_cell_num = (uint16)ret_cell_num;
/* If there is already a same type created, use it instead */
for (j = 0; j < i; ++j) {
if (wasm_type_equal(type, j)) {
bh_assert(module->types[j]->ref_count != UINT16_MAX);
destroy_wasm_type(type);
module->types[i] = module->types[j];
module->types[j]->ref_count++;
break;
}
}
}
}
@ -2400,7 +2425,7 @@ wasm_loader_unload(WASMModule *module)
if (module->types) {
for (i = 0; i < module->type_count; i++) {
if (module->types[i])
wasm_runtime_free(module->types[i]);
destroy_wasm_type(module->types[i]);
}
wasm_runtime_free(module->types);
}

View File

@ -787,13 +787,13 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
if (!(global->import_module_inst = get_sub_module_inst(
module_inst, global_import->import_module))) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return NULL;
goto fail;
}
if (!(global->import_global_inst = wasm_lookup_global(
global->import_module_inst, global_import->field_name))) {
set_error_buf(error_buf, error_buf_size, "unknown global");
return NULL;
goto fail;
}
/* The linked global instance has been initialized, we
@ -829,7 +829,7 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
if (!check_global_init_expr(module, init_expr->u.global_index,
error_buf, error_buf_size)) {
return NULL;
goto fail;
}
bh_memcpy_s(
@ -853,6 +853,9 @@ globals_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
*p_global_data_size = global_data_offset;
(void)module_inst;
return globals;
fail:
wasm_runtime_free(globals);
return NULL;
}
/**
@ -2663,7 +2666,7 @@ call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 elem_idx,
else
cur_func_type = func_inst->u.func->func_type;
if (!wasm_type_equal(cur_type, cur_func_type)) {
if (cur_type != cur_func_type) {
wasm_set_exception(module_inst, "indirect call type mismatch");
goto got_exception;
}