enable pthread for AoT && update AOT current version to 2 (#311)

This commit is contained in:
Xu Jun
2020-07-16 20:35:04 +08:00
committed by GitHub
parent ca938f3634
commit 32b2943369
32 changed files with 1549 additions and 584 deletions

View File

@ -349,6 +349,14 @@ fail:
return false;
}
static void
destroy_import_memories(AOTImportMemory *import_memories,
bool is_jit_mode)
{
if (!is_jit_mode)
wasm_runtime_free(import_memories);
}
static void
destroy_mem_init_data_list(AOTMemInitData **data_list, uint32 count,
bool is_jit_mode)
@ -420,11 +428,28 @@ load_memory_info(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module,
char *error_buf, uint32 error_buf_size)
{
uint32 i;
uint64 total_size;
const uint8 *buf = *p_buf;
read_uint32(buf, buf_end, module->num_bytes_per_page);
read_uint32(buf, buf_end, module->mem_init_page_count);
read_uint32(buf, buf_end, module->mem_max_page_count);
read_uint32(buf, buf_end, module->import_memory_count);
/* We don't support import_memory_count > 0 currently */
bh_assert(module->import_memory_count == 0);
read_uint32(buf, buf_end, module->memory_count);
total_size = sizeof(AOTMemory) * (uint64)module->memory_count;
if (!(module->memories =
loader_malloc(total_size, error_buf, error_buf_size))) {
return false;
}
for (i = 0; i < module->memory_count; i++) {
read_uint32(buf, buf_end, module->memories[i].memory_flags);
read_uint32(buf, buf_end, module->memories[i].num_bytes_per_page);
read_uint32(buf, buf_end, module->memories[i].mem_init_page_count);
read_uint32(buf, buf_end, module->memories[i].mem_max_page_count);
}
read_uint32(buf, buf_end, module->mem_init_data_count);
/* load memory init data list */
@ -439,6 +464,20 @@ fail:
return false;
}
static void
destroy_import_tables(AOTImportTable *import_tables, bool is_jit_mode)
{
if (!is_jit_mode)
wasm_runtime_free(import_tables);
}
static void
destroy_tables(AOTTable *tables, bool is_jit_mode)
{
if (!is_jit_mode)
wasm_runtime_free(tables);
}
static void
destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count,
bool is_jit_mode)
@ -452,6 +491,36 @@ destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count,
}
}
static bool
load_table_list(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module, char *error_buf, uint32 error_buf_size)
{
const uint8 *buf = *p_buf;
AOTTable *table;
uint64 size;
uint32 i;
/* Allocate memory */
size = sizeof(AOTTable) * (uint64)module->table_count;
if (!(module->tables = table =
loader_malloc(size, error_buf, error_buf_size))) {
return false;
}
/* Create each table data segment */
for (i = 0; i < module->table_count; i++, table++) {
read_uint32(buf, buf_end, table->elem_type);
read_uint32(buf, buf_end, table->table_flags);
read_uint32(buf, buf_end, table->table_init_size);
read_uint32(buf, buf_end, table->table_max_size);
}
*p_buf = buf;
return true;
fail:
return false;
}
static bool
load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module,
@ -471,9 +540,10 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
/* Create each table data segment */
for (i = 0; i < module->table_init_data_count; i++) {
uint32 init_expr_type, func_index_count;
uint32 table_index, init_expr_type, func_index_count;
uint64 init_expr_value, size1;
read_uint32(buf, buf_end, table_index);
read_uint32(buf, buf_end, init_expr_type);
read_uint64(buf, buf_end, init_expr_value);
read_uint32(buf, buf_end, func_index_count);
@ -485,6 +555,7 @@ load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
return false;
}
data_list[i]->table_index = table_index;
data_list[i]->offset.init_expr_type = (uint8)init_expr_type;
data_list[i]->offset.u.i64 = (int64)init_expr_value;
data_list[i]->func_index_count = func_index_count;
@ -504,7 +575,16 @@ load_table_info(const uint8 **p_buf, const uint8 *buf_end,
{
const uint8 *buf = *p_buf;
read_uint32(buf, buf_end, module->table_size);
read_uint32(buf, buf_end, module->import_table_count);
/* We don't support import_table_count > 0 currently */
bh_assert(module->import_table_count == 0);
read_uint32(buf, buf_end, module->table_count);
if (module->table_count > 0
&& !load_table_list(&buf, buf_end, module,
error_buf, error_buf_size))
return false;
read_uint32(buf, buf_end, module->table_init_data_count);
/* load table init data list */
@ -1088,40 +1168,42 @@ fail:
}
static void
destroy_export_funcs(AOTExportFunc *export_funcs, bool is_jit_mode)
destroy_exports(AOTExport *exports, bool is_jit_mode)
{
if (!is_jit_mode)
wasm_runtime_free(export_funcs);
wasm_runtime_free(exports);
}
static bool
load_export_funcs(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module,
char *error_buf, uint32 error_buf_size)
load_exports(const uint8 **p_buf, const uint8 *buf_end,
AOTModule *module, char *error_buf, uint32 error_buf_size)
{
const uint8 *buf = *p_buf;
AOTExportFunc *export_funcs;
AOTExport *exports;
uint64 size;
uint32 i;
/* Allocate memory */
size = sizeof(AOTExportFunc) * (uint64)module->export_func_count;
if (!(module->export_funcs = export_funcs =
size = sizeof(AOTExport) * (uint64)module->export_count;
if (!(module->exports = exports =
loader_malloc(size, error_buf, error_buf_size))) {
return false;
}
/* Create each export func */
for (i = 0; i < module->export_func_count; i++) {
read_uint32(buf, buf_end, export_funcs[i].func_index);
if (export_funcs[i].func_index >=
/* Create each export */
for (i = 0; i < module->export_count; i++) {
read_uint32(buf, buf_end, exports[i].index);
read_uint8(buf, buf_end, exports[i].kind);
read_string(buf, buf_end, exports[i].name);
#if 0 /* TODO: check kind and index */
if (export_funcs[i].index >=
module->func_count + module->import_func_count) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"function index is out of range.");
return false;
}
read_string(buf, buf_end, export_funcs[i].func_name);
#endif
}
*p_buf = buf;
@ -1138,9 +1220,9 @@ load_export_section(const uint8 *buf, const uint8 *buf_end,
const uint8 *p = buf, *p_end = buf_end;
/* load export functions */
read_uint32(p, p_end, module->export_func_count);
if (module->export_func_count > 0
&& !load_export_funcs(&p, p_end, module, error_buf, error_buf_size))
read_uint32(p, p_end, module->export_count);
if (module->export_count > 0
&& !load_exports(&p, p_end, module, error_buf, error_buf_size))
return false;
if (p != p_end) {
@ -1385,12 +1467,11 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
{
AOTRelocationGroup *groups = NULL, *group;
uint32 symbol_count = 0;
uint32 group_count = 0, i, j, func_index, func_type_index;
uint32 group_count = 0, i, j;
uint64 size;
uint32 *symbol_offsets, total_string_len;
uint8 *symbol_buf, *symbol_buf_end;
bool ret = false;
AOTExportFunc *export_func;
read_uint32(buf, buf_end, symbol_count);
@ -1510,21 +1591,6 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
}
}
export_func = module->export_funcs;
for (i = 0; i < module->export_func_count; i++, export_func++) {
func_index = export_func->func_index - module->import_func_count;
if (func_index >= module->func_count) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"invalid export function index.");
ret = false;
goto fail;
}
func_type_index = module->func_type_indexes[func_index];
export_func->func_type = module->func_types[func_type_index];
export_func->func_ptr = module->func_ptrs[func_index];
}
ret = true;
fail:
@ -1621,17 +1687,13 @@ static void aot_free(void *ptr)
static AOTModule*
create_module(char *error_buf, uint32 error_buf_size)
{
AOTModule *module = wasm_runtime_malloc(sizeof(AOTModule));
AOTModule *module =
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
if (!module) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"allocate memory failed.");
return NULL;
}
memset(module, 0, sizeof(AOTModule));
module->module_type = Wasm_Module_AoT;
if (!(module->const_str_set =
@ -1703,10 +1765,9 @@ create_sections(const uint8 *buf, uint32 size,
read_uint32(p, p_end, section_size);
CHECK_BUF(p, p_end, section_size);
if (!(section = wasm_runtime_malloc(sizeof(AOTSection)))) {
set_error_buf(error_buf, error_buf_size,
"AOT module load failed: "
"allocate memory failed.");
if (!(section =
loader_malloc(sizeof(AOTSection),
error_buf, error_buf_size))) {
goto fail;
}
@ -1858,25 +1919,38 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
AOTModule *module;
/* Allocate memory for module */
if (!(module = wasm_runtime_malloc(sizeof(AOTModule)))) {
set_error_buf(error_buf, error_buf_size,
"Allocate memory for AOT module failed.");
if (!(module =
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size))) {
return NULL;
}
memset(module, 0, sizeof(AOTModule));
module->module_type = Wasm_Module_AoT;
module->num_bytes_per_page = comp_data->num_bytes_per_page;
module->mem_init_page_count = comp_data->mem_init_page_count;
module->mem_max_page_count = comp_data->mem_max_page_count;
module->import_memory_count = comp_data->import_memory_count;
module->import_memories = comp_data->import_memories;
module->memory_count = comp_data->memory_count;
if (module->memory_count) {
size = sizeof(AOTMemory) * (uint64)module->memory_count;
if (!(module->memories =
loader_malloc(size, error_buf, error_buf_size))) {
goto fail1;
}
bh_memcpy_s(module->memories, size, comp_data->memories, size);
}
module->mem_init_data_list = comp_data->mem_init_data_list;
module->mem_init_data_count = comp_data->mem_init_data_count;
module->import_table_count = comp_data->import_table_count;
module->import_tables = comp_data->import_tables;
module->table_count = comp_data->table_count;
module->tables = comp_data->tables;
module->table_init_data_list = comp_data->table_init_data_list;
module->table_init_data_count = comp_data->table_init_data_count;
module->table_size = comp_data->table_size;
module->func_type_count = comp_data->func_type_count;
module->func_types = comp_data->func_types;
@ -1899,15 +1973,13 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
/* Allocate memory for function pointers */
size = (uint64)module->func_count * sizeof(void *);
if (size >= UINT32_MAX
|| !(module->func_ptrs = wasm_runtime_malloc((uint32)size))) {
set_error_buf(error_buf, error_buf_size, "Create func ptrs fail.");
goto fail1;
if (!(module->func_ptrs =
loader_malloc(size, error_buf, error_buf_size))) {
goto fail2;
}
/* Resolve function addresses */
bh_assert(comp_ctx->exec_engine);
memset(module->func_ptrs, 0, (uint32)size);
for (i = 0; i < comp_data->func_count; i++) {
snprintf(func_name, sizeof(func_name), "%s%d", AOT_FUNC_PREFIX, i);
if (!(module->func_ptrs[i] =
@ -1915,30 +1987,21 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
func_name))) {
set_error_buf(error_buf, error_buf_size,
"Get function address fail.");
goto fail2;
goto fail3;
}
}
/* Allocation memory for function type indexes */
size = (uint64)module->func_count * sizeof(uint32);
if (size >= UINT32_MAX
|| !(module->func_type_indexes = wasm_runtime_malloc((uint32)size))) {
set_error_buf(error_buf, error_buf_size, "Create func type indexes fail.");
goto fail2;
if (!(module->func_type_indexes =
loader_malloc(size, error_buf, error_buf_size))) {
goto fail3;
}
memset(module->func_type_indexes, 0, (uint32)size);
for (i = 0; i < comp_data->func_count; i++)
module->func_type_indexes[i] = comp_data->funcs[i]->func_type_index;
module->export_func_count = comp_data->export_func_count;
module->export_funcs = comp_data->export_funcs;
/* Set export function pointers */
for (i = 0; i < module->export_func_count; i++) {
module->export_funcs[i].func_ptr =
module->func_ptrs[module->export_funcs[i].func_index
- module->import_func_count];
}
module->export_count = comp_data->wasm_module->export_count;
module->exports = comp_data->wasm_module->exports;
module->start_func_index = comp_data->start_func_index;
if (comp_data->start_func_index != (uint32)-1) {
@ -1975,8 +2038,11 @@ aot_load_from_comp_data(AOTCompData *comp_data, AOTCompContext *comp_ctx,
return module;
fail2:
fail3:
wasm_runtime_free(module->func_ptrs);
fail2:
if (module->memory_count > 0)
wasm_runtime_free(module->memories);
fail1:
wasm_runtime_free(module);
return NULL;
@ -2001,6 +2067,9 @@ aot_convert_wasm_module(WASMModule *wasm_module,
}
option.is_jit_mode = true;
#if WASM_ENABLE_THREAD_MGR != 0
option.enable_thread_mgr = true;
#endif
comp_ctx = aot_create_comp_context(comp_data, &option);
if (!comp_ctx) {
aot_last_error = aot_get_last_error();
@ -2046,11 +2115,25 @@ aot_unload(AOTModule *module)
wasm_loader_unload(module->wasm_module);
#endif
if (module->import_memories)
destroy_import_memories(module->import_memories,
module->is_jit_mode);
if (module->memories)
wasm_runtime_free(module->memories);
if (module->mem_init_data_list)
destroy_mem_init_data_list(module->mem_init_data_list,
module->mem_init_data_count,
module->is_jit_mode);
if (module->import_tables)
destroy_import_tables(module->import_tables,
module->is_jit_mode);
if (module->tables)
destroy_tables(module->tables, module->is_jit_mode);
if (module->table_init_data_list)
destroy_table_init_data_list(module->table_init_data_list,
module->table_init_data_count,
@ -2073,9 +2156,9 @@ aot_unload(AOTModule *module)
destroy_import_funcs(module->import_funcs,
module->is_jit_mode);
if (module->export_funcs)
destroy_export_funcs(module->export_funcs,
module->is_jit_mode);
if (module->exports)
destroy_exports(module->exports,
module->is_jit_mode);
if (module->func_type_indexes)
wasm_runtime_free(module->func_type_indexes);

View File

@ -6,6 +6,9 @@
#include "aot_runtime.h"
#include "bh_log.h"
#include "mem_alloc.h"
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "../common/wasm_shared_memory.h"
#endif
static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
@ -38,7 +41,7 @@ global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 i;
InitializerExpression *init_expr;
uint8 *p = (uint8*)module_inst->global_data.ptr;
AOTImportGlobal *import_global = module->import_globals;;
AOTImportGlobal *import_global = module->import_globals;
AOTGlobal *global = module->globals;
/* Initialize import global data */
@ -146,22 +149,93 @@ table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
return true;
}
static bool
static void
memories_deinstantiate(AOTModuleInstance *module_inst)
{
uint32 i;
AOTMemoryInstance *memory_inst;
for (i = 0; i < module_inst->memory_count; i++) {
memory_inst = ((AOTMemoryInstance **)module_inst->memories.ptr)[i];
if (memory_inst) {
#if WASM_ENABLE_SHARED_MEMORY != 0
if (memory_inst->is_shared) {
int32 ref_count =
shared_memory_dec_reference(
(WASMModuleCommon *)module_inst->aot_module.ptr);
bh_assert(ref_count >= 0);
/* if the reference count is not zero,
don't free the memory */
if (ref_count > 0)
continue;
}
#endif
if (memory_inst->heap_handle.ptr)
mem_allocator_destroy(memory_inst->heap_handle.ptr);
if (memory_inst->heap_data.ptr) {
#ifndef OS_ENABLE_HW_BOUND_CHECK
wasm_runtime_free(memory_inst->heap_data.ptr);
#else
os_munmap((uint8*)memory_inst->memory_data.ptr - 2 * (uint64)BH_GB,
8 * (uint64)BH_GB);
#endif
}
}
}
wasm_runtime_free(module_inst->memories.ptr);
}
static AOTMemoryInstance*
memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
AOTMemoryInstance *memory_inst, AOTMemory *memory,
uint32 heap_size, char *error_buf, uint32 error_buf_size)
{
uint32 i, global_index, global_data_offset, base_offset, length;
AOTMemInitData *data_seg;
void *heap_handle;
uint64 memory_data_size = (uint64)module->num_bytes_per_page
* module->mem_init_page_count;
uint64 memory_data_size = (uint64)memory->num_bytes_per_page
* memory->mem_init_page_count;
uint64 total_size = heap_size + memory_data_size;
uint8 *p;
#if WASM_ENABLE_SHARED_MEMORY != 0
AOTMemoryInstance *shared_memory_instance;
bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
uint64 max_memory_data_size = (uint64)memory->num_bytes_per_page
* memory->mem_max_page_count;
/* Shared memory */
if (is_shared_memory) {
WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module);
/* If the memory of this module has been instantiated,
return the memory instance directly */
if (node) {
uint32 ref_count;
ref_count = shared_memory_inc_reference(
(WASMModuleCommon *)module);
bh_assert(ref_count > 0);
shared_memory_instance =
(AOTMemoryInstance *)shared_memory_get_memory_inst(node);
bh_assert(shared_memory_instance);
/* Set the shared memory flag, so the runtime will get the
actual memory inst through module_inst->memories array */
memory_inst->is_shared = true;
(void)ref_count;
return shared_memory_instance;
}
#ifndef OS_ENABLE_HW_BOUND_CHECK
/* Allocate max page for shared memory */
total_size = heap_size + max_memory_data_size;
#endif
}
#endif
#ifndef OS_ENABLE_HW_BOUND_CHECK
/* Allocate memory */
if (!(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
return false;
return NULL;
}
#else
uint8 *mapped_mem;
@ -178,7 +252,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
MMAP_PROT_NONE, MMAP_MAP_NONE))) {
set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: mmap memory failed.");
return false;
return NULL;
}
p = mapped_mem + 2 * (uint64)BH_GB - heap_size;
@ -186,40 +260,128 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: mprotec memory failed.");
os_munmap(mapped_mem, map_size);
return false;
return NULL;
}
memset(p, 0, (uint32)total_size);
#endif
memory_inst->module_type = Wasm_Module_AoT;
/* Initialize heap info */
module_inst->heap_data.ptr = p;
memory_inst->heap_data.ptr = p;
p += heap_size;
module_inst->heap_data_end.ptr = p;
module_inst->heap_data_size = heap_size;
module_inst->heap_base_offset = -(int32)heap_size;
memory_inst->heap_data_end.ptr = p;
memory_inst->heap_data_size = heap_size;
memory_inst->heap_base_offset = -(int32)heap_size;
if (heap_size > 0) {
if (!(heap_handle = mem_allocator_create(module_inst->heap_data.ptr,
if (!(heap_handle = mem_allocator_create(memory_inst->heap_data.ptr,
heap_size))) {
set_error_buf(error_buf, error_buf_size,
"AOT module instantiate failed: init app heap failed.");
"AOT module instantiate failed:"
"init app heap failed.");
goto fail1;
}
module_inst->heap_handle.ptr = heap_handle;
memory_inst->heap_handle.ptr = heap_handle;
}
/* Init memory info */
module_inst->memory_data.ptr = p;
p += (uint32)memory_data_size;
module_inst->memory_data_end.ptr = p;
module_inst->memory_data_size = (uint32)memory_data_size;
module_inst->mem_cur_page_count = module->mem_init_page_count;
module_inst->mem_max_page_count = module->mem_max_page_count;
memory_inst->memory_data.ptr = p;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) {
p += (uint32)max_memory_data_size;
}
else
#endif
{
p += (uint32)memory_data_size;
}
memory_inst->memory_data_end.ptr = p;
memory_inst->memory_data_size = (uint32)memory_data_size;
memory_inst->mem_cur_page_count = memory->mem_init_page_count;
memory_inst->mem_max_page_count = memory->mem_max_page_count;
module_inst->mem_bound_check_heap_base = (int64)module_inst->heap_base_offset;
module_inst->mem_bound_check_1byte = (int64)module_inst->memory_data_size - 1;
module_inst->mem_bound_check_2bytes = (int64)module_inst->memory_data_size - 2;
module_inst->mem_bound_check_4bytes = (int64)module_inst->memory_data_size - 4;
module_inst->mem_bound_check_8bytes = (int64)module_inst->memory_data_size - 8;
memory_inst->mem_bound_check_heap_base = memory_inst->heap_base_offset;
memory_inst->mem_bound_check_1byte =
(int64)memory_inst->memory_data_size - 1;
memory_inst->mem_bound_check_2bytes =
(int64)memory_inst->memory_data_size - 2;
memory_inst->mem_bound_check_4bytes =
(int64)memory_inst->memory_data_size - 4;
memory_inst->mem_bound_check_8bytes =
(int64)memory_inst->memory_data_size - 8;
#if WASM_ENABLE_SHARED_MEMORY != 0
if (is_shared_memory) {
memory_inst->is_shared = true;
if (!shared_memory_set_memory_inst((WASMModuleCommon *)module,
(WASMMemoryInstanceCommon *)memory_inst)) {
set_error_buf(error_buf, error_buf_size,
"Instantiate memory failed:"
"allocate memory failed.");
goto fail2;
}
}
#endif
return memory_inst;
#if WASM_ENABLE_SHARED_MEMORY != 0
fail2:
if (heap_size > 0) {
mem_allocator_destroy(memory_inst->heap_handle.ptr);
memory_inst->heap_handle.ptr = NULL;
}
#endif
fail1:
#ifndef OS_ENABLE_HW_BOUND_CHECK
wasm_runtime_free(memory_inst->heap_data.ptr);
#else
os_munmap(mapped_mem, map_size);
#endif
memory_inst->heap_data.ptr = NULL;
return NULL;
}
static AOTMemoryInstance*
aot_get_default_memory(AOTModuleInstance *module_inst)
{
if (module_inst->memories.ptr)
return ((AOTMemoryInstance **)module_inst->memories.ptr)[0];
else
return NULL;
}
static bool
memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
uint32 heap_size, char *error_buf, uint32 error_buf_size)
{
uint32 global_index, global_data_offset, base_offset, length;
uint32 i, memory_count = module->memory_count;
AOTMemoryInstance *memories, *memory_inst;
AOTMemInitData *data_seg;
uint64 total_size;
module_inst->memory_count = memory_count;
total_size = sizeof(AOTPointer) * (uint64)memory_count;
if (!(module_inst->memories.ptr =
runtime_malloc(total_size, error_buf, error_buf_size))) {
return false;
}
memories = module_inst->global_table_data.memory_instances;
for (i = 0; i < memory_count; i++, memories++) {
memory_inst =
memory_instantiate(module_inst, module,
memories, &module->memories[i],
heap_size, error_buf, error_buf_size);
if (!memory_inst) {
return false;
}
((AOTMemoryInstance **)module_inst->memories.ptr)[i] = memory_inst;
}
/* Get default memory instance */
memory_inst = aot_get_default_memory(module_inst);
for (i = 0; i < module->mem_init_data_count; i++) {
data_seg = module->mem_init_data_list[i];
@ -255,47 +417,34 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
}
/* Copy memory data */
bh_assert(module_inst->memory_data.ptr);
bh_assert(memory_inst->memory_data.ptr);
/* Check memory data */
/* check offset since length might negative */
if (base_offset > module_inst->memory_data_size) {
if (base_offset > memory_inst->memory_data_size) {
LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
module_inst->memory_data_size);
memory_inst->memory_data_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail2;
return false;
}
/* check offset + length(could be zero) */
length = data_seg->byte_count;
if (base_offset + length > module_inst->memory_data_size) {
if (base_offset + length > memory_inst->memory_data_size) {
LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
base_offset, length, module_inst->memory_data_size);
base_offset, length, memory_inst->memory_data_size);
set_error_buf(error_buf, error_buf_size,
"data segment does not fit");
goto fail2;
return false;
}
memcpy((uint8*)module_inst->memory_data.ptr + base_offset,
data_seg->bytes, length);
bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset,
memory_inst->memory_data_size - base_offset,
data_seg->bytes, length);
}
return true;
fail2:
if (heap_size > 0) {
mem_allocator_destroy(module_inst->heap_handle.ptr);
module_inst->heap_handle.ptr = NULL;
}
fail1:
#ifndef OS_ENABLE_HW_BOUND_CHECK
wasm_runtime_free(module_inst->heap_data.ptr);
#else
os_munmap(mapped_mem, map_size);
#endif
module_inst->heap_data.ptr = NULL;
return false;
}
static bool
@ -349,6 +498,64 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
return true;
}
static bool
create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
char *error_buf, uint32 error_buf_size)
{
AOTExport *exports = module->exports;
AOTFunctionInstance *export_func;
uint64 size;
uint32 i, func_index, ftype_index;
for (i = 0; i < module->export_count; i++) {
if (exports[i].kind == EXPORT_KIND_FUNC)
module_inst->export_func_count++;
}
if (module_inst->export_func_count > 0) {
/* Allocate memory */
size = sizeof(AOTFunctionInstance)
* (uint64)module_inst->export_func_count;
if (!(module_inst->export_funcs.ptr = export_func =
runtime_malloc(size, error_buf, error_buf_size))) {
return false;
}
for (i = 0; i < module->export_count; i++) {
if (exports[i].kind == EXPORT_KIND_FUNC) {
export_func->func_name = exports[i].name;
export_func->func_index = exports[i].index;
if (export_func->func_index < module->import_func_count) {
export_func->is_import_func = true;
export_func->u.func_import =
&module->import_funcs[export_func->func_index];
}
else {
export_func->is_import_func = false;
func_index = export_func->func_index
- module->import_func_count;
ftype_index = module->func_type_indexes[func_index];
export_func->u.func.func_type =
module->func_types[ftype_index];
export_func->u.func.func_ptr =
module->func_ptrs[func_index];
}
export_func++;
}
}
}
return true;
}
static bool
create_exports(AOTModuleInstance *module_inst, AOTModule *module,
char *error_buf, uint32 error_buf_size)
{
return create_export_funcs(module_inst, module,
error_buf, error_buf_size);
}
static bool
execute_post_inst_function(AOTModuleInstance *module_inst)
{
@ -386,6 +593,22 @@ execute_start_function(AOTModuleInstance *module_inst)
return !aot_get_exception(module_inst);
}
#if WASM_ENABLE_BULK_MEMORY != 0
static bool
execute_memory_init_function(AOTModuleInstance *module_inst)
{
AOTFunctionInstance *memory_init_func =
aot_lookup_function(module_inst, "__wasm_call_ctors", "()");
if (!memory_init_func)
/* Not found */
return true;
return aot_create_exec_env_and_call_function(module_inst, memory_init_func,
0, NULL);
}
#endif
AOTModuleInstance*
aot_instantiate(AOTModule *module, bool is_sub_inst,
uint32 stack_size, uint32 heap_size,
@ -394,8 +617,13 @@ aot_instantiate(AOTModule *module, bool is_sub_inst,
AOTModuleInstance *module_inst;
uint32 module_inst_struct_size =
offsetof(AOTModuleInstance, global_table_data.bytes);
uint64 table_data_size = (uint64)module->table_size * sizeof(uint32);
uint64 module_inst_mem_inst_size =
(uint64)module->memory_count * sizeof(AOTMemoryInstance);
uint32 table_size = module->table_count > 0 ?
module->tables[0].table_init_size : 0;
uint64 table_data_size = (uint64)table_size * sizeof(uint32);
uint64 total_size = (uint64)module_inst_struct_size
+ module_inst_mem_inst_size
+ module->global_data_size
+ table_data_size;
uint8 *p;
@ -418,7 +646,8 @@ aot_instantiate(AOTModule *module, bool is_sub_inst,
module_inst->aot_module.ptr = module;
/* Initialize global info */
p = (uint8*)module_inst + module_inst_struct_size;
p = (uint8*)module_inst + module_inst_struct_size +
module_inst_mem_inst_size;
module_inst->global_data.ptr = p;
module_inst->global_data_size = module->global_data_size;
if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
@ -427,15 +656,15 @@ aot_instantiate(AOTModule *module, bool is_sub_inst,
/* Initialize table info */
p += module->global_data_size;
module_inst->table_data.ptr = p;
module_inst->table_size = module->table_size;
module_inst->table_size = table_size;
/* Set all elements to -1 to mark them as uninitialized elements */
memset(module_inst->table_data.ptr, -1, (uint32)table_data_size);
if (!table_instantiate(module_inst, module, error_buf, error_buf_size))
goto fail;
/* Initialize memory space */
if (!memory_instantiate(module_inst, module, heap_size,
error_buf, error_buf_size))
if (!memories_instantiate(module_inst, module, heap_size,
error_buf, error_buf_size))
goto fail;
/* Initialize function pointers */
@ -446,19 +675,24 @@ aot_instantiate(AOTModule *module, bool is_sub_inst,
if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
goto fail;
#if WASM_ENABLE_LIBC_WASI != 0
if (heap_size > 0
&& !wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
module->wasi_args.dir_list,
module->wasi_args.dir_count,
module->wasi_args.map_dir_list,
module->wasi_args.map_dir_count,
module->wasi_args.env,
module->wasi_args.env_count,
module->wasi_args.argv,
module->wasi_args.argc,
error_buf, error_buf_size))
if (!create_exports(module_inst, module, error_buf, error_buf_size))
goto fail;
#if WASM_ENABLE_LIBC_WASI != 0
if (!is_sub_inst) {
if (heap_size > 0
&& !wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
module->wasi_args.dir_list,
module->wasi_args.dir_count,
module->wasi_args.map_dir_list,
module->wasi_args.map_dir_count,
module->wasi_args.env,
module->wasi_args.env_count,
module->wasi_args.argv,
module->wasi_args.argc,
error_buf, error_buf_size))
goto fail;
}
#endif
/* Initialize the thread related data */
@ -478,6 +712,25 @@ aot_instantiate(AOTModule *module, bool is_sub_inst,
goto fail;
}
#if WASM_ENABLE_BULK_MEMORY != 0
#if WASM_ENABLE_LIBC_WASI != 0
if (!module->is_wasi_module) {
#endif
/* Only execute the memory init function for main instance because
the data segments will be dropped once initialized.
*/
if (!is_sub_inst) {
if (!execute_memory_init_function(module_inst)) {
set_error_buf(error_buf, error_buf_size,
module_inst->cur_exception);
goto fail;
}
}
#if WASM_ENABLE_LIBC_WASI != 0
}
#endif
#endif
return module_inst;
fail:
@ -498,17 +751,11 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
#endif
if (module_inst->heap_handle.ptr)
mem_allocator_destroy(module_inst->heap_handle.ptr);
if (module_inst->memories.ptr)
memories_deinstantiate(module_inst);
if (module_inst->heap_data.ptr) {
#ifndef OS_ENABLE_HW_BOUND_CHECK
wasm_runtime_free(module_inst->heap_data.ptr);
#else
os_munmap((uint8*)module_inst->memory_data.ptr - 2 * (uint64)BH_GB,
8 * (uint64)BH_GB);
#endif
}
if (module_inst->export_funcs.ptr)
wasm_runtime_free(module_inst->export_funcs.ptr);
if (module_inst->func_ptrs.ptr)
wasm_runtime_free(module_inst->func_ptrs.ptr);
@ -524,11 +771,12 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
const char *name, const char *signature)
{
uint32 i;
AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
AOTFunctionInstance *export_funcs = (AOTFunctionInstance *)
module_inst->export_funcs.ptr;
for (i = 0; i < module->export_func_count; i++)
if (!strcmp(module->export_funcs[i].func_name, name))
return &module->export_funcs[i];
for (i = 0; i < module_inst->export_func_count; i++)
if (!strcmp(export_funcs[i].func_name, name))
return &export_funcs[i];
(void)signature;
return NULL;
}
@ -565,6 +813,7 @@ static void
aot_signal_handler(void *sig_addr)
{
AOTModuleInstance *module_inst;
AOTMemoryInstance *memory_inst;
WASMJmpBuf *jmpbuf_node;
uint8 *mapped_mem_start_addr, *mapped_mem_end_addr;
uint8 *stack_min_addr;
@ -577,17 +826,22 @@ aot_signal_handler(void *sig_addr)
&& (jmpbuf_node = aot_exec_env->jmpbuf_stack_top)) {
/* Get mapped mem info of current instance */
module_inst = (AOTModuleInstance *)aot_exec_env->module_inst;
mapped_mem_start_addr = (uint8*)module_inst->memory_data.ptr
- 2 * (uint64)BH_GB;
mapped_mem_end_addr = (uint8*)module_inst->memory_data.ptr
+ 6 * (uint64)BH_GB;
/* Get the default memory instance */
memory_inst = aot_get_default_memory(module_inst);
if (memory_inst) {
mapped_mem_start_addr = (uint8*)memory_inst->memory_data.ptr
- 2 * (uint64)BH_GB;
mapped_mem_end_addr = (uint8*)memory_inst->memory_data.ptr
+ 6 * (uint64)BH_GB;
}
/* Get stack info of current thread */
page_size = os_getpagesize();
stack_min_addr = get_stack_min_addr(aot_exec_env, page_size);
if (mapped_mem_start_addr <= (uint8*)sig_addr
&& (uint8*)sig_addr < mapped_mem_end_addr) {
if (memory_inst
&& (mapped_mem_start_addr <= (uint8*)sig_addr
&& (uint8*)sig_addr < mapped_mem_end_addr)) {
/* The address which causes segmentation fault is inside
aot instance's guard regions */
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS);
@ -721,7 +975,7 @@ aot_call_function(WASMExecEnv *exec_env,
unsigned argc, uint32 argv[])
{
AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
AOTFuncType *func_type = function->func_type;
AOTFuncType *func_type = function->u.func.func_type;
uint32 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
bool ret;
@ -758,7 +1012,7 @@ aot_call_function(WASMExecEnv *exec_env,
cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
}
ret = invoke_native_internal(exec_env, function->func_ptr,
ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
func_type, NULL, NULL, argv1, argc, argv);
if (!ret || aot_get_exception(module_inst)) {
if (argv1 != argv1_buf)
@ -789,7 +1043,7 @@ aot_call_function(WASMExecEnv *exec_env,
return true;
}
else {
ret = invoke_native_internal(exec_env, function->func_ptr,
ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
func_type, NULL, NULL, argv, argc, argv);
return ret && !aot_get_exception(module_inst) ? true : false;
}
@ -894,24 +1148,26 @@ int32
aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
void **p_native_addr)
{
uint8 *addr = mem_allocator_malloc(module_inst->heap_handle.ptr, size);
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
uint8 *addr = mem_allocator_malloc(memory_inst->heap_handle.ptr, size);
if (!addr) {
aot_set_exception(module_inst, "out of memory");
return 0;
}
if (p_native_addr)
*p_native_addr = addr;
return (int32)(addr - (uint8*)module_inst->memory_data.ptr);
return (int32)(addr - (uint8*)memory_inst->memory_data.ptr);
}
void
aot_module_free(AOTModuleInstance *module_inst, int32 ptr)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
if (ptr) {
uint8 *addr = (uint8*)module_inst->memory_data.ptr + ptr;
if ((uint8*)module_inst->heap_data.ptr < addr
&& addr < (uint8*)module_inst->memory_data.ptr)
mem_allocator_free(module_inst->heap_handle.ptr, addr);
uint8 *addr = (uint8*)memory_inst->memory_data.ptr + ptr;
if ((uint8*)memory_inst->heap_data.ptr < addr
&& addr < (uint8*)memory_inst->memory_data.ptr)
mem_allocator_free(memory_inst->heap_handle.ptr, addr);
}
}
@ -934,13 +1190,14 @@ bool
aot_validate_app_addr(AOTModuleInstance *module_inst,
int32 app_offset, uint32 size)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
/* integer overflow check */
if(app_offset + (int32)size < app_offset) {
goto fail;
}
if (module_inst->heap_base_offset <= app_offset
&& app_offset + (int32)size <= (int32)module_inst->memory_data_size) {
if (memory_inst->heap_base_offset <= app_offset
&& app_offset + (int32)size <= (int32)memory_inst->memory_data_size) {
return true;
}
fail:
@ -953,15 +1210,16 @@ aot_validate_native_addr(AOTModuleInstance *module_inst,
void *native_ptr, uint32 size)
{
uint8 *addr = (uint8*)native_ptr;
int32 memory_data_size = (int32)module_inst->memory_data_size;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
int32 memory_data_size = (int32)memory_inst->memory_data_size;
/* integer overflow check */
if (addr + size < addr) {
goto fail;
}
if ((uint8*)module_inst->heap_data.ptr <= addr
&& addr + size <= (uint8*)module_inst->memory_data.ptr
if ((uint8*)memory_inst->heap_data.ptr <= addr
&& addr + size <= (uint8*)memory_inst->memory_data.ptr
+ memory_data_size) {
return true;
}
@ -973,11 +1231,12 @@ fail:
void *
aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset)
{
int32 memory_data_size = (int32)module_inst->memory_data_size;
uint8 *addr = (uint8 *)module_inst->memory_data.ptr + app_offset;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
int32 memory_data_size = (int32)memory_inst->memory_data_size;
uint8 *addr = (uint8 *)memory_inst->memory_data.ptr + app_offset;
if ((uint8*)module_inst->heap_data.ptr <= addr
&& addr < (uint8*)module_inst->memory_data.ptr
if ((uint8*)memory_inst->heap_data.ptr <= addr
&& addr < (uint8*)memory_inst->memory_data.ptr
+ memory_data_size)
return addr;
return NULL;
@ -987,12 +1246,13 @@ int32
aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr)
{
uint8 *addr = (uint8*)native_ptr;
int32 memory_data_size = (int32)module_inst->memory_data_size;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
int32 memory_data_size = (int32)memory_inst->memory_data_size;
if ((uint8*)module_inst->heap_data.ptr <= addr
&& addr < (uint8*)module_inst->memory_data.ptr
if ((uint8*)memory_inst->heap_data.ptr <= addr
&& addr < (uint8*)memory_inst->memory_data.ptr
+ memory_data_size)
return (int32)(addr - (uint8*)module_inst->memory_data.ptr);
return (int32)(addr - (uint8*)memory_inst->memory_data.ptr);
return 0;
}
@ -1002,12 +1262,13 @@ aot_get_app_addr_range(AOTModuleInstance *module_inst,
int32 *p_app_start_offset,
int32 *p_app_end_offset)
{
int32 memory_data_size = (int32)module_inst->memory_data_size;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
int32 memory_data_size = (int32)memory_inst->memory_data_size;
if (module_inst->heap_base_offset <= app_offset
if (memory_inst->heap_base_offset <= app_offset
&& app_offset < memory_data_size) {
if (p_app_start_offset)
*p_app_start_offset = module_inst->heap_base_offset;
*p_app_start_offset = memory_inst->heap_base_offset;
if (p_app_end_offset)
*p_app_end_offset = memory_data_size;
return true;
@ -1022,15 +1283,16 @@ aot_get_native_addr_range(AOTModuleInstance *module_inst,
uint8 **p_native_end_addr)
{
uint8 *addr = (uint8*)native_ptr;
int32 memory_data_size = (int32)module_inst->memory_data_size;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
int32 memory_data_size = (int32)memory_inst->memory_data_size;
if ((uint8*)module_inst->heap_data.ptr <= addr
&& addr < (uint8*)module_inst->memory_data.ptr
if ((uint8*)memory_inst->heap_data.ptr <= addr
&& addr < (uint8*)memory_inst->memory_data.ptr
+ memory_data_size) {
if (p_native_start_addr)
*p_native_start_addr = (uint8*)module_inst->heap_data.ptr;
*p_native_start_addr = (uint8*)memory_inst->heap_data.ptr;
if (p_native_end_addr)
*p_native_end_addr = (uint8*)module_inst->memory_data.ptr
*p_native_end_addr = (uint8*)memory_inst->memory_data.ptr
+ memory_data_size;
return true;
}
@ -1041,18 +1303,19 @@ aot_get_native_addr_range(AOTModuleInstance *module_inst,
bool
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
{
uint8 *heap_data_old = module_inst->heap_data.ptr, *heap_data;
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
uint8 *heap_data_old = memory_inst->heap_data.ptr, *heap_data;
uint32 num_bytes_per_page =
((AOTModule*)module_inst->aot_module.ptr)->num_bytes_per_page;
uint32 cur_page_count = module_inst->mem_cur_page_count;
uint32 max_page_count = module_inst->mem_max_page_count;
((AOTModule*)module_inst->aot_module.ptr)->memories[0].num_bytes_per_page;
uint32 cur_page_count = memory_inst->mem_cur_page_count;
uint32 max_page_count = memory_inst->mem_max_page_count;
uint32 total_page_count = cur_page_count + inc_page_count;
uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count;
uint32 heap_size = (uint32)((uint8*)module_inst->memory_data.ptr
- (uint8*)module_inst->heap_data.ptr);
uint32 total_size_old = heap_size + module_inst->memory_data_size;
uint32 heap_size = (uint32)((uint8*)memory_inst->memory_data.ptr
- (uint8*)memory_inst->heap_data.ptr);
uint32 total_size_old = heap_size + memory_inst->memory_data_size;
uint64 total_size = heap_size + memory_data_size;
void *heap_handle_old = module_inst->heap_handle.ptr;
void *heap_handle_old = memory_inst->heap_handle.ptr;
if (inc_page_count <= 0)
/* No need to enlarge memory */
@ -1069,16 +1332,25 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
return false;
}
#if WASM_ENABLE_SHARED_MEMORY != 0
if (memory_inst->is_shared) {
/* For shared memory, we have reserved the maximum spaces during
instantiate, only change the cur_page_count here */
memory_inst->mem_cur_page_count = total_page_count;
return true;
}
#endif
if (heap_size > 0) {
/* Destroy heap's lock firstly, if its memory is re-allocated,
we cannot access its lock again. */
mem_allocator_destroy_lock(module_inst->heap_handle.ptr);
mem_allocator_destroy_lock(memory_inst->heap_handle.ptr);
}
if (!(heap_data = wasm_runtime_realloc(heap_data_old, (uint32)total_size))) {
if (!(heap_data = wasm_runtime_malloc((uint32)total_size))) {
if (heap_size > 0) {
/* Restore heap's lock if memory re-alloc failed */
mem_allocator_reinit_lock(module_inst->heap_handle.ptr);
mem_allocator_reinit_lock(memory_inst->heap_handle.ptr);
}
aot_set_exception(module_inst, "fail to enlarge memory.");
return false;
@ -1091,39 +1363,40 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
memset(heap_data + total_size_old,
0, (uint32)total_size - total_size_old);
module_inst->heap_data.ptr = heap_data;
module_inst->heap_data_end.ptr = heap_data + heap_size;
memory_inst->heap_data.ptr = heap_data;
memory_inst->heap_data_end.ptr = heap_data + heap_size;
if (heap_size > 0) {
module_inst->heap_handle.ptr = (uint8*)heap_handle_old
memory_inst->heap_handle.ptr = (uint8*)heap_handle_old
+ (heap_data - heap_data_old);
if (mem_allocator_migrate(module_inst->heap_handle.ptr,
if (mem_allocator_migrate(memory_inst->heap_handle.ptr,
heap_handle_old) != 0) {
aot_set_exception(module_inst, "fail to enlarge memory.");
return false;
}
}
module_inst->mem_cur_page_count = total_page_count;
module_inst->memory_data_size = (uint32)memory_data_size;
module_inst->memory_data.ptr = (uint8*)heap_data + heap_size;
module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr
memory_inst->mem_cur_page_count = total_page_count;
memory_inst->memory_data_size = (uint32)memory_data_size;
memory_inst->memory_data.ptr = (uint8*)heap_data + heap_size;
memory_inst->memory_data_end.ptr = (uint8*)memory_inst->memory_data.ptr
+ (uint32)memory_data_size;
module_inst->mem_bound_check_1byte = module_inst->memory_data_size - 1;
module_inst->mem_bound_check_2bytes = module_inst->memory_data_size - 2;
module_inst->mem_bound_check_4bytes = module_inst->memory_data_size - 4;
module_inst->mem_bound_check_8bytes = module_inst->memory_data_size - 8;
memory_inst->mem_bound_check_1byte = memory_inst->memory_data_size - 1;
memory_inst->mem_bound_check_2bytes = memory_inst->memory_data_size - 2;
memory_inst->mem_bound_check_4bytes = memory_inst->memory_data_size - 4;
memory_inst->mem_bound_check_8bytes = memory_inst->memory_data_size - 8;
return true;
}
#else
bool
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
uint32 num_bytes_per_page =
((AOTModule*)module_inst->aot_module.ptr)->num_bytes_per_page;
uint32 cur_page_count = module_inst->mem_cur_page_count;
uint32 max_page_count = module_inst->mem_max_page_count;
((AOTModule*)module_inst->aot_module.ptr)->memories[0].num_bytes_per_page;
uint32 cur_page_count = memory_inst->mem_cur_page_count;
uint32 max_page_count = memory_inst->mem_max_page_count;
uint32 total_page_count = cur_page_count + inc_page_count;
uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count;
@ -1137,24 +1410,24 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
return false;
}
if (os_mprotect(module_inst->memory_data.ptr, memory_data_size,
if (os_mprotect(memory_inst->memory_data.ptr, memory_data_size,
MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
aot_set_exception(module_inst, "fail to enlarge memory.");
return false;
}
memset(module_inst->memory_data_end.ptr, 0,
memset(memory_inst->memory_data_end.ptr, 0,
num_bytes_per_page * inc_page_count);
module_inst->mem_cur_page_count = total_page_count;
module_inst->memory_data_size = (uint32)memory_data_size;
module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr
memory_inst->mem_cur_page_count = total_page_count;
memory_inst->memory_data_size = (uint32)memory_data_size;
memory_inst->memory_data_end.ptr = (uint8*)memory_inst->memory_data.ptr
+ (uint32)memory_data_size;
module_inst->mem_bound_check_1byte = module_inst->memory_data_size - 1;
module_inst->mem_bound_check_2bytes = module_inst->memory_data_size - 2;
module_inst->mem_bound_check_4bytes = module_inst->memory_data_size - 4;
module_inst->mem_bound_check_8bytes = module_inst->memory_data_size - 8;
memory_inst->mem_bound_check_1byte = memory_inst->memory_data_size - 1;
memory_inst->mem_bound_check_2bytes = memory_inst->memory_data_size - 2;
memory_inst->mem_bound_check_4bytes = memory_inst->memory_data_size - 4;
memory_inst->mem_bound_check_8bytes = memory_inst->memory_data_size - 8;
return true;
}
#endif
@ -1389,6 +1662,7 @@ bool
aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index,
uint32 offset, uint32 len, uint32 dst)
{
AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
AOTModule *aot_module;
uint8 *data = NULL;
uint8 *maddr;
@ -1416,7 +1690,7 @@ aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index,
maddr = aot_addr_app_to_native(module_inst, dst);
bh_memcpy_s(maddr, module_inst->memory_data_size - dst,
bh_memcpy_s(maddr, memory_inst->memory_data_size - dst,
data + offset, len);
return true;
}
@ -1441,3 +1715,68 @@ aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
return true;
}
#endif /* WASM_ENABLE_BULK_MEMORY */
#if WASM_ENABLE_THREAD_MGR != 0
bool
aot_set_aux_stack(WASMExecEnv *exec_env,
uint32 start_offset, uint32 size)
{
AOTModuleInstance *module_inst =
(AOTModuleInstance*)exec_env->module_inst;
AOTModule *module = (AOTModule *)module_inst->aot_module.ptr;
uint32 stack_top_idx =
module->llvm_aux_stack_global_index;
uint32 data_end =
module->llvm_aux_data_end;
uint32 stack_bottom =
module->llvm_aux_stack_bottom;
bool is_stack_before_data =
stack_bottom < data_end ? true : false;
/* Check the aux stack space, currently we don't allocate space in heap */
if ((is_stack_before_data && (size > start_offset))
|| ((!is_stack_before_data) && (start_offset - data_end < size)))
return false;
if ((stack_bottom != (uint32)-1) && (stack_top_idx != (uint32)-1)) {
/* The aux stack top is a wasm global,
set the initial value for the global */
uint32 global_offset =
module->globals[stack_top_idx].data_offset;
uint8 *global_addr = module_inst->global_data.ptr + global_offset;
*(int32*)global_addr = start_offset;
/* The aux stack boundary is a constant value,
set the value to exec_env */
exec_env->aux_stack_boundary = start_offset - size;
return true;
}
return false;
}
bool
aot_get_aux_stack(WASMExecEnv *exec_env,
uint32 *start_offset, uint32 *size)
{
AOTModuleInstance *module_inst =
(AOTModuleInstance*)exec_env->module_inst;
AOTModule *module = (AOTModule *)module_inst->aot_module.ptr;
/* The aux stack information is resolved in loader
and store in module */
uint32 stack_bottom = module->llvm_aux_stack_bottom;
uint32 total_aux_stack_size = module->llvm_aux_stack_size;
if (stack_bottom != 0 && total_aux_stack_size != 0) {
if (start_offset)
*start_offset = stack_bottom;
if (size)
*size = total_aux_stack_size;
return true;
}
return false;
}
#endif

View File

@ -69,18 +69,45 @@ typedef struct AOTRelocationGroup {
AOTRelocation *relocations;
} AOTRelocationGroup;
/* AOT function instance */
typedef struct AOTFunctionInstance {
char *func_name;
uint32 func_index;
bool is_import_func;
union {
struct {
AOTFuncType *func_type;
/* function pointer linked */
void *func_ptr;
} func;
AOTImportFunc *func_import;
} u;
} AOTFunctionInstance;
typedef struct AOTModule {
uint32 module_type;
/* import memories */
uint32 import_memory_count;
AOTImportMemory *import_memories;
/* memory info */
uint32 num_bytes_per_page;
uint32 mem_init_page_count;
uint32 mem_max_page_count;
uint32 memory_count;
AOTMemory *memories;
/* init data */
uint32 mem_init_data_count;
AOTMemInitData **mem_init_data_list;
/* table info */
uint32 table_size;
/* import tables */
uint32 import_table_count;
AOTImportTable *import_tables;
/* tables */
uint32 table_count;
AOTTable *tables;
/* table init data info */
uint32 table_init_data_count;
AOTTableInitData **table_init_data_list;
@ -110,9 +137,9 @@ typedef struct AOTModule {
/* function type indexes */
uint32 *func_type_indexes;
/* export function info */
uint32 export_func_count;
AOTExportFunc *export_funcs;
/* export info */
uint32 export_count;
AOTExport *exports;
/* start function index, -1 denotes no start function */
uint32 start_func_index;
@ -160,13 +187,15 @@ typedef union {
void *ptr;
} AOTPointer;
typedef struct AOTModuleInstance {
typedef struct AOTMemoryInstance {
uint32 module_type;
/* shared memory flag */
bool is_shared;
/* memory space info */
uint32 mem_cur_page_count;
uint32 mem_max_page_count;
uint32 memory_data_size;
uint32 __padding__;
AOTPointer memory_data;
AOTPointer memory_data_end;
@ -177,6 +206,21 @@ typedef struct AOTModuleInstance {
AOTPointer heap_data_end;
AOTPointer heap_handle;
/* boundary check constants for aot code */
int64 mem_bound_check_heap_base;
int64 mem_bound_check_1byte;
int64 mem_bound_check_2bytes;
int64 mem_bound_check_4bytes;
int64 mem_bound_check_8bytes;
} AOTMemoryInstance;
typedef struct AOTModuleInstance {
uint32 module_type;
/* memories */
uint32 memory_count;
AOTPointer memories;
/* global and table info */
uint32 global_data_size;
uint32 table_size;
@ -188,6 +232,16 @@ typedef struct AOTModuleInstance {
/* function type indexes */
AOTPointer func_type_indexes;
/* export info */
uint32 export_func_count;
uint32 export_global_count;
uint32 export_mem_count;
uint32 export_tab_count;
AOTPointer export_funcs;
AOTPointer export_globals;
AOTPointer export_memories;
AOTPointer export_tables;
/* The exception buffer for current thread. */
char cur_exception[128];
/* The custom data that can be set/get by
@ -198,13 +252,6 @@ typedef struct AOTModuleInstance {
/* WASI context */
AOTPointer wasi_ctx;
/* boundary check constants for aot code */
int64 mem_bound_check_heap_base;
int64 mem_bound_check_1byte;
int64 mem_bound_check_2bytes;
int64 mem_bound_check_4bytes;
int64 mem_bound_check_8bytes;
/* others */
int32 temp_ret;
uint32 llvm_stack;
@ -215,12 +262,11 @@ typedef struct AOTModuleInstance {
union {
uint64 _make_it_8_byte_aligned_;
AOTMemoryInstance memory_instances[1];
uint8 bytes[1];
} global_table_data;
} AOTModuleInstance;
typedef AOTExportFunc AOTFunctionInstance;
/* Target info, read from ELF header of object file */
typedef struct AOTTargetInfo {
/* Binary type, elf32l/elf32b/elf64l/elf64b */
@ -467,6 +513,16 @@ bool
aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index);
#endif
#if WASM_ENABLE_THREAD_MGR != 0
bool
aot_set_aux_stack(WASMExecEnv *exec_env,
uint32 start_offset, uint32 size);
bool
aot_get_aux_stack(WASMExecEnv *exec_env,
uint32 *start_offset, uint32 *size);
#endif
#ifdef OS_ENABLE_HW_BOUND_CHECK
bool
aot_signal_init();