Implement performance profiler and call stack dump, and update toolchain document (#501)
And remove redundant FAST_INTERP macros in wasm_interp_fast.c, and fix wamrc --help wrong line order issue. Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
@ -26,6 +26,10 @@ typedef struct WASMInterpFrame {
|
||||
/* Instruction pointer of the bytecode array. */
|
||||
uint8 *ip;
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
uint64 time_started;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
/* return offset of the first return value of current frame.
|
||||
the callee will put return values here continuously */
|
||||
@ -74,11 +78,6 @@ wasm_interp_call_wasm(struct WASMModuleInstance *module_inst,
|
||||
struct WASMFunctionInstance *function,
|
||||
uint32 argc, uint32 argv[]);
|
||||
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
void
|
||||
wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -900,8 +900,12 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
|
||||
{
|
||||
WASMInterpFrame *frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
|
||||
|
||||
if (frame)
|
||||
if (frame) {
|
||||
frame->prev_frame = prev_frame;
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = os_time_get_boot_microsecond();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
|
||||
"stack overflow");
|
||||
@ -913,6 +917,13 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
|
||||
static inline void
|
||||
FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *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);
|
||||
}
|
||||
|
||||
@ -3361,7 +3372,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst,
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
wasm_interp_dump_call_stack(exec_env);
|
||||
#endif
|
||||
LOG_DEBUG("meet an exception %s", wasm_get_exception(module_inst));
|
||||
|
||||
@ -909,8 +909,12 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
|
||||
{
|
||||
WASMInterpFrame *frame = wasm_exec_env_alloc_wasm_frame(exec_env, size);
|
||||
|
||||
if (frame)
|
||||
if (frame) {
|
||||
frame->prev_frame = prev_frame;
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
frame->time_started = os_time_get_boot_microsecond();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
wasm_set_exception((WASMModuleInstance*)exec_env->module_inst,
|
||||
"stack overflow");
|
||||
@ -922,6 +926,13 @@ ALLOC_FRAME(WASMExecEnv *exec_env, uint32 size, WASMInterpFrame *prev_frame)
|
||||
static inline void
|
||||
FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *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);
|
||||
}
|
||||
|
||||
@ -1086,9 +1097,6 @@ wasm_interp_dump_op_count()
|
||||
#else
|
||||
#define HANDLE_OP(opcode) HANDLE_##opcode
|
||||
#endif
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
#define FETCH_OPCODE_AND_DISPATCH() goto *handle_table[*frame_ip++]
|
||||
#else
|
||||
#if WASM_ENABLE_ABS_LABEL_ADDR != 0
|
||||
#define FETCH_OPCODE_AND_DISPATCH() do { \
|
||||
const void *p_label_addr = *(void**)frame_ip; \
|
||||
@ -1103,7 +1111,6 @@ wasm_interp_dump_op_count()
|
||||
goto *p_label_addr; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
#define HANDLE_OP_END() FETCH_OPCODE_AND_DISPATCH()
|
||||
|
||||
#else /* else of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
@ -1113,9 +1120,7 @@ wasm_interp_dump_op_count()
|
||||
|
||||
#endif /* end of WASM_ENABLE_LABELS_AS_VALUES */
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
static void **global_handle_table;
|
||||
#endif
|
||||
|
||||
static void
|
||||
wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
@ -1150,13 +1155,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
DEFINE_GOTO_TABLE (const void*, handle_table);
|
||||
#undef HANDLE_OPCODE
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
if (exec_env == NULL) {
|
||||
global_handle_table = (void **)handle_table;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES == 0
|
||||
while (frame_ip < frame_ip_end) {
|
||||
@ -3330,7 +3333,6 @@ recover_br_info:
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
void **
|
||||
wasm_interp_get_handle_table()
|
||||
{
|
||||
@ -3339,7 +3341,6 @@ wasm_interp_get_handle_table()
|
||||
wasm_interp_call_func_bytecode(&module, NULL, NULL, NULL);
|
||||
return global_handle_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_interp_call_wasm(WASMModuleInstance *module_inst,
|
||||
@ -3412,7 +3413,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst,
|
||||
argv[i] = *(frame->lp + i);
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
wasm_interp_dump_call_stack(exec_env);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1448,7 +1448,6 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
static bool
|
||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
BlockAddr *block_addr_cache,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
@ -1472,9 +1471,7 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
uint32 aux_stack_top = (uint32)-1, global_index, func_index, i;
|
||||
uint32 aux_data_end_global_index = (uint32)-1;
|
||||
uint32 aux_heap_base_global_index = (uint32)-1;
|
||||
BlockAddr *block_addr_cache;
|
||||
WASMType *func_type;
|
||||
uint64 total_size;
|
||||
|
||||
/* Find code and function sections if have */
|
||||
while (section) {
|
||||
@ -1746,22 +1743,13 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
handle_table = wasm_interp_get_handle_table();
|
||||
#endif
|
||||
|
||||
total_size = sizeof(BlockAddr) * (uint64)BLOCK_ADDR_CACHE_SIZE * BLOCK_ADDR_CONFLICT_SIZE;
|
||||
if (!(block_addr_cache = loader_malloc
|
||||
(total_size, error_buf, error_buf_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < module->function_count; i++) {
|
||||
WASMFunction *func = module->functions[i];
|
||||
memset(block_addr_cache, 0, (uint32)total_size);
|
||||
if (!wasm_loader_prepare_bytecode(module, func, block_addr_cache,
|
||||
if (!wasm_loader_prepare_bytecode(module, func,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_runtime_free(block_addr_cache);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
wasm_runtime_free(block_addr_cache);
|
||||
|
||||
if (!module->possible_memory_grow) {
|
||||
WASMMemoryImport *memory_import;
|
||||
@ -4251,7 +4239,6 @@ fail:
|
||||
|
||||
static bool
|
||||
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
BlockAddr *block_addr_cache,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
uint8 *p = func->code, *p_end = func->code + func->code_size, *p_org;
|
||||
|
||||
@ -1657,6 +1657,49 @@ wasm_get_exception(WASMModuleInstance *module_inst)
|
||||
return module_inst->cur_exception;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
void
|
||||
wasm_dump_perf_profiling(const WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMExportFuncInstance *export_func;
|
||||
WASMFunctionInstance *func_inst;
|
||||
char *func_name;
|
||||
uint32 i, j;
|
||||
|
||||
os_printf("Performance profiler data:\n");
|
||||
for (i = 0; i < module_inst->function_count; i++) {
|
||||
func_inst = module_inst->functions + i;
|
||||
if (func_inst->is_import_func) {
|
||||
func_name = func_inst->u.func_import->field_name;
|
||||
}
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
else if (func_inst->u.func->field_name) {
|
||||
func_name = func_inst->u.func->field_name;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
func_name = NULL;
|
||||
for (j = 0; j < module_inst->export_func_count; j++) {
|
||||
export_func = module_inst->export_functions + j;
|
||||
if (export_func->function == func_inst) {
|
||||
func_name = export_func->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (func_name)
|
||||
os_printf(" func %s, execution time: %.3f ms, execution count: %d times\n",
|
||||
func_name, module_inst->functions[i].total_exec_time / 1000.0f,
|
||||
module_inst->functions[i].total_exec_cnt);
|
||||
else
|
||||
os_printf(" func %d, execution time: %.3f ms, execution count: %d times\n",
|
||||
i, module_inst->functions[i].total_exec_time / 1000.0f,
|
||||
module_inst->functions[i].total_exec_cnt);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32
|
||||
wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
|
||||
void **p_native_addr)
|
||||
@ -2205,7 +2248,7 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst,
|
||||
#endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0)
|
||||
|| (WASM_ENABLE_MEMORY_TRACING != 0) */
|
||||
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
void
|
||||
wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||
{
|
||||
@ -2214,18 +2257,33 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||
WASMInterpFrame *cur_frame =
|
||||
wasm_exec_env_get_cur_frame(exec_env);
|
||||
WASMFunctionInstance *func_inst;
|
||||
WASMExportFuncInstance *export_func;
|
||||
const char *func_name = NULL;
|
||||
uint32 n;
|
||||
uint32 n, i;
|
||||
|
||||
os_printf("\n");
|
||||
for (n = 0; cur_frame && cur_frame->function; n++) {
|
||||
func_name = NULL;
|
||||
func_inst = cur_frame->function;
|
||||
|
||||
if (func_inst->is_import_func) {
|
||||
func_name = func_inst->u.func_import->field_name;
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
|
||||
func_name = func_inst->u.func->field_name;
|
||||
#endif
|
||||
/* if custom name section is not generated,
|
||||
search symbols from export table */
|
||||
if (!func_name) {
|
||||
for (i = 0; i < module_inst->export_func_count; i++) {
|
||||
export_func = module_inst->export_functions + i;
|
||||
if (export_func->function == func_inst) {
|
||||
func_name = export_func->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* function name not exported, print number instead */
|
||||
@ -2240,4 +2298,4 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env)
|
||||
}
|
||||
os_printf("\n");
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_CUSTOM_NAME_SECTION */
|
||||
#endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
|
||||
|
||||
@ -120,6 +120,12 @@ struct WASMFunctionInstance {
|
||||
WASMModuleInstance *import_module_inst;
|
||||
WASMFunctionInstance *import_func_inst;
|
||||
#endif
|
||||
#if WASM_ENABLE_PERF_PROFILING != 0
|
||||
/* total execution time */
|
||||
uint64 total_exec_time;
|
||||
/* total execution count */
|
||||
uint32 total_exec_cnt;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct WASMExportFuncInstance {
|
||||
@ -281,12 +287,15 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
void
|
||||
wasm_dump_perf_profiling(const WASMModuleInstance *module_inst);
|
||||
|
||||
void
|
||||
wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst);
|
||||
|
||||
WASMFunctionInstance *
|
||||
wasm_lookup_function(const WASMModuleInstance *module_inst,
|
||||
const char *name, const char *signature);
|
||||
const char *name, const char *signature);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMGlobalInstance *
|
||||
@ -383,6 +392,12 @@ wasm_get_module_mem_consumption(const WASMModule *module,
|
||||
void
|
||||
wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module,
|
||||
WASMModuleInstMemConsumption *mem_conspn);
|
||||
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
void
|
||||
wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user