Ver código fonte

Fix interpreter read linear memory size for multi-threading (#2088)

Load memory data size in each time memory access boundary check in
multi-threading mode since it may be changed by other threads when
memory growing.

And use `memory->memory_data_size` instead of
`memory->num_bytes_per_page * memory->cur_page_count` to refine
the code.
Wenyong Huang 2 anos atrás
pai
commit
5fc48e3584

+ 37 - 21
core/iwasm/interpreter/wasm_interp_classic.c

@@ -28,12 +28,23 @@ typedef float64 CellType_F64;
 
 #define BR_TABLE_TMP_BUF_LEN 32
 
+#if WASM_ENABLE_THREAD_MGR == 0
+#define get_linear_mem_size() linear_mem_size
+#else
+/**
+ * Load memory data size in each time boundary check in
+ * multi-threading mode since it may be changed by other
+ * threads in memory.grow
+ */
+#define get_linear_mem_size() memory->memory_data_size
+#endif
+
 #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
 #define CHECK_MEMORY_OVERFLOW(bytes)                            \
     do {                                                        \
         uint64 offset1 = (uint64)offset + (uint64)addr;         \
-        if (offset1 + bytes <= (uint64)linear_mem_size)         \
+        if (offset1 + bytes <= (uint64)get_linear_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;              \
@@ -41,15 +52,15 @@ typedef float64 CellType_F64;
             goto out_of_bounds;                                 \
     } while (0)
 
-#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
-    do {                                                \
-        uint64 offset1 = (uint32)(start);               \
-        if (offset1 + bytes <= (uint64)linear_mem_size) \
-            /* App heap space is not valid space for    \
-             bulk memory operation */                   \
-            maddr = memory->memory_data + offset1;      \
-        else                                            \
-            goto out_of_bounds;                         \
+#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr)       \
+    do {                                                      \
+        uint64 offset1 = (uint32)(start);                     \
+        if (offset1 + bytes <= (uint64)get_linear_mem_size()) \
+            /* App heap space is not valid space for          \
+             bulk memory operation */                         \
+            maddr = memory->memory_data + offset1;            \
+        else                                                  \
+            goto out_of_bounds;                               \
     } while (0)
 #else
 #define CHECK_MEMORY_OVERFLOW(bytes)                    \
@@ -1134,22 +1145,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if WASM_ENABLE_SHARED_MEMORY != 0
     WASMSharedMemNode *node =
         wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
-#else
-    void *node = NULL;
 #endif
-
     WASMMemoryInstance *memory = wasm_get_default_memory(module);
-    uint8 *global_data = module->global_data;
 #if !defined(OS_ENABLE_HW_BOUND_CHECK)              \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
-    uint32 num_bytes_per_page =
-        memory ? wasm_get_num_bytes_per_page(memory, node) : 0;
-    uint32 linear_mem_size =
-        memory ? wasm_get_linear_memory_size(memory, node) : 0;
+    uint32 linear_mem_size = memory ? memory->memory_data_size : 0;
 #endif
     WASMType **wasm_types = module->module->types;
     WASMGlobalInstance *globals = module->e->globals, *global;
+    uint8 *global_data = module->global_data;
     uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
     WASMInterpFrame *frame = NULL;
     /* Points to this special opcode so as to jump to the
@@ -2122,8 +2127,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if !defined(OS_ENABLE_HW_BOUND_CHECK)              \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
-                    linear_mem_size =
-                        num_bytes_per_page * memory->cur_page_count;
+                    linear_mem_size = memory->memory_data_size;
 #endif
                 }
 
@@ -3127,6 +3131,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         offset = (uint64)(uint32)POP_I32();
                         addr = (uint32)POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR != 0
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
 #else
@@ -3165,6 +3173,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         src = POP_I32();
                         dst = POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR != 0
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
@@ -3192,6 +3204,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         fill_val = POP_I32();
                         dst = POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR != 0
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #else
@@ -3865,7 +3881,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
             if (memory)
-                linear_mem_size = num_bytes_per_page * memory->cur_page_count;
+                linear_mem_size = memory->memory_data_size;
 #endif
             if (wasm_copy_exception(module, NULL))
                 goto got_exception;

+ 29 - 14
core/iwasm/interpreter/wasm_interp_fast.c

@@ -19,12 +19,23 @@ typedef int64 CellType_I64;
 typedef float32 CellType_F32;
 typedef float64 CellType_F64;
 
+#if WASM_ENABLE_THREAD_MGR == 0
+#define get_linear_mem_size() linear_mem_size
+#else
+/**
+ * Load memory data size in each time boundary check in
+ * multi-threading mode since it may be changed by other
+ * threads in memory.grow
+ */
+#define get_linear_mem_size() memory->memory_data_size
+#endif
+
 #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
 #define CHECK_MEMORY_OVERFLOW(bytes)                             \
     do {                                                         \
         uint64 offset1 = (uint64)offset + (uint64)addr;          \
-        if (offset1 + bytes <= (uint64)linear_mem_size)          \
+        if (offset1 + bytes <= (uint64)get_linear_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;               \
@@ -35,7 +46,7 @@ typedef float64 CellType_F64;
 #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
     do {                                                \
         uint64 offset1 = (uint32)(start);               \
-        if (offset1 + bytes <= linear_mem_size)         \
+        if (offset1 + bytes <= get_linear_mem_size())   \
             /* App heap space is not valid space for    \
                bulk memory operation */                 \
             maddr = memory->memory_data + offset1;      \
@@ -1158,23 +1169,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if WASM_ENABLE_SHARED_MEMORY != 0
     WASMSharedMemNode *node =
         wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
-#else
-    void *node = NULL;
 #endif
-
     WASMMemoryInstance *memory = wasm_get_default_memory(module);
-
 #if !defined(OS_ENABLE_HW_BOUND_CHECK)              \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
-    uint32 num_bytes_per_page =
-        memory ? wasm_get_num_bytes_per_page(memory, node) : 0;
-    uint32 linear_mem_size =
-        memory ? wasm_get_linear_memory_size(memory, node) : 0;
+    uint32 linear_mem_size = memory ? memory->memory_data_size : 0;
 #endif
-    uint8 *global_data = module->global_data;
     WASMGlobalInstance *globals = module->e ? module->e->globals : NULL;
     WASMGlobalInstance *global;
+    uint8 *global_data = module->global_data;
     uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
     WASMInterpFrame *frame = NULL;
     /* Points to this special opcode so as to jump to the
@@ -1892,8 +1896,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
 #if !defined(OS_ENABLE_HW_BOUND_CHECK)              \
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
-                    linear_mem_size =
-                        num_bytes_per_page * memory->cur_page_count;
+                    linear_mem_size = memory->memory_data_size;
 #endif
                 }
 
@@ -2975,6 +2978,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         offset = (uint64)POP_I32();
                         addr = POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
 #else
@@ -3012,6 +3019,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         src = POP_I32();
                         dst = POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
@@ -3038,6 +3049,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
                         fill_val = POP_I32();
                         dst = POP_I32();
 
+#if WASM_ENABLE_THREAD_MGR
+                        linear_mem_size = memory->memory_data_size;
+#endif
+
 #ifndef OS_ENABLE_HW_BOUND_CHECK
                         CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
 #else
@@ -3805,7 +3820,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
     || WASM_ENABLE_BULK_MEMORY != 0
             if (memory)
-                linear_mem_size = num_bytes_per_page * memory->cur_page_count;
+                linear_mem_size = memory->memory_data_size;
 #endif
             if (wasm_copy_exception(module, NULL))
                 goto got_exception;