Selaa lähdekoodia

Fix linear memory page count issues (#1380)

Fix issue reported in #1289 and #1371.
Enable to set the max page count to 65536.
Wenyong Huang 3 vuotta sitten
vanhempi
sitoutus
ccd627d2c6

+ 145 - 116
core/iwasm/aot/aot_runtime.c

@@ -412,18 +412,27 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
     if (init_page_count == max_page_count && init_page_count == 1) {
     if (init_page_count == max_page_count && init_page_count == 1) {
         /* If only one page and at most one page, we just append
         /* If only one page and at most one page, we just append
            the app heap to the end of linear memory, enlarge the
            the app heap to the end of linear memory, enlarge the
-           num_bytes_per_page, and don't change the page count*/
+           num_bytes_per_page, and don't change the page count */
         heap_offset = num_bytes_per_page;
         heap_offset = num_bytes_per_page;
         num_bytes_per_page += heap_size;
         num_bytes_per_page += heap_size;
         if (num_bytes_per_page < heap_size) {
         if (num_bytes_per_page < heap_size) {
             set_error_buf(error_buf, error_buf_size,
             set_error_buf(error_buf, error_buf_size,
-                          "memory size must be at most 65536 pages (4GiB)");
+                          "failed to insert app heap into linear memory, "
+                          "try using `--heap_size=0` option");
             return NULL;
             return NULL;
         }
         }
     }
     }
     else if (heap_size > 0) {
     else if (heap_size > 0) {
-        if (module->aux_heap_base_global_index != (uint32)-1
-            && module->aux_heap_base < num_bytes_per_page * init_page_count) {
+        if (init_page_count == max_page_count && init_page_count == 0) {
+            /* If the memory data size is always 0, we resize it to
+               one page for app heap */
+            num_bytes_per_page = heap_size;
+            heap_offset = 0;
+            inc_page_count = 1;
+        }
+        else if (module->aux_heap_base_global_index != (uint32)-1
+                 && module->aux_heap_base
+                        < num_bytes_per_page * init_page_count) {
             /* Insert app heap before __heap_base */
             /* Insert app heap before __heap_base */
             aux_heap_base = module->aux_heap_base;
             aux_heap_base = module->aux_heap_base;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
@@ -464,13 +473,18 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
         }
         }
         init_page_count += inc_page_count;
         init_page_count += inc_page_count;
         max_page_count += inc_page_count;
         max_page_count += inc_page_count;
-        if (init_page_count > 65536) {
+        if (init_page_count > DEFAULT_MAX_PAGES) {
             set_error_buf(error_buf, error_buf_size,
             set_error_buf(error_buf, error_buf_size,
-                          "memory size must be at most 65536 pages (4GiB)");
+                          "failed to insert app heap into linear memory, "
+                          "try using `--heap_size=0` option");
             return NULL;
             return NULL;
         }
         }
-        if (max_page_count > 65536)
-            max_page_count = 65536;
+        else if (init_page_count == DEFAULT_MAX_PAGES) {
+            num_bytes_per_page = UINT32_MAX;
+            init_page_count = max_page_count = 1;
+        }
+        if (max_page_count > DEFAULT_MAX_PAGES)
+            max_page_count = DEFAULT_MAX_PAGES;
     }
     }
 
 
     LOG_VERBOSE("Memory instantiate:");
     LOG_VERBOSE("Memory instantiate:");
@@ -487,6 +501,7 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
         total_size = (uint64)num_bytes_per_page * max_page_count;
         total_size = (uint64)num_bytes_per_page * max_page_count;
     }
     }
 #endif
 #endif
+    bh_assert(total_size <= UINT32_MAX);
 
 
 #ifndef OS_ENABLE_HW_BOUND_CHECK
 #ifndef OS_ENABLE_HW_BOUND_CHECK
     /* Allocate memory */
     /* Allocate memory */
@@ -502,9 +517,8 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
      * both i and memarg.offset are u32 in range 0 to 4G
      * both i and memarg.offset are u32 in range 0 to 4G
      * so the range of ea is 0 to 8G
      * so the range of ea is 0 to 8G
      */
      */
-    if (total_size >= UINT32_MAX
-        || !(p = mapped_mem =
-                 os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
+    if (!(p = mapped_mem =
+              os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
         set_error_buf(error_buf, error_buf_size, "mmap memory failed");
         set_error_buf(error_buf, error_buf_size, "mmap memory failed");
         return NULL;
         return NULL;
     }
     }
@@ -529,15 +543,18 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
      * again here */
      * again here */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
 
+    if (total_size > UINT32_MAX)
+        total_size = UINT32_MAX;
+
     memory_inst->module_type = Wasm_Module_AoT;
     memory_inst->module_type = Wasm_Module_AoT;
     memory_inst->num_bytes_per_page = num_bytes_per_page;
     memory_inst->num_bytes_per_page = num_bytes_per_page;
     memory_inst->cur_page_count = init_page_count;
     memory_inst->cur_page_count = init_page_count;
     memory_inst->max_page_count = max_page_count;
     memory_inst->max_page_count = max_page_count;
+    memory_inst->memory_data_size = (uint32)total_size;
 
 
     /* Init memory info */
     /* Init memory info */
     memory_inst->memory_data.ptr = p;
     memory_inst->memory_data.ptr = p;
     memory_inst->memory_data_end.ptr = p + (uint32)total_size;
     memory_inst->memory_data_end.ptr = p + (uint32)total_size;
-    memory_inst->memory_data_size = (uint32)total_size;
 
 
     /* Initialize heap info */
     /* Initialize heap info */
     memory_inst->heap_data.ptr = p + heap_offset;
     memory_inst->heap_data.ptr = p + heap_offset;
@@ -561,21 +578,19 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
     }
     }
 
 
     if (total_size > 0) {
     if (total_size > 0) {
-        if (sizeof(uintptr_t) == sizeof(uint64)) {
-            memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
-            memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
-            memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
-            memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
-            memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
-        }
-        else {
-            memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
-            memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
-            memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
-            memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
-            memory_inst->mem_bound_check_16bytes.u32[0] =
-                (uint32)total_size - 16;
-        }
+#if UINTPTR_MAX == UINT64_MAX
+        memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
+        memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
+        memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
+        memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
+        memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
+#else
+        memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
+        memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
+        memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
+        memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
+        memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
+#endif
     }
     }
 
 
 #if WASM_ENABLE_SHARED_MEMORY != 0
 #if WASM_ENABLE_SHARED_MEMORY != 0
