Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement aot_alloc_frame/aot_free_frame with LLVM IRs #2830

Merged
3 changes: 2 additions & 1 deletion core/iwasm/aot/aot_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ typedef struct {
#if WASM_ENABLE_AOT_STACK_FRAME != 0
#define REG_AOT_TRACE_SYM() \
REG_SYM(aot_alloc_frame), \
REG_SYM(aot_free_frame),
REG_SYM(aot_free_frame), \
REG_SYM(aot_frame_update_profile_info),
#else
#define REG_AOT_TRACE_SYM()
#endif
Expand Down
41 changes: 41 additions & 0 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ bh_static_assert(offsetof(WASMExecEnv, aux_stack_bottom)
bh_static_assert(offsetof(WASMExecEnv, native_symbol) == 8 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, native_stack_top_min)
== 9 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, wasm_stack.top_boundary)
== 10 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, wasm_stack.top)
== 11 * sizeof(uintptr_t));
bh_static_assert(offsetof(WASMExecEnv, wasm_stack.bottom)
== 12 * sizeof(uintptr_t));

bh_static_assert(offsetof(AOTModuleInstance, memories) == 1 * sizeof(uint64));
bh_static_assert(offsetof(AOTModuleInstance, func_ptrs) == 5 * sizeof(uint64));
Expand All @@ -49,6 +55,11 @@ bh_static_assert(offsetof(AOTTableInstance, elems) == 24);

bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);

bh_static_assert(offsetof(AOTFrame, prev_frame) == sizeof(uintptr_t) * 0);
bh_static_assert(offsetof(AOTFrame, func_index) == sizeof(uintptr_t) * 1);
bh_static_assert(offsetof(AOTFrame, time_started) == sizeof(uintptr_t) * 2);
bh_static_assert(offsetof(AOTFrame, func_perf_prof_info)
== sizeof(uintptr_t) * 3);
bh_static_assert(offsetof(AOTFrame, ip_offset) == sizeof(uintptr_t) * 4);
bh_static_assert(offsetof(AOTFrame, sp) == sizeof(uintptr_t) * 5);
bh_static_assert(offsetof(AOTFrame, frame_ref) == sizeof(uintptr_t) * 6);
Expand Down Expand Up @@ -3237,6 +3248,36 @@ aot_free_frame(WASMExecEnv *exec_env)
wasm_exec_env_free_wasm_frame(exec_env, cur_frame);
exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
}

void
aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
{
#if WASM_ENABLE_PERF_PROFILING != 0
AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
AOTFuncPerfProfInfo *func_perf_prof =
module_inst->func_perf_profilings + cur_frame->func_index;

if (alloc_frame) {
cur_frame->time_started = (uintptr_t)os_time_get_boot_microsecond();
cur_frame->func_perf_prof_info = func_perf_prof;
}
else {
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

#if WASM_ENABLE_MEMORY_PROFILING != 0
if (alloc_frame) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems alloc_frame means start of the function, is it correct to measure stack use at the start of the function rather than end of the function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it does the same thing in aot_alloc_frame, which calls wasm_exec_env_alloc_wasm_frame, and wasm_exec_env_alloc_wasm_frame sets exec_env->max_wasm_stack_used if needed:

https://github.com/bytecodealliance/wasm-micro-runtime/blob/dev/gc_refactor/core/iwasm/aot/aot_runtime.c#L3173

https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/common/wasm_exec_env.h#L234-L235

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_AOT_STACK_FRAME != 0 */

#if WASM_ENABLE_DUMP_CALL_STACK != 0
Expand Down
3 changes: 3 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,9 @@ aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index);
void
aot_free_frame(WASMExecEnv *exec_env);

void
aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame);

bool
aot_create_call_stack(struct WASMExecEnv *exec_env);

