Skip to content

Commit 32338bb

Browse files
author
Georgii Rylov :slightly_smiling_face
committed
Copy read only API behind a flag instead of using user defined callback
1 parent 267379c commit 32338bb

File tree

9 files changed

+143
-89
lines changed

9 files changed

+143
-89
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ if (NOT DEFINED WAMR_BUILD_LIB_WASI_THREADS)
104104
set (WAMR_BUILD_LIB_WASI_THREADS 0)
105105
endif ()
106106

107+
if (NOT DEFINED WAMR_ENABLE_COPY_CALLSTACK)
108+
# Disable copy callstack by default
109+
set (WAMR_ENABLE_COPY_CALLSTACK 0)
110+
endif()
111+
107112
if (NOT DEFINED WAMR_BUILD_MINI_LOADER)
108113
# Disable wasm mini loader by default
109114
set (WAMR_BUILD_MINI_LOADER 0)

build-scripts/config_common.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ if (WAMR_BUILD_SHARED_HEAP EQUAL 1)
319319
message (" Shared heap enabled")
320320
endif()
321321

322+
if (WAMR_ENABLE_COPY_CALLSTACK EQUAL 1)
323+
add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=1)
324+
message(" Copy callstack enabled")
325+
else ()
326+
add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=0)
327+
message(" Copy callstack disabled")
328+
endif()
329+
322330
if (WAMR_BUILD_MEMORY64 EQUAL 1)
323331
# if native is 32-bit or cross-compiled to 32-bit
324332
if (NOT WAMR_BUILD_TARGET MATCHES ".*64.*")

core/iwasm/aot/aot_runtime.c

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4103,11 +4103,11 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
41034103
}
41044104
#endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 */
41054105

4106-
#if WASM_ENABLE_DUMP_CALL_STACK != 0
4107-
void
4108-
aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env,
4109-
const wasm_frame_callback frame_handler,
4110-
void *user_data)
4106+
#if WAMR_ENABLE_COPY_CALLSTACK != 0
4107+
uint32
4108+
aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer,
4109+
const uint32 length,
4110+
const uint32 skip_n)
41114111
{
41124112
/*
41134113
* Note for devs: please refrain from such modifications inside of
@@ -4122,35 +4122,43 @@ aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env,
41224122
uint8 *top = exec_env->wasm_stack.top;
41234123
uint8 *bottom = exec_env->wasm_stack.bottom;
41244124

4125+
uint32 count = 0;
4126+
41254127
bool is_top_index_in_range =
41264128
top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame));
41274129
if (!is_top_index_in_range) {
4128-
return;
4130+
return count;
41294131
}
41304132
bool is_top_aligned_with_bottom =
41314133
(unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0;
41324134
if (!is_top_aligned_with_bottom) {
4133-
return;
4135+
return count;
41344136
}
41354137

41364138
AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame));
41374139
WASMCApiFrame record_frame;
4138-
while (frame && (uint8_t *)frame >= bottom) {
4140+
while (frame && (uint8_t *)frame >= bottom
4141+
&& count < (skip_n + length)) {
4142+
if (count < skip_n) {
4143+
++count;
4144+
frame -= 1;
4145+
continue;
4146+
}
41394147
record_frame.instance = exec_env->module_inst;
41404148
record_frame.module_offset = 0;
41414149
record_frame.func_index = frame->func_index;
41424150
record_frame.func_offset = frame->ip_offset;
4143-
if (!frame_handler(user_data, &record_frame)) {
4144-
break;
4145-
}
4151+
buffer[count - skip_n] = record_frame;
41464152
frame -= 1;
4153+
++count;
41474154
}
4155+
return count;
41484156
}
41494157

4150-
void
4151-
aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env,
4152-
const wasm_frame_callback frame_handler,
4153-
void *user_data)
4158+
uint32
4159+
aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer,
4160+
const uint32 length,
4161+
const uint32 skip_n)
41544162
{
41554163
/*
41564164
* Note for devs: please refrain from such modifications inside of
@@ -4169,17 +4177,24 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env,
41694177
uint8 *bottom = exec_env->wasm_stack.bottom;
41704178
uint32 frame_size = (uint32)offsetof(AOTFrame, lp);
41714179

4180+
uint32 count = 0;
4181+
41724182
WASMCApiFrame record_frame;
41734183
while (cur_frame && (uint8_t *)cur_frame >= bottom
4174-
&& (uint8_t *)cur_frame + frame_size <= top_boundary) {
4184+
&& (uint8_t *)cur_frame + frame_size <= top_boundary
4185+
&& count < (skip_n + length)) {
4186+
if (count < skip_n) {
4187+
++count;
4188+
cur_frame = cur_frame->prev_frame;
4189+
continue;
4190+
}
41754191
record_frame.instance = module_inst;
41764192
record_frame.module_offset = 0;
41774193
record_frame.func_index = (uint32)cur_frame->func_index;
41784194
record_frame.func_offset = (uint32)cur_frame->ip_offset;
4179-
if (!frame_handler(user_data, &record_frame)) {
4180-
break;
4181-
}
4195+
buffer[count - skip_n] = record_frame;
41824196
cur_frame = cur_frame->prev_frame;
4197+
++count;
41834198
}
41844199
#else
41854200
/*
@@ -4189,9 +4204,11 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env,
41894204
#endif
41904205
}
41914206

4192-
void
4193-
aot_iterate_callstack(WASMExecEnv *exec_env,
4194-
const wasm_frame_callback frame_handler, void *user_data)
4207+
4208+
uint32
4209+
aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer,
4210+
const uint32 length,
4211+
const uint32 skip_n)
41954212
{
41964213
/*
41974214
* Note for devs: please refrain from such modifications inside of
@@ -4203,14 +4220,15 @@ aot_iterate_callstack(WASMExecEnv *exec_env,
42034220
* wasm_export.h
42044221
*/
42054222
if (!is_tiny_frame(exec_env)) {
4206-
aot_iterate_callstack_standard_frame(exec_env, frame_handler,
4207-
user_data);
4223+
return aot_copy_callstack_standard_frame(exec_env, buffer, length, skip_n);
42084224
}
42094225
else {
4210-
aot_iterate_callstack_tiny_frame(exec_env, frame_handler, user_data);
4226+
return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n);
42114227
}
42124228
}
4229+
#endif // WAMR_ENABLE_COPY_CALLSTACK
42134230