@@ -2032,26 +2047,29 @@ aot_get_native_addr_range(AOTModuleInstance *module_inst, uint8 *native_ptr,
 bool
 bool
 aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
 aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
 {
 {
-    AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
-    uint32 num_bytes_per_page, cur_page_count, max_page_count;
-    uint32 total_page_count, total_size_old, heap_size;
-    uint64 total_size;
-    uint8 *memory_data_old, *heap_data_old, *memory_data, *heap_data;
+    AOTMemoryInstance *memory = aot_get_default_memory(module_inst);
+    uint8 *memory_data_old, *memory_data_new, *heap_data_old;
+    uint32 num_bytes_per_page, heap_size, total_size_old;
+    uint32 cur_page_count, max_page_count, total_page_count;
+    uint64 total_size_new;
     bool ret = true;
     bool ret = true;
 
 
-    if (!memory_inst)
+    if (!memory)
         return false;
         return false;
 
 
-    num_bytes_per_page = memory_inst->num_bytes_per_page;
-    cur_page_count = memory_inst->cur_page_count;
-    max_page_count = memory_inst->max_page_count;
-    total_page_count = cur_page_count + inc_page_count;
-    total_size_old = memory_inst->memory_data_size;
-    total_size = (uint64)num_bytes_per_page * total_page_count;
-    heap_size = (uint32)((uint8 *)memory_inst->heap_data_end.ptr
-                         - (uint8 *)memory_inst->heap_data.ptr);
-    memory_data_old = (uint8 *)memory_inst->memory_data.ptr;
-    heap_data_old = (uint8 *)memory_inst->heap_data.ptr;
+    heap_data_old = (uint8 *)memory->heap_data.ptr;
+    heap_size = (uint32)((uint8 *)memory->heap_data_end.ptr
+                         - (uint8 *)memory->heap_data.ptr);
+
+    memory_data_old = (uint8 *)memory->memory_data.ptr;
+    total_size_old =
+        (uint32)((uint8 *)memory->memory_data_end.ptr - memory_data_old);
+
+    num_bytes_per_page = memory->num_bytes_per_page;
+    cur_page_count = memory->cur_page_count;
+    max_page_count = memory->max_page_count;
+    total_page_count = inc_page_count + cur_page_count;
+    total_size_new = num_bytes_per_page * (uint64)total_page_count;
 
 
     if (inc_page_count <= 0)
     if (inc_page_count <= 0)
         /* No need to enlarge memory */
         /* No need to enlarge memory */
@@ -2062,94 +2080,103 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
         return false;
         return false;
     }
     }
 
 
-    if (total_size >= UINT32_MAX) {
-        return false;
+    bh_assert(total_size_new <= 4 * (uint64)BH_GB);
+    if (total_size_new > UINT32_MAX) {
+        /* Resize to 1 page with size 4G-1 */
+        num_bytes_per_page = UINT32_MAX;
+        total_page_count = max_page_count = 1;
+        total_size_new = UINT32_MAX;
     }
     }
 
 
 #if WASM_ENABLE_SHARED_MEMORY != 0
 #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->cur_page_count = total_page_count;
+    if (memory->is_shared) {
+        memory->num_bytes_per_page = UINT32_MAX;
+        memory->cur_page_count = total_page_count;
+        memory->max_page_count = max_page_count;
+        memory->memory_data_size = (uint32)total_size_new;
         return true;
         return true;
     }
     }
 #endif
 #endif
 
 
     if (heap_size > 0) {
     if (heap_size > 0) {
-        if (mem_allocator_is_heap_corrupted(memory_inst->heap_handle.ptr)) {
+        if (mem_allocator_is_heap_corrupted(memory->heap_handle.ptr)) {
             wasm_runtime_show_app_heap_corrupted_prompt();
             wasm_runtime_show_app_heap_corrupted_prompt();
             return false;
             return false;
         }
         }
     }
     }
 
 
-    if (!(memory_data =
-              wasm_runtime_realloc(memory_data_old, (uint32)total_size))) {
-        if (!(memory_data = wasm_runtime_malloc((uint32)total_size))) {
+    if (!(memory_data_new =
+              wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
+        if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
             return false;
             return false;
         }
         }
         if (memory_data_old) {
         if (memory_data_old) {
-            bh_memcpy_s(memory_data, (uint32)total_size, memory_data_old,
-                        total_size_old);
+            bh_memcpy_s(memory_data_new, (uint32)total_size_new,
+                        memory_data_old, total_size_old);
             wasm_runtime_free(memory_data_old);
             wasm_runtime_free(memory_data_old);
         }
         }
     }
     }
 
 
