mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-16 09:18:29 +00:00
Refactor aot stack frame commit (#2976)
- Commit locals, stacks and stack pointer to aot frame only when gc is enabled - Commit instruction pointer to aot frame when stack frame is enabled - Refine alloc/free aot frame when gc isn't enabled: use fixed frame size - Support dump call stack with bytecode offset
This commit is contained in:
parent
cc23a09d5e
commit
d31455fc4e
|
@ -3485,6 +3485,76 @@ get_func_name_from_index(const AOTModuleInstance *module_inst,
|
|||
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 || \
|
||||
WASM_ENABLE_PERF_PROFILING != 0 */
|
||||
|
||||
#if WASM_ENABLE_GC == 0
|
||||
bool
|
||||
aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
AOTFuncPerfProfInfo *func_perf_prof =
|
||||
module_inst->func_perf_profilings + func_index;
|
||||
#endif
|
||||
AOTFrame *cur_frame, *frame;
|
||||
uint32 size = (uint32)offsetof(AOTFrame, lp);
|
||||
|
||||
cur_frame = (AOTFrame *)exec_env->cur_frame;
|
||||
if (!cur_frame)
|
||||
frame = (AOTFrame *)exec_env->wasm_stack.bottom;
|
||||
else
|
||||
frame = (AOTFrame *)((uint8 *)cur_frame + size);
|
||||
|
||||
if ((uint8 *)frame + size > exec_env->wasm_stack.top_boundary) {
|
||||
aot_set_exception(module_inst, "wasm operand stack overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->func_index = func_index;
|
||||
/* No need to initialize ip, it will be committed in jitted code
|
||||
when needed */
|
||||
/* frame->ip = NULL; */
|
||||
frame->prev_frame = (AOTFrame *)exec_env->cur_frame;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = (uintptr_t)os_time_get_boot_microsecond();
|
||||
frame->func_perf_prof_info = func_perf_prof;
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
{
|
||||
uint32 wasm_stack_used =
|
||||
(uint8 *)frame + size - exec_env->wasm_stack.bottom;
|
||||
if (wasm_stack_used > exec_env->max_wasm_stack_used)
|
||||
exec_env->max_wasm_stack_used = wasm_stack_used;
|
||||
}
|
||||
#endif
|
||||
|
||||
exec_env->cur_frame = (struct WASMInterpFrame *)frame;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
aot_free_frame_internal(WASMExecEnv *exec_env)
|
||||
{
|
||||
AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
|
||||
AOTFrame *prev_frame = cur_frame->prev_frame;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
cur_frame->func_perf_prof_info->total_exec_time +=
|
||||
(uintptr_t)os_time_get_boot_microsecond() - cur_frame->time_started;
|
||||
cur_frame->func_perf_prof_info->total_exec_cnt++;
|
||||
#endif
|
||||
|
||||
exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
|
||||
}
|
||||
|
||||
void
|
||||
aot_free_frame(WASMExecEnv *exec_env)
|
||||
{
|
||||
aot_free_frame_internal(exec_env);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool
|
||||
aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
||||
{
|
||||
|
@ -3528,9 +3598,9 @@ aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
|||
frame->time_started = (uintptr_t)os_time_get_boot_microsecond();
|
||||
frame->func_perf_prof_info = func_perf_prof;
|
||||
#endif
|
||||
frame->sp = frame->lp + max_local_cell_num;
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
frame->sp = frame->lp + max_local_cell_num;
|
||||
frame->frame_ref = (uint8 *)(frame->sp + max_stack_cell_num);
|
||||
|
||||
/* Initialize frame ref flags for import function */
|
||||
|
@ -3568,8 +3638,8 @@ aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
aot_free_frame(WASMExecEnv *exec_env)
|
||||
static inline void
|
||||
aot_free_frame_internal(WASMExecEnv *exec_env)
|
||||
{
|
||||
AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
|
||||
AOTFrame *prev_frame = cur_frame->prev_frame;
|
||||
|
@ -3584,6 +3654,14 @@ aot_free_frame(WASMExecEnv *exec_env)
|
|||
exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
|
||||
}
|
||||
|
||||
void
|
||||
aot_free_frame(WASMExecEnv *exec_env)
|
||||
{
|
||||
aot_free_frame_internal(exec_env);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
|
||||
{
|
||||
|
@ -3606,8 +3684,14 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
|
|||
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
if (alloc_frame) {
|
||||
#if WASM_ENABLE_GC == 0
|
||||
uint32 wasm_stack_used = (uint8 *)exec_env->cur_frame
|
||||
+ (uint32)offsetof(AOTFrame, lp)
|
||||
- exec_env->wasm_stack.bottom;
|
||||
#else
|
||||
uint32 wasm_stack_used =
|
||||
exec_env->wasm_stack.top - exec_env->wasm_stack.bottom;
|
||||
#endif
|
||||
if (wasm_stack_used > exec_env->max_wasm_stack_used)
|
||||
exec_env->max_wasm_stack_used = wasm_stack_used;
|
||||
}
|
||||
|
@ -3676,8 +3760,8 @@ aot_create_call_stack(struct WASMExecEnv *exec_env)
|
|||
}
|
||||
bh_memcpy_s(frame.lp, lp_size, cur_frame->lp, lp_size);
|
||||
|
||||
frame.sp = frame.lp + (cur_frame->sp - cur_frame->lp);
|
||||
#if WASM_ENABLE_GC != 0
|
||||
frame.sp = frame.lp + (cur_frame->sp - cur_frame->lp);
|
||||
frame.frame_ref = (uint8 *)frame.lp
|
||||
+ (cur_frame->frame_ref - (uint8 *)cur_frame->lp);
|
||||
#endif
|
||||
|
@ -3739,14 +3823,14 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
|
|||
|
||||
/* function name not exported, print number instead */
|
||||
if (frame.func_name_wp == NULL) {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " $f%" PRIu32 "\n", n, frame.func_index);
|
||||
line_length = snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " $f%" PRIu32 " (0x%04x)\n", n,
|
||||
frame.func_index, frame.func_offset);
|
||||
}
|
||||
else {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n", n,
|
||||
frame.func_name_wp);
|
||||
line_length = snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " %s (0x%04x)\n", n,
|
||||
frame.func_name_wp, frame.func_offset);
|
||||
}
|
||||
|
||||
if (line_length >= sizeof(line_buf)) {
|
||||
|
|
|
@ -534,8 +534,7 @@ aot_gen_commit_values(AOTCompFrame *frame)
|
|||
}
|
||||
|
||||
bool
|
||||
aot_gen_commit_sp_ip(AOTCompFrame *frame, const AOTValueSlot *sp,
|
||||
const uint8 *ip)
|
||||
aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip)
|
||||
{
|
||||
AOTCompContext *comp_ctx = frame->comp_ctx;
|
||||
AOTFuncContext *func_ctx = frame->func_ctx;
|
||||
|
@ -544,9 +543,8 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, const AOTValueSlot *sp,
|
|||
LLVMTypeRef int8_ptr_ptr_type;
|
||||
uint32 offset_ip, offset_sp, n;
|
||||
bool is_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
|
||||
/* TODO: only commit sp currently, will add more options to
|
||||
control whether to commit sp/ip in the future */
|
||||
bool commit_sp = true, commit_ip = false;
|
||||
const AOTValueSlot *sp = frame->sp;
|
||||
const uint8 *ip = frame->frame_ip;
|
||||
|
||||
if (!comp_ctx->is_jit_mode) {
|
||||
offset_ip = frame->comp_ctx->pointer_size * 4;
|
||||
|
@ -578,12 +576,11 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, const AOTValueSlot *sp,
|
|||
}
|
||||
|
||||
if (!comp_ctx->is_jit_mode) {
|
||||
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||
if (is_64bit)
|
||||
value = I64_CONST(
|
||||
(uint64)(uintptr_t)(ip - func_ctx->aot_func->code));
|
||||
value = I64_CONST((uint64)(uintptr_t)(ip - module->load_addr));
|
||||
else
|
||||
value = I32_CONST(
|
||||
(uint32)(uintptr_t)(ip - func_ctx->aot_func->code));
|
||||
value = I32_CONST((uint32)(uintptr_t)(ip - module->load_addr));
|
||||
}
|
||||
else {
|
||||
if (is_64bit)
|
||||
|
@ -909,7 +906,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index];
|
||||
uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64;
|
||||
uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size;
|
||||
uint8 *param_types = NULL, *frame_ip_org;
|
||||
uint8 *param_types = NULL;
|
||||
uint8 *result_types = NULL;
|
||||
uint8 value_type;
|
||||
uint16 param_count;
|
||||
|
@ -941,6 +938,10 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
while (frame_ip < frame_ip_end) {
|
||||
opcode = *frame_ip++;
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
comp_ctx->aot_frame->frame_ip = frame_ip - 1;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
location = dwarf_gen_location(
|
||||
comp_ctx, func_ctx,
|
||||
|
@ -1035,30 +1036,23 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
case WASM_OP_BR:
|
||||
{
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
|
||||
if (!aot_compile_op_br(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_org, &frame_ip))
|
||||
if (!aot_compile_op_br(comp_ctx, func_ctx, br_depth, &frame_ip))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
case WASM_OP_BR_IF:
|
||||
{
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
|
||||
if (!aot_compile_op_br_if(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_org, &frame_ip))
|
||||
&frame_ip))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
case WASM_OP_BR_TABLE:
|
||||
{
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_count);
|
||||
if (!(br_depths = wasm_runtime_malloc((uint32)sizeof(uint32)
|
||||
* (br_count + 1)))) {
|
||||
|
@ -1074,8 +1068,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
#endif
|
||||
|
||||
if (!aot_compile_op_br_table(comp_ctx, func_ctx, br_depths,
|
||||
br_count, frame_ip_org,
|
||||
&frame_ip)) {
|
||||
br_count, &frame_ip)) {
|
||||
wasm_runtime_free(br_depths);
|
||||
return false;
|
||||
}
|
||||
|
@ -1090,8 +1083,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
BrTableCache *node = bh_list_first_elem(
|
||||
comp_ctx->comp_data->wasm_module->br_table_cache_list);
|
||||
BrTableCache *node_next;
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
const uint8 *frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_count);
|
||||
|
||||
|
@ -1101,7 +1093,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
br_depths = node->br_depths;
|
||||
if (!aot_compile_op_br_table(comp_ctx, func_ctx,
|
||||
br_depths, br_count,
|
||||
frame_ip_org, &frame_ip)) {
|
||||
&frame_ip)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -1121,11 +1113,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
|
||||
case WASM_OP_CALL:
|
||||
{
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
|
||||
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, false))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1134,8 +1123,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
{
|
||||
uint32 tbl_idx;
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
|
||||
if (comp_ctx->enable_gc || comp_ctx->enable_ref_types) {
|
||||
|
@ -1147,7 +1134,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
}
|
||||
|
||||
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
|
||||
tbl_idx, frame_ip_org))
|
||||
tbl_idx))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1160,11 +1147,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
return false;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
|
||||
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, true,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, true))
|
||||
return false;
|
||||
if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
|
||||
return false;
|
||||
|
@ -1180,8 +1164,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
return false;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
if (comp_ctx->enable_gc || comp_ctx->enable_ref_types) {
|
||||
read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
|
||||
|
@ -1192,7 +1174,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
}
|
||||
|
||||
if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx,
|
||||
tbl_idx, frame_ip_org))
|
||||
tbl_idx))
|
||||
return false;
|
||||
if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
|
||||
return false;
|
||||
|
@ -1306,11 +1288,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc_and_ref_types;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, func_idx);
|
||||
if (!aot_compile_op_ref_func(comp_ctx, func_ctx, func_idx,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_ref_func(comp_ctx, func_ctx, func_idx))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1323,11 +1302,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx,
|
||||
false, frame_ip_org))
|
||||
false))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1338,11 +1315,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, type_idx);
|
||||
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx, true,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_call_ref(comp_ctx, func_ctx, type_idx,
|
||||
true))
|
||||
return false;
|
||||
if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
|
||||
return false;
|
||||
|
@ -1373,11 +1348,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
|
||||
if (!aot_compile_op_br_on_null(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_org, &frame_ip))
|
||||
&frame_ip))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1388,11 +1361,9 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, br_depth);
|
||||
if (!aot_compile_op_br_on_non_null(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_org, &frame_ip))
|
||||
&frame_ip))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1405,8 +1376,6 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
goto unsupport_gc;
|
||||
}
|
||||
|
||||
frame_ip_org = frame_ip - 1;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, opcode1);
|
||||
opcode = (uint8)opcode1;
|
||||
|
||||
|
@ -1416,8 +1385,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
if (!aot_compile_op_struct_new(
|
||||
comp_ctx, func_ctx, type_index,
|
||||
opcode == WASM_OP_STRUCT_NEW_DEFAULT,
|
||||
frame_ip_org))
|
||||
opcode == WASM_OP_STRUCT_NEW_DEFAULT))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -1451,8 +1419,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
if (!aot_compile_op_array_new(
|
||||
comp_ctx, func_ctx, type_index,
|
||||
opcode == WASM_OP_ARRAY_NEW_DEFAULT,
|
||||
opcode == WASM_OP_ARRAY_NEW_FIXED, array_len,
|
||||
frame_ip_org))
|
||||
opcode == WASM_OP_ARRAY_NEW_FIXED, array_len))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -1460,8 +1427,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
read_leb_uint32(frame_ip, frame_ip_end, type_index);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, data_seg_idx);
|
||||
if (!aot_compile_op_array_new_data(
|
||||
comp_ctx, func_ctx, type_index, data_seg_idx,
|
||||
frame_ip_org))
|
||||
comp_ctx, func_ctx, type_index, data_seg_idx))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -1577,7 +1543,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
comp_ctx, func_ctx, dst_heap_type,
|
||||
castflags & 0x02,
|
||||
opcode == WASM_OP_BR_ON_CAST_FAIL, br_depth,
|
||||
frame_ip_org, &frame_ip))
|
||||
&frame_ip))
|
||||
return false;
|
||||
|
||||
(void)heap_type;
|
||||
|
@ -1591,8 +1557,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
break;
|
||||
|
||||
case WASM_OP_EXTERN_CONVERT_ANY:
|
||||
if (!aot_compile_op_extern_externalize(
|
||||
comp_ctx, func_ctx, frame_ip_org))
|
||||
if (!aot_compile_op_extern_externalize(comp_ctx,
|
||||
func_ctx))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -1620,8 +1586,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
flag = WTF8;
|
||||
}
|
||||
|
||||
if (!aot_compile_op_string_new(comp_ctx, func_ctx, flag,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_string_new(comp_ctx, func_ctx,
|
||||
flag))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1630,8 +1596,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
uint32 contents;
|
||||
read_leb_uint32(frame_ip, frame_ip_end, contents);
|
||||
|
||||
if (!aot_compile_op_string_const(
|
||||
comp_ctx, func_ctx, contents, frame_ip_org))
|
||||
if (!aot_compile_op_string_const(comp_ctx, func_ctx,
|
||||
contents))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
@ -1685,8 +1651,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
break;
|
||||
}
|
||||
case WASM_OP_STRING_CONCAT:
|
||||
if (!aot_compile_op_string_concat(comp_ctx, func_ctx,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_string_concat(comp_ctx, func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRING_EQ:
|
||||
|
@ -1699,8 +1664,7 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
return false;
|
||||
break;
|
||||
case WASM_OP_STRING_AS_WTF8:
|
||||
if (!aot_compile_op_string_as_wtf8(comp_ctx, func_ctx,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_string_as_wtf8(comp_ctx, func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF8_ADVANCE:
|
||||
|
@ -1735,13 +1699,12 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF8_SLICE:
|
||||
if (!aot_compile_op_stringview_wtf8_slice(
|
||||
comp_ctx, func_ctx, frame_ip_org))
|
||||
if (!aot_compile_op_stringview_wtf8_slice(comp_ctx,
|
||||
func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRING_AS_WTF16:
|
||||
if (!aot_compile_op_string_as_wtf16(comp_ctx, func_ctx,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_string_as_wtf16(comp_ctx, func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_WTF16_LENGTH:
|
||||
|
@ -1765,13 +1728,12 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
break;
|
||||
}
|
||||
case WASM_OP_STRINGVIEW_WTF16_SLICE:
|
||||
if (!aot_compile_op_stringview_wtf16_slice(
|
||||
comp_ctx, func_ctx, frame_ip_org))
|
||||
if (!aot_compile_op_stringview_wtf16_slice(comp_ctx,
|
||||
func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRING_AS_ITER:
|
||||
if (!aot_compile_op_string_as_iter(comp_ctx, func_ctx,
|
||||
frame_ip_org))
|
||||
if (!aot_compile_op_string_as_iter(comp_ctx, func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_ITER_NEXT:
|
||||
|
@ -1790,8 +1752,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
return false;
|
||||
break;
|
||||
case WASM_OP_STRINGVIEW_ITER_SLICE:
|
||||
if (!aot_compile_op_stringview_iter_slice(
|
||||
comp_ctx, func_ctx, frame_ip_org))
|
||||
if (!aot_compile_op_stringview_iter_slice(comp_ctx,
|
||||
func_ctx))
|
||||
return false;
|
||||
break;
|
||||
case WASM_OP_STRING_NEW_UTF8_ARRAY:
|
||||
|
@ -1814,8 +1776,8 @@ aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
|
|||
flag = WTF8;
|
||||
}
|
||||
|
||||
if (!aot_compile_op_string_new_array(
|
||||
comp_ctx, func_ctx, flag, frame_ip_org))
|
||||
if (!aot_compile_op_string_new_array(comp_ctx, func_ctx,
|
||||
flag))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
|
|
@ -193,8 +193,7 @@ aot_gen_commit_values(AOTCompFrame *frame);
|
|||
* @param frame the frame information
|
||||
*/
|
||||
bool
|
||||
aot_gen_commit_sp_ip(AOTCompFrame *frame, const AOTValueSlot *sp,
|
||||
const uint8 *ip);
|
||||
aot_gen_commit_sp_ip(AOTCompFrame *frame, bool commit_sp, bool commit_ip);
|
||||
|
||||
bool
|
||||
aot_frame_store_value(AOTCompContext *comp_ctx, LLVMValueRef value,
|
||||
|
|
|
@ -580,7 +580,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
func_ctx->block_stack.block_index[label_type]++;
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (label_type != LABEL_TYPE_BLOCK
|
||||
if (label_type != LABEL_TYPE_BLOCK && comp_ctx->enable_gc
|
||||
&& !aot_gen_commit_values(comp_ctx->aot_frame)) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -754,7 +754,7 @@ aot_compile_op_else(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
if (aot_frame) {
|
||||
bh_assert(block->frame_sp_begin == aot_frame->sp);
|
||||
if (!aot_gen_commit_values(aot_frame)) {
|
||||
if (comp_ctx->enable_gc && !aot_gen_commit_values(aot_frame)) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -812,7 +812,7 @@ aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (block->label_type != LABEL_TYPE_FUNCTION
|
||||
if (block->label_type != LABEL_TYPE_FUNCTION && comp_ctx->enable_gc
|
||||
&& !aot_gen_commit_values(comp_ctx->aot_frame)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -841,7 +841,6 @@ fail:
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
bool
|
||||
check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool check_terminate_and_suspend)
|
||||
|
@ -912,11 +911,10 @@ check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
#endif /* End of WASM_ENABLE_THREAD_MGR */
|
||||
|
||||
bool
|
||||
aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br, uint8 **p_frame_ip)
|
||||
uint32 br_depth, uint8 **p_frame_ip)
|
||||
{
|
||||
AOTBlock *block_dst;
|
||||
LLVMValueRef value_ret, value_param;
|
||||
|
@ -929,17 +927,16 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (block_dst->label_type == LABEL_TYPE_LOOP) {
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
/* Commit sp when GC is enabled, don't commit ip */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
|
||||
comp_ctx->aot_frame->sp, frame_ip_br))
|
||||
comp_ctx->enable_gc, false))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
|
||||
|
@ -947,14 +944,12 @@ aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Terminate or suspend current thread only when this is a backward jump */
|
||||
if (comp_ctx->enable_thread_mgr
|
||||
&& block_dst->label_type == LABEL_TYPE_LOOP) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (block_dst->label_type == LABEL_TYPE_LOOP) {
|
||||
/* Dest block is Loop block */
|
||||
|
@ -999,7 +994,7 @@ fail:
|
|||
static bool
|
||||
aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, LLVMValueRef value_cmp,
|
||||
const uint8 *frame_ip_br_if, uint8 **p_frame_ip)
|
||||
uint8 **p_frame_ip)
|
||||
{
|
||||
AOTBlock *block_dst;
|
||||
LLVMValueRef value, *values = NULL;
|
||||
|
@ -1013,18 +1008,16 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (block_dst->label_type == LABEL_TYPE_LOOP) {
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
/* Commit sp when GC is enabled, don't commit ip */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
|
||||
comp_ctx->aot_frame->sp,
|
||||
frame_ip_br_if))
|
||||
comp_ctx->enable_gc, false))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
|
||||
|
@ -1032,7 +1025,6 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Terminate or suspend current thread only when this is
|
||||
a backward jump */
|
||||
if (comp_ctx->enable_thread_mgr
|
||||
|
@ -1040,7 +1032,6 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (LLVMIsUndef(value_cmp)
|
||||
#if LLVM_VERSION_NUMBER >= 12
|
||||
|
@ -1138,8 +1129,7 @@ aot_compile_conditional_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
else {
|
||||
if ((int32)LLVMConstIntGetZExtValue(value_cmp) != 0) {
|
||||
/* Compare value is not 0, condition is true, same as op_br */
|
||||
return aot_compile_op_br(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_br_if, p_frame_ip);
|
||||
return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
|
||||
}
|
||||
else {
|
||||
/* Compare value is not 0, condition is false, skip br_if */
|
||||
|
@ -1155,23 +1145,21 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_if,
|
||||
uint8 **p_frame_ip)
|
||||
uint32 br_depth, uint8 **p_frame_ip)
|
||||
{
|
||||
LLVMValueRef value_cmp;
|
||||
|
||||
POP_COND(value_cmp);
|
||||
|
||||
return aot_compile_conditional_br(comp_ctx, func_ctx, br_depth, value_cmp,
|
||||
frame_ip_br_if, p_frame_ip);
|
||||
p_frame_ip);
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 *br_depths, uint32 br_count,
|
||||
const uint8 *frame_ip_br_table, uint8 **p_frame_ip)
|
||||
uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip)
|
||||
{
|
||||
uint32 i, j;
|
||||
LLVMValueRef value_switch, value_cmp, value_case, value, *values = NULL;
|
||||
|
@ -1199,17 +1187,16 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
if (!LLVMIsEfficientConstInt(value_cmp)) {
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
if (comp_ctx->enable_gc
|
||||
&& !aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
/* Commit sp when GC is enabled, don't commit ip */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
|
||||
comp_ctx->aot_frame->sp,
|
||||
frame_ip_br_table))
|
||||
comp_ctx->enable_gc, false))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i <= br_count; i++) {
|
||||
target_block = get_target_block(func_ctx, br_depths[i]);
|
||||
|
@ -1224,7 +1211,6 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
for (i = 0; i <= br_count; i++) {
|
||||
target_block = get_target_block(func_ctx, br_depths[i]);
|
||||
|
@ -1239,7 +1225,6 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compare value is not constant, create switch IR */
|
||||
for (i = 0; i <= br_count; i++) {
|
||||
|
@ -1340,8 +1325,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (depth_idx < br_count) {
|
||||
br_depth = br_depths[depth_idx];
|
||||
}
|
||||
return aot_compile_op_br(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_br_table, p_frame_ip);
|
||||
return aot_compile_op_br(comp_ctx, func_ctx, br_depth, p_frame_ip);
|
||||
}
|
||||
fail:
|
||||
if (values)
|
||||
|
@ -1432,8 +1416,7 @@ aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
|
|||
#if WASM_ENABLE_GC != 0
|
||||
static bool
|
||||
commit_gc_and_check_suspend_flags(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 br_depth,
|
||||
const uint8 *frame_ip_br_on)
|
||||
AOTFuncContext *func_ctx, uint32 br_depth)
|
||||
{
|
||||
AOTBlock *block_dst;
|
||||
|
||||
|
@ -1442,18 +1425,16 @@ commit_gc_and_check_suspend_flags(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
/* Note that GC is enabled, no need to check it again */
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (block_dst->label_type == LABEL_TYPE_LOOP) {
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame,
|
||||
comp_ctx->aot_frame->sp,
|
||||
frame_ip_br_on))
|
||||
/* Note that GC is enabled, no need to check it again */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, false))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
if (comp_ctx->aot_frame->sp > block_dst->frame_sp_max_reached)
|
||||
|
@ -1461,7 +1442,6 @@ commit_gc_and_check_suspend_flags(AOTCompContext *comp_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Terminate or suspend current thread only when this is
|
||||
a backward jump */
|
||||
if (comp_ctx->enable_thread_mgr
|
||||
|
@ -1469,7 +1449,6 @@ commit_gc_and_check_suspend_flags(AOTCompContext *comp_ctx,
|
|||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1574,13 +1553,11 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_br_on_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_on_null,
|
||||
uint8 **p_frame_ip)
|
||||
uint32 br_depth, uint8 **p_frame_ip)
|
||||
{
|
||||
LLVMValueRef gc_obj, value_cmp;
|
||||
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_br_on_null)) {
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1605,13 +1582,11 @@ fail:
|
|||
bool
|
||||
aot_compile_op_br_on_non_null(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 br_depth,
|
||||
const uint8 *frame_ip_br_on_non_null,
|
||||
uint8 **p_frame_ip)
|
||||
{
|
||||
LLVMValueRef gc_obj, value_cmp;
|
||||
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_br_on_non_null)) {
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1636,14 +1611,12 @@ fail:
|
|||
bool
|
||||
aot_compile_op_br_on_cast(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 heap_type, bool nullable, bool br_on_fail,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_on_cast,
|
||||
uint8 **p_frame_ip)
|
||||
uint32 br_depth, uint8 **p_frame_ip)
|
||||
{
|
||||
LLVMValueRef gc_obj, is_null, castable, not_castable, br_if_phi;
|
||||
LLVMBasicBlockRef block_curr, block_non_null, block_br_if;
|
||||
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth,
|
||||
frame_ip_br_on_cast)) {
|
||||
if (!commit_gc_and_check_suspend_flags(comp_ctx, func_ctx, br_depth)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,18 +28,15 @@ aot_compile_op_end(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_br(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br,
|
||||
uint8 **p_frame_ip);
|
||||
uint32 br_depth, uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_if,
|
||||
uint8 **p_frame_ip);
|
||||
uint32 br_depth, uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 *br_depths, uint32 br_count,
|
||||
const uint8 *frame_ip_br_table, uint8 **p_frame_ip);
|
||||
uint32 *br_depths, uint32 br_count, uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
|
@ -53,29 +50,25 @@ bool
|
|||
aot_handle_next_reachable_block(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint8 **p_frame_ip);
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
bool
|
||||
check_suspend_flags(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
bool check_terminate_and_suspend);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
bool
|
||||
aot_compile_op_br_on_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_on_null,
|
||||
uint8 **p_frame_ip);
|
||||
uint32 br_depth, uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_br_on_non_null(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 br_depth,
|
||||
const uint8 *frame_ip_br_on_non_null,
|
||||
|
||||
uint8 **p_frame_ip);
|
||||
|
||||
bool
|
||||
aot_compile_op_br_on_cast(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 heap_type, bool nullable, bool br_on_fail,
|
||||
uint32 br_depth, const uint8 *frame_ip_br_on_cast,
|
||||
uint8 **p_frame_ip);
|
||||
uint32 br_depth, uint8 **p_frame_ip);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -7,6 +7,46 @@
|
|||
#include "../interpreter/wasm_runtime.h"
|
||||
#include "../aot/aot_runtime.h"
|
||||
|
||||
static bool
|
||||
commit_ip(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef exce_ip, bool is_64bit)
|
||||
{
|
||||
LLVMValueRef cur_frame = func_ctx->cur_frame;
|
||||
LLVMValueRef value_offset, value_addr, value_ptr;
|
||||
uint32 offset_ip;
|
||||
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
offset_ip = comp_ctx->pointer_size * 4;
|
||||
else
|
||||
offset_ip = offsetof(WASMInterpFrame, ip);
|
||||
|
||||
if (!(value_offset = I32_CONST(offset_ip))) {
|
||||
aot_set_last_error("llvm build const failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(value_addr =
|
||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, cur_frame,
|
||||
&value_offset, 1, "ip_addr"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(value_ptr = LLVMBuildBitCast(
|
||||
comp_ctx->builder, value_addr,
|
||||
is_64bit ? INT64_PTR_TYPE : INT32_PTR_TYPE, "ip_ptr"))) {
|
||||
aot_set_last_error("llvm build bit cast failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LLVMBuildStore(comp_ctx->builder, exce_ip, value_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
int32 exception_id, bool is_cond_br, LLVMValueRef cond_br_if,
|
||||
|
@ -16,23 +56,12 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMValueRef exce_id = I32_CONST((uint32)exception_id), func_const, func;
|
||||
LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
|
||||
LLVMValueRef param_values[2];
|
||||
bool is_64bit = (comp_ctx->pointer_size == sizeof(uint64)) ? true : false;
|
||||
|
||||
bh_assert(exception_id >= 0 && exception_id < EXCE_NUM);
|
||||
|
||||
CHECK_LLVM_CONST(exce_id);
|
||||
|
||||
#if 0
|
||||
/* Seems no need to commit values since when dumping call stacks
|
||||
after exception was thrown, we only need to know the ip (instruction
|
||||
pointer) info. */
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
/* TODO: commit ip if needed when dumping call stacks after exception
|
||||
was thrown */
|
||||
|
||||
/* Create got_exception block if needed */
|
||||
if (!func_ctx->got_exception_block) {
|
||||
if (!(func_ctx->got_exception_block = LLVMAppendBasicBlockInContext(
|
||||
|
@ -44,13 +73,23 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMPositionBuilderAtEnd(comp_ctx->builder,
|
||||
func_ctx->got_exception_block);
|
||||
|
||||
/* Create exection id phi */
|
||||
/* Create exception id phi */
|
||||
if (!(func_ctx->exception_id_phi = LLVMBuildPhi(
|
||||
comp_ctx->builder, I32_TYPE, "exception_id_phi"))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
/* Create exception ip phi */
|
||||
if (!(func_ctx->exception_ip_phi = LLVMBuildPhi(
|
||||
comp_ctx->builder, is_64bit ? I64_TYPE : I32_TYPE,
|
||||
"exception_ip_phi"))) {
|
||||
aot_set_last_error("llvm build phi failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call aot_set_exception_with_id() to throw exception */
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
param_types[1] = I32_TYPE;
|
||||
|
@ -115,6 +154,12 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!commit_ip(comp_ctx, func_ctx, func_ctx->exception_ip_phi,
|
||||
is_64bit))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create return IR */
|
||||
AOTFuncType *aot_func_type = func_ctx->aot_func->func_type;
|
||||
if (!aot_build_zero_function_ret(comp_ctx, func_ctx, aot_func_type)) {
|
||||
|
@ -128,6 +173,35 @@ aot_emit_exception(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
/* Add phi incoming value to got_exception block */
|
||||
LLVMAddIncoming(func_ctx->exception_id_phi, &exce_id, &block_curr, 1);
|
||||
|
||||
if (comp_ctx->aot_frame) {
|
||||
const uint8 *ip = comp_ctx->aot_frame->frame_ip;
|
||||
LLVMValueRef exce_ip = NULL;
|
||||
|
||||
if (!comp_ctx->is_jit_mode) {
|
||||
WASMModule *module = comp_ctx->comp_data->wasm_module;
|
||||
if (is_64bit)
|
||||
exce_ip =
|
||||
I64_CONST((uint64)(uintptr_t)(ip - module->load_addr));
|
||||
else
|
||||
exce_ip =
|
||||
I32_CONST((uint32)(uintptr_t)(ip - module->load_addr));
|
||||
}
|
||||
else {
|
||||
if (is_64bit)
|
||||
exce_ip = I64_CONST((uint64)(uintptr_t)ip);
|
||||
else
|
||||
exce_ip = I32_CONST((uint32)(uintptr_t)ip);
|
||||
}
|
||||
|
||||
if (!exce_ip) {
|
||||
aot_set_last_error("llvm build const failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add phi incoming value to got_exception block */
|
||||
LLVMAddIncoming(func_ctx->exception_ip_phi, &exce_ip, &block_curr, 1);
|
||||
}
|
||||
|
||||
if (!is_cond_br) {
|
||||
/* not condition br, create br IR */
|
||||
if (!LLVMBuildBr(comp_ctx->builder, func_ctx->got_exception_block)) {
|
||||
|
|
|
@ -89,7 +89,7 @@ check_exception_thrown(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Add check exection success block */
|
||||
/* Add check exception success block */
|
||||
if (!(check_exce_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_exce_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
|
@ -129,7 +129,7 @@ check_call_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Add check exection success block */
|
||||
/* Add check exception success block */
|
||||
if (!(check_call_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_call_succ"))) {
|
||||
aot_set_last_error("llvm add basic block failed.");
|
||||
|
@ -292,7 +292,7 @@ call_aot_invoke_native_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
static bool
|
||||
call_aot_alloc_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
LLVMValueRef func_idx)
|
||||
|
@ -307,9 +307,11 @@ call_aot_alloc_frame_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
param_types[1] = I32_TYPE;
|
||||
ret_type = INT8_TYPE;
|
||||
|
||||
#if WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
if (comp_ctx->is_jit_mode)
|
||||
GET_AOT_FUNCTION(llvm_jit_alloc_frame, 2);
|
||||
else
|
||||
#endif
|
||||
GET_AOT_FUNCTION(aot_alloc_frame, 2);
|
||||
|
||||
param_values[0] = func_ctx->exec_env;
|
||||
|
@ -362,28 +364,34 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
LLVMValueRef wasm_stack_top_bound = func_ctx->wasm_stack_top_bound;
|
||||
LLVMValueRef wasm_stack_top_ptr = func_ctx->wasm_stack_top_ptr,
|
||||
wasm_stack_top;
|
||||
LLVMValueRef wasm_stack_top_max, wasm_stack_top_new, offset, cmp;
|
||||
LLVMValueRef wasm_stack_top_max, offset, cmp;
|
||||
LLVMValueRef cur_frame, new_frame, prev_frame_ptr;
|
||||
LLVMValueRef cur_frame_ptr = func_ctx->cur_frame_ptr;
|
||||
LLVMValueRef frame_sp, frame_sp_ptr, frame_ref, frame_ref_ptr;
|
||||
LLVMValueRef func_idx_ptr, func_idx_val, func_inst_ptr, func_inst;
|
||||
LLVMTypeRef int8_ptr_type;
|
||||
LLVMBasicBlockRef check_wasm_stack_succ;
|
||||
uint32 import_func_count = comp_ctx->comp_data->import_func_count;
|
||||
uint32 param_cell_num = 0, local_cell_num = 0, i, j, k;
|
||||
uint32 param_cell_num = 0, local_cell_num = 0, i;
|
||||
uint32 max_local_cell_num, max_stack_cell_num;
|
||||
uint32 all_cell_num, frame_size, frame_size_with_outs_area;
|
||||
uint32 aot_frame_ptr_num = offsetof(AOTFrame, lp) / sizeof(uintptr_t);
|
||||
AOTImportFunc *import_funcs = comp_ctx->comp_data->import_funcs;
|
||||
AOTFuncType *func_type;
|
||||
AOTFuncType *aot_func_type;
|
||||
AOTFunc *aot_func = NULL;
|
||||
|
||||
/* `int8 **` type */
|
||||
int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0);
|
||||
if (!int8_ptr_type) {
|
||||
aot_set_last_error("create llvm pointer type failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get param_cell_num, local_cell_num and max_stack_cell_num */
|
||||
if (func_idx < import_func_count) {
|
||||
func_type = import_funcs[func_idx].func_type;
|
||||
for (i = 0; i < func_type->param_count; i++)
|
||||
aot_func_type = import_funcs[func_idx].func_type;
|
||||
for (i = 0; i < aot_func_type->param_count; i++)
|
||||
param_cell_num += wasm_value_type_cell_num_internal(
|
||||
func_type->types[i], comp_ctx->pointer_size);
|
||||
aot_func_type->types[i], comp_ctx->pointer_size);
|
||||
max_local_cell_num = param_cell_num > 2 ? param_cell_num : 2;
|
||||
max_stack_cell_num = 0;
|
||||
}
|
||||
|
@ -402,54 +410,74 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!comp_ctx->is_jit_mode) {
|
||||
/* Refer to aot_alloc_frame */
|
||||
if (!comp_ctx->enable_gc) {
|
||||
frame_size =
|
||||
comp_ctx->pointer_size * aot_frame_ptr_num + all_cell_num * 4;
|
||||
frame_size = frame_size_with_outs_area =
|
||||
comp_ctx->pointer_size * aot_frame_ptr_num;
|
||||
}
|
||||
else
|
||||
else {
|
||||
frame_size = comp_ctx->pointer_size * aot_frame_ptr_num
|
||||
+ align_uint(all_cell_num * 5, 4);
|
||||
frame_size_with_outs_area = frame_size
|
||||
+ comp_ctx->pointer_size * aot_frame_ptr_num
|
||||
+ max_stack_cell_num * 4;
|
||||
frame_size_with_outs_area =
|
||||
frame_size + comp_ctx->pointer_size * aot_frame_ptr_num
|
||||
+ max_stack_cell_num * 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Refer to wasm_interp_interp_frame_size */
|
||||
if (!comp_ctx->enable_gc)
|
||||
frame_size = offsetof(WASMInterpFrame, lp) + all_cell_num * 4;
|
||||
else
|
||||
if (!comp_ctx->enable_gc) {
|
||||
frame_size = frame_size_with_outs_area =
|
||||
offsetof(WASMInterpFrame, lp);
|
||||
}
|
||||
else {
|
||||
frame_size =
|
||||
offsetof(WASMInterpFrame, lp) + align_uint(all_cell_num * 5, 4);
|
||||
frame_size_with_outs_area =
|
||||
frame_size + offsetof(WASMInterpFrame, lp) + max_stack_cell_num * 4;
|
||||
}
|
||||
|
||||
/* `int8 **` type */
|
||||
int8_ptr_type = LLVMPointerType(INT8_PTR_TYPE, 0);
|
||||
if (!int8_ptr_type) {
|
||||
aot_set_last_error("create llvm pointer type failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get exec_env->wasm_stack.top */
|
||||
if (!(wasm_stack_top =
|
||||
LLVMBuildLoad2(comp_ctx->builder, INT8_PTR_TYPE,
|
||||
wasm_stack_top_ptr, "wasm_stack_top"))) {
|
||||
aot_set_last_error("load wasm_stack.top failed");
|
||||
return false;
|
||||
frame_size_with_outs_area = frame_size
|
||||
+ offsetof(WASMInterpFrame, lp)
|
||||
+ max_stack_cell_num * 4;
|
||||
}
|
||||
}
|
||||
|
||||
cur_frame = func_ctx->cur_frame;
|
||||
new_frame = wasm_stack_top;
|
||||
|
||||
/* Check whether wasm operand stack is overflow */
|
||||
offset = I32_CONST(frame_size_with_outs_area);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(wasm_stack_top_max = LLVMBuildInBoundsGEP2(
|
||||
comp_ctx->builder, INT8_TYPE, wasm_stack_top, &offset, 1,
|
||||
"wasm_stack_top_max"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
if (!comp_ctx->enable_gc) {
|
||||
offset = I32_CONST(frame_size);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(wasm_stack_top =
|
||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, cur_frame,
|
||||
&offset, 1, "wasm_stack_top"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = I32_CONST(frame_size * 2);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(wasm_stack_top_max =
|
||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, cur_frame,
|
||||
&offset, 1, "wasm_stack_top_max"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Get exec_env->wasm_stack.top */
|
||||
if (!(wasm_stack_top =
|
||||
LLVMBuildLoad2(comp_ctx->builder, INT8_PTR_TYPE,
|
||||
wasm_stack_top_ptr, "wasm_stack_top"))) {
|
||||
aot_set_last_error("load wasm_stack.top failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check whether wasm operand stack is overflow */
|
||||
offset = I32_CONST(frame_size_with_outs_area);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(wasm_stack_top_max = LLVMBuildInBoundsGEP2(
|
||||
comp_ctx->builder, INT8_TYPE, wasm_stack_top, &offset, 1,
|
||||
"wasm_stack_top_max"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
new_frame = wasm_stack_top;
|
||||
|
||||
if (!(check_wasm_stack_succ = LLVMAppendBasicBlockInContext(
|
||||
comp_ctx->context, func_ctx->func, "check_wasm_stack_succ"))) {
|
||||
|
@ -471,62 +499,67 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* exec_env->wasm_stack.top += frame_size */
|
||||
offset = I32_CONST(frame_size);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(wasm_stack_top_new = LLVMBuildInBoundsGEP2(
|
||||
comp_ctx->builder, INT8_TYPE, wasm_stack_top, &offset, 1,
|
||||
"wasm_stack_top_new"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
if (!LLVMBuildStore(comp_ctx->builder, wasm_stack_top_new,
|
||||
wasm_stack_top_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
}
|
||||
#if WASM_ENABLE_GC != 0
|
||||
if (comp_ctx->enable_gc) {
|
||||
LLVMValueRef wasm_stack_top_new, frame_ref, frame_ref_ptr;
|
||||
uint32 j, k;
|
||||
|
||||
if (func_idx < import_func_count) {
|
||||
/* Only need to initialize new_frame->sp when it's import function
|
||||
otherwise they will be committed in AOT code if needed */
|
||||
|
||||
/* new_frame->sp = new_frame->lp + max_local_cell_num */
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
offset = I32_CONST(comp_ctx->pointer_size * 5);
|
||||
else
|
||||
offset = I32_CONST(offsetof(WASMInterpFrame, sp));
|
||||
/* exec_env->wasm_stack.top += frame_size */
|
||||
offset = I32_CONST(frame_size);
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(frame_sp_ptr =
|
||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, new_frame,
|
||||
&offset, 1, "frame_sp_addr"))
|
||||
|| !(frame_sp_ptr =
|
||||
LLVMBuildBitCast(comp_ctx->builder, frame_sp_ptr,
|
||||
int8_ptr_type, "frame_sp_ptr"))) {
|
||||
aot_set_last_error("llvm get frame_sp_ptr failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
offset = I32_CONST(comp_ctx->pointer_size * aot_frame_ptr_num
|
||||
+ max_local_cell_num * sizeof(uint32));
|
||||
else
|
||||
offset = I32_CONST(offsetof(WASMInterpFrame, lp)
|
||||
+ max_local_cell_num * sizeof(uint32));
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(frame_sp =
|
||||
LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE, new_frame,
|
||||
&offset, 1, "frame_sp"))) {
|
||||
if (!(wasm_stack_top_new = LLVMBuildInBoundsGEP2(
|
||||
comp_ctx->builder, INT8_TYPE, wasm_stack_top, &offset, 1,
|
||||
"wasm_stack_top_new"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
if (!LLVMBuildStore(comp_ctx->builder, frame_sp, frame_sp_ptr)) {
|
||||
if (!LLVMBuildStore(comp_ctx->builder, wasm_stack_top_new,
|
||||
wasm_stack_top_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
if (comp_ctx->enable_gc) {
|
||||
if (func_idx < import_func_count) {
|
||||
LLVMValueRef frame_sp, frame_sp_ptr;
|
||||
|
||||
/* Only need to initialize new_frame->sp when it's import function
|
||||
otherwise they will be committed in AOT code if needed */
|
||||
|
||||
/* new_frame->sp = new_frame->lp + max_local_cell_num */
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
offset = I32_CONST(comp_ctx->pointer_size * 5);
|
||||
else
|
||||
offset = I32_CONST(offsetof(WASMInterpFrame, sp));
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(frame_sp_ptr = LLVMBuildInBoundsGEP2(
|
||||
comp_ctx->builder, INT8_TYPE, new_frame, &offset, 1,
|
||||
"frame_sp_addr"))
|
||||
|| !(frame_sp_ptr =
|
||||
LLVMBuildBitCast(comp_ctx->builder, frame_sp_ptr,
|
||||
int8_ptr_type, "frame_sp_ptr"))) {
|
||||
aot_set_last_error("llvm get frame_sp_ptr failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!comp_ctx->is_jit_mode)
|
||||
offset = I32_CONST(comp_ctx->pointer_size * aot_frame_ptr_num
|
||||
+ max_local_cell_num * sizeof(uint32));
|
||||
else
|
||||
offset = I32_CONST(offsetof(WASMInterpFrame, lp)
|
||||
+ max_local_cell_num * sizeof(uint32));
|
||||
CHECK_LLVM_CONST(offset);
|
||||
if (!(frame_sp = LLVMBuildInBoundsGEP2(comp_ctx->builder, INT8_TYPE,
|
||||
new_frame, &offset, 1,
|
||||
"frame_sp"))) {
|
||||
aot_set_last_error("llvm build in bounds gep failed");
|
||||
return false;
|
||||
}
|
||||
if (!LLVMBuildStore(comp_ctx->builder, frame_sp, frame_sp_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!comp_ctx->is_jit_mode) {
|
||||
/* new_frame->frame_ref = new_frame->lp + max_local_cell_num
|
||||
+ max_stack_cell_num */
|
||||
|
@ -573,10 +606,10 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Initialize frame ref flags for import function */
|
||||
if (func_idx < import_func_count) {
|
||||
func_type = import_funcs[func_idx].func_type;
|
||||
for (i = 0, j = 0; i < func_type->param_count; i++) {
|
||||
if (aot_is_type_gc_reftype(func_type->types[i])
|
||||
&& !wasm_is_reftype_i31ref(func_type->types[i])) {
|
||||
aot_func_type = import_funcs[func_idx].func_type;
|
||||
for (i = 0, j = 0; i < aot_func_type->param_count; i++) {
|
||||
if (aot_is_type_gc_reftype(aot_func_type->types[i])
|
||||
&& !wasm_is_reftype_i31ref(aot_func_type->types[i])) {
|
||||
for (k = 0; k < comp_ctx->pointer_size / sizeof(uint32);
|
||||
k++) {
|
||||
/* frame_ref[j++] = 1 */
|
||||
|
@ -596,7 +629,7 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
else {
|
||||
uint32 value_type_cell_num =
|
||||
wasm_value_type_cell_num_internal(
|
||||
func_type->types[i], comp_ctx->pointer_size);
|
||||
aot_func_type->types[i], comp_ctx->pointer_size);
|
||||
for (k = 0; k < value_type_cell_num; k++) {
|
||||
/* frame_ref[j++] = 0 */
|
||||
offset = I32_CONST(j);
|
||||
|
@ -720,7 +753,7 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
|
||||
/* No need to initialize new_frame->sp and new_frame->ip_offset
|
||||
since they will be committed in AOT code if needed */
|
||||
since they will be committed in AOT/JIT code if needed */
|
||||
|
||||
/* exec_env->cur_frame = new_frame */
|
||||
if (!LLVMBuildStore(comp_ctx->builder, new_frame, cur_frame_ptr)) {
|
||||
|
@ -730,7 +763,7 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
if (comp_ctx->enable_perf_profiling || comp_ctx->enable_memory_profiling) {
|
||||
LLVMTypeRef param_types[2], func_type, func_ptr_type;
|
||||
LLVMValueRef param_values[2], func, res;
|
||||
LLVMValueRef param_values[2], func = NULL, res;
|
||||
char *func_name = "aot_frame_update_profile_info";
|
||||
|
||||
/* Call aot_frame_update_profile_info for AOT or
|
||||
|
@ -750,6 +783,8 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_JIT != 0 \
|
||||
&& (WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_MEMORY_PROFILING != 0)
|
||||
/* JIT mode, call the function directly */
|
||||
if (!(func = I64_CONST(
|
||||
(uint64)(uintptr_t)llvm_jit_frame_update_profile_info))
|
||||
|
@ -757,6 +792,7 @@ alloc_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
aot_set_last_error("create LLVM value failed.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (comp_ctx->is_indirect_mode) {
|
||||
int32 func_index;
|
||||
|
@ -815,7 +851,7 @@ free_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
if (comp_ctx->enable_perf_profiling) {
|
||||
LLVMTypeRef param_types[2], func_type, func_ptr_type;
|
||||
LLVMValueRef param_values[2], func, res;
|
||||
LLVMValueRef param_values[2], func = NULL, res;
|
||||
char *func_name = "aot_frame_update_profile_info";
|
||||
|
||||
/* call aot_frame_update_profile_info for AOT or
|
||||
|
@ -835,6 +871,8 @@ free_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_JIT != 0 \
|
||||
&& (WASM_ENABLE_PERF_PROFILING != 0 || WASM_ENABLE_MEMORY_PROFILING != 0)
|
||||
/* JIT mode, call the function directly */
|
||||
if (!(func = I64_CONST(
|
||||
(uint64)(uintptr_t)llvm_jit_frame_update_profile_info))
|
||||
|
@ -842,6 +880,7 @@ free_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
aot_set_last_error("create LLVM value failed.");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (comp_ctx->is_indirect_mode) {
|
||||
int32 func_index;
|
||||
|
@ -878,17 +917,19 @@ free_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
/* cur_frame = exec_env->cur_frame */
|
||||
if (!(cur_frame = LLVMBuildLoad2(comp_ctx->builder, INT8_PTR_TYPE,
|
||||
cur_frame_ptr, "cur_frame"))) {
|
||||
aot_set_last_error("llvm build load failed");
|
||||
return false;
|
||||
}
|
||||
if (comp_ctx->enable_gc) {
|
||||
/* cur_frame = exec_env->cur_frame */
|
||||
if (!(cur_frame = LLVMBuildLoad2(comp_ctx->builder, INT8_PTR_TYPE,
|
||||
cur_frame_ptr, "cur_frame"))) {
|
||||
aot_set_last_error("llvm build load failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* exec_env->wasm_stack.top = cur_frame */
|
||||
if (!LLVMBuildStore(comp_ctx->builder, cur_frame, wasm_stack_top_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
/* exec_env->wasm_stack.top = cur_frame */
|
||||
if (!LLVMBuildStore(comp_ctx->builder, cur_frame, wasm_stack_top_ptr)) {
|
||||
aot_set_last_error("llvm build store failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* exec_env->cur_frame = prev_frame */
|
||||
|
@ -900,8 +941,8 @@ free_frame_for_aot_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) \
|
||||
|| (WASM_ENABLE_PERF_PROFILING != 0) */
|
||||
#endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 || \
|
||||
WASM_ENABLE_JIT_STACK_FRAME != 0 */
|
||||
|
||||
/**
|
||||
* Check whether the app address and its buffer are inside the linear memory,
|
||||
|
@ -1138,7 +1179,7 @@ commit_params_to_frame_of_import_func(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx, bool tail_call, const uint8 *frame_ip_call)
|
||||
uint32 func_idx, bool tail_call)
|
||||
{
|
||||
uint32 import_func_count = comp_ctx->comp_data->import_func_count;
|
||||
AOTImportFunc *import_funcs = comp_ctx->comp_data->import_funcs;
|
||||
|
@ -1179,28 +1220,27 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Commit stack operands, sp and ip */
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_call))
|
||||
/* Commit sp if gc is enabled and commit ip for func call */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->enable_gc,
|
||||
true))
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
if (!alloc_frame_for_aot_func(comp_ctx, func_ctx, func_idx))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get param cell number */
|
||||
param_cell_num = func_type->param_cell_num;
|
||||
|
@ -1521,20 +1561,18 @@ aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
if (!free_frame_for_aot_func(comp_ctx, func_ctx))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, false))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = true;
|
||||
fail:
|
||||
|
@ -1705,8 +1743,7 @@ call_aot_call_indirect_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_idx, uint32 tbl_idx,
|
||||
const uint8 *frame_ip_call_indirect)
|
||||
uint32 type_idx, uint32 tbl_idx)
|
||||
{
|
||||
AOTFuncType *func_type;
|
||||
LLVMValueRef tbl_idx_value, elem_idx, func_idx;
|
||||
|
@ -1755,21 +1792,20 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
func_type);
|
||||
/* Commit stack operands, sp and ip */
|
||||
if (comp_ctx->aot_frame) {
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
if (comp_ctx->enable_gc && !aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_call_indirect))
|
||||
/* Commit sp if gc is enabled and always commit ip for call_indirect */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->enable_gc,
|
||||
true))
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
func_param_count = func_type->param_count;
|
||||
func_result_count = func_type->result_count;
|
||||
|
@ -2085,14 +2121,14 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
/* TODO: use current frame instead of allocating new frame
|
||||
for WASM_OP_RETURN_CALL_INDIRECT */
|
||||
if (!call_aot_alloc_frame_func(comp_ctx, func_ctx, func_idx))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add basic blocks */
|
||||
block_call_import = LLVMAppendBasicBlockInContext(
|
||||
|
@ -2275,20 +2311,18 @@ aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
PUSH(result_phis[i], func_type->types[func_param_count + i]);
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
if (!free_frame_for_aot_func(comp_ctx, func_ctx))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, false))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = true;
|
||||
|
||||
|
@ -2354,7 +2388,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx, const uint8 *frame_ip_ref_func)
|
||||
uint32 func_idx)
|
||||
{
|
||||
LLVMValueRef ref_idx;
|
||||
#if WASM_ENABLE_GC != 0
|
||||
|
@ -2371,8 +2405,8 @@ aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_ref_func))
|
||||
/* Commit sp and ip if gc is enabled */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
if (!aot_call_aot_create_func_obj(comp_ctx, func_ctx, ref_idx,
|
||||
|
@ -2396,8 +2430,7 @@ fail:
|
|||
#if WASM_ENABLE_GC != 0
|
||||
bool
|
||||
aot_compile_op_call_ref(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_idx, bool tail_call,
|
||||
const uint8 *frame_ip_call_ref)
|
||||
uint32 type_idx, bool tail_call)
|
||||
{
|
||||
AOTFuncType *func_type;
|
||||
LLVMValueRef func_obj, func_idx;
|
||||
|
@ -2431,21 +2464,20 @@ aot_compile_op_call_ref(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
/* Commit stack operands, sp and ip to aot frame */
|
||||
if (comp_ctx->aot_frame) {
|
||||
/* Note that GC is enabled, no need to check it again */
|
||||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_call_ref))
|
||||
/* Commit sp if gc is enabled and always commit ip for call_ref */
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, true))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
POP_GC_REF(func_obj);
|
||||
|
||||
|
@ -2586,14 +2618,14 @@ aot_compile_op_call_ref(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
/* TODO: use current frame instead of allocating new frame
|
||||
for WASM_OP_RETURN_CALL_REF */
|
||||
if (!call_aot_alloc_frame_func(comp_ctx, func_ctx, func_idx))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add basic blocks */
|
||||
block_call_import = LLVMAppendBasicBlockInContext(
|
||||
|
@ -2783,20 +2815,18 @@ aot_compile_op_call_ref(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
PUSH(result_phis[i], func_type->types[func_param_count + i]);
|
||||
}
|
||||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
|
||||
if (comp_ctx->enable_aux_stack_frame) {
|
||||
#if WASM_ENABLE_AOT_STACK_FRAME != 0 || WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
if (!free_frame_for_aot_func(comp_ctx, func_ctx))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, false))
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = true;
|
||||
|
||||
|
|
|
@ -14,13 +14,11 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_op_call(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx, bool tail_call,
|
||||
const uint8 *frame_ip_call);
|
||||
uint32 func_idx, bool tail_call);
|
||||
|
||||
bool
|
||||
aot_compile_op_call_indirect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_idx, uint32 tbl_idx,
|
||||
const uint8 *frame_ip_call_indirect);
|
||||
uint32 type_idx, uint32 tbl_idx);
|
||||
|
||||
bool
|
||||
aot_compile_op_ref_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
@ -30,13 +28,12 @@ aot_compile_op_ref_is_null(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
|||
|
||||
bool
|
||||
aot_compile_op_ref_func(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 func_idx, const uint8 *frame_ip_ref_func);
|
||||
uint32 func_idx);
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
bool
|
||||
aot_compile_op_call_ref(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_idx, bool tail_call,
|
||||
const uint8 *frame_ip_call_ref);
|
||||
uint32 type_idx, bool tail_call);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -529,8 +529,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_struct_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_index, bool init_with_default,
|
||||
const uint8 *frame_ip_struct_new)
|
||||
uint32 type_index, bool init_with_default)
|
||||
{
|
||||
LLVMValueRef rtt_type, struct_obj, cmp;
|
||||
LLVMBasicBlockRef check_rtt_type_succ, check_struct_obj_succ;
|
||||
|
@ -538,8 +537,7 @@ aot_compile_op_struct_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_struct_new))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
/* Generate call wasm_rtt_type_new and check for exception */
|
||||
|
@ -1116,8 +1114,7 @@ fail:
|
|||
bool
|
||||
aot_compile_op_array_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_index, bool init_with_default,
|
||||
bool fixed_size, uint32 array_len,
|
||||
const uint8 *frame_ip_array_new)
|
||||
bool fixed_size, uint32 array_len)
|
||||
{
|
||||
LLVMValueRef array_length, array_elem = NULL, array_obj;
|
||||
LLVMValueRef rtt_type, cmp, elem_idx;
|
||||
|
@ -1131,8 +1128,7 @@ aot_compile_op_array_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_array_new))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
/* Generate call aot_rtt_type_new and check for exception */
|
||||
|
@ -1241,8 +1237,7 @@ fail:
|
|||
bool
|
||||
aot_compile_op_array_new_data(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 type_index,
|
||||
uint32 data_seg_index,
|
||||
const uint8 *frame_ip_array_new_data)
|
||||
uint32 data_seg_index)
|
||||
{
|
||||
LLVMValueRef array_length, data_seg_offset, rtt_type,
|
||||
elem_size = NULL, array_elem, array_obj, cmp;
|
||||
|
@ -1255,8 +1250,7 @@ aot_compile_op_array_new_data(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_array_new_data))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
/* Generate call aot_rtt_type_new and check for exception */
|
||||
|
@ -2083,8 +2077,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_extern_externalize(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_extern_externalize)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef gc_obj, cmp, external_obj_phi, externref_obj;
|
||||
LLVMBasicBlockRef block_curr, block_obj_non_null, block_end;
|
||||
|
@ -2092,8 +2085,7 @@ aot_compile_op_extern_externalize(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_extern_externalize))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_GC_REF(gc_obj);
|
||||
|
|
|
@ -39,8 +39,7 @@ aot_compile_op_ref_as_non_null(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_struct_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_index, bool init_with_default,
|
||||
const uint8 *frame_ip_struct_new);
|
||||
uint32 type_index, bool init_with_default);
|
||||
|
||||
bool
|
||||
aot_compile_op_struct_get(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
|
@ -53,14 +52,12 @@ aot_compile_op_struct_set(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
bool
|
||||
aot_compile_op_array_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 type_index, bool init_with_default,
|
||||
bool fixed_size, uint32 array_len,
|
||||
const uint8 *frame_ip_array_new);
|
||||
bool fixed_size, uint32 array_len);
|
||||
|
||||
bool
|
||||
aot_compile_op_array_new_data(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 type_index,
|
||||
uint32 data_seg_index,
|
||||
const uint8 *frame_ip_array_new_data);
|
||||
uint32 data_seg_index);
|
||||
|
||||
bool
|
||||
aot_array_obj_length(AOTCompContext *comp_ctx, LLVMValueRef array_obj,
|
||||
|
@ -111,8 +108,7 @@ aot_compile_op_extern_internalize(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_extern_externalize(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_extern_externalize);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1504,13 +1504,11 @@ aot_compile_op_atomic_wait(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
|
||||
PUSH_I32(ret_value);
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
/* Insert suspend check point */
|
||||
if (comp_ctx->enable_thread_mgr) {
|
||||
if (!check_suspend_flags(comp_ctx, func_ctx, false))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
fail:
|
||||
|
|
|
@ -371,7 +371,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 encoding, const uint8 *frame_ip_stringref_new)
|
||||
uint32 encoding)
|
||||
{
|
||||
LLVMValueRef maddr, byte_length, offset, str_obj, stringref_obj;
|
||||
LLVMValueRef param_values[5], func, value;
|
||||
|
@ -381,8 +381,7 @@ aot_compile_op_string_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_stringref_new))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_I32(byte_length);
|
||||
|
@ -427,7 +426,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 contents, const uint8 *frame_ip_string_const)
|
||||
uint32 contents)
|
||||
{
|
||||
LLVMValueRef param_values[2], func, value, str_obj, stringref_obj;
|
||||
LLVMTypeRef param_types[2], ret_type, func_type, func_ptr_type;
|
||||
|
@ -436,8 +435,7 @@ aot_compile_op_string_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_const))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
param_types[0] = INT8_PTR_TYPE;
|
||||
|
@ -556,8 +554,7 @@ fail:
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_concat)
|
||||
aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef param_values[2], func, value, str_obj_lhs, str_obj_rhs,
|
||||
stringref_obj_lhs, stringref_obj_rhs, stringref_obj_new;
|
||||
|
@ -567,8 +564,7 @@ aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_concat))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_GC_REF(stringref_obj_rhs);
|
||||
|
@ -695,8 +691,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_as_wtf8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_wtf8)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef str_obj, stringref_obj, stringview_wtf8_obj;
|
||||
DEFINE_STRINGREF_CHECK_VAR();
|
||||
|
@ -704,8 +699,7 @@ aot_compile_op_string_as_wtf8(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_as_wtf8))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_GC_REF(stringref_obj);
|
||||
|
@ -830,8 +824,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf8_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_wtf8_slice)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
|
||||
DEFINE_STRINGREF_CHECK_VAR();
|
||||
|
@ -839,8 +832,7 @@ aot_compile_op_stringview_wtf8_slice(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_wtf8_slice))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_I32(start);
|
||||
|
@ -869,8 +861,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_as_wtf16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_wtf16)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef str_obj, stringref_obj, stringview_wtf16_obj;
|
||||
DEFINE_STRINGREF_CHECK_VAR();
|
||||
|
@ -878,8 +869,7 @@ aot_compile_op_string_as_wtf16(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_as_wtf16))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_GC_REF(stringref_obj);
|
||||
|
@ -1045,8 +1035,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf16_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_wtf16_slice)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef stringref_obj, start, end, stringref_obj_new, value;
|
||||
DEFINE_STRINGREF_CHECK_VAR();
|
||||
|
@ -1054,8 +1043,7 @@ aot_compile_op_stringview_wtf16_slice(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_wtf16_slice))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_I32(end);
|
||||
|
@ -1084,8 +1072,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_as_iter(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_iter)
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef stringref_obj, stringview_iter_obj, str_obj;
|
||||
DEFINE_STRINGREF_CHECK_VAR();
|
||||
|
@ -1093,8 +1080,7 @@ aot_compile_op_string_as_iter(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_as_iter))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_GC_REF(stringref_obj);
|
||||
|
@ -1258,9 +1244,8 @@ aot_compile_op_stringview_iter_rewind(AOTCompContext *comp_ctx,
|
|||
}
|
||||
|
||||
bool
|
||||
aot_compile_op_stringview_iter_slice(
|
||||
AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_stringview_iter_slice)
|
||||
aot_compile_op_stringview_iter_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx)
|
||||
{
|
||||
LLVMValueRef stringview_iter_obj, start, end, stringref_obj_new, value,
|
||||
iter_pos_addr, code_points_count;
|
||||
|
@ -1269,8 +1254,7 @@ aot_compile_op_stringview_iter_slice(
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_stringview_iter_slice))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_I32(code_points_count);
|
||||
|
@ -1315,8 +1299,7 @@ fail:
|
|||
|
||||
bool
|
||||
aot_compile_op_string_new_array(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 encoding,
|
||||
const uint8 *frame_ip_string_new_array)
|
||||
AOTFuncContext *func_ctx, uint32 encoding)
|
||||
{
|
||||
LLVMValueRef start, end, count, str_obj, stringref_obj, array_obj,
|
||||
elem_data_ptr;
|
||||
|
@ -1327,8 +1310,7 @@ aot_compile_op_string_new_array(AOTCompContext *comp_ctx,
|
|||
if (!aot_gen_commit_values(comp_ctx->aot_frame))
|
||||
return false;
|
||||
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, comp_ctx->aot_frame->sp,
|
||||
frame_ip_string_new_array))
|
||||
if (!aot_gen_commit_sp_ip(comp_ctx->aot_frame, true, true))
|
||||
return false;
|
||||
|
||||
POP_I32(end);
|
||||
|
|
|
@ -14,12 +14,11 @@ extern "C" {
|
|||
|
||||
bool
|
||||
aot_compile_op_string_new(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 encoding, const uint8 *frame_ip_stringref_new);
|
||||
uint32 encoding);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_const(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
uint32 contents,
|
||||
const uint8 *frame_ip_string_const);
|
||||
uint32 contents);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_measure(AOTCompContext *comp_ctx,
|
||||
|
@ -30,8 +29,8 @@ aot_compile_op_string_encode(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
|||
uint32 mem_idx, uint32 encoding);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_concat(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_concat);
|
||||
aot_compile_op_string_concat(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_eq(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx);
|
||||
|
@ -42,8 +41,7 @@ aot_compile_op_string_is_usv_sequence(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_string_as_wtf8(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_wtf8);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf8_advance(AOTCompContext *comp_ctx,
|
||||
|
@ -56,13 +54,11 @@ aot_compile_op_stringview_wtf8_encode(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf8_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_wtf8_slice);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_as_wtf16(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_wtf16);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf16_length(AOTCompContext *comp_ctx,
|
||||
|
@ -79,13 +75,11 @@ aot_compile_op_stringview_wtf16_encode(AOTCompContext *comp_ctx,
|
|||
|
||||
bool
|
||||
aot_compile_op_stringview_wtf16_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_wtf16_slice);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_as_iter(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_string_as_iter);
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_stringview_iter_next(AOTCompContext *comp_ctx,
|
||||
|
@ -100,14 +94,12 @@ aot_compile_op_stringview_iter_rewind(AOTCompContext *comp_ctx,
|
|||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_stringview_iter_slice(
|
||||
AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
|
||||
const uint8 *frame_ip_stringview_iter_slice);
|
||||
aot_compile_op_stringview_iter_slice(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_new_array(AOTCompContext *comp_ctx,
|
||||
AOTFuncContext *func_ctx, uint32 encoding,
|
||||
const uint8 *frame_ip_string_new_array);
|
||||
AOTFuncContext *func_ctx, uint32 encoding);
|
||||
|
||||
bool
|
||||
aot_compile_op_string_encode_array(AOTCompContext *comp_ctx,
|
||||
|
|
|
@ -117,6 +117,8 @@ typedef struct AOTCompFrame {
|
|||
struct AOTCompContext *comp_ctx;
|
||||
/* The current function context */
|
||||
struct AOTFuncContext *func_ctx;
|
||||
/* The current instruction pointer which is being compiled */
|
||||
const uint8 *frame_ip;
|
||||
|
||||
/* Max local slot number */
|
||||
uint32 max_local_cell_num;
|
||||
|
@ -241,6 +243,8 @@ typedef struct AOTFuncContext {
|
|||
LLVMBasicBlockRef got_exception_block;
|
||||
LLVMBasicBlockRef func_return_block;
|
||||
LLVMValueRef exception_id_phi;
|
||||
/* current ip when exception is thrown */
|
||||
LLVMValueRef exception_ip_phi;
|
||||
LLVMValueRef func_type_indexes;
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
LLVMMetadataRef debug_func;
|
||||
|
|
|
@ -870,8 +870,8 @@ struct WASMModule {
|
|||
uint64 buf_code_size;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_DEBUG_AOT != 0 \
|
||||
|| WASM_ENABLE_FAST_JIT != 0
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \
|
||||
|| WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0
|
||||
uint8 *load_addr;
|
||||
uint64 load_size;
|
||||
#endif
|
||||
|
|
|
@ -6034,6 +6034,229 @@ fast_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
|||
#endif /* end of WASM_ENABLE_FAST_JIT != 0 */
|
||||
|
||||
#if WASM_ENABLE_JIT != 0
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_PERF_PROFILING != 0 \
|
||||
|| WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
#if WASM_ENABLE_GC == 0
|
||||
bool
|
||||
llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
||||
{
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
WASMInterpFrame *cur_frame, *frame;
|
||||
uint32 size = (uint32)offsetof(WASMInterpFrame, lp);
|
||||
|
||||
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
cur_frame = exec_env->cur_frame;
|
||||
if (!cur_frame)
|
||||
frame = (WASMInterpFrame *)exec_env->wasm_stack.bottom;
|
||||
else
|
||||
frame = (WASMInterpFrame *)((uint8 *)cur_frame + size);
|
||||
|
||||
if ((uint8 *)frame + size > exec_env->wasm_stack.top_boundary) {
|
||||
wasm_set_exception(module_inst, "wasm operand stack overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->function = module_inst->e->functions + func_index;
|
||||
/* No need to initialize ip, it will be committed in jitted code
|
||||
when needed */
|
||||
/* frame->ip = NULL; */
|
||||
frame->prev_frame = cur_frame;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = os_time_get_boot_microsecond();
|
||||
#endif
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
{
|
||||
uint32 wasm_stack_used =
|
||||
(uint8 *)frame + size - exec_env->wasm_stack.bottom;
|
||||
if (wasm_stack_used > exec_env->max_wasm_stack_used)
|
||||
exec_env->max_wasm_stack_used = wasm_stack_used;
|
||||
}
|
||||
#endif
|
||||
|
||||
exec_env->cur_frame = frame;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
llvm_jit_free_frame_internal(WASMExecEnv *exec_env)
|
||||
{
|
||||
WASMInterpFrame *frame = exec_env->cur_frame;
|
||||
WASMInterpFrame *prev_frame = frame->prev_frame;
|
||||
|
||||
bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
if (frame->function) {
|
||||
frame->function->total_exec_time +=
|
||||
os_time_get_boot_microsecond() - frame->time_started;
|
||||
frame->function->total_exec_cnt++;
|
||||
}
|
||||
#endif
|
||||
exec_env->cur_frame = prev_frame;
|
||||
}
|
||||
|
||||
void
|
||||
llvm_jit_free_frame(WASMExecEnv *exec_env)
|
||||
{
|
||||
llvm_jit_free_frame_internal(exec_env);
|
||||
}
|
||||
|
||||
#else /* else of WASM_ENABLE_GC == 0 */
|
||||
|
||||
bool
|
||||
llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
||||
{
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMModule *module;
|
||||
WASMInterpFrame *frame;
|
||||
uint32 size, max_local_cell_num, max_stack_cell_num;
|
||||
|
||||
bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
module_inst = (WASMModuleInstance *)exec_env->module_inst;
|
||||
module = module_inst->module;
|
||||
|
||||
if (func_index >= func_index - module->import_function_count) {
|
||||
WASMFunction *func =
|
||||
module->functions[func_index - module->import_function_count];
|
||||
|
||||
max_local_cell_num = func->param_cell_num + func->local_cell_num;
|
||||
max_stack_cell_num = func->max_stack_cell_num;
|
||||
}
|
||||
else {
|
||||
WASMFunctionImport *func =
|
||||
&((module->import_functions + func_index)->u.function);
|
||||
|
||||
max_local_cell_num = func->func_type->param_cell_num > 2
|
||||
? func->func_type->param_cell_num
|
||||
: 2;
|
||||
max_stack_cell_num = 0;
|
||||
}
|
||||
|
||||
size =
|
||||
wasm_interp_interp_frame_size(max_local_cell_num + max_stack_cell_num);
|
||||
|
||||
frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
|
||||
if (!frame) {
|
||||
wasm_set_exception(module_inst, "wasm operand stack overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->function = module_inst->e->functions + func_index;
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = os_time_get_boot_microsecond();
|
||||
#endif
|
||||
frame->prev_frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||
|
||||
/* No need to initialize ip, it will be committed in jitted code
|
||||
when needed */
|
||||
/* frame->ip = NULL; */
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
frame->sp = frame->lp + max_local_cell_num;
|
||||
|
||||
/* Initialize frame ref flags for import function */
|
||||
if (func_index < module->import_function_count) {
|
||||
WASMFunctionImport *func =
|
||||
&((module->import_functions + func_index)->u.function);
|
||||
WASMFuncType *func_type = func->func_type;
|
||||
/* native function doesn't have operand stack and label stack */
|
||||
uint8 *frame_ref = (uint8 *)frame->sp;
|
||||
uint32 i, j, k, value_type_cell_num;
|
||||
|
||||
for (i = 0, j = 0; i < func_type->param_count; i++) {
|
||||
if (wasm_is_type_reftype(func_type->types[i])
|
||||
&& !wasm_is_reftype_i31ref(func_type->types[i])) {
|
||||
frame_ref[j++] = 1;
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
frame_ref[j++] = 1;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
value_type_cell_num =
|
||||
wasm_value_type_cell_num(func_type->types[i]);
|
||||
for (k = 0; k < value_type_cell_num; k++)
|
||||
frame_ref[j++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
wasm_exec_env_set_cur_frame(exec_env, frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void
|
||||
llvm_jit_free_frame_internal(WASMExecEnv *exec_env)
|
||||
{
|
||||
WASMInterpFrame *frame;
|
||||
WASMInterpFrame *prev_frame;
|
||||
|
||||
bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||
prev_frame = frame->prev_frame;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
if (frame->function) {
|
||||
frame->function->total_exec_time +=
|
||||
os_time_get_boot_microsecond() - frame->time_started;
|
||||
frame->function->total_exec_cnt++;
|
||||
}
|
||||
#endif
|
||||
wasm_exec_env_free_wasm_frame(exec_env, frame);
|
||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||
}
|
||||
|
||||
void
|
||||
llvm_jit_free_frame(WASMExecEnv *exec_env)
|
||||
{
|
||||
llvm_jit_free_frame_internal(exec_env);
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_GC == 0 */
|
||||
|
||||
void
|
||||
llvm_jit_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
|
||||
{
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
WASMInterpFrame *cur_frame = exec_env->cur_frame;
|
||||
|
||||
if (alloc_frame) {
|
||||
cur_frame->time_started = (uintptr_t)os_time_get_boot_microsecond();
|
||||
}
|
||||
else {
|
||||
if (cur_frame->function) {
|
||||
cur_frame->function->total_exec_time +=
|
||||
os_time_get_boot_microsecond() - cur_frame->time_started;
|
||||
cur_frame->function->total_exec_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
if (alloc_frame) {
|
||||
#if WASM_ENABLE_GC == 0
|
||||
uint32 wasm_stack_used = (uint8 *)exec_env->cur_frame
|
||||
+ (uint32)offsetof(WASMInterpFrame, lp)
|
||||
- exec_env->wasm_stack.bottom;
|
||||
#else
|
||||
uint32 wasm_stack_used =
|
||||
exec_env->wasm_stack.top - exec_env->wasm_stack.bottom;
|
||||
#endif
|
||||
if (wasm_stack_used > exec_env->max_wasm_stack_used)
|
||||
exec_env->max_wasm_stack_used = wasm_stack_used;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 \
|
||||
|| WASM_ENABLE_PERF_PROFILING != 0 \
|
||||
|| WASM_ENABLE_JIT_STACK_FRAME != 0 */
|
||||
|
||||
static bool
|
||||
llvm_jit_call_func_bytecode(WASMModuleInstance *module_inst,
|
||||
WASMExecEnv *exec_env,
|
||||
|
@ -6147,7 +6370,7 @@ fail:
|
|||
|
||||
#if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0) \
|
||||
|| (WASM_ENABLE_JIT_STACK_FRAME != 0)
|
||||
llvm_jit_free_frame(exec_env);
|
||||
llvm_jit_free_frame_internal(exec_env);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -6121,7 +6121,8 @@ wasm_loader_load(uint8 *buf, uint32 size,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_FAST_JIT != 0 \
|
||||
|| WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_JIT != 0
|
||||
module->load_addr = (uint8 *)buf;
|
||||
module->load_size = size;
|
||||
#endif
|
||||
|
|
|
@ -3177,7 +3177,8 @@ wasm_loader_load(uint8 *buf, uint32 size, char *error_buf,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
#if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_DUMP_CALL_STACK != 0 \
|
||||
|| WASM_ENABLE_JIT != 0
|
||||
module->load_addr = (uint8 *)buf;
|
||||
module->load_size = size;
|
||||
#endif
|
||||
|
|
|
@ -3601,7 +3601,7 @@ wasm_interp_create_call_stack(struct WASMExecEnv *exec_env)
|
|||
frame.func_offset = 0;
|
||||
}
|
||||
else {
|
||||
frame.func_offset = (uint32)(cur_frame->ip - func_code_base);
|
||||
frame.func_offset = (uint32)(cur_frame->ip - module->load_addr);
|
||||
}
|
||||
|
||||
/* look for the function name */
|
||||
|
@ -3663,13 +3663,13 @@ wasm_interp_create_call_stack(struct WASMExecEnv *exec_env)
|
|||
}
|
||||
bh_memcpy_s(frame.lp, lp_size, cur_frame->lp, lp_size);
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
frame.sp = frame.lp + (cur_frame->sp - cur_frame->lp);
|
||||
#else
|
||||
/* for fast-interp, let frame sp point to the end of the frame */
|
||||
frame.sp = frame.lp + all_cell_num;
|
||||
#endif
|
||||
#if WASM_ENABLE_GC != 0
|
||||
frame.frame_ref = (uint8 *)frame.lp
|
||||
+ (wasm_interp_get_frame_ref(cur_frame)
|
||||
- (uint8 *)cur_frame->lp);
|
||||
|
@ -3734,15 +3734,36 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
|
|||
}
|
||||
|
||||
/* function name not exported, print number instead */
|
||||
if (frame.func_name_wp == NULL) {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " $f%" PRIu32 "\n", n, frame.func_index);
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
if (module_inst->e->running_mode == Mode_Fast_JIT
|
||||
|| module_inst->e->running_mode == Mode_Multi_Tier_JIT) {
|
||||
/* Fast JIT doesn't support committing ip (instruction
|
||||
pointer) yet */
|
||||
if (frame.func_name_wp == NULL) {
|
||||
line_length = snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " $f%" PRIu32 "\n", n,
|
||||
frame.func_index);
|
||||
}
|
||||
else {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n",
|
||||
n, frame.func_name_wp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n", n,
|
||||
frame.func_name_wp);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (frame.func_name_wp == NULL) {
|
||||
line_length =
|
||||
snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " $f%" PRIu32 " (0x%04x)\n", n,
|
||||
frame.func_index, frame.func_offset);
|
||||
}
|
||||
else {
|
||||
line_length = snprintf(line_buf, sizeof(line_buf),
|
||||
"#%02" PRIu32 " %s (0x%04x)\n", n,
|
||||
frame.func_name_wp, frame.func_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (line_length >= sizeof(line_buf)) {
|
||||
|
@ -4123,141 +4144,6 @@ llvm_jit_table_grow(WASMModuleInstance *module_inst, uint32 tbl_idx,
|
|||
}
|
||||
#endif /* end of WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
|
||||
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_PERF_PROFILING != 0 \
|
||||
|| WASM_ENABLE_JIT_STACK_FRAME != 0
|
||||
bool
|
||||
llvm_jit_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
|
||||
{
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMModule *module;
|
||||
WASMInterpFrame *frame;
|
||||
uint32 size, max_local_cell_num, max_stack_cell_num;
|
||||
|
||||
bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
module_inst = (WASMModuleInstance *)exec_env->module_inst;
|
||||
module = module_inst->module;
|
||||
|
||||
if (func_index >= func_index - module->import_function_count) {
|
||||
WASMFunction *func =
|
||||
module->functions[func_index - module->import_function_count];
|
||||
|
||||
max_local_cell_num = func->param_cell_num + func->local_cell_num;
|
||||
max_stack_cell_num = func->max_stack_cell_num;
|
||||
}
|
||||
else {
|
||||
WASMFunctionImport *func =
|
||||
&((module->import_functions + func_index)->u.function);
|
||||
|
||||
max_local_cell_num = func->func_type->param_cell_num > 2
|
||||
? func->func_type->param_cell_num
|
||||
: 2;
|
||||
max_stack_cell_num = 0;
|
||||
}
|
||||
|
||||
size =
|
||||
wasm_interp_interp_frame_size(max_local_cell_num + max_stack_cell_num);
|
||||
|
||||
frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
|
||||
if (!frame) {
|
||||
wasm_set_exception(module_inst, "wasm operand stack overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->function = module_inst->e->functions + func_index;
|
||||
frame->ip = NULL;
|
||||
frame->sp = frame->lp + max_local_cell_num;
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = os_time_get_boot_microsecond();
|
||||
#endif
|
||||
frame->prev_frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
/* Initialize frame ref flags for import function */
|
||||
if (func_index < module->import_function_count) {
|
||||
WASMFunctionImport *func =
|
||||
&((module->import_functions + func_index)->u.function);
|
||||
WASMFuncType *func_type = func->func_type;
|
||||
/* native function doesn't have operand stack and label stack */
|
||||
uint8 *frame_ref = (uint8 *)frame->sp;
|
||||
uint32 i, j, k, value_type_cell_num;
|
||||
|
||||
for (i = 0, j = 0; i < func_type->param_count; i++) {
|
||||
if (wasm_is_type_reftype(func_type->types[i])
|
||||
&& !wasm_is_reftype_i31ref(func_type->types[i])) {
|
||||
frame_ref[j++] = 1;
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
frame_ref[j++] = 1;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
value_type_cell_num =
|
||||
wasm_value_type_cell_num(func_type->types[i]);
|
||||
for (k = 0; k < value_type_cell_num; k++)
|
||||
frame_ref[j++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
wasm_exec_env_set_cur_frame(exec_env, frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
llvm_jit_free_frame(WASMExecEnv *exec_env)
|
||||
{
|
||||
WASMInterpFrame *frame;
|
||||
WASMInterpFrame *prev_frame;
|
||||
|
||||
bh_assert(exec_env->module_inst->module_type == Wasm_Module_Bytecode);
|
||||
|
||||
frame = wasm_exec_env_get_cur_frame(exec_env);
|
||||
prev_frame = frame->prev_frame;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
if (frame->function) {
|
||||
frame->function->total_exec_time +=
|
||||
os_time_get_boot_microsecond() - frame->time_started;
|
||||
frame->function->total_exec_cnt++;
|
||||
}
|
||||
#endif
|
||||
wasm_exec_env_free_wasm_frame(exec_env, frame);
|
||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||
}
|
||||
|
||||
void
|
||||
llvm_jit_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
|
||||
{
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
WASMInterpFrame *cur_frame = exec_env->cur_frame;
|
||||
|
||||
if (alloc_frame) {
|
||||
cur_frame->time_started = (uintptr_t)os_time_get_boot_microsecond();
|
||||
}
|
||||
else {
|
||||
if (cur_frame->function) {
|
||||
cur_frame->function->total_exec_time +=
|
||||
os_time_get_boot_microsecond() - cur_frame->time_started;
|
||||
cur_frame->function->total_exec_cnt++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MEMORY_PROFILING != 0
|
||||
if (alloc_frame) {
|
||||
uint32 wasm_stack_used =
|
||||
exec_env->wasm_stack.top - exec_env->wasm_stack.bottom;
|
||||
if (wasm_stack_used > exec_env->max_wasm_stack_used)
|
||||
exec_env->max_wasm_stack_used = wasm_stack_used;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 \
|
||||
|| WASM_ENABLE_PERF_PROFILING != 0 \
|
||||
|| WASM_ENABLE_JIT_STACK_FRAME != 0 */
|
||||
|
||||
#if WASM_ENABLE_GC != 0
|
||||
void *
|
||||
llvm_jit_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
||||
|
|
Loading…
Reference in New Issue
Block a user