Skip to content

Commit

Permalink
Enhance wasm loading with LoadArgs and support module names (bytecode…
Browse files Browse the repository at this point in the history
…alliance#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
  • Loading branch information
lum1n0us authored Apr 7, 2024
1 parent cee9b82 commit 4ef724b
Show file tree
Hide file tree
Showing 28 changed files with 3,008 additions and 346 deletions.
116 changes: 11 additions & 105 deletions core/iwasm/aot/aot_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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@"
Expand Down Expand Up @@ -3601,104 +3605,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
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,
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand All @@ -4193,10 +4099,10 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
}

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;
Expand Down
120 changes: 120 additions & 0 deletions core/iwasm/aot/aot_perf_map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#include "aot_perf_map.h"
#include "bh_log.h"
#include "bh_platform.h"

#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 = wasm_runtime_malloc(content_len);
if (!sorted_func_ptrs) {
snprintf(error_buf, error_buf_size,
"allocate memory failed when creating perf map");
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;
}

bool
aot_create_perf_map(const AOTModule *module, char *error_buf,
uint32 error_buf_size)
{
struct func_info *sorted_func_ptrs = NULL;
char perf_map_path[64] = { 0 };
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_path, sizeof(perf_map_path) - 1, "/tmp/perf-%d.map", pid);
perf_map = fopen(perf_map_path, "a");
if (!perf_map) {
LOG_WARNING("warning: can't create /tmp/perf-%d.map, because %s", pid,
strerror(errno));
goto quit;
}

const char *module_name = aot_get_module_name((AOTModule *)module);
for (i = 0; i < module->func_count; i++) {
memset(perf_map_info, 0, 128);
if (strlen(module_name) > 0)
snprintf(perf_map_info, 128, "%lx %x [%s]#aot_func#%u\n",
(uintptr_t)sorted_func_ptrs[i].ptr,
get_func_size(module, sorted_func_ptrs, i), module_name,
sorted_func_ptrs[i].idx);
else
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() is thread safe */
fwrite(perf_map_info, 1, strlen(perf_map_info), perf_map);
}

LOG_VERBOSE("write map information from %s into /tmp/perf-%d.map",
module_name, pid);
ret = true;

quit:
if (sorted_func_ptrs)
wasm_runtime_free(sorted_func_ptrs);

if (perf_map)
fclose(perf_map);

return ret;
}
#endif /* WASM_ENABLE_LINUX_PERF != 0 */
15 changes: 15 additions & 0 deletions core/iwasm/aot/aot_perf_map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#ifndef _AOT_PERF_MAP_H_
#define _AOT_PERF_MAP_H_

#include "aot_runtime.h"

bool
aot_create_perf_map(const AOTModule *module, char *error_buf,
uint32 error_buf_size);

#endif /* _AOT_PERF_MAP_H_ */
4 changes: 2 additions & 2 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,8 @@ typedef struct LLVMProfileData_64 {
* @return return AOT module loaded, NULL if failed
*/
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);

/**
* Load a AOT module from a specified AOT section list.
Expand Down
15 changes: 12 additions & 3 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2234,7 +2234,8 @@ try_reuse_loaded_module(wasm_store_t *store, char *binary_hash)
#endif /* WASM_ENABLE_WASM_CACHE != 0 */

wasm_module_t *
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
wasm_module_new_ex(wasm_store_t *store, const wasm_byte_vec_t *binary,
const LoadArgs *args)
{
char error_buf[128] = { 0 };
wasm_module_ex_t *module_ex = NULL;
Expand Down Expand Up @@ -2290,8 +2291,8 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
if (!module_ex->binary->data)
goto free_binary;

module_ex->module_comm_rt = wasm_runtime_load(
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size,
module_ex->module_comm_rt = wasm_runtime_load_ex(
(uint8 *)module_ex->binary->data, (uint32)module_ex->binary->size, args,
error_buf, (uint32)sizeof(error_buf));
if (!(module_ex->module_comm_rt)) {
LOG_ERROR("%s", error_buf);
Expand Down Expand Up @@ -2337,6 +2338,14 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
return NULL;
}

wasm_module_t *
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
{
LoadArgs args = { 0 };
args.name = "";
return wasm_module_new_ex(store, binary, &args);
}

bool
wasm_module_validate(wasm_store_t *store, const wasm_byte_vec_t *binary)
{
Expand Down
Loading

0 comments on commit 4ef724b

Please sign in to comment.