Make heap and linear memory contiguous to refine compilation time and footprint (#233)

Use FastISel for JIT mode
Use united aot version in aot file and aot runtime
Disable check signature failed warning for wamrc
Fix fast interpreter x86_32 float issue
Remove unused empty lvgl folder
This commit is contained in:
wenyongh
2020-04-13 10:49:40 +08:00
committed by GitHub
parent ffd975d2d6
commit b40e79c160
27 changed files with 983 additions and 755 deletions

View File

@ -223,28 +223,17 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define CHECK_MEMORY_OVERFLOW() do { \
uint64 offset1 = offset + addr; \
/* if (flags != 2) \
LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\
/* The WASM spec doesn't require that the dynamic address operand must be \
unsigned, so we don't check whether integer overflow or not here. */ \
/* if (offset1 < offset) \
goto out_of_bounds; */ \
if (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= memory_data_size) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->memory_data + offset1; \
} \
else if (offset1 > DEFAULT_APP_HEAP_BASE_OFFSET \
&& (offset1 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= \
DEFAULT_APP_HEAP_BASE_OFFSET + heap_data_size)) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->heap_data + offset1 - memory->heap_base_offset; \
} \
else \
goto out_of_bounds; \
#define CHECK_MEMORY_OVERFLOW(bytes) do { \
int32 offset1 = (int32)(offset + addr); \
uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \
/* if (flags != 2) \
LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \
if (offset2 + LOAD_SIZE[opcode - WASM_OP_I32_LOAD] <= total_mem_size) \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)
static inline uint32
@ -798,9 +787,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *prev_frame)
{
WASMMemoryInstance *memory = module->default_memory;
int32 heap_base_offset = memory ? memory->heap_base_offset : 0;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
- heap_base_offset : 0;
uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals;
@ -1419,7 +1409,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
PUSH_I32(prev_page_count);
/* update the memory instance ptr */
memory = module->default_memory;
memory_data_size = num_bytes_per_page * memory->cur_page_count;
total_mem_size = num_bytes_per_page * memory->cur_page_count
- heap_base_offset;
global_data = memory->global_data;
}

View File