Expand Down
9 changes: 5 additions & 4 deletions core/iwasm/common/wasm_exec_env.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
uint32 stack_size)
{
uint64 total_size =
offsetof(WASMExecEnv, wasm_stack.s.bottom) + (uint64)stack_size;
offsetof(WASMExecEnv, wasm_stack_u.bottom) + (uint64)stack_size;
WASMExecEnv *exec_env;

if (total_size >= UINT32_MAX
Expand Down Expand Up @@ -68,9 +68,10 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,

exec_env->module_inst = module_inst;
exec_env->wasm_stack_size = stack_size;
exec_env->wasm_stack.s.top_boundary =
exec_env->wasm_stack.s.bottom + stack_size;
exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
exec_env->wasm_stack.bottom = exec_env->wasm_stack_u.bottom;
exec_env->wasm_stack.top_boundary =
exec_env->wasm_stack.bottom + stack_size;
exec_env->wasm_stack.top = exec_env->wasm_stack.bottom;

#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
Expand Down
38 changes: 19 additions & 19 deletions core/iwasm/common/wasm_exec_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ typedef struct WASMExecEnv {
*/
uint8 *native_stack_top_min;

struct {
/* The top boundary of the stack. */
uint8 *top_boundary;
/* The top to of the wasm stack which is free. */
uint8 *top;
/* The bottom of the wasm stack. */
uint8 *bottom;
} wasm_stack;

#if WASM_ENABLE_FAST_JIT != 0
/**
* Cache for
Expand Down Expand Up @@ -153,18 +162,9 @@ typedef struct WASMExecEnv {
/* The WASM stack of current thread */
union {
uint64 __make_it_8_byte_aligned_;

struct {
/* The top boundary of the stack. */
uint8 *top_boundary;

/* Top cell index which is free. */
uint8 *top;

/* The WASM stack. */
uint8 bottom[1];
} s;
} wasm_stack;
/* The WASM stack. */
uint8 bottom[1];
} wasm_stack_u;
} WASMExecEnv;

#if WASM_ENABLE_MEMORY_PROFILING != 0
Expand Down Expand Up @@ -211,7 +211,7 @@ wasm_exec_env_is_aux_stack_managed_by_runtime(WASMExecEnv *exec_env)
static inline void *
wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
{
uint8 *addr = exec_env->wasm_stack.s.top;
uint8 *addr = exec_env->wasm_stack.top;

bh_assert(!(size & 3));

Expand All @@ -222,17 +222,17 @@ wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
frame size, we should check again before putting the function arguments
into the outs area. */
if (size * 2
> (uint32)(uintptr_t)(exec_env->wasm_stack.s.top_boundary - addr)) {
> (uint32)(uintptr_t)(exec_env->wasm_stack.top_boundary - addr)) {
/* WASM stack overflow. */
return NULL;
}

exec_env->wasm_stack.s.top += size;
exec_env->wasm_stack.top += size;

#if WASM_ENABLE_MEMORY_PROFILING != 0
{
uint32 wasm_stack_used =
exec_env->wasm_stack.s.top - exec_env->wasm_stack.s.bottom;
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;
}
Expand All @@ -243,8 +243,8 @@ wasm_exec_env_alloc_wasm_frame(WASMExecEnv *exec_env, unsigned size)
static inline void
wasm_exec_env_free_wasm_frame(WASMExecEnv *exec_env, void *prev_top)
{
bh_assert((uint8 *)prev_top >= exec_env->wasm_stack.s.bottom);
exec_env->wasm_stack.s.top = (uint8 *)prev_top;
bh_assert((uint8 *)prev_top >= exec_env->wasm_stack.bottom);
exec_env->wasm_stack.top = (uint8 *)prev_top;
}

/**
Expand All @@ -257,7 +257,7 @@ wasm_exec_env_free_wasm_frame(WASMExecEnv *exec_env, void *prev_top)
static inline void *
wasm_exec_env_wasm_stack_top(WASMExecEnv *exec_env)
{
return exec_env->wasm_stack.s.top;
return exec_env->wasm_stack.top;
}

/**
Expand Down
12 changes: 6 additions & 6 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,9 +557,9 @@ static bool
wasm_runtime_exec_env_check(WASMExecEnv *exec_env)
{
return exec_env && exec_env->module_inst && exec_env->wasm_stack_size > 0
&& exec_env->wasm_stack.s.top_boundary
== exec_env->wasm_stack.s.bottom + exec_env->wasm_stack_size
&& exec_env->wasm_stack.s.top <= exec_env->wasm_stack.s.top_boundary;
&& exec_env->wasm_stack.top_boundary
== exec_env->wasm_stack.bottom + exec_env->wasm_stack_size
&& exec_env->wasm_stack.top <= exec_env->wasm_stack.top_boundary;
}

bool
Expand Down Expand Up @@ -1578,11 +1578,11 @@ void
wasm_runtime_dump_exec_env_mem_consumption(const WASMExecEnv *exec_env)
{
uint32 total_size =
offsetof(WASMExecEnv, wasm_stack.s.bottom) + exec_env->wasm_stack_size;
offsetof(WASMExecEnv, wasm_stack_u.bottom) + exec_env->wasm_stack_size;

os_printf("Exec env memory consumption, total size: %u\n", total_size);
os_printf(" exec env struct size: %u\n",
offsetof(WASMExecEnv, wasm_stack.s.bottom));
offsetof(WASMExecEnv, wasm_stack_u.bottom));
#if WASM_ENABLE_INTERP != 0 && WASM_ENABLE_FAST_INTERP == 0
os_printf(" block addr cache size: %u\n",
sizeof(exec_env->block_addr_cache));
Expand Down Expand Up @@ -1643,7 +1643,7 @@ wasm_runtime_dump_mem_consumption(WASMExecEnv *exec_env)
app_heap_peak_size = gc_get_heap_highmark_size(heap_handle);
}

total_size = offsetof(WASMExecEnv, wasm_stack.s.bottom)
total_size = offsetof(WASMExecEnv, wasm_stack_u.bottom)
+ exec_env->wasm_stack_size + module_mem_consps.total_size
+ module_inst_mem_consps.total_size;

Expand Down
56 changes: 33 additions & 23 deletions core/iwasm/compilation/aot_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,29 +170,7 @@ uint32
offset_of_local_in_outs_area(AOTCompContext *comp_ctx, unsigned n)
{
AOTCompFrame *frame = comp_ctx->aot_frame;
uint32 max_local_cell_num = frame->max_local_cell_num;
uint32 max_stack_cell_num = frame->max_stack_cell_num;
uint32 all_cell_num = max_local_cell_num + max_stack_cell_num;
uint32 frame_size;

if (!comp_ctx->is_jit_mode) {
/* Refer to aot_alloc_frame */
if (!comp_ctx->enable_gc)
frame_size = comp_ctx->pointer_size * 7 + all_cell_num * 4;
else
frame_size =
comp_ctx->pointer_size * 7 + align_uint(all_cell_num * 5, 4);
}
else {
/* Refer to wasm_interp_interp_frame_size */
if (!comp_ctx->enable_gc)
frame_size = offsetof(WASMInterpFrame, lp) + all_cell_num * 4;
else
frame_size =
offsetof(WASMInterpFrame, lp) + align_uint(all_cell_num * 5, 4);
}

return frame_size + offset_of_local(comp_ctx, n);
return frame->cur_frame_size + offset_of_local(comp_ctx, n);
}

