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.
This commit is contained in:
Wenyong Huang 2023-04-04 09:05:52 +08:00 committed by GitHub
parent e1d0c27ef9
commit 5fc48e3584
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 35 deletions

View File

@ -28,12 +28,23 @@ typedef float64 CellType_F64;
#define BR_TABLE_TMP_BUF_LEN 32 #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) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0
#define CHECK_MEMORY_OVERFLOW(bytes) \ #define CHECK_MEMORY_OVERFLOW(bytes) \
do { \ do { \
uint64 offset1 = (uint64)offset + (uint64)addr; \ 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 \ /* If offset1 is in valid range, maddr must also \
be in valid range, no need to check it again. */ \ be in valid range, no need to check it again. */ \
maddr = memory->memory_data + offset1; \ maddr = memory->memory_data + offset1; \
@ -44,7 +55,7 @@ typedef float64 CellType_F64;
#define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \ #define CHECK_BULK_MEMORY_OVERFLOW(start, bytes, maddr) \
do { \ do { \
uint64 offset1 = (uint32)(start); \ uint64 offset1 = (uint32)(start); \
if (offset1 + bytes <= (uint64)linear_mem_size) \ if (offset1 + bytes <= (uint64)get_linear_mem_size()) \
/* App heap space is not valid space for \ /* App heap space is not valid space for \
bulk memory operation */ \ bulk memory operation */ \
maddr = memory->memory_data + offset1; \ maddr = memory->memory_data + offset1; \
@ -1134,22 +1145,16 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
WASMSharedMemNode *node = WASMSharedMemNode *node =
wasm_module_get_shared_memory((WASMModuleCommon *)module->module); wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
#else
void *node = NULL;
#endif #endif
WASMMemoryInstance *memory = wasm_get_default_memory(module); WASMMemoryInstance *memory = wasm_get_default_memory(module);
uint8 *global_data = module->global_data;
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_BULK_MEMORY != 0
uint32 num_bytes_per_page = uint32 linear_mem_size = memory ? memory->memory_data_size : 0;
memory ? wasm_get_num_bytes_per_page(memory, node) : 0;
uint32 linear_mem_size =
memory ? wasm_get_linear_memory_size(memory, node) : 0;
#endif #endif
WASMType **wasm_types = module->module->types; WASMType **wasm_types = module->module->types;
WASMGlobalInstance *globals = module->e->globals, *global; WASMGlobalInstance *globals = module->e->globals, *global;
uint8 *global_data = module->global_data;
uint8 opcode_IMPDEP = WASM_OP_IMPDEP; uint8 opcode_IMPDEP = WASM_OP_IMPDEP;
WASMInterpFrame *frame = NULL; WASMInterpFrame *frame = NULL;
/* Points to this special opcode so as to jump to the /* 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) \ #if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_BULK_MEMORY != 0
linear_mem_size = linear_mem_size = memory->memory_data_size;
num_bytes_per_page * memory->cur_page_count;
#endif #endif
} }
@ -3127,6 +3131,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
offset = (uint64)(uint32)POP_I32(); offset = (uint64)(uint32)POP_I32();
addr = (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 #ifndef OS_ENABLE_HW_BOUND_CHECK
CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr); CHECK_BULK_MEMORY_OVERFLOW(addr, bytes, maddr);
#else #else
@ -3165,6 +3173,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
src = POP_I32(); src = POP_I32();
dst = 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 #ifndef OS_ENABLE_HW_BOUND_CHECK
CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc); CHECK_BULK_MEMORY_OVERFLOW(src, len, msrc);
CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
@ -3192,6 +3204,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
fill_val = POP_I32(); fill_val = POP_I32();
dst = 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 #ifndef OS_ENABLE_HW_BOUND_CHECK
CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst); CHECK_BULK_MEMORY_OVERFLOW(dst, len, mdst);
#else #else
@ -3865,7 +3881,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \ || WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|| WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_BULK_MEMORY != 0
if (memory) if (memory)
linear_mem_size = num_bytes_per_page * memory->cur_page_count; linear_mem_size = memory->memory_data_size;
#endif #endif
if (wasm_copy_exception(module, NULL)) if (wasm_copy_exception(module, NULL))
goto got_exception; goto got_exception;

View File

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