@ -225,28 +225,17 @@ LOAD_I16(void *addr)
#endif /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
#define CHECK_MEMORY_OVERFLOW(bytes) do { \
uint64 offset1 = offset + addr; \
/* if (flags != 2) \
LOG_VERBOSE("unaligned load/store in wasm interp, flag: %d.\n", flags); */\
/* The WASM spec doesn't require that the dynamic address operand must be \
unsigned, so we don't check whether integer overflow or not here. */ \
/* if (offset1 < offset) \
goto out_of_bounds; */ \
if (offset1 + bytes <= memory_data_size) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->memory_data + offset1; \
} \
else if (offset1 > DEFAULT_APP_HEAP_BASE_OFFSET \
&& (offset1 + bytes <= \
DEFAULT_APP_HEAP_BASE_OFFSET + heap_data_size)) { \
/* If offset1 is in valid range, maddr must also be in valid range, \
no need to check it again. */ \
maddr = memory->heap_data + offset1 - DEFAULT_APP_HEAP_BASE_OFFSET; \
} \
else \
goto out_of_bounds; \
#define CHECK_MEMORY_OVERFLOW(bytes) do { \
int32 offset1 = (int32)(offset + addr); \
uint64 offset2 = (uint64)(uint32)(offset1 - heap_base_offset); \
/* if (flags != 2) \
LOG_VERBOSE("unaligned load/store, flag: %d.\n", flags); */ \
if (offset2 + bytes <= total_mem_size) \
/* If offset1 is in valid range, maddr must also be in valid range,\
no need to check it again. */ \
maddr = memory->memory_data + offset1; \
else \
goto out_of_bounds; \
} while (0)
static inline uint32
@ -501,10 +490,18 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
frame_ip += 6; \
} while (0)
#if defined(BUILD_TARGET_X86_32)
#define DEF_OP_REINTERPRET(src_type) do { \
void *src = frame_lp + GET_OFFSET(); \
void *dst = frame_lp + GET_OFFSET(); \
bh_memcpy_s(dst, sizeof(src_type), src, sizeof(src_type)); \
} while (0)
#else
#define DEF_OP_REINTERPRET(src_type) do { \
SET_OPERAND(src_type, 2, GET_OPERAND(src_type, 0)); \
frame_ip += 4; \
} while (0)
#endif
#if WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0
#define DEF_OP_NUMERIC_64 DEF_OP_NUMERIC
@ -779,9 +776,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMInterpFrame *prev_frame)
{
WASMMemoryInstance *memory = module->default_memory;
int32 heap_base_offset = memory ? memory->heap_base_offset : 0;
uint32 num_bytes_per_page = memory ? memory->num_bytes_per_page : 0;
uint32 memory_data_size = memory ? num_bytes_per_page * memory->cur_page_count : 0;
uint32 heap_data_size = memory ? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
uint32 total_mem_size = memory ? num_bytes_per_page * memory->cur_page_count
- heap_base_offset : 0;
uint8 *global_data = memory ? memory->global_data : NULL;
WASMTableInstance *table = module->default_table;
WASMGlobalInstance *globals = module->globals;
@ -929,10 +927,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr2 = GET_OFFSET();
addr_ret = GET_OFFSET();
if (!cond)
if (!cond) {
#if defined(BUILD_TARGET_X86_32)
if (addr_ret != addr1)
bh_memcpy_s(frame_lp + addr_ret, sizeof(int32),
frame_lp + addr1, sizeof(int32));
#else
frame_lp[addr_ret] = frame_lp[addr1];
else
#endif
}
else {
#if defined(BUILD_TARGET_X86_32)
if (addr_ret != addr2)
bh_memcpy_s(frame_lp + addr_ret, sizeof(int32),
frame_lp + addr2, sizeof(int32));
#else
frame_lp[addr_ret] = frame_lp[addr2];
#endif
}
HANDLE_OP_END ();
}
@ -943,10 +955,24 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
addr2 = GET_OFFSET();
addr_ret = GET_OFFSET();
if (!cond)
if (!cond) {
#if defined(BUILD_TARGET_X86_32)
if (addr_ret != addr1)
bh_memcpy_s(frame_lp + addr_ret, sizeof(int64),
frame_lp + addr1, sizeof(int64));
#else
*(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr1);
else
#endif
}
else {
#if defined(BUILD_TARGET_X86_32)
if (addr_ret != addr2)
bh_memcpy_s(frame_lp + addr_ret, sizeof(int64),
frame_lp + addr2, sizeof(int64));
#else
*(int64*)(frame_lp + addr_ret) = *(int64*)(frame_lp + addr2);
#endif
}
HANDLE_OP_END ();
}
@ -1288,7 +1314,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_lp[addr_ret] = prev_page_count;
/* update the memory instance ptr */
memory = module->default_memory;
memory_data_size = num_bytes_per_page * memory->cur_page_count;
total_mem_size = num_bytes_per_page * memory->cur_page_count
- heap_base_offset;
global_data = memory->global_data;
}
@ -2061,13 +2088,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP (EXT_OP_COPY_STACK_TOP):
addr1 = GET_OFFSET();
addr2 = GET_OFFSET();
#if defined(BUILD_TARGET_X86_32)
bh_memcpy_s(frame_lp + addr2, sizeof(int32),
frame_lp + addr1, sizeof(int32));
#else
frame_lp[addr2] = frame_lp[addr1];
#endif
HANDLE_OP_END ();
HANDLE_OP (EXT_OP_COPY_STACK_TOP_I64):
addr1 = GET_OFFSET();
addr2 = GET_OFFSET();
#if defined(BUILD_TARGET_X86_32)
bh_memcpy_s(frame_lp + addr2, sizeof(int64),
frame_lp + addr1, sizeof(int64));
#else
*(float64*)(frame_lp + addr2) = *(float64*)(frame_lp + addr1);
#endif
HANDLE_OP_END ();
HANDLE_OP (WASM_OP_SET_LOCAL):

View File

