Fix memory sharing (#2415)
- Inherit shared memory from the parent instance, instead of trying to look it up by the underlying module. The old method works correctly only when every cluster uses different module. - Use reference count in WASMMemoryInstance/AOTMemoryInstance to mark whether the memory is shared or not - Retire WASMSharedMemNode - For atomic opcode implementations in the interpreters, use a global lock for now - Update the internal API users (wasi-threads, lib-pthread, wasm_runtime_spawn_thread) Fixes https://github.com/bytecodealliance/wasm-micro-runtime/issues/1962
This commit is contained in:
@ -710,28 +710,28 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint32)(*(uint8 *)maddr); \
|
||||
*(uint8 *)maddr = (uint8)(readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint32)LOAD_U16(maddr); \
|
||||
STORE_U16(maddr, (uint16)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = LOAD_I32(maddr); \
|
||||
STORE_U32(maddr, readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
PUSH_I32(readv); \
|
||||
break; \
|
||||
@ -750,39 +750,39 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min,
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)(*(uint8 *)maddr); \
|
||||
*(uint8 *)maddr = (uint8)(readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_U16(maddr); \
|
||||
STORE_U16(maddr, (uint16)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_U32(maddr); \
|
||||
STORE_U32(maddr, (uint32)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else { \
|
||||
uint64 op_result; \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_I64(maddr); \
|
||||
op_result = readv op sval; \
|
||||
STORE_I64(maddr, op_result); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
PUSH_I64(readv); \
|
||||
break; \
|
||||
@ -1156,10 +1156,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMFunctionInstance *cur_func,
|
||||
WASMInterpFrame *prev_frame)
|
||||
{
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
|
||||
#endif
|
||||
WASMMemoryInstance *memory = wasm_get_default_memory(module);
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||
@ -3526,23 +3522,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)(*(uint8 *)maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)LOAD_U16(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I32(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
|
||||
PUSH_I32(readv);
|
||||
@ -3561,30 +3557,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)(*(uint8 *)maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U16(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U32(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I64(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
|
||||
PUSH_I64(readv);
|
||||
@ -3603,23 +3599,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
*(uint8 *)maddr = (uint8)sval;
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I32_STORE16) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U16(maddr, (uint16)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U32(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3637,30 +3633,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
*(uint8 *)maddr = (uint8)sval;
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_STORE16) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U16(maddr, (uint16)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_STORE32) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U32(maddr, (uint32)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
PUT_I64_TO_ADDR((uint32 *)maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3680,32 +3676,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
expect = (uint8)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)(*(uint8 *)maddr);
|
||||
if (readv == expect)
|
||||
*(uint8 *)maddr = (uint8)(sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
expect = (uint16)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)LOAD_U16(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U16(maddr, (uint16)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I32(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U32(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
PUSH_I32(readv);
|
||||
break;
|
||||
@ -3726,43 +3722,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
expect = (uint8)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)(*(uint8 *)maddr);
|
||||
if (readv == expect)
|
||||
*(uint8 *)maddr = (uint8)(sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
expect = (uint16)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U16(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U16(maddr, (uint16)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
expect = (uint32)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U32(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U32(maddr, (uint32)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS();
|
||||
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_I64(maddr);
|
||||
if (readv == expect)
|
||||
STORE_I64(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
PUSH_I64(readv);
|
||||
break;
|
||||
|
||||
@ -482,28 +482,28 @@ LOAD_PTR(void *addr)
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint32)(*(uint8 *)maddr); \
|
||||
*(uint8 *)maddr = (uint8)(readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint32)LOAD_U16(maddr); \
|
||||
STORE_U16(maddr, (uint16)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = LOAD_I32(maddr); \
|
||||
STORE_U32(maddr, readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
PUSH_I32(readv); \
|
||||
break; \
|
||||
@ -522,39 +522,39 @@ LOAD_PTR(void *addr)
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)(*(uint8 *)maddr); \
|
||||
*(uint8 *)maddr = (uint8)(readv op sval); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_U16(maddr); \
|
||||
STORE_U16(maddr, (uint16)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_U32(maddr); \
|
||||
STORE_U32(maddr, (uint32)(readv op sval)); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
else { \
|
||||
uint64 op_result; \
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(8); \
|
||||
\
|
||||
os_mutex_lock(&node->shared_mem_lock); \
|
||||
shared_memory_lock(memory); \
|
||||
readv = (uint64)LOAD_I64(maddr); \
|
||||
op_result = readv op sval; \
|
||||
STORE_I64(maddr, op_result); \
|
||||
os_mutex_unlock(&node->shared_mem_lock); \
|
||||
shared_memory_unlock(memory); \
|
||||
} \
|
||||
PUSH_I64(readv); \
|
||||
break; \
|
||||
@ -1166,10 +1166,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMFunctionInstance *cur_func,
|
||||
WASMInterpFrame *prev_frame)
|
||||
{
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
|
||||
#endif
|
||||
WASMMemoryInstance *memory = wasm_get_default_memory(module);
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||
@ -3353,23 +3349,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)(*(uint8 *)maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)LOAD_U16(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I32(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
|
||||
PUSH_I32(readv);
|
||||
@ -3388,30 +3384,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)(*(uint8 *)maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U16(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U32(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(8);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I64(maddr);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
|
||||
PUSH_I64(readv);
|
||||
@ -3429,23 +3425,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I32_STORE8) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
*(uint8 *)maddr = (uint8)sval;
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I32_STORE16) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U16(maddr, (uint16)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U32(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3463,30 +3459,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
if (opcode == WASM_OP_ATOMIC_I64_STORE8) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
*(uint8 *)maddr = (uint8)sval;
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_STORE16) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U16(maddr, (uint16)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_I64_STORE32) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_U32(maddr, (uint32)sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(8);
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
STORE_I64(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3506,32 +3502,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
|
||||
expect = (uint8)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)(*(uint8 *)maddr);
|
||||
if (readv == expect)
|
||||
*(uint8 *)maddr = (uint8)(sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
|
||||
expect = (uint16)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint32)LOAD_U16(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U16(maddr, (uint16)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = LOAD_I32(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U32(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
PUSH_I32(readv);
|
||||
break;
|
||||
@ -3552,43 +3548,43 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(1);
|
||||
|
||||
expect = (uint8)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)(*(uint8 *)maddr);
|
||||
if (readv == expect)
|
||||
*(uint8 *)maddr = (uint8)(sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(2);
|
||||
|
||||
expect = (uint16)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U16(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U16(maddr, (uint16)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(4);
|
||||
|
||||
expect = (uint32)expect;
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_U32(maddr);
|
||||
if (readv == expect)
|
||||
STORE_U32(maddr, (uint32)(sval));
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
else {
|
||||
CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr);
|
||||
CHECK_ATOMIC_MEMORY_ACCESS(8);
|
||||
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
shared_memory_lock(memory);
|
||||
readv = (uint64)LOAD_I64(maddr);
|
||||
if (readv == expect)
|
||||
STORE_I64(maddr, sval);
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
shared_memory_unlock(memory);
|
||||
}
|
||||
PUSH_I64(readv);
|
||||
break;
|
||||
|
||||
@ -122,11 +122,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memories[i]->is_shared) {
|
||||
int32 ref_count = shared_memory_dec_reference(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(ref_count >= 0);
|
||||
|
||||
if (shared_memory_is_shared(memories[i])) {
|
||||
uint32 ref_count = shared_memory_dec_reference(memories[i]);
|
||||
/* if the reference count is not zero,
|
||||
don't free the memory */
|
||||
if (ref_count > 0)
|
||||
@ -159,7 +156,8 @@ memories_deinstantiate(WASMModuleInstance *module_inst,
|
||||
}
|
||||
|
||||
static WASMMemoryInstance *
|
||||
memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
|
||||
memory_instantiate(WASMModuleInstance *module_inst, WASMModuleInstance *parent,
|
||||
WASMMemoryInstance *memory, uint32 memory_idx,
|
||||
uint32 num_bytes_per_page, uint32 init_page_count,
|
||||
uint32 max_page_count, uint32 heap_size, uint32 flags,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
@ -180,22 +178,11 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
|
||||
bool is_shared_memory = flags & 0x02 ? true : false;
|
||||
|
||||
/* shared memory */
|
||||
if (is_shared_memory) {
|
||||
WASMSharedMemNode *node = wasm_module_get_shared_memory(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
/* If the memory of this module has been instantiated,
|
||||
return the memory instance directly */
|
||||
if (node) {
|
||||
uint32 ref_count;
|
||||
ref_count = shared_memory_inc_reference(
|
||||
(WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(ref_count > 0);
|
||||
memory = (WASMMemoryInstance *)shared_memory_get_memory_inst(node);
|
||||
bh_assert(memory);
|
||||
|
||||
(void)ref_count;
|
||||
return memory;
|
||||
}
|
||||
if (is_shared_memory && parent != NULL) {
|
||||
bh_assert(parent->memory_count > memory_idx);
|
||||
memory = parent->memories[memory_idx];
|
||||
shared_memory_inc_reference(memory);
|
||||
return memory;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_SHARED_MEMORY */
|
||||
|
||||
@ -388,24 +375,13 @@ memory_instantiate(WASMModuleInstance *module_inst, WASMMemoryInstance *memory,
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (is_shared_memory) {
|
||||
memory->is_shared = true;
|
||||
if (!shared_memory_set_memory_inst(
|
||||
(WASMModuleCommon *)module_inst->module,
|
||||
(WASMMemoryInstanceCommon *)memory)) {
|
||||
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
|
||||
goto fail4;
|
||||
}
|
||||
memory->ref_count = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_VERBOSE("Memory instantiate success.");
|
||||
return memory;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
fail4:
|
||||
if (heap_size > 0)
|
||||
mem_allocator_destroy(memory->heap_handle);
|
||||
#endif
|
||||
fail3:
|
||||
if (heap_size > 0)
|
||||
wasm_runtime_free(memory->heap_handle);
|
||||
@ -428,7 +404,8 @@ fail1:
|
||||
*/
|
||||
static WASMMemoryInstance **
|
||||
memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
uint32 heap_size, char *error_buf, uint32 error_buf_size)
|
||||
WASMModuleInstance *parent, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMImport *import;
|
||||
uint32 mem_index = 0, i,
|
||||
@ -474,26 +451,29 @@ memories_instantiate(const WASMModule *module, WASMModuleInstance *module_inst,
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (!(memories[mem_index++] = memory_instantiate(
|
||||
module_inst, memory, num_bytes_per_page, init_page_count,
|
||||
max_page_count, actual_heap_size, flags, error_buf,
|
||||
error_buf_size))) {
|
||||
if (!(memories[mem_index] = memory_instantiate(
|
||||
module_inst, parent, memory, mem_index,
|
||||
num_bytes_per_page, init_page_count, max_page_count,
|
||||
actual_heap_size, flags, error_buf, error_buf_size))) {
|
||||
memories_deinstantiate(module_inst, memories, memory_count);
|
||||
return NULL;
|
||||
}
|
||||
mem_index++;
|
||||
}
|
||||
}
|
||||
|
||||
/* instantiate memories from memory section */
|
||||
for (i = 0; i < module->memory_count; i++, memory++) {
|
||||
if (!(memories[mem_index++] = memory_instantiate(
|
||||
module_inst, memory, module->memories[i].num_bytes_per_page,
|
||||
if (!(memories[mem_index] = memory_instantiate(
|
||||
module_inst, parent, memory, mem_index,
|
||||
module->memories[i].num_bytes_per_page,
|
||||
module->memories[i].init_page_count,
|
||||
module->memories[i].max_page_count, heap_size,
|
||||
module->memories[i].flags, error_buf, error_buf_size))) {
|
||||
memories_deinstantiate(module_inst, memories, memory_count);
|
||||
return NULL;
|
||||
}
|
||||
mem_index++;
|
||||
}
|
||||
|
||||
bh_assert(mem_index == memory_count);
|
||||
@ -1301,7 +1281,7 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
|
||||
WASMModuleInstance *sub_module_inst = NULL;
|
||||
|
||||
sub_module_inst =
|
||||
wasm_instantiate(sub_module, false, NULL, stack_size, heap_size,
|
||||
wasm_instantiate(sub_module, NULL, NULL, stack_size, heap_size,
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module_inst) {
|
||||
LOG_DEBUG("instantiate %s failed",
|
||||
@ -1646,7 +1626,7 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
|
||||
* Instantiate module
|
||||
*/
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
@ -1663,6 +1643,7 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bool ret = false;
|
||||
#endif
|
||||
const bool is_sub_inst = parent != NULL;
|
||||
|
||||
if (!module)
|
||||
return NULL;
|
||||
@ -1781,8 +1762,9 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
|
||||
/* Instantiate memories/tables/functions */
|
||||
if ((module_inst->memory_count > 0
|
||||
&& !(module_inst->memories = memories_instantiate(
|
||||
module, module_inst, heap_size, error_buf, error_buf_size)))
|
||||
&& !(module_inst->memories =
|
||||
memories_instantiate(module, module_inst, parent, heap_size,
|
||||
error_buf, error_buf_size)))
|
||||
|| (module_inst->table_count > 0
|
||||
&& !(module_inst->tables =
|
||||
tables_instantiate(module, module_inst, first_table,
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#define _WASM_RUNTIME_H
|
||||
|
||||
#include "wasm.h"
|
||||
#include "bh_atomic.h"
|
||||
#include "bh_hashmap.h"
|
||||
#include "../common/wasm_runtime_common.h"
|
||||
#include "../common/wasm_exec_env.h"
|
||||
@ -79,7 +80,7 @@ struct WASMMemoryInstance {
|
||||
/* Module type */
|
||||
uint32 module_type;
|
||||
/* Shared memory flag */
|
||||
bool is_shared;
|
||||
bh_atomic_32_t ref_count; /* 0: non-shared, > 0: reference count */
|
||||
|
||||
/* Number bytes per page */
|
||||
uint32 num_bytes_per_page;
|
||||
@ -400,7 +401,7 @@ void
|
||||
wasm_unload(WASMModule *module);
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
||||
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, char *error_buf, uint32 error_buf_size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user