4231+
#if WASM_ENABLE_DUMP_CALL_STACK != 0
42144232
bool
42154233
aot_create_call_stack(struct WASMExecEnv *exec_env)
42164234
{
@@ -4391,7 +4409,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
43914409

43924410
return total_len + 1;
43934411
}
4394-
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 */
4412+
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 && WASM_ENABLE_AOT_STACK_FRAME != 0 */
43954413

43964414
#if WASM_ENABLE_PERF_PROFILING != 0
43974415
void

core/iwasm/aot/aot_runtime.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../common/wasm_runtime_common.h"
1111
#include "../interpreter/wasm_runtime.h"
1212
#include "../compilation/aot.h"
13+
#include "platform_common.h"
1314
#if WASM_ENABLE_GC != 0
1415
#include "gc_export.h"
1516
#endif
@@ -777,9 +778,12 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame);
777778
bool
778779
aot_create_call_stack(struct WASMExecEnv *exec_env);
779780

780-
void
781-
aot_iterate_callstack(WASMExecEnv *exec_env,
782-
const wasm_frame_callback frame_handler, void *user_data);
781+
#if WAMR_ENABLE_COPY_CALLSTACK != 0
782+
uint32
783+
aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer,
784+
const uint32 length,
785+
const uint32 skip_n);
786+
#endif // WAMR_ENABLE_COPY_CALLSTACK
783787

784788
/**
785789
* @brief Dump wasm call stack or get the size

core/iwasm/common/wasm_runtime_common.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "bh_common.h"
88
#include "bh_assert.h"
99
#include "bh_log.h"
10+
#include "platform_common.h"
1011
#include "wasm_export.h"
1112
#include "wasm_native.h"
1213
#include "wasm_runtime_common.h"
@@ -1741,18 +1742,19 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env)
17411742
wasm_exec_env_destroy(exec_env);
17421743
}
17431744

1744-
void
1745-
wasm_iterate_callstack(const wasm_exec_env_t exec_env,
1746-
const wasm_frame_callback frame_callback,
1747-
void *user_data)
1745+
#if WAMR_ENABLE_COPY_CALLSTACK != 0
1746+
uint32
1747+
wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer,
1748+
const uint32 length,
1749+
const uint32 skip_n)
17481750
{
17491751
/*
17501752
* Note for devs: please refrain from such modifications inside of
1751-
* wasm_iterate_callstack to preserve async-signal-safety
1753+
* wasm_copy_callstack to preserve async-signal-safety
17521754
* - any allocations/freeing memory
17531755
* - dereferencing any pointers other than: exec_env, exec_env->module_inst,
17541756
* exec_env->module_inst->module, pointers between stack's bottom and
1755-
* top_boundary For more details check wasm_iterate_callstack in
1757+
* top_boundary For more details check wasm_copy_callstack in
17561758
* wasm_export.h
17571759
*/
17581760
#if WASM_ENABLE_DUMP_CALL_STACK
@@ -1761,17 +1763,18 @@ wasm_iterate_callstack(const wasm_exec_env_t exec_env,
17611763

17621764
#if WASM_ENABLE_INTERP != 0
17631765
if (module_inst->module_type == Wasm_Module_Bytecode) {
1764-
wasm_interp_iterate_callstack(exec_env, frame_callback, user_data);
1766+
return wasm_interp_copy_callstack(exec_env, buffer, length, skip_n);
17651767
}
17661768
#endif
17671769

17681770
#if WASM_ENABLE_AOT != 0
17691771
if (module_inst->module_type == Wasm_Module_AoT) {
1770-
aot_iterate_callstack(exec_env, frame_callback, user_data);
1772+
return aot_copy_callstack(exec_env, buffer, length, skip_n);
17711773
}
17721774
#endif
17731775
#endif
17741776
}
1777+
#endif // WAMR_ENABLE_COPY_CALLSTACK
17751778