@ -2816,21 +2816,21 @@ wasm_loader_check_br(WASMLoaderContext *ctx, uint32 depth,
#define GET_CONST_OFFSET(type, val) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \
val, 0, 0, &operand_offset, \
&val, &operand_offset, \
error_buf, error_buf_size))) \
goto fail; \
} while (0)
#define GET_CONST_F32_OFFSET(type, fval) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \
0, fval, 0, &operand_offset, \
&fval, &operand_offset, \
error_buf, error_buf_size))) \
goto fail; \
} while (0)
#define GET_CONST_F64_OFFSET(type, fval) do { \
if (!(wasm_loader_get_const_offset(loader_ctx, type, \
0, 0, fval, &operand_offset, \
&fval, &operand_offset, \
error_buf, error_buf_size))) \
goto fail; \
} while (0)
@ -3110,9 +3110,11 @@ wasm_loader_push_frame_offset(WASMLoaderContext *ctx, uint8 type,
}
ctx->frame_offset++;
ctx->dynamic_offset++;
if (ctx->dynamic_offset > ctx->max_dynamic_offset)
ctx->max_dynamic_offset = ctx->dynamic_offset;
if (!disable_emit) {
ctx->dynamic_offset++;
if (ctx->dynamic_offset > ctx->max_dynamic_offset)
ctx->max_dynamic_offset = ctx->dynamic_offset;
}
return true;
}
@ -3170,8 +3172,7 @@ wasm_loader_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
static bool
wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
int64 val_int, float32 val_f32,
float64 val_f64, int16 *offset,
void *value, int16 *offset,
char *error_buf, uint32 error_buf_size)
{
int16 operand_offset = 0;
@ -3179,10 +3180,12 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
for (c = (Const *)ctx->const_buf;
(uint8*)c < ctx->const_buf + ctx->num_const * sizeof(Const); c ++) {
if ((type == c->value_type)
&& ((type == VALUE_TYPE_I64 && (int64)val_int == c->value.i64)
|| (type == VALUE_TYPE_I32 && (int32)val_int == c->value.i32)
|| (type == VALUE_TYPE_F64 && (float64)val_f64 == c->value.f64)
|| (type == VALUE_TYPE_F32 && (float32)val_f32 == c->value.f32))) {
&& ((type == VALUE_TYPE_I64 && *(int64*)value == c->value.i64)
|| (type == VALUE_TYPE_I32 && *(int32*)value == c->value.i32)
|| (type == VALUE_TYPE_F64
&& (0 == memcmp(value, &(c->value.f64), sizeof(float64))))
|| (type == VALUE_TYPE_F32
&& (0 == memcmp(value, &(c->value.f32), sizeof(float32)))))) {
operand_offset = c->slot_index;
break;
}
@ -3203,23 +3206,23 @@ wasm_loader_get_const_offset(WASMLoaderContext *ctx, uint8 type,
c->value_type = type;
switch (type) {
case VALUE_TYPE_F64:
c->value.f64 = (float64)val_f64;
bh_memcpy_s(&(c->value.f64), sizeof(WASMValue), value, sizeof(float64));
ctx->const_cell_num += 2;
/* The const buf will be reversed, we use the second cell */
/* of the i64/f64 const so the finnal offset is corrent */
operand_offset ++;
break;
case VALUE_TYPE_I64:
c->value.i64 = (int64)val_int;
c->value.i64 = *(int64*)value;
ctx->const_cell_num += 2;
operand_offset ++;
break;
case VALUE_TYPE_F32:
c->value.f32 = (float32)val_f32;
bh_memcpy_s(&(c->value.f32), sizeof(WASMValue), value, sizeof(float32));
ctx->const_cell_num ++;
break;
case VALUE_TYPE_I32:
c->value.i32 = (int32)val_int;
c->value.i32 = *(int32*)value;
ctx->const_cell_num ++;
break;
default:
@ -3495,8 +3498,8 @@ re_scan:
if (loader_ctx->code_compiled_size > 0) {
if (!wasm_loader_ctx_reinit(loader_ctx)) {
set_error_buf(error_buf, error_buf_size,
"WASM loader prepare bytecode failed: "
"allocate memory failed");
"WASM loader prepare bytecode failed: "
"allocate memory failed");
goto fail;
}
p = func->code;
@ -4005,7 +4008,7 @@ handle_next_reachable_block:
#if WASM_ENABLE_FAST_INTERP != 0
if (loader_ctx->p_code_compiled) {
#if WASM_ENABLE_ABS_LABEL_ADDR != 0
*(void**)(loader_ctx->p_code_compiled - 10) =
*(void**)(loader_ctx->p_code_compiled - 2 - sizeof(void*)) =
handle_table[WASM_OP_SELECT_64];
#else
*((int16*)loader_ctx->p_code_compiled - 2) = (int16)
@ -4373,7 +4376,7 @@ handle_next_reachable_block:
#if WASM_ENABLE_FAST_INTERP != 0
skip_label();
disable_emit = true;
f32 = *(float32 *)p_org;
bh_memcpy_s((uint8*)&f32, sizeof(float32), p_org, sizeof(float32));
GET_CONST_F32_OFFSET(VALUE_TYPE_F32, f32);
#endif
PUSH_F32();
@ -4385,7 +4388,7 @@ handle_next_reachable_block:
skip_label();
disable_emit = true;
/* Some MCU may require 8-byte align */
memcpy((uint8*)&f64, p_org, sizeof(float64));
bh_memcpy_s((uint8*)&f64, sizeof(float64), p_org, sizeof(float64));
GET_CONST_F64_OFFSET(VALUE_TYPE_F64, f64);
#endif
PUSH_F64();
@ -4687,10 +4690,11 @@ handle_next_reachable_block:
if (c->value_type == VALUE_TYPE_F64
|| c->value_type == VALUE_TYPE_I64) {
bh_memcpy_s(func_const, func_const_end - func_const,
&c->value.f64, sizeof(int64));
&(c->value.f64), sizeof(int64));
func_const += sizeof(int64);
} else {
*(uint32*)func_const = c->value.i32;
bh_memcpy_s(func_const, func_const_end - func_const,
&(c->value.f32), sizeof(int32));
func_const += sizeof(int32);
}
}

View File

@ -51,7 +51,6 @@ memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
if (memories[i]) {
if (memories[i]->heap_handle)
mem_allocator_destroy(memories[i]->heap_handle);
wasm_runtime_free(memories[i]->heap_data);
wasm_runtime_free(memories[i]);
}
wasm_runtime_free(memories);
@ -67,6 +66,7 @@ memory_instantiate(uint32 num_bytes_per_page,
{
WASMMemoryInstance *memory;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
(uint64)heap_size +
num_bytes_per_page * (uint64)init_page_count +
global_data_size;
@ -83,42 +83,28 @@ memory_instantiate(uint32 num_bytes_per_page,
memory->cur_page_count = init_page_count;
memory->max_page_count = max_page_count;
memory->memory_data = memory->base_addr;
memory->heap_data = memory->base_addr;
memory->memory_data = memory->heap_data + heap_size;
memory->global_data = memory->memory_data +
num_bytes_per_page * 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_runtime_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;
bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size);
/* Initialize heap */
if (!(memory->heap_handle = mem_allocator_create
(memory->heap_data, heap_size))) {
goto fail2;
wasm_runtime_free(memory);
return NULL;
}
#if WASM_ENABLE_MEMORY_GROW != 0
memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET;
#if WASM_ENABLE_SPEC_TEST == 0
memory->heap_base_offset = -(int32)heap_size;
#else
memory->heap_base_offset = memory->end_addr - memory->memory_data;
memory->heap_base_offset = 0;
#endif
return memory;
fail2:
wasm_runtime_free(memory->heap_data);
fail1:
wasm_runtime_free(memory);
return NULL;
}
/**
@ -811,6 +797,10 @@ wasm_instantiate(WASMModule *module,
/* Initialize the thread related data */
if (stack_size == 0)
stack_size = DEFAULT_WASM_STACK_SIZE;
#if WASM_ENABLE_SPEC_TEST != 0
if (stack_size < 48 *1024)
stack_size = 48 * 1024;
#endif
module_inst->default_wasm_stack_size = stack_size;
/* Execute __post_instantiate function */
@ -923,13 +913,13 @@ wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
{
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = mem_allocator_malloc(memory->heap_handle, size);
if (p_native_addr)
*p_native_addr = addr;
if (!addr) {
wasm_set_exception(module_inst, "out of memory");
return 0;
}
return memory->heap_base_offset + (int32)(addr - memory->heap_data);
if (p_native_addr)
*p_native_addr = addr;
return (int32)(addr - memory->memory_data);
}
void
@ -937,8 +927,8 @@ wasm_module_free(WASMModuleInstance *module_inst, int32 ptr)
{
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)
uint8 *addr = memory->memory_data + ptr;
if (memory->heap_data < addr && addr < memory->memory_data)
mem_allocator_free(memory->heap_handle, addr);
}
}
@ -961,31 +951,20 @@ bool
wasm_validate_app_addr(WASMModuleInstance *module_inst,
int32 app_offset, uint32 size)
{
WASMMemoryInstance *memory;
uint8 *addr;
WASMMemoryInstance *memory = module_inst->default_memory;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
/* integer overflow check */
if(app_offset + (int32)size < app_offset) {
if (app_offset + (int32)size < app_offset) {
goto fail;
}
memory = module_inst->default_memory;
if (0 <= app_offset
&& 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;
if (app_offset <= memory->heap_base_offset
|| app_offset + (int32)size > memory_data_size) {
goto fail;
}
else if (memory->heap_base_offset < app_offset
&& app_offset < memory->heap_base_offset
+ (memory->heap_data_end - memory->heap_data)) {
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;
}
return true;
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
@ -995,18 +974,20 @@ bool
wasm_validate_native_addr(WASMModuleInstance *module_inst,
void *native_ptr, uint32 size)
{
uint8 *addr = native_ptr;
uint8 *addr = (uint8*)native_ptr;
WASMMemoryInstance *memory = module_inst->default_memory;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
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;
if (addr <= memory->heap_data
|| addr + size > memory->memory_data + memory_data_size) {
goto fail;
}
return true;
fail:
wasm_set_exception(module_inst, "out of bounds memory access");
return false;
@ -1017,14 +998,13 @@ wasm_addr_app_to_native(WASMModuleInstance *module_inst,
int32 app_offset)
{
WASMMemoryInstance *memory = module_inst->default_memory;
if (0 <= app_offset && app_offset < memory->heap_base_offset)
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (memory->heap_base_offset < app_offset
&& app_offset < memory_data_size)
return memory->memory_data + app_offset;
else if (memory->heap_base_offset < app_offset
&& app_offset < memory->heap_base_offset
+ (memory->heap_data_end - memory->heap_data))
return memory->heap_data + (app_offset - memory->heap_base_offset);
else
return NULL;
return NULL;
}
int32
@ -1032,15 +1012,14 @@ wasm_addr_native_to_app(WASMModuleInstance *module_inst,
void *native_ptr)
{
WASMMemoryInstance *memory = module_inst->default_memory;
if (memory->base_addr <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->end_addr)
return (int32)((uint8*)native_ptr - memory->memory_data);
else if (memory->heap_data <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->heap_data_end)
return memory->heap_base_offset
+ (int32)((uint8*)native_ptr - memory->heap_data);
else
return 0;
uint8 *addr = (uint8*)native_ptr;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (memory->heap_data < addr
&& addr < memory->memory_data + memory_data_size)
return (int32)(addr - memory->memory_data);
return 0;
}
bool
@ -1049,28 +1028,19 @@ wasm_get_app_addr_range(WASMModuleInstance *module_inst,
int32 *p_app_start_offset,
int32 *p_app_end_offset)
{
int32 app_start_offset, app_end_offset;
WASMMemoryInstance *memory = module_inst->default_memory;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (0 <= app_offset && app_offset < memory->heap_base_offset) {
app_start_offset = 0;
app_end_offset = (int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (memory->heap_base_offset < app_offset
&& app_offset < memory_data_size) {
if (p_app_start_offset)
*p_app_start_offset = memory->heap_base_offset;
if (p_app_end_offset)
*p_app_end_offset = memory_data_size;
return true;
}
else if (memory->heap_base_offset < app_offset
&& app_offset < memory->heap_base_offset
+ (memory->heap_data_end - memory->heap_data)) {
app_start_offset = memory->heap_base_offset;
app_end_offset = memory->heap_base_offset
+ (int32)(memory->heap_data_end - memory->heap_data);
}
else
return false;
if (p_app_start_offset)
*p_app_start_offset = app_start_offset;
if (p_app_end_offset)
*p_app_end_offset = app_end_offset;
return true;
return false;
}
bool
@ -1079,42 +1049,36 @@ wasm_get_native_addr_range(WASMModuleInstance *module_inst,
uint8 **p_native_start_addr,
uint8 **p_native_end_addr)
{
uint8 *native_start_addr, *native_end_addr;
WASMMemoryInstance *memory = module_inst->default_memory;
uint8 *addr = (uint8*)native_ptr;
int32 memory_data_size =
(int32)(memory->num_bytes_per_page * memory->cur_page_count);
if (memory->base_addr <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->end_addr) {
native_start_addr = memory->memory_data;
native_end_addr = memory->memory_data
+ memory->num_bytes_per_page * memory->cur_page_count;
if (memory->heap_data < addr
&& addr < memory->memory_data + memory_data_size) {
if (p_native_start_addr)
*p_native_start_addr = memory->heap_data;
if (p_native_end_addr)
*p_native_end_addr = memory->memory_data + memory_data_size;
return true;
}
else if (memory->heap_data <= (uint8*)native_ptr
&& (uint8*)native_ptr < memory->heap_data_end) {
native_start_addr = memory->heap_data;
native_end_addr = memory->heap_data_end;
}
else
return false;
if (p_native_start_addr)
*p_native_start_addr = native_start_addr;
if (p_native_end_addr)
*p_native_end_addr = native_end_addr;
return true;
return false;
}
bool
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
{
#if WASM_ENABLE_MEMORY_GROW != 0
WASMMemoryInstance *memory = module->default_memory, *new_memory;
uint32 heap_size = memory->memory_data - memory->heap_data;
uint32 old_page_count = memory->cur_page_count;
uint32 total_size_old = memory->end_addr - (uint8*)memory;
uint32 total_page_count = inc_page_count + memory->cur_page_count;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
memory->num_bytes_per_page * (uint64)total_page_count +
memory->global_data_size;
uint64 total_size = offsetof(WASMMemoryInstance, base_addr)
+ (uint64)heap_size
+ memory->num_bytes_per_page * (uint64)total_page_count
+ memory->global_data_size;
uint8 *global_data_old;
void *heap_handle_old = memory->heap_handle;
if (inc_page_count <= 0)
/* No need to enlarge memory */
@ -1131,8 +1095,13 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return false;
}
/* Destroy heap's lock firstly, if its memory is re-allocated,
we cannot access its lock again. */
mem_allocator_destroy_lock(memory->heap_handle);
if (!(new_memory = wasm_runtime_realloc(memory, (uint32)total_size))) {
if (!(new_memory = wasm_runtime_malloc((uint32)total_size))) {
/* Restore heap's lock if memory re-alloc failed */
mem_allocator_reinit_lock(memory->heap_handle);
wasm_set_exception(module, "fail to enlarge memory.");
return false;
}
@ -1144,8 +1113,17 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
memset((uint8*)new_memory + total_size_old,
0, (uint32)total_size - total_size_old);
new_memory->heap_handle = (uint8*)heap_handle_old +
((uint8*)new_memory - (uint8*)memory);
if (mem_allocator_migrate(new_memory->heap_handle,
heap_handle_old) != 0) {
wasm_set_exception(module, "fail to enlarge memory.");
return false;
}
new_memory->cur_page_count = total_page_count;
new_memory->memory_data = new_memory->base_addr;
new_memory->heap_data = new_memory->base_addr;
new_memory->memory_data = new_memory->base_addr + heap_size;
new_memory->global_data = new_memory->memory_data +
new_memory->num_bytes_per_page * total_page_count;
new_memory->end_addr = new_memory->global_data + new_memory->global_data_size;
@ -1160,10 +1138,6 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
module->memories[0] = module->default_memory = new_memory;
return true;
#else /* else of WASM_ENABLE_MEMORY_GROW */
wasm_set_exception(module, "unsupported operation: enlarge memory.");
return false;
#endif /* end of WASM_ENABLE_MEMORY_GROW */
}

View File

@ -23,17 +23,16 @@ typedef struct WASMMemoryInstance {
/* Maximum page count */
uint32 max_page_count;
/* Heap data base address */
uint8 *heap_data;
/* Heap data end address */
uint8 *heap_data_end;
/* The heap created */
void *heap_handle;
/* Heap base offset of wasm app */
int32 heap_base_offset;
/* Heap data base address */
uint8 *heap_data;
/* The heap created */
void *heap_handle;
/* Memory data */
uint8 *memory_data;
/* Global data of global instances */
uint8 *global_data;
uint32 global_data_size;
@ -42,12 +41,11 @@ typedef struct WASMMemoryInstance {
uint8 *end_addr;
/* Base address, the layout is:
thunk_argv data + thunk arg offsets +
memory data + global data
heap_data + memory data + global data
memory data init size is: num_bytes_per_page * cur_page_count
global data size is calculated in module instantiating
Note: when memory is re-allocated, the thunk argv data, thunk
argv offsets and memory data must be copied to new memory also.
Note: when memory is re-allocated, the heap data and memory data
must be copied to new memory also.
*/
uint8 base_addr[1];
} WASMMemoryInstance;