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:
Wenyong Huang 2024-01-08 11:18:49 +08:00 committed by GitHub
parent cc23a09d5e
commit d31455fc4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 761 additions and 574 deletions

View File

@ -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)) {

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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)) {

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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,