Enhance wasm loading with LoadArgs and support module names (#3265)

- Add new API wasm_runtime_load_ex() in wasm_export.h
  and wasm_module_new_ex in wasm_c_api.h
- Put aot_create_perf_map() into a separated file aot_perf_map.c
- In perf.map, function names include user specified module name
- Enhance the script to help flamegraph generations
This commit is contained in:
liang.he
2024-04-07 15:04:35 +08:00
committed by GitHub
parent cee9b826a5
commit 4ef724bbff
28 changed files with 3008 additions and 346 deletions

View File

@ -16,6 +16,10 @@
#include "debug/jit_debug.h"
#endif
#if WASM_ENABLE_LINUX_PERF != 0
#include "aot_perf_map.h"
#endif
#define YMM_PLT_PREFIX "__ymm@"
#define XMM_PLT_PREFIX "__xmm@"
#define REAL_PLT_PREFIX "__real@"
@ -3601,104 +3605,6 @@ fail:
return ret;
}
#if WASM_ENABLE_LINUX_PERF != 0
struct func_info {
uint32 idx;
void *ptr;
};
static uint32
get_func_size(const AOTModule *module, struct func_info *sorted_func_ptrs,
uint32 idx)
{
uint32 func_sz;
if (idx == module->func_count - 1)
func_sz = (uintptr_t)module->code + module->code_size
- (uintptr_t)(sorted_func_ptrs[idx].ptr);
else
func_sz = (uintptr_t)(sorted_func_ptrs[idx + 1].ptr)
- (uintptr_t)(sorted_func_ptrs[idx].ptr);
return func_sz;
}
static int
compare_func_ptrs(const void *f1, const void *f2)
{
return (intptr_t)((struct func_info *)f1)->ptr
- (intptr_t)((struct func_info *)f2)->ptr;
}
static struct func_info *
sort_func_ptrs(const AOTModule *module, char *error_buf, uint32 error_buf_size)
{
uint64 content_len;
struct func_info *sorted_func_ptrs;
unsigned i;
content_len = (uint64)sizeof(struct func_info) * module->func_count;
sorted_func_ptrs = loader_malloc(content_len, error_buf, error_buf_size);
if (!sorted_func_ptrs)
return NULL;
for (i = 0; i < module->func_count; i++) {
sorted_func_ptrs[i].idx = i;
sorted_func_ptrs[i].ptr = module->func_ptrs[i];
}
qsort(sorted_func_ptrs, module->func_count, sizeof(struct func_info),
compare_func_ptrs);
return sorted_func_ptrs;
}
static bool
create_perf_map(const AOTModule *module, char *error_buf, uint32 error_buf_size)
{
struct func_info *sorted_func_ptrs = NULL;
char perf_map_info[128] = { 0 };
FILE *perf_map = NULL;
uint32 i;
pid_t pid = getpid();
bool ret = false;
sorted_func_ptrs = sort_func_ptrs(module, error_buf, error_buf_size);
if (!sorted_func_ptrs)
goto quit;
snprintf(perf_map_info, 128, "/tmp/perf-%d.map", pid);
perf_map = fopen(perf_map_info, "w");
if (!perf_map) {
LOG_WARNING("warning: can't create /tmp/perf-%d.map, because %s", pid,
strerror(errno));
goto quit;
}
for (i = 0; i < module->func_count; i++) {
memset(perf_map_info, 0, 128);
snprintf(perf_map_info, 128, "%lx %x aot_func#%u\n",
(uintptr_t)sorted_func_ptrs[i].ptr,
get_func_size(module, sorted_func_ptrs, i),
sorted_func_ptrs[i].idx);
fwrite(perf_map_info, 1, strlen(perf_map_info), perf_map);
}
LOG_VERBOSE("generate /tmp/perf-%d.map", pid);
ret = true;
quit:
if (sorted_func_ptrs)
free(sorted_func_ptrs);
if (perf_map)
fclose(perf_map);
return ret;
}
#endif /* WASM_ENABLE_LINUX_PERF != 0*/
static bool
load_from_sections(AOTModule *module, AOTSection *sections,
bool is_load_from_file_buf, char *error_buf,
@ -3889,7 +3795,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
}
static AOTModule *
create_module(char *error_buf, uint32 error_buf_size)
create_module(char *name, char *error_buf, uint32 error_buf_size)
{
AOTModule *module =
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
@ -3901,7 +3807,7 @@ create_module(char *error_buf, uint32 error_buf_size)
module->module_type = Wasm_Module_AoT;
module->name = "";
module->name = name;
#if WASM_ENABLE_MULTI_MODULE != 0
module->import_module_list = &module->import_module_list_head;
@ -3937,7 +3843,7 @@ AOTModule *
aot_load_from_sections(AOTSection *section_list, char *error_buf,
uint32 error_buf_size)
{
AOTModule *module = create_module(error_buf, error_buf_size);
AOTModule *module = create_module("", error_buf, error_buf_size);
if (!module)
return NULL;
@ -4183,7 +4089,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
#if WASM_ENABLE_LINUX_PERF != 0
if (wasm_runtime_get_linux_perf())
if (!create_perf_map(module, error_buf, error_buf_size))
if (!aot_create_perf_map(module, error_buf, error_buf_size))
goto fail;
#endif
@ -4193,10 +4099,10 @@ fail:
}
AOTModule *
aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
uint32 error_buf_size)
aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
char *error_buf, uint32 error_buf_size)
{
AOTModule *module = create_module(error_buf, error_buf_size);
AOTModule *module = create_module(args->name, error_buf, error_buf_size);
if (!module)
return NULL;