17761779
bool
17771780
wasm_runtime_init_thread_env(void)

core/iwasm/common/wasm_runtime_common.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "bh_platform.h"
1010
#include "bh_common.h"
11+
#include "platform_common.h"
1112
#include "wasm_exec_env.h"
1213
#include "wasm_native.h"
1314
#include "../include/wasm_export.h"
@@ -464,19 +465,6 @@ typedef struct WASMRegisteredModule {
464465
typedef package_type_t PackageType;
465466
typedef wasm_section_t WASMSection, AOTSection;
466467

467-
typedef struct wasm_frame_t {
468-
/* wasm_instance_t */
469-
void *instance;
470-
uint32 module_offset;
471-
uint32 func_index;
472-
uint32 func_offset;
473-
const char *func_name_wp;
474-
475-
uint32 *sp;
476-
uint8 *frame_ref;
477-
uint32 *lp;
478-
} WASMCApiFrame;
479-
480468
#if WASM_ENABLE_JIT != 0
481469
typedef struct LLVMJITOptions {
482470
uint32 opt_level;
@@ -652,10 +640,11 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
652640
WASM_RUNTIME_API_EXTERN void
653641
wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env);
654642

655-
WASM_RUNTIME_API_EXTERN void
656-
wasm_iterate_callstack(const wasm_exec_env_t exec_env,
657-
const wasm_frame_callback frame_handler,
658-
void *user_data);
643+
#if WAMR_ENABLE_COPY_CALLSTACK != 0
644+
WASM_RUNTIME_API_EXTERN uint32_t
645+
wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer,
646+
const uint32 length, const uint32 skip_n);
647+
#endif // WAMR_ENABLE_COPY_CALLSTACK
659648

660649
/* See wasm_export.h for description */
661650
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *

core/iwasm/include/wasm_export.h

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,23 @@ typedef WASMFunctionInstanceCommon *wasm_function_inst_t;
126126
struct WASMMemoryInstance;
127127
typedef struct WASMMemoryInstance *wasm_memory_inst_t;
128128

129-
struct wasm_frame_t;
129+
130+
typedef struct wasm_frame_t {
131+
/* wasm_instance_t */
132+
void *instance;
133+
uint32_t module_offset;
134+
uint32_t func_index;
135+
uint32_t func_offset;
136+
const char *func_name_wp;
137+
138+
uint32_t *sp;
139+
uint8_t *frame_ref;
140+
uint32_t *lp;
141+
} WASMCApiFrame;
142+
143+
// #if WAMR_ENABLE_COPY_CALLSTACK != 0
130144
typedef struct wasm_frame_t *wasm_frame_ptr_t;
145+
// #endif // WAMR_ENABLE_COPY_CALLSTACK
131146

132147
/* WASM section */
133148
typedef struct wasm_section_t {
@@ -867,16 +882,10 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst,
867882
WASM_RUNTIME_API_EXTERN void
868883
wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env);
869884

870-
/**
871-
* Callback to be called on wasm_frame_t*.
872-
* It accepts void* as a context that can be used for closures.
873-
* It returns bool so the iterating can stop when the callback returns false.
874-
* E.g. callback that returns false after processing 100 frames
875-
*/
876-
typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t);
877885

886+
// #if WAMR_ENABLE_COPY_CALLSTACK != 0
878887
/**
879-
* @brief Iterate over callstack frames and execute callback on it.
888+
* @brief Copy callstack frames.
880889
*
881890
* Caution: This is not a thread-safe function. Ensure the exec_env
882891
* is suspended before calling it from another thread.
@@ -892,12 +901,16 @@ typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t);
892901
* - exec_env->module_inst->module
893902
*
894903
* @param exec_env the execution environment that containes frames
895-
* @param callback the callback function provided by the user
896-
* @param user_data context for callback provided by the user
904+
* @param buffer the buffer of size equal length * sizeof(frame) to copy frames to
905+
* @param length the number of frames to copy
906+
* @param skip_n the number of frames to skip from the top of the stack
907+
*
908+
* @return number of copied frames
897909
*/
898-
WASM_RUNTIME_API_EXTERN void
899-
wasm_iterate_callstack(const wasm_exec_env_t exec_env,
900-
const wasm_frame_callback callback, void *user_data);
910+
WASM_RUNTIME_API_EXTERN uint32_t
911+
wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer,
912+
const uint32_t length, const uint32_t skip_n);
913+
// #endif
901914

902915
/**
903916
* Get the singleton execution environment for the instance.

0 commit comments

Comments
 (0)