mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Implement memory.grow and limit heap space base offset to 1G (#36)
* Implement memory profiler, optimize memory usage, modify code indent * Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default
This commit is contained in:
parent
ff7cbdd2fb
commit
504268b297
|
@ -175,7 +175,7 @@ cd iwasm/products/linux/bin
|
|||
You will get the following output:
|
||||
```
|
||||
Hello world!
|
||||
buf ptr: 0x000101ac
|
||||
buf ptr: 0x400002b0
|
||||
buf: 1234
|
||||
```
|
||||
If you would like to run the test app on Zephyr, we have embedded a test sample into its OS image. You will need to execute:
|
||||
|
|
|
@ -29,8 +29,8 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
|
|||
add_definitions(-DNVALGRIND)
|
||||
endif ()
|
||||
|
||||
# Currently build as 32-bit by default.
|
||||
set (BUILD_AS_64BIT_SUPPORT "NO")
|
||||
# Currently build as 64-bit by default.
|
||||
set (BUILD_AS_64BIT_SUPPORT "YES")
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
|
||||
|
@ -44,6 +44,11 @@ else ()
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
|
||||
|
||||
|
|
|
@ -35,15 +35,14 @@ static int print_help()
|
|||
{
|
||||
wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n");
|
||||
wasm_printf("options:\n");
|
||||
wasm_printf(" -f|--function name Specify function name to run "
|
||||
"in module rather than main\n");
|
||||
wasm_printf(" -f|--function name Specify function name to run in module\n"
|
||||
" rather than main\n");
|
||||
#if WASM_ENABLE_LOG != 0
|
||||
wasm_printf(
|
||||
" -v=X Set log verbose level (0 to 2, default is 1), larger level with more log\n");
|
||||
wasm_printf(" -v=X Set log verbose level (0 to 2, default is 1),\n"
|
||||
" larger level with more log\n");
|
||||
#endif
|
||||
wasm_printf(
|
||||
" --repl Start a very simple REPL (read-eval-print-loop) mode \n"
|
||||
" that runs commands in the form of `FUNC ARG...`\n");
|
||||
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
||||
" that runs commands in the form of `FUNC ARG...`\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
|
|||
const char *exception;
|
||||
|
||||
wasm_application_execute_func(module_inst, func_name, app_argc - 1,
|
||||
app_argv + 1);
|
||||
app_argv + 1);
|
||||
if ((exception = wasm_runtime_get_exception(module_inst)))
|
||||
wasm_printf("%s\n", exception);
|
||||
return NULL;
|
||||
|
@ -122,7 +121,7 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
|||
}
|
||||
if (app_argc != 0) {
|
||||
wasm_application_execute_func(module_inst, app_argv[0],
|
||||
app_argc - 1, app_argv + 1);
|
||||
app_argc - 1, app_argv + 1);
|
||||
}
|
||||
free(app_argv);
|
||||
}
|
||||
|
@ -177,7 +176,7 @@ int main(int argc, char *argv[])
|
|||
app_argv = argv;
|
||||
|
||||
if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
|
||||
!= 0) {
|
||||
!= 0) {
|
||||
wasm_printf("Init global heap failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -190,19 +189,22 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* load WASM byte buffer from WASM bin file */
|
||||
if (!(wasm_file_buf = (uint8*) wasm_read_file_to_buffer(wasm_file,
|
||||
&wasm_file_size)))
|
||||
&wasm_file_size)))
|
||||
goto fail2;
|
||||
|
||||
/* load WASM module */
|
||||
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
wasm_printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024,
|
||||
8 * 1024, error_buf, sizeof(error_buf)))) {
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
|
||||
16 * 1024, /* stack size */
|
||||
8 * 1024, /* heap size */
|
||||
error_buf,
|
||||
sizeof(error_buf)))) {
|
||||
wasm_printf("%s\n", error_buf);
|
||||
goto fail4;
|
||||
}
|
||||
|
@ -217,21 +219,20 @@ int main(int argc, char *argv[])
|
|||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
|
||||
fail4:
|
||||
fail4:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
|
||||
fail3:
|
||||
fail3:
|
||||
/* free the file buffer */
|
||||
wasm_free(wasm_file_buf);
|
||||
|
||||
fail2:
|
||||
fail2:
|
||||
/* destroy runtime environment */
|
||||
wasm_runtime_destroy();
|
||||
|
||||
fail1: bh_memory_destroy();
|
||||
|
||||
(void) func_name;
|
||||
fail1:
|
||||
bh_memory_destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,26 +74,28 @@ GET_F64_FROM_ADDR (uint32 *addr)
|
|||
}
|
||||
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
|
||||
|
||||
#define is_valid_addr(memory, heap, addr) \
|
||||
(memory->base_addr <= addr && addr <= memory->end_addr) \
|
||||
|
||||
#define CHECK_MEMORY_OVERFLOW() do { \
|
||||
uint32 offset1 = offset + addr; \
|
||||
uint8 *maddr1; \
|
||||
if (flags != 2) \
|
||||
LOG_VERBOSE("unaligned load/store in wasm interp, flag is: %d.\n", flags);\
|
||||
if (offset + addr < addr) { \
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access"); \
|
||||
goto got_exception; \
|
||||
if (offset1 < offset) \
|
||||
goto out_of_bounds; \
|
||||
if (offset1 < heap_base_offset) { \
|
||||
maddr = memory->memory_data + offset1; \
|
||||
if (maddr < memory->base_addr) \
|
||||
goto out_of_bounds; \
|
||||
maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \
|
||||
if (maddr1 > memory->end_addr) \
|
||||
goto out_of_bounds; \
|
||||
} \
|
||||
maddr = memory->memory_data + (offset + addr); \
|
||||
if (!is_valid_addr(memory, NULL, maddr)) { \
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \
|
||||
if (!is_valid_addr(memory, NULL, maddr1)) { \
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access"); \
|
||||
goto got_exception; \
|
||||
else { \
|
||||
maddr = memory->heap_data + offset1 - memory->heap_base_offset; \
|
||||
if (maddr < memory->heap_data) \
|
||||
goto out_of_bounds; \
|
||||
maddr1 = maddr + LOAD_SIZE[opcode - WASM_OP_I32_LOAD]; \
|
||||
if (maddr1 > memory->heap_data_end) \
|
||||
goto out_of_bounds; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -712,6 +714,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
|||
{
|
||||
WASMModuleInstance *module = self->module_inst;
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
int32 heap_base_offset = memory ? memory->heap_base_offset : 0;
|
||||
WASMTableInstance *table = module->default_table;
|
||||
uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
|
||||
WASMInterpFrame *frame = NULL;
|
||||
|
@ -1247,26 +1250,25 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
|||
|
||||
HANDLE_OP (WASM_OP_MEMORY_GROW):
|
||||
{
|
||||
uint32 reserved, prev_page_count, delta, tmp;
|
||||
uint32 reserved, delta, prev_page_count = memory->cur_page_count;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, reserved);
|
||||
prev_page_count = memory->cur_page_count;
|
||||
delta = POP_I32();
|
||||
PUSH_I32(prev_page_count);
|
||||
if (delta == 0)
|
||||
HANDLE_OP_END ();
|
||||
else if (delta + prev_page_count > memory->max_page_count ||
|
||||
delta + prev_page_count < prev_page_count) {
|
||||
tmp = POP_I32();
|
||||
|
||||
if (!wasm_runtime_enlarge_memory(module, delta)) {
|
||||
/* fail to memory.grow, return -1 */
|
||||
PUSH_I32(-1);
|
||||
(void)tmp;
|
||||
HANDLE_OP_END ();
|
||||
if (wasm_runtime_get_exception(module)) {
|
||||
printf("%s\n", wasm_runtime_get_exception(module));
|
||||
wasm_runtime_set_exception(module, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* success, return previous page count */
|
||||
PUSH_I32(prev_page_count);
|
||||
/* update the memory instance ptr */
|
||||
memory = module->default_memory;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_enlarge_memory(module, delta))
|
||||
goto got_exception;
|
||||
|
||||
memory = module->default_memory;
|
||||
|
||||
(void)reserved;
|
||||
HANDLE_OP_END ();
|
||||
|
@ -2093,6 +2095,9 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
|||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
out_of_bounds:
|
||||
wasm_runtime_set_exception(module, "out of bounds memory access");
|
||||
|
||||
got_exception:
|
||||
if (depths && depths != depth_buf) {
|
||||
wasm_free(depths);
|
||||
|
|
|
@ -314,14 +314,20 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
|
|||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
uint32 pool_size = bh_memory_pool_size();
|
||||
uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
|
||||
/ NumBytesPerPage;
|
||||
|
||||
read_leb_uint32(p, p_end, memory->flags);
|
||||
read_leb_uint32(p, p_end, memory->init_page_count);
|
||||
if (memory->flags & 1)
|
||||
if (memory->flags & 1) {
|
||||
read_leb_uint32(p, p_end, memory->max_page_count);
|
||||
if (memory->max_page_count > max_page_count)
|
||||
memory->max_page_count = max_page_count;
|
||||
}
|
||||
else
|
||||
/* Limit the maximum memory size to 4GB */
|
||||
memory->max_page_count = 0x10000;
|
||||
/* Limit the maximum memory size to max_page_count */
|
||||
memory->max_page_count = max_page_count;
|
||||
|
||||
*p_buf = p;
|
||||
return true;
|
||||
|
@ -351,14 +357,20 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
|
|||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
const uint8 *p = *p_buf, *p_end = buf_end;
|
||||
uint32 pool_size = bh_memory_pool_size();
|
||||
uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
|
||||
/ NumBytesPerPage;
|
||||
|
||||
read_leb_uint32(p, p_end, memory->flags);
|
||||
read_leb_uint32(p, p_end, memory->init_page_count);
|
||||
if (memory->flags & 1)
|
||||
if (memory->flags & 1) {
|
||||
read_leb_uint32(p, p_end, memory->max_page_count);
|
||||
if (memory->max_page_count > max_page_count)
|
||||
memory->max_page_count = max_page_count;
|
||||
}
|
||||
else
|
||||
/* Limit the maximum memory size to 4GB */
|
||||
memory->max_page_count = 0x10000;
|
||||
/* Limit the maximum memory size to max_page_count */
|
||||
memory->max_page_count = max_page_count;
|
||||
|
||||
*p_buf = p;
|
||||
return true;
|
||||
|
|
|
@ -163,6 +163,7 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
|
|||
if (memories[i]) {
|
||||
if (memories[i]->heap_handle)
|
||||
mem_allocator_destroy(memories[i]->heap_handle);
|
||||
wasm_free(memories[i]->heap_data);
|
||||
wasm_free(memories[i]);
|
||||
}
|
||||
wasm_free(memories);
|
||||
|
@ -177,10 +178,10 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count,
|
|||
{
|
||||
WASMMemoryInstance *memory;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
NumBytesPerPage * init_page_count +
|
||||
addr_data_size + global_data_size +
|
||||
heap_size;
|
||||
NumBytesPerPage * init_page_count +
|
||||
addr_data_size + global_data_size;
|
||||
|
||||
/* Allocate memory space, addr data and global data */
|
||||
if (!(memory = wasm_malloc(total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: allocate memory failed.");
|
||||
|
@ -190,28 +191,46 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count,
|
|||
memset(memory, 0, total_size);
|
||||
memory->cur_page_count = init_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
|
||||
memory->addr_data = memory->base_addr;
|
||||
memory->addr_data_size = addr_data_size;
|
||||
|
||||
memory->memory_data = memory->addr_data + addr_data_size;
|
||||
|
||||
memory->heap_data = memory->memory_data +
|
||||
NumBytesPerPage * memory->cur_page_count;;
|
||||
memory->heap_data_size = heap_size;
|
||||
|
||||
memory->global_data = memory->heap_data + memory->heap_data_size;
|
||||
memory->global_data = memory->memory_data +
|
||||
NumBytesPerPage * memory->cur_page_count;;
|
||||
memory->global_data_size = global_data_size;
|
||||
|
||||
memory->end_addr = memory->global_data + global_data_size;
|
||||
|
||||
/* Allocate heap space */
|
||||
if (!(memory->heap_data = wasm_malloc(heap_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: allocate memory failed.");
|
||||
goto fail1;
|
||||
}
|
||||
memory->heap_data_end = memory->heap_data + heap_size;
|
||||
|
||||
/* Initialize heap */
|
||||
if (!(memory->heap_handle = mem_allocator_create
|
||||
(memory->heap_data, memory->heap_data_size))) {
|
||||
wasm_free(memory);
|
||||
return NULL;
|
||||
(memory->heap_data, heap_size))) {
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY_GROW != 0
|
||||
memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET;
|
||||
#else
|
||||
memory->heap_base_offset = memory->end_addr - memory->memory_data;
|
||||
#endif
|
||||
|
||||
return memory;
|
||||
|
||||
fail2:
|
||||
wasm_free(memory->heap_data);
|
||||
|
||||
fail1:
|
||||
wasm_free(memory);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -975,58 +994,65 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
|
|||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
{
|
||||
#if 1
|
||||
wasm_runtime_set_exception(module, "unsupported operation: enlarge memory.");
|
||||
return false;
|
||||
#else
|
||||
#if WASM_ENABLE_MEMORY_GROW != 0
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
WASMMemoryInstance *new_memory;
|
||||
uint32 total_page_count = inc_page_count + memory->cur_page_count;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
memory->addr_data_size +
|
||||
NumBytesPerPage * total_page_count +
|
||||
memory->global_data_size +
|
||||
memory->thunk_argv_data_size +
|
||||
sizeof(uint32) * memory->thunk_argc;
|
||||
memory->global_data_size;
|
||||
|
||||
if (inc_page_count <= 0)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < memory->cur_page_count /* integer overflow */
|
||||
|| total_page_count > memory->max_page_count) {
|
||||
wasm_runtime_set_exception(module, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(new_memory = wasm_malloc(total_size))) {
|
||||
wasm_runtime_set_exception(module, "alloc memory for enlarge memory failed.");
|
||||
wasm_runtime_set_exception(module, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
new_memory->cur_page_count = total_page_count;
|
||||
new_memory->max_page_count = memory->max_page_count > total_page_count
|
||||
? memory->max_page_count : total_page_count;
|
||||
new_memory->max_page_count = memory->max_page_count;
|
||||
|
||||
new_memory->addr_data = new_memory->base_addr;
|
||||
new_memory->addr_data_size = memory->addr_data_size;
|
||||
|
||||
new_memory->thunk_argv_data = new_memory->addr_data + memory->addr_data_size;
|
||||
new_memory->thunk_argv_data_size = memory->thunk_argv_data_size;
|
||||
new_memory->thunk_argc = memory->thunk_argc;
|
||||
new_memory->thunk_argv_offsets = new_memory->thunk_argv_data +
|
||||
memory->thunk_argv_data_size;
|
||||
new_memory->memory_data = new_memory->addr_data + new_memory->addr_data_size;
|
||||
|
||||
new_memory->memory_data = new_memory->thunk_argv_offsets +
|
||||
sizeof(uint32) * memory->thunk_argc;
|
||||
new_memory->global_data = new_memory->memory_data +
|
||||
NumBytesPerPage * new_memory->cur_page_count;
|
||||
NumBytesPerPage * total_page_count;
|
||||
new_memory->global_data_size = memory->global_data_size;
|
||||
|
||||
new_memory->end_addr = new_memory->global_data + memory->global_data_size;
|
||||
|
||||
/* Copy addr data, thunk argv data, thunk argv offsets and memory data */
|
||||
/* Copy addr data and memory data */
|
||||
memcpy(new_memory->addr_data, memory->addr_data,
|
||||
memory->global_data - memory->addr_data);
|
||||
/* Copy global data */
|
||||
memcpy(new_memory->global_data, memory->global_data,
|
||||
memory->end_addr - memory->global_data);
|
||||
memory->global_data_size);
|
||||
/* Init free space of new memory */
|
||||
memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
|
||||
0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
|
||||
0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
|
||||
|
||||
new_memory->heap_data = memory->heap_data;
|
||||
new_memory->heap_data_end = memory->heap_data_end;
|
||||
new_memory->heap_handle = memory->heap_handle;
|
||||
new_memory->heap_base_offset = memory->heap_base_offset;
|
||||
|
||||
wasm_free(memory);
|
||||
module->memories[0] = module->default_memory = new_memory;
|
||||
wasm_free(memory);
|
||||
return true;
|
||||
#else
|
||||
wasm_runtime_set_exception(module, "unsupported operation: enlarge memory.");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1098,29 +1124,29 @@ wasm_runtime_get_current_module_inst()
|
|||
int32
|
||||
wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
|
||||
{
|
||||
uint8 *memory_base = module_inst->default_memory->memory_data;
|
||||
void *heap = module_inst->default_memory->heap_handle;
|
||||
uint8 *addr = mem_allocator_malloc(heap, size);
|
||||
if (!addr)
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
uint8 *addr = mem_allocator_malloc(memory->heap_handle, size);
|
||||
if (!addr) {
|
||||
wasm_runtime_set_exception(module_inst, "out of memory");
|
||||
return addr ? addr - memory_base : 0;
|
||||
return 0;
|
||||
}
|
||||
return memory->heap_base_offset + (addr - memory->heap_data);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_module_free(WASMModuleInstance *module_inst, int32 ptr)
|
||||
{
|
||||
uint8 *memory_base = module_inst->default_memory->memory_data;
|
||||
uint8 *heap_base = module_inst->default_memory->heap_data;
|
||||
uint32 heap_size = module_inst->default_memory->heap_data_size;
|
||||
void *heap = module_inst->default_memory->heap_handle;
|
||||
uint8 *addr = ptr ? memory_base + ptr : NULL;
|
||||
if (addr && (heap_base < addr && addr < heap_base + heap_size))
|
||||
mem_allocator_free(heap, addr);
|
||||
if (ptr) {
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
uint8 *addr = memory->heap_data + (ptr - memory->heap_base_offset);
|
||||
if (memory->heap_data < addr && addr < memory->heap_data_end)
|
||||
mem_allocator_free(memory->heap_handle, addr);
|
||||
}
|
||||
}
|
||||
|
||||
int32
|
||||
int32
|
||||
wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
|
||||
const char *src, uint32 size)
|
||||
const char *src, uint32 size)
|
||||
{
|
||||
int32 buffer_offset = wasm_runtime_module_malloc(module_inst, size);
|
||||
if (buffer_offset != 0) {
|
||||
|
@ -1135,22 +1161,32 @@ bool
|
|||
wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
|
||||
int32 app_offset, uint32 size)
|
||||
{
|
||||
WASMMemoryInstance *memory;
|
||||
uint8 *addr;
|
||||
|
||||
/* integer overflow check */
|
||||
if(app_offset < 0 ||
|
||||
app_offset + size < size) {
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
app_offset + size < app_offset) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uint8 *memory_base = module_inst->default_memory->memory_data;
|
||||
uint8 *addr = memory_base + app_offset;
|
||||
uint8 *base_addr = module_inst->default_memory->base_addr;
|
||||
uint8 *end_addr = module_inst->default_memory->end_addr;
|
||||
bool ret = (base_addr <= addr
|
||||
&& addr + size <= end_addr);
|
||||
if (!ret)
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return ret;
|
||||
memory = module_inst->default_memory;
|
||||
if (app_offset < memory->heap_base_offset) {
|
||||
addr = memory->memory_data + app_offset;
|
||||
if (!(memory->base_addr <= addr && addr + size <= memory->end_addr))
|
||||
goto fail;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
addr = memory->heap_data + (app_offset - memory->heap_base_offset);
|
||||
if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end))
|
||||
goto fail;
|
||||
return true;
|
||||
}
|
||||
|
||||
fail:
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1158,26 +1194,42 @@ wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
|
|||
void *native_ptr, uint32 size)
|
||||
{
|
||||
uint8 *addr = native_ptr;
|
||||
uint8 *base_addr = module_inst->default_memory->base_addr;
|
||||
uint8 *end_addr = module_inst->default_memory->end_addr;
|
||||
bool ret = (base_addr <= addr && addr + size <= end_addr);
|
||||
if (!ret || (addr + size < addr)/* integer overflow */)
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return ret;
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
|
||||
if (addr + size < addr) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((memory->base_addr <= addr && addr + size <= memory->end_addr)
|
||||
|| (memory->heap_data <= addr && addr + size <= memory->heap_data_end))
|
||||
return true;
|
||||
|
||||
fail:
|
||||
wasm_runtime_set_exception(module_inst, "out of bounds memory access");
|
||||
return false;
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
|
||||
int32 app_offset)
|
||||
{
|
||||
return module_inst->default_memory->memory_data + app_offset;
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
if (app_offset < memory->heap_base_offset)
|
||||
return memory->memory_data + app_offset;
|
||||
else
|
||||
return memory->heap_data + (app_offset - memory->heap_base_offset);
|
||||
}
|
||||
|
||||
int32
|
||||
wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
|
||||
void *native_ptr)
|
||||
{
|
||||
return (uint8*)native_ptr - module_inst->default_memory->memory_data;
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
if ((uint8*)native_ptr < memory->heap_data)
|
||||
return (uint8*)native_ptr - memory->memory_data;
|
||||
else
|
||||
return memory->heap_base_offset
|
||||
+ ((uint8*)native_ptr - memory->heap_data);
|
||||
}
|
||||
|
||||
uint32
|
||||
|
|
|
@ -37,20 +37,14 @@ typedef struct WASMMemoryInstance {
|
|||
/* Size of addr_data */
|
||||
uint32 addr_data_size;
|
||||
|
||||
/* Thunk data of argument strings */
|
||||
uint8 *thunk_argv_data;
|
||||
uint32 thunk_argv_data_size;
|
||||
/* Thunk argument count */
|
||||
uint32 thunk_argc;
|
||||
/* Thunk argument offsets */
|
||||
uint8 *thunk_argv_offsets;
|
||||
|
||||
/* Heap data */
|
||||
/* Heap data base address */
|
||||
uint8 *heap_data;
|
||||
/* Heap size */
|
||||
uint32 heap_data_size;
|
||||
/* Heap data end address */
|
||||
uint8 *heap_data_end;
|
||||
/* The heap created */
|
||||
void *heap_handle;
|
||||
/* Heap base offset of wasm app */
|
||||
int32 heap_base_offset;
|
||||
|
||||
/* Memory data */
|
||||
uint8 *memory_data;
|
||||
|
@ -63,7 +57,7 @@ typedef struct WASMMemoryInstance {
|
|||
|
||||
/* Base address, the layout is:
|
||||
addr_data + thunk_argv data + thunk arg offsets +
|
||||
heap data + memory data + global data
|
||||
memory data + global data
|
||||
memory data init size is: NumBytesPerPage * cur_page_count
|
||||
addr data size and global data size is calculated in module instantiating
|
||||
Note: when memory is re-allocated, the addr data, thunk argv data, thunk
|
||||
|
|
|
@ -52,6 +52,12 @@ int bh_memory_init_with_allocator(void *malloc_func, void *free_func);
|
|||
*/
|
||||
void bh_memory_destroy();
|
||||
|
||||
/**
|
||||
* Get the pool size of memory, if memory is initialized with allocator,
|
||||
* return 1GB by default.
|
||||
*/
|
||||
int bh_memory_pool_size();
|
||||
|
||||
#if BEIHAI_ENABLE_MEMORY_PROFILING == 0
|
||||
|
||||
/**
|
||||
|
|
|
@ -80,6 +80,15 @@
|
|||
#define WORKING_FLOW_HEAP_SIZE 0
|
||||
*/
|
||||
|
||||
/* Support memory.grow opcode and enlargeMemory function */
|
||||
#define WASM_ENABLE_MEMORY_GROW 1
|
||||
|
||||
/* The max percentage of global heap that app memory space can grow */
|
||||
#define APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT 1 / 3
|
||||
|
||||
/* Default base offset of app heap space */
|
||||
#define DEFAULT_APP_HEAP_BASE_OFFSET (1 * BH_GB)
|
||||
|
||||
/* Default min/max heap size of each app */
|
||||
#define APP_HEAP_SIZE_DEFAULT (8 * 1024)
|
||||
#define APP_HEAP_SIZE_MIN (2 * 1024)
|
||||
|
|
|
@ -49,7 +49,9 @@ static korp_mutex profile_lock;
|
|||
#ifndef MALLOC_MEMORY_FROM_SYSTEM
|
||||
|
||||
typedef enum Memory_Mode {
|
||||
MEMORY_MODE_UNKNOWN = 0, MEMORY_MODE_POOL, MEMORY_MODE_ALLOCATOR
|
||||
MEMORY_MODE_UNKNOWN = 0,
|
||||
MEMORY_MODE_POOL,
|
||||
MEMORY_MODE_ALLOCATOR
|
||||
} Memory_Mode;
|
||||
|
||||
static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
|
||||
|
@ -59,6 +61,8 @@ static mem_allocator_t pool_allocator = NULL;
|
|||
static void *(*malloc_func)(unsigned int size) = NULL;
|
||||
static void (*free_func)(void *ptr) = NULL;
|
||||
|
||||
static unsigned int global_pool_size;
|
||||
|
||||
int bh_memory_init_with_pool(void *mem, unsigned int bytes)
|
||||
{
|
||||
mem_allocator_t _allocator = mem_allocator_create(mem, bytes);
|
||||
|
@ -69,6 +73,7 @@ int bh_memory_init_with_pool(void *mem, unsigned int bytes)
|
|||
#if BEIHAI_ENABLE_MEMORY_PROFILING != 0
|
||||
vm_mutex_init(&profile_lock);
|
||||
#endif
|
||||
global_pool_size = bytes;
|
||||
return 0;
|
||||
}
|
||||
printf("Init memory with pool (%p, %u) failed.\n", mem, bytes);
|
||||
|
@ -101,6 +106,14 @@ void bh_memory_destroy()
|
|||
memory_mode = MEMORY_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
int bh_memory_pool_size()
|
||||
{
|
||||
if (memory_mode == MEMORY_MODE_POOL)
|
||||
return global_pool_size;
|
||||
else
|
||||
return 1 * BH_GB;
|
||||
}
|
||||
|
||||
void* bh_malloc_internal(unsigned int size)
|
||||
{
|
||||
if (memory_mode == MEMORY_MODE_UNKNOWN) {
|
||||
|
|
|
@ -75,7 +75,7 @@ static void *vm_thread_wrapper(void *arg)
|
|||
{
|
||||
thread_wrapper_arg * targ = arg;
|
||||
LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
|
||||
targ->stack = (void *) ((unsigned int) (&arg) & ~0xfff);
|
||||
targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff);
|
||||
_vm_tls_put(1, targ);
|
||||
targ->start(targ->arg);
|
||||
bh_free(targ);
|
||||
|
|
Loading…
Reference in New Issue
Block a user