static bool
Expand Down Expand Up @@ -669,6 +647,36 @@ aot_gen_commit_sp_ip(AOTCompFrame *frame, const AOTValueSlot *sp,
return true;
}

static uint32
get_cur_frame_size(const AOTCompContext *comp_ctx, uint32 max_local_cell_num,
uint32 max_stack_cell_num)
{
uint32 all_cell_num = max_local_cell_num + max_stack_cell_num;
uint32 frame_size;

if (!comp_ctx->is_jit_mode) {
/* Refer to aot_alloc_frame */
if (!comp_ctx->enable_gc)
frame_size = comp_ctx->pointer_size
* (offsetof(AOTFrame, lp) / sizeof(uintptr_t))
+ all_cell_num * 4;
else
frame_size = comp_ctx->pointer_size
* (offsetof(AOTFrame, lp) / sizeof(uintptr_t))
+ align_uint(all_cell_num * 5, 4);
}
else {
/* Refer to wasm_interp_interp_frame_size */
if (!comp_ctx->enable_gc)
frame_size = offsetof(WASMInterpFrame, lp) + all_cell_num * 4;
else
frame_size =
offsetof(WASMInterpFrame, lp) + align_uint(all_cell_num * 5, 4);
}

return frame_size;
}

static bool
init_comp_frame(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
uint32 func_idx)
Expand Down Expand Up @@ -715,6 +723,8 @@ init_comp_frame(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,

aot_frame->max_local_cell_num = max_local_cell_num;
aot_frame->max_stack_cell_num = max_stack_cell_num;
aot_frame->cur_frame_size =
get_cur_frame_size(comp_ctx, max_local_cell_num, max_stack_cell_num);

aot_frame->sp = aot_frame->lp + max_local_cell_num;

Expand Down
9 changes: 8 additions & 1 deletion core/iwasm/compilation/aot_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "aot.h"
#include "aot_llvm.h"
#include "../interpreter/wasm_interp.h"
#include "../aot/aot_runtime.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -146,7 +147,9 @@ offset_of_local(AOTCompContext *comp_ctx, unsigned n)
{
if (!comp_ctx->is_jit_mode)
/* In AOTFrame, there are 7 pointers before field lp */
return comp_ctx->pointer_size * 7 + sizeof(uint32) * n;
return comp_ctx->pointer_size
* (offsetof(AOTFrame, lp) / sizeof(uintptr_t))
+ sizeof(uint32) * n;
else
return offsetof(WASMInterpFrame, lp) + sizeof(uint32) * n;
}
Expand Down Expand Up @@ -623,6 +626,7 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
#define I1_ZERO LLVM_CONST(i1_zero)
#define I1_ONE LLVM_CONST(i1_one)
#define I8_ZERO LLVM_CONST(i8_zero)
#define I8_ONE LLVM_CONST(i8_one)
#define I32_ZERO LLVM_CONST(i32_zero)
#define I64_ZERO LLVM_CONST(i64_zero)
#define F32_ZERO LLVM_CONST(f32_zero)
Expand All @@ -636,6 +640,9 @@ set_local_gc_ref(AOTCompFrame *frame, int n, LLVMValueRef value, uint8 ref_type)
#define I32_SEVEN LLVM_CONST(i32_seven)
#define I32_EIGHT LLVM_CONST(i32_eight)
#define I32_NINE LLVM_CONST(i32_nine)
#define I32_TEN LLVM_CONST(i32_ten)
#define I32_ELEVEN LLVM_CONST(i32_eleven)
#define I32_TWELVE LLVM_CONST(i32_twelve)
#define I32_NEG_ONE LLVM_CONST(i32_neg_one)
#define I64_NEG_ONE LLVM_CONST(i64_neg_one)
#define I32_MIN LLVM_CONST(i32_min)
Expand Down
Loading
Loading