Refine opcode br_table for classic interpreter (#1112)
Refine opcode br_table for classic interpreter as there may be a lot of
leb128 decoding when the br count is big:
1. Use the bytecode itself to store the decoded leb br depths if each
decoded depth can be stored with one byte
2. Create br_table cache to store the decode leb br depths if the decoded
depth cannot be stored with one byte
After the optimization, the class interpreter can access the br depths array
with index, no need to decode the leb128 again.
And fix function record_fast_op() return value unchecked issue in source
debugging feature.
This commit is contained in:
@ -2151,6 +2151,9 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModule *module =
|
||||
loader_malloc(sizeof(WASMModule), error_buf, error_buf_size);
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
bh_list_status ret;
|
||||
#endif
|
||||
|
||||
if (!module) {
|
||||
return NULL;
|
||||
@ -2161,6 +2164,13 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||
/* Set start_function to -1, means no start function */
|
||||
module->start_function = (uint32)-1;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
module->br_table_cache_list = &module->br_table_cache_list_head;
|
||||
ret = bh_list_init(module->br_table_cache_list);
|
||||
bh_assert(ret == BH_LIST_SUCCESS);
|
||||
(void)ret;
|
||||
#endif
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -2432,6 +2442,18 @@ wasm_loader_unload(WASMModule *module)
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
if (module->br_table_cache_list) {
|
||||
BrTableCache *node = bh_list_first_elem(module->br_table_cache_list);
|
||||
BrTableCache *node_next;
|
||||
while (node) {
|
||||
node_next = bh_list_elem_next(node);
|
||||
wasm_runtime_free(node);
|
||||
node = node_next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
wasm_runtime_free(module);
|
||||
}
|
||||
|
||||
@ -2557,10 +2579,24 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
|
||||
|
||||
case WASM_OP_BR_TABLE:
|
||||
read_leb_uint32(p, p_end, count); /* lable num */
|
||||
for (i = 0; i <= count; i++) /* lableidxs */
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
for (i = 0; i <= count; i++) /* lableidxs */
|
||||
skip_leb_uint32(p, p_end);
|
||||
#else
|
||||
p += count + 1;
|
||||
while (*p == WASM_OP_NOP)
|
||||
p++;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
case EXT_OP_BR_TABLE_CACHE:
|
||||
read_leb_uint32(p, p_end, count); /* lable num */
|
||||
while (*p == WASM_OP_NOP)
|
||||
p++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WASM_OP_RETURN:
|
||||
break;
|
||||
|
||||
@ -5149,6 +5185,13 @@ re_scan:
|
||||
{
|
||||
uint8 *ret_types = NULL;
|
||||
uint32 ret_count = 0;
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
uint8 *p_depth_begin, *p_depth;
|
||||
uint32 depth, j;
|
||||
BrTableCache *br_table_cache = NULL;
|
||||
|
||||
p_org = p - 1;
|
||||
#endif
|
||||
|
||||
read_leb_uint32(p, p_end, count);
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
@ -5156,13 +5199,65 @@ re_scan:
|
||||
#endif
|
||||
POP_I32();
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
p_depth_begin = p_depth = p;
|
||||
#endif
|
||||
for (i = 0; i <= count; i++) {
|
||||
if (!(frame_csp_tmp =
|
||||
check_branch_block(loader_ctx, &p, p_end,
|
||||
error_buf, error_buf_size)))
|
||||
goto fail;
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
depth = (uint32)(loader_ctx->frame_csp - 1 - frame_csp_tmp);
|
||||
if (br_table_cache) {
|
||||
br_table_cache->br_depths[i] = depth;
|
||||
}
|
||||
else {
|
||||
if (depth > 255) {
|
||||
/* The depth cannot be stored in one byte,
|
||||
create br_table cache to store each depth */
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
if (!record_fast_op(module, p_org, *p_org,
|
||||
error_buf, error_buf_size)) {
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
if (!(br_table_cache = loader_malloc(
|
||||
offsetof(BrTableCache, br_depths)
|
||||
+ sizeof(uint32)
|
||||
* (uint64)(count + 1),
|
||||
error_buf, error_buf_size))) {
|
||||
goto fail;
|
||||
}
|
||||
*p_org = EXT_OP_BR_TABLE_CACHE;
|
||||
br_table_cache->br_table_op_addr = p_org;
|
||||
br_table_cache->br_count = count;
|
||||
/* Copy previous depths which are one byte */
|
||||
for (j = 0; j < i; j++) {
|
||||
br_table_cache->br_depths[j] = p_depth_begin[j];
|
||||
}
|
||||
br_table_cache->br_depths[i] = depth;
|
||||
bh_list_insert(module->br_table_cache_list,
|
||||
br_table_cache);
|
||||
}
|
||||
else {
|
||||
/* The depth can be stored in one byte, use the
|
||||
byte of the leb to store it */
|
||||
*p_depth++ = (uint8)depth;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
/* Set the tailing bytes to nop */
|
||||
if (br_table_cache)
|
||||
p_depth = p_depth_begin;
|
||||
while (p_depth < p)
|
||||
*p_depth++ = WASM_OP_NOP;
|
||||
#endif
|
||||
|
||||
RESET_STACK();
|
||||
SET_CUR_BLOCK_STACK_POLYMORPHIC_STATE(true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user