-    memset(memory_data + total_size_old, 0,
-           (uint32)total_size - total_size_old);
-
-    memory_inst->cur_page_count = total_page_count;
-    memory_inst->memory_data_size = (uint32)total_size;
-    memory_inst->memory_data.ptr = memory_data;
-    memory_inst->memory_data_end.ptr = memory_data + total_size;
+    memset(memory_data_new + total_size_old, 0,
+           (uint32)total_size_new - total_size_old);
 
 
     if (heap_size > 0) {
     if (heap_size > 0) {
-        if (mem_allocator_migrate(memory_inst->heap_handle.ptr,
+        if (mem_allocator_migrate(memory->heap_handle.ptr,
                                   (char *)heap_data_old
                                   (char *)heap_data_old
-                                      + (memory_data - memory_data_old),
-                                  heap_size)) {
+                                      + (memory_data_new - memory_data_old),
+                                  heap_size)
+            != 0) {
             /* Don't return here as memory->memory_data is obsolete and
             /* Don't return here as memory->memory_data is obsolete and
                must be updated to be correctly used later. */
                must be updated to be correctly used later. */
             ret = false;
             ret = false;
         }
         }
     }
     }
 
 
-    heap_data = memory_data + (heap_data_old - memory_data_old);
-    memory_inst->heap_data.ptr = heap_data;
-    memory_inst->heap_data_end.ptr = heap_data + heap_size;
+    memory->heap_data.ptr = memory_data_new + (heap_data_old - memory_data_old);
+    memory->heap_data_end.ptr = (uint8 *)memory->heap_data.ptr + heap_size;
+
+    memory->num_bytes_per_page = num_bytes_per_page;
+    memory->cur_page_count = total_page_count;
+    memory->max_page_count = max_page_count;
+
+    memory->memory_data.ptr = memory_data_new;
+    memory->memory_data_end.ptr = memory_data_new + (uint32)total_size_new;
+    memory->memory_data_size = (uint32)total_size_new;
+
+#if UINTPTR_MAX == UINT64_MAX
+    memory->mem_bound_check_1byte.u64 = total_size_new - 1;
+    memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
+    memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
+    memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
+    memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
+#else
+    memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
+    memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
+    memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
+    memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
+    memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
+#endif
 
 
-    if (sizeof(uintptr_t) == sizeof(uint64)) {
-        memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
-    }
-    else {
-        memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
-    }
     return ret;
     return ret;
 }
 }
 #else /* else of OS_ENABLE_HW_BOUND_CHECK */
 #else /* else of OS_ENABLE_HW_BOUND_CHECK */
 bool
 bool
 aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
 aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
 {
 {
-    AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
-    uint32 num_bytes_per_page, cur_page_count, max_page_count;
-    uint32 total_page_count;
-    uint64 total_size;
+    AOTMemoryInstance *memory = aot_get_default_memory(module_inst);
+    uint32 num_bytes_per_page, total_size_old;
+    uint32 cur_page_count, max_page_count, total_page_count;
+    uint64 total_size_new;
 
 
-    if (!memory_inst)
+    if (!memory)
         return false;
         return false;
 
 
-    num_bytes_per_page = memory_inst->num_bytes_per_page;
-    cur_page_count = memory_inst->cur_page_count;
-    max_page_count = memory_inst->max_page_count;
-    total_page_count = cur_page_count + inc_page_count;
-    total_size = (uint64)num_bytes_per_page * total_page_count;
+    num_bytes_per_page = memory->num_bytes_per_page;
+    cur_page_count = memory->cur_page_count;
+    max_page_count = memory->max_page_count;
+    total_size_old = num_bytes_per_page * cur_page_count;
+    total_page_count = inc_page_count + cur_page_count;
+    total_size_new = num_bytes_per_page * (uint64)total_page_count;
 
 
     if (inc_page_count <= 0)
     if (inc_page_count <= 0)
         /* No need to enlarge memory */
         /* No need to enlarge memory */
@@ -2160,21 +2187,29 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
         return false;
         return false;
     }
     }
 
 
+    bh_assert(total_size_new <= 4 * (uint64)BH_GB);
+    if (total_size_new > UINT32_MAX) {
+        /* Resize to 1 page with size 4G-1 */
+        num_bytes_per_page = UINT32_MAX;
+        total_page_count = max_page_count = 1;
+        total_size_new = UINT32_MAX;
+    }
+
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
-    if (!os_mem_commit(memory_inst->memory_data_end.ptr,
-                       num_bytes_per_page * inc_page_count,
+    if (!os_mem_commit(memory->memory_data_end.ptr,
+                       (uint32)total_size_new - total_size_old,
                        MMAP_PROT_READ | MMAP_PROT_WRITE)) {
                        MMAP_PROT_READ | MMAP_PROT_WRITE)) {
         return false;
         return false;
     }
     }
 #endif
 #endif
 
 
-    if (os_mprotect(memory_inst->memory_data_end.ptr,
-                    num_bytes_per_page * inc_page_count,
+    if (os_mprotect(memory->memory_data_end.ptr,
+                    (uint32)total_size_new - total_size_old,
                     MMAP_PROT_READ | MMAP_PROT_WRITE)
                     MMAP_PROT_READ | MMAP_PROT_WRITE)
         != 0) {
         != 0) {
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
-        os_mem_decommit(memory_inst->memory_data_end.ptr,
-                        num_bytes_per_page * inc_page_count);
+        os_mem_decommit(memory->memory_data_end.ptr,
+                        (uint32)total_size_new - total_size_old);
 #endif
 #endif
         return false;
         return false;
     }
     }
@@ -2182,25 +2217,19 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
     /* The increased pages are filled with zero by the OS when os_mmap,
     /* The increased pages are filled with zero by the OS when os_mmap,
        no need to memset it again here */
        no need to memset it again here */
 
 
-    memory_inst->cur_page_count = total_page_count;
-    memory_inst->memory_data_size = (uint32)total_size;
-    memory_inst->memory_data_end.ptr =
-        (uint8 *)memory_inst->memory_data.ptr + (uint32)total_size;
+    memory->num_bytes_per_page = num_bytes_per_page;
+    memory->cur_page_count = total_page_count;
+    memory->max_page_count = max_page_count;
+    memory->memory_data_size = (uint32)total_size_new;
+    memory->memory_data_end.ptr =
+        (uint8 *)memory->memory_data.ptr + (uint32)total_size_new;
+
+    memory->mem_bound_check_1byte.u64 = total_size_new - 1;
+    memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
+    memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
+    memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
+    memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
 
 
-    if (sizeof(uintptr_t) == sizeof(uint64)) {
-        memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
-    }
-    else {
-        memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
-        memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
-        memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
-        memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
-        memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
-    }
     return true;
     return true;
 }
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */

