Explorar el Código

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
wenyongh hace 6 años
padre
commit
504268b297

+ 1 - 1
README.md

@@ -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:

+ 7 - 2
core/iwasm/products/linux/CMakeLists.txt

@@ -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")
 

+ 21 - 20
core/iwasm/products/linux/main.c

@@ -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;
 }
 

+ 35 - 30
core/iwasm/runtime/vmcore-wasm/wasm_interp.c

@@ -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;                                                       \
-    }                                                                           \
-    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;                                                       \
+    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;                                                     \
     }                                                                           \
-    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);

+ 18 - 6
core/iwasm/runtime/vmcore-wasm/wasm_loader.c

@@ -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;

+ 119 - 67
core/iwasm/runtime/vmcore-wasm/wasm_runtime.c

@@ -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

+ 6 - 12
core/iwasm/runtime/vmcore-wasm/wasm_runtime.h

@@ -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

+ 6 - 0
core/shared-lib/include/bh_memory.h

@@ -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
 
 /**

+ 9 - 0
core/shared-lib/include/config.h

@@ -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)

+ 14 - 1
core/shared-lib/mem-alloc/bh_memory.c

@@ -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) {

+ 1 - 1
core/shared-lib/platform/linux/bh_thread.c

@@ -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);