+ 1 - 0
core/iwasm/interpreter/wasm.h

@@ -29,6 +29,7 @@ extern "C" {
 #define VALUE_TYPE_ANY 0x42
 #define VALUE_TYPE_ANY 0x42
 
 
 #define DEFAULT_NUM_BYTES_PER_PAGE 65536
 #define DEFAULT_NUM_BYTES_PER_PAGE 65536
+#define DEFAULT_MAX_PAGES 65536
 
 
 #define NULL_REF (0xFFFFFFFF)
 #define NULL_REF (0xFFFFFFFF)
 
 

+ 27 - 14
core/iwasm/interpreter/wasm_loader.c

@@ -1266,7 +1266,7 @@ fail:
 static bool
 static bool
 check_memory_init_size(uint32 init_size, char *error_buf, uint32 error_buf_size)
 check_memory_init_size(uint32 init_size, char *error_buf, uint32 error_buf_size)
 {
 {
-    if (init_size > 65536) {
+    if (init_size > DEFAULT_MAX_PAGES) {
         set_error_buf(error_buf, error_buf_size,
         set_error_buf(error_buf, error_buf_size,
                       "memory size must be at most 65536 pages (4GiB)");
                       "memory size must be at most 65536 pages (4GiB)");
         return false;
         return false;
@@ -1284,7 +1284,7 @@ check_memory_max_size(uint32 init_size, uint32 max_size, char *error_buf,
         return false;
         return false;
     }
     }
 
 
-    if (max_size > 65536) {
+    if (max_size > DEFAULT_MAX_PAGES) {
         set_error_buf(error_buf, error_buf_size,
         set_error_buf(error_buf, error_buf_size,
                       "memory size must be at most 65536 pages (4GiB)");
                       "memory size must be at most 65536 pages (4GiB)");
         return false;
         return false;
@@ -1299,12 +1299,12 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
                    char *error_buf, uint32 error_buf_size)
                    char *error_buf, uint32 error_buf_size)
 {
 {
     const uint8 *p = *p_buf, *p_end = buf_end;
     const uint8 *p = *p_buf, *p_end = buf_end;
-    uint32 pool_size = wasm_runtime_memory_pool_size();
 #if WASM_ENABLE_APP_FRAMEWORK != 0
 #if WASM_ENABLE_APP_FRAMEWORK != 0
+    uint32 pool_size = wasm_runtime_memory_pool_size();
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
                             / DEFAULT_NUM_BYTES_PER_PAGE;
                             / DEFAULT_NUM_BYTES_PER_PAGE;
 #else
 #else
-    uint32 max_page_count = pool_size / DEFAULT_NUM_BYTES_PER_PAGE;
+    uint32 max_page_count = DEFAULT_MAX_PAGES;
 #endif /* WASM_ENABLE_APP_FRAMEWORK */
 #endif /* WASM_ENABLE_APP_FRAMEWORK */
     uint32 declare_max_page_count_flag = 0;
     uint32 declare_max_page_count_flag = 0;
     uint32 declare_init_page_count = 0;
     uint32 declare_init_page_count = 0;
@@ -1529,12 +1529,12 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
             char *error_buf, uint32 error_buf_size)
             char *error_buf, uint32 error_buf_size)
 {
 {
     const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
     const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
-    uint32 pool_size = wasm_runtime_memory_pool_size();
 #if WASM_ENABLE_APP_FRAMEWORK != 0
 #if WASM_ENABLE_APP_FRAMEWORK != 0
+    uint32 pool_size = wasm_runtime_memory_pool_size();
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
                             / DEFAULT_NUM_BYTES_PER_PAGE;
                             / DEFAULT_NUM_BYTES_PER_PAGE;
 #else
 #else
-    uint32 max_page_count = pool_size / DEFAULT_NUM_BYTES_PER_PAGE;
+    uint32 max_page_count = DEFAULT_MAX_PAGES;
 #endif
 #endif
 
 
     p_org = p;
     p_org = p;
@@ -3317,17 +3317,30 @@ load_from_sections(WASMModule *module, WASMSection *sections,
 #if WASM_ENABLE_MULTI_MODULE == 0
 #if WASM_ENABLE_MULTI_MODULE == 0
         if (module->import_memory_count) {
         if (module->import_memory_count) {
             memory_import = &module->import_memories[0].u.memory;
             memory_import = &module->import_memories[0].u.memory;
-            /* Memory init page count cannot be larger than 65536, we don't
-               check integer overflow again. */
-            memory_import->num_bytes_per_page *= memory_import->init_page_count;
-            memory_import->init_page_count = memory_import->max_page_count = 1;
+            if (memory_import->init_page_count < DEFAULT_MAX_PAGES)
+                memory_import->num_bytes_per_page *=
+                    memory_import->init_page_count;
+            else
+                memory_import->num_bytes_per_page = UINT32_MAX;
+
+            if (memory_import->init_page_count > 0)
+                memory_import->init_page_count = memory_import->max_page_count =
+                    1;
+            else
+                memory_import->init_page_count = memory_import->max_page_count =
+                    0;
         }
         }
         if (module->memory_count) {
         if (module->memory_count) {
-            /* Memory init page count cannot be larger than 65536, we don't
-               check integer overflow again. */
             memory = &module->memories[0];
             memory = &module->memories[0];
-            memory->num_bytes_per_page *= memory->init_page_count;
-            memory->init_page_count = memory->max_page_count = 1;
+            if (memory->init_page_count < DEFAULT_MAX_PAGES)
+                memory->num_bytes_per_page *= memory->init_page_count;
+            else
+                memory->num_bytes_per_page = UINT32_MAX;
+
+            if (memory->init_page_count > 0)
+                memory->init_page_count = memory->max_page_count = 1;
+            else
+                memory->init_page_count = memory->max_page_count = 0;
         }
         }
 #endif
 #endif
     }
     }

+ 25 - 12
core/iwasm/interpreter/wasm_mini_loader.c

@@ -534,12 +534,12 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
                    char *error_buf, uint32 error_buf_size)
                    char *error_buf, uint32 error_buf_size)
 {
 {
     const uint8 *p = *p_buf, *p_end = buf_end;
     const uint8 *p = *p_buf, *p_end = buf_end;
-    uint32 pool_size = wasm_runtime_memory_pool_size();
 #if WASM_ENABLE_APP_FRAMEWORK != 0
 #if WASM_ENABLE_APP_FRAMEWORK != 0
+    uint32 pool_size = wasm_runtime_memory_pool_size();
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
                             / DEFAULT_NUM_BYTES_PER_PAGE;
                             / DEFAULT_NUM_BYTES_PER_PAGE;
 #else
 #else
-    uint32 max_page_count = pool_size / DEFAULT_NUM_BYTES_PER_PAGE;
+    uint32 max_page_count = DEFAULT_MAX_PAGES;
 #endif /* WASM_ENABLE_APP_FRAMEWORK */
 #endif /* WASM_ENABLE_APP_FRAMEWORK */
     uint32 declare_max_page_count_flag = 0;
     uint32 declare_max_page_count_flag = 0;
     uint32 declare_init_page_count = 0;
     uint32 declare_init_page_count = 0;
@@ -650,12 +650,12 @@ load_memory(const uint8 **p_buf, const uint8 *buf_end, WASMMemory *memory,
             char *error_buf, uint32 error_buf_size)
             char *error_buf, uint32 error_buf_size)
 {
 {
     const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
     const uint8 *p = *p_buf, *p_end = buf_end, *p_org;
-    uint32 pool_size = wasm_runtime_memory_pool_size();
 #if WASM_ENABLE_APP_FRAMEWORK != 0
 #if WASM_ENABLE_APP_FRAMEWORK != 0
+    uint32 pool_size = wasm_runtime_memory_pool_size();
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
     uint32 max_page_count = pool_size * APP_MEMORY_MAX_GLOBAL_HEAP_PERCENT
                             / DEFAULT_NUM_BYTES_PER_PAGE;
                             / DEFAULT_NUM_BYTES_PER_PAGE;
 #else
 #else
-    uint32 max_page_count = pool_size / DEFAULT_NUM_BYTES_PER_PAGE;
+    uint32 max_page_count = DEFAULT_MAX_PAGES;
 #endif
 #endif
 
 
     p_org = p;
     p_org = p;
@@ -2153,18 +2153,31 @@ load_from_sections(WASMModule *module, WASMSection *sections,
 
 
         if (module->import_memory_count) {
         if (module->import_memory_count) {
             memory_import = &module->import_memories[0].u.memory;
             memory_import = &module->import_memories[0].u.memory;
-            /* Memory init page count cannot be larger than 65536, we don't
-               check integer overflow again. */
-            memory_import->num_bytes_per_page *= memory_import->init_page_count;
-            memory_import->init_page_count = memory_import->max_page_count = 1;
+            if (memory_import->init_page_count < DEFAULT_MAX_PAGES)
+                memory_import->num_bytes_per_page *=
+                    memory_import->init_page_count;
+            else
+                memory_import->num_bytes_per_page = UINT32_MAX;
+
+            if (memory_import->init_page_count > 0)
+                memory_import->init_page_count = memory_import->max_page_count =
+                    1;
+            else
+                memory_import->init_page_count = memory_import->max_page_count =
+                    0;
         }
         }
 
 
         if (module->memory_count) {
         if (module->memory_count) {
-            /* Memory init page count cannot be larger than 65536, we don't
-               check integer overflow again. */
             memory = &module->memories[0];
             memory = &module->memories[0];
-            memory->num_bytes_per_page *= memory->init_page_count;
-            memory->init_page_count = memory->max_page_count = 1;
+            if (memory->init_page_count < DEFAULT_MAX_PAGES)
+                memory->num_bytes_per_page *= memory->init_page_count;
+            else
+                memory->num_bytes_per_page = UINT32_MAX;
+
+            if (memory->init_page_count > 0)
+                memory->init_page_count = memory->max_page_count = 1;
+            else
+                memory->init_page_count = memory->max_page_count = 0;
         }
         }
     }
     }
 
 

+ 116 - 60
core/iwasm/interpreter/wasm_runtime.c

@@ -206,18 +206,27 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
     if (init_page_count == max_page_count && init_page_count == 1) {
     if (init_page_count == max_page_count && init_page_count == 1) {
         /* If only one page and at most one page, we just append
         /* If only one page and at most one page, we just append
            the app heap to the end of linear memory, enlarge the
            the app heap to the end of linear memory, enlarge the
-           num_bytes_per_page, and don't change the page count*/
+           num_bytes_per_page, and don't change the page count */
         heap_offset = num_bytes_per_page;
         heap_offset = num_bytes_per_page;
         num_bytes_per_page += heap_size;
         num_bytes_per_page += heap_size;
         if (num_bytes_per_page < heap_size) {
         if (num_bytes_per_page < heap_size) {
             set_error_buf(error_buf, error_buf_size,
             set_error_buf(error_buf, error_buf_size,
-                          "memory size must be at most 65536 pages (4GiB)");
+                          "failed to insert app heap into linear memory, "
+                          "try using `--heap_size=0` option");
             return NULL;
             return NULL;
         }
         }
     }
     }
     else if (heap_size > 0) {
     else if (heap_size > 0) {
-        if (module->aux_heap_base_global_index != (uint32)-1
-            && module->aux_heap_base < num_bytes_per_page * init_page_count) {
+        if (init_page_count == max_page_count && init_page_count == 0) {
+            /* If the memory data size is always 0, we resize it to
+               one page for app heap */
+            num_bytes_per_page = heap_size;
+            heap_offset = 0;
+            inc_page_count = 1;
+        }
+        else if (module->aux_heap_base_global_index != (uint32)-1
+                 && module->aux_heap_base
+                        < num_bytes_per_page * init_page_count) {
             /* Insert app heap before __heap_base */
             /* Insert app heap before __heap_base */
             aux_heap_base = module->aux_heap_base;
             aux_heap_base = module->aux_heap_base;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
             bytes_of_last_page = aux_heap_base % num_bytes_per_page;
@@ -259,13 +268,18 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
         }
         }
         init_page_count += inc_page_count;
         init_page_count += inc_page_count;
         max_page_count += inc_page_count;
         max_page_count += inc_page_count;
-        if (init_page_count > 65536) {
+        if (init_page_count > DEFAULT_MAX_PAGES) {
             set_error_buf(error_buf, error_buf_size,
             set_error_buf(error_buf, error_buf_size,
-                          "memory size must be at most 65536 pages (4GiB)");
+                          "failed to insert app heap into linear memory, "
+                          "try using `--heap_size=0` option");
             return NULL;
             return NULL;
         }
         }
-        if (max_page_count > 65536)
-            max_page_count = 65536;
+        else if (init_page_count == DEFAULT_MAX_PAGES) {
+            num_bytes_per_page = UINT32_MAX;
+            init_page_count = max_page_count = 1;
+        }
+        if (max_page_count > DEFAULT_MAX_PAGES)
+            max_page_count = DEFAULT_MAX_PAGES;
     }
     }
 
 
     LOG_VERBOSE("Memory instantiate:");
     LOG_VERBOSE("Memory instantiate:");
@@ -280,6 +294,7 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
         memory_data_size = (uint64)num_bytes_per_page * max_page_count;
         memory_data_size = (uint64)num_bytes_per_page * max_page_count;
     }
     }
 #endif
 #endif
+    bh_assert(memory_data_size <= 4 * (uint64)BH_GB);
 
 
     /* Allocate memory space, addr data and global data */
     /* Allocate memory space, addr data and global data */
     if (!(memory = runtime_malloc((uint64)sizeof(WASMMemoryInstance), error_buf,
     if (!(memory = runtime_malloc((uint64)sizeof(WASMMemoryInstance), error_buf,
@@ -301,9 +316,8 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
      * both i and memarg.offset are u32 in range 0 to 4G
      * both i and memarg.offset are u32 in range 0 to 4G
      * so the range of ea is 0 to 8G
      * so the range of ea is 0 to 8G
      */
      */
-    if (memory_data_size >= UINT32_MAX
-        || !(memory->memory_data = mapped_mem =
-                 os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
+    if (!(memory->memory_data = mapped_mem =
+              os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
         set_error_buf(error_buf, error_buf_size, "mmap memory failed");
         set_error_buf(error_buf, error_buf_size, "mmap memory failed");
         goto fail1;
         goto fail1;
     }
     }
@@ -327,10 +341,14 @@ memory_instantiate(WASMModuleInstance *module_inst, uint32 num_bytes_per_page,
      * again here */
      * again here */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 
 
+    if (memory_data_size > UINT32_MAX)
+        memory_data_size = (uint32)memory_data_size;
+
     memory->module_type = Wasm_Module_Bytecode;
     memory->module_type = Wasm_Module_Bytecode;
     memory->num_bytes_per_page = num_bytes_per_page;
     memory->num_bytes_per_page = num_bytes_per_page;
     memory->cur_page_count = init_page_count;
     memory->cur_page_count = init_page_count;
     memory->max_page_count = max_page_count;
     memory->max_page_count = max_page_count;
+    memory->memory_data_size = (uint32)memory_data_size;
 
 
     memory->heap_data = memory->memory_data + heap_offset;
     memory->heap_data = memory->memory_data + heap_offset;
     memory->heap_data_end = memory->heap_data + heap_size;
     memory->heap_data_end = memory->heap_data + heap_size;
@@ -2419,39 +2437,49 @@ bool
 wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 {
 {
     WASMMemoryInstance *memory = module->default_memory;
     WASMMemoryInstance *memory = module->default_memory;
-    uint8 *new_memory_data, *memory_data, *heap_data_old;
-    uint32 heap_size, total_size_old, total_page_count;
-    uint64 total_size;
+    uint8 *memory_data_old, *memory_data_new, *heap_data_old;
+    uint32 num_bytes_per_page, heap_size, total_size_old;
+    uint32 cur_page_count, max_page_count, total_page_count;
+    uint64 total_size_new;
     bool ret = true;
     bool ret = true;
 
 
     if (!memory)
     if (!memory)
         return false;
         return false;
 
 
-    memory_data = memory->memory_data;
-    heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
-    total_size_old = (uint32)(memory->memory_data_end - memory_data);
-    total_page_count = inc_page_count + memory->cur_page_count;
-    total_size = memory->num_bytes_per_page * (uint64)total_page_count;
     heap_data_old = memory->heap_data;
     heap_data_old = memory->heap_data;
+    heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
+
+    memory_data_old = memory->memory_data;
+    total_size_old = memory->memory_data_size;
+
+    num_bytes_per_page = memory->num_bytes_per_page;
+    cur_page_count = memory->cur_page_count;
+    max_page_count = memory->max_page_count;
+    total_page_count = inc_page_count + cur_page_count;
+    total_size_new = num_bytes_per_page * (uint64)total_page_count;
 
 
     if (inc_page_count <= 0)
     if (inc_page_count <= 0)
         /* No need to enlarge memory */
         /* No need to enlarge memory */
         return true;
         return true;
 
 
-    if (total_page_count < memory->cur_page_count /* integer overflow */
-        || total_page_count > memory->max_page_count) {
+    if (total_page_count < cur_page_count /* integer overflow */
+        || total_page_count > max_page_count) {
         return false;
         return false;
     }
     }
 
 
-    if (total_size >= UINT32_MAX) {
-        return false;
+    bh_assert(total_size_new <= 4 * (uint64)BH_GB);
+    if (total_size_new > UINT32_MAX) {
+        /* Resize to 1 page with size 4G-1 */
+        num_bytes_per_page = UINT32_MAX;
+        total_page_count = max_page_count = 1;
+        total_size_new = UINT32_MAX;
     }
     }
 
 
 #if WASM_ENABLE_SHARED_MEMORY != 0
 #if WASM_ENABLE_SHARED_MEMORY != 0
     if (memory->is_shared) {
     if (memory->is_shared) {
-        /* For shared memory, we have reserved the maximum spaces during
-            instantiate, only change the cur_page_count here */
+        memory->num_bytes_per_page = UINT32_MAX;
         memory->cur_page_count = total_page_count;
         memory->cur_page_count = total_page_count;
+        memory->max_page_count = max_page_count;
         return true;
         return true;
     }
     }
 #endif
 #endif
@@ -2463,25 +2491,25 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
         }
         }
     }
     }
 
 
-    if (!(new_memory_data =
-              wasm_runtime_realloc(memory_data, (uint32)total_size))) {
-        if (!(new_memory_data = wasm_runtime_malloc((uint32)total_size))) {
+    if (!(memory_data_new =
+              wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
+        if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
             return false;
             return false;
         }
         }
-        if (memory_data) {
-            bh_memcpy_s(new_memory_data, (uint32)total_size, memory_data,
-                        total_size_old);
-            wasm_runtime_free(memory_data);
+        if (memory_data_old) {
+            bh_memcpy_s(memory_data_new, (uint32)total_size_new,
+                        memory_data_old, total_size_old);
+            wasm_runtime_free(memory_data_old);
         }
         }
     }
     }
 
 
-    memset(new_memory_data + total_size_old, 0,
-           (uint32)total_size - total_size_old);
+    memset(memory_data_new + total_size_old, 0,
+           (uint32)total_size_new - total_size_old);
 
 
     if (heap_size > 0) {
     if (heap_size > 0) {
         if (mem_allocator_migrate(memory->heap_handle,
         if (mem_allocator_migrate(memory->heap_handle,
                                   (char *)heap_data_old
                                   (char *)heap_data_old
-                                      + (new_memory_data - memory_data),
+                                      + (memory_data_new - memory_data_old),
                                   heap_size)
                                   heap_size)
             != 0) {
             != 0) {
             /* Don't return here as memory->memory_data is obsolete and
             /* Don't return here as memory->memory_data is obsolete and
@@ -2490,26 +2518,30 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
         }
         }
     }
     }
 
 
-    memory->memory_data = new_memory_data;
-    memory->cur_page_count = total_page_count;
-    memory->heap_data = new_memory_data + (heap_data_old - memory_data);
+    memory->heap_data = memory_data_new + (heap_data_old - memory_data_old);
     memory->heap_data_end = memory->heap_data + heap_size;
     memory->heap_data_end = memory->heap_data + heap_size;
-    memory->memory_data_end =
-        memory->memory_data + memory->num_bytes_per_page * total_page_count;
+
+    memory->num_bytes_per_page = num_bytes_per_page;
+    memory->cur_page_count = total_page_count;
+    memory->max_page_count = max_page_count;
+    memory->memory_data_size = (uint32)total_size_new;
+
+    memory->memory_data = memory_data_new;
+    memory->memory_data_end = memory_data_new + (uint32)total_size_new;
 
 
 #if WASM_ENABLE_FAST_JIT != 0
 #if WASM_ENABLE_FAST_JIT != 0
 #if UINTPTR_MAX == UINT64_MAX
 #if UINTPTR_MAX == UINT64_MAX
-    memory->mem_bound_check_1byte = total_size - 1;
-    memory->mem_bound_check_2bytes = total_size - 2;
-    memory->mem_bound_check_4bytes = total_size - 4;
-    memory->mem_bound_check_8bytes = total_size - 8;
-    memory->mem_bound_check_16bytes = total_size - 16;
+    memory->mem_bound_check_1byte = total_size_new - 1;
+    memory->mem_bound_check_2bytes = total_size_new - 2;
+    memory->mem_bound_check_4bytes = total_size_new - 4;
+    memory->mem_bound_check_8bytes = total_size_new - 8;
+    memory->mem_bound_check_16bytes = total_size_new - 16;
 #else
 #else
-    memory->mem_bound_check_1byte = (uint32)total_size - 1;
-    memory->mem_bound_check_2bytes = (uint32)total_size - 2;
-    memory->mem_bound_check_4bytes = (uint32)total_size - 4;
-    memory->mem_bound_check_8bytes = (uint32)total_size - 8;
-    memory->mem_bound_check_16bytes = (uint32)total_size - 16;
+    memory->mem_bound_check_1byte = (uint32)total_size_new - 1;
+    memory->mem_bound_check_2bytes = (uint32)total_size_new - 2;
+    memory->mem_bound_check_4bytes = (uint32)total_size_new - 4;
+    memory->mem_bound_check_8bytes = (uint32)total_size_new - 8;
+    memory->mem_bound_check_16bytes = (uint32)total_size_new - 16;
 #endif
 #endif
 #endif
 #endif
 
 
@@ -2520,39 +2552,52 @@ bool
 wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
 {
 {
     WASMMemoryInstance *memory = module->default_memory;
     WASMMemoryInstance *memory = module->default_memory;
-    uint32 num_bytes_per_page, total_page_count;
+    uint32 num_bytes_per_page, total_size_old;
+    uint32 cur_page_count, max_page_count, total_page_count;
+    uint64 total_size_new;
 
 
     if (!memory)
     if (!memory)
         return false;
         return false;
 
 
-    total_page_count = inc_page_count + memory->cur_page_count;
+    num_bytes_per_page = memory->num_bytes_per_page;
+    cur_page_count = memory->cur_page_count;
+    max_page_count = memory->max_page_count;
+    total_size_old = num_bytes_per_page * cur_page_count;
+    total_page_count = inc_page_count + cur_page_count;
+    total_size_new = num_bytes_per_page * (uint64)total_page_count;
 
 
     if (inc_page_count <= 0)
     if (inc_page_count <= 0)
         /* No need to enlarge memory */
         /* No need to enlarge memory */
         return true;
         return true;
 
 
-    if (total_page_count < memory->cur_page_count /* integer overflow */
-        || total_page_count > memory->max_page_count) {
+    if (total_page_count < cur_page_count /* integer overflow */
+        || total_page_count > max_page_count) {
         return false;
         return false;
     }
     }
 
 
-    num_bytes_per_page = memory->num_bytes_per_page;
+    bh_assert(total_size_new <= 4 * (uint64)BH_GB);
+    if (total_size_new > UINT32_MAX) {
+        /* Resize to 1 page with size 4G-1 */
+        num_bytes_per_page = UINT32_MAX;
+        total_page_count = max_page_count = 1;
+        total_size_new = UINT32_MAX;
+    }
 
 
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
     if (!os_mem_commit(memory->memory_data_end,
     if (!os_mem_commit(memory->memory_data_end,
-                       num_bytes_per_page * inc_page_count,
+                       (uint32)total_size_new - total_size_old,
                        MMAP_PROT_READ | MMAP_PROT_WRITE)) {
                        MMAP_PROT_READ | MMAP_PROT_WRITE)) {
         return false;
         return false;
     }
     }
 #endif
 #endif
 
 
     if (os_mprotect(memory->memory_data_end,
     if (os_mprotect(memory->memory_data_end,
-                    num_bytes_per_page * inc_page_count,
+                    (uint32)total_size_new - total_size_old,
                     MMAP_PROT_READ | MMAP_PROT_WRITE)
                     MMAP_PROT_READ | MMAP_PROT_WRITE)
         != 0) {
         != 0) {
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
         os_mem_decommit(memory->memory_data_end,
         os_mem_decommit(memory->memory_data_end,
-                        num_bytes_per_page * inc_page_count);
+                        (uint32)total_size_new - total_size_old);
 #endif
 #endif
         return false;
         return false;
     }
     }
@@ -2560,9 +2605,20 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
     /* The increased pages are filled with zero by the OS when os_mmap,
     /* The increased pages are filled with zero by the OS when os_mmap,
        no need to memset it again here */
        no need to memset it again here */
 
 
+    memory->num_bytes_per_page = num_bytes_per_page;
     memory->cur_page_count = total_page_count;
     memory->cur_page_count = total_page_count;
-    memory->memory_data_end =
-        memory->memory_data + num_bytes_per_page * total_page_count;
+    memory->max_page_count = max_page_count;
+    memory->memory_data_size = (uint32)total_size_new;
+    memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
+
+#if WASM_ENABLE_FAST_JIT != 0
+    memory->mem_bound_check_1byte = total_size_new - 1;
+    memory->mem_bound_check_2bytes = total_size_new - 2;
+    memory->mem_bound_check_4bytes = total_size_new - 4;
+    memory->mem_bound_check_8bytes = total_size_new - 8;
+    memory->mem_bound_check_16bytes = total_size_new - 16;
+#endif
+
     return true;
     return true;
 }
 }
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
 #endif /* end of OS_ENABLE_HW_BOUND_CHECK */

+ 13 - 8
core/iwasm/interpreter/wasm_runtime.h

@@ -26,12 +26,25 @@ struct WASMMemoryInstance {
     uint32 module_type;
     uint32 module_type;
     /* Shared memory flag */
     /* Shared memory flag */
     bool is_shared;
     bool is_shared;
+
     /* Number bytes per page */
     /* Number bytes per page */
     uint32 num_bytes_per_page;
     uint32 num_bytes_per_page;
     /* Current page count */
     /* Current page count */
     uint32 cur_page_count;
     uint32 cur_page_count;
     /* Maximum page count */
     /* Maximum page count */
     uint32 max_page_count;
     uint32 max_page_count;
+    /* Memory data size */
+    uint32 memory_data_size;
+
+    /**
+     * Memory data begin address, Note:
+     *   the app-heap might be inserted in to the linear memory,
+     *   when memory is re-allocated, the heap data and memory data
+     *   must be copied to new memory also
+     */
+    uint8 *memory_data;
+    /* Memory data end address */
+    uint8 *memory_data_end;
 
 
     /* Heap data base address */
     /* Heap data base address */
     uint8 *heap_data;
     uint8 *heap_data;
@@ -45,14 +58,6 @@ struct WASMMemoryInstance {
     korp_mutex mem_lock;
     korp_mutex mem_lock;
 #endif
 #endif
 
 
-    /* Memory data end address */
-    uint8 *memory_data_end;
-
-    /* Memory data begin address, the layout is: memory data + heap data
-       Note: when memory is re-allocated, the heap data and memory data
-             must be copied to new memory also. */
-    uint8 *memory_data;
-
 #if WASM_ENABLE_FAST_JIT != 0
 #if WASM_ENABLE_FAST_JIT != 0
 #if UINTPTR_MAX == UINT64_MAX
 #if UINTPTR_MAX == UINT64_MAX
     uint64 mem_bound_check_1byte;
     uint64 mem_bound_check_1byte;