Skip to content

Commit 4dacef2

Browse files
authored
shared heap: Fix some issues and add basic unit test case (#3801)
Fix some issues and add basic unit test case for shared heap feature. Signed-off-by: wenlingyun1 <[email protected]>
1 parent 5e20cf3 commit 4dacef2

File tree

11 files changed

+332
-56
lines changed

11 files changed

+332
-56
lines changed

core/iwasm/common/wasm_memory.c

+24-23
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,13 @@ static void
148148
wasm_munmap_linear_memory(void *mapped_mem, uint64 commit_size,
149149
uint64 map_size);
150150

151-
static void
152-
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
153-
{
154-
if (error_buf != NULL) {
155-
snprintf(error_buf, error_buf_size,
156-
"Operation of shared heap failed: %s", string);
157-
}
158-
}
159-
160151
static void *
161-
runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
152+
runtime_malloc(uint64 size)
162153
{
163154
void *mem;
164155

165156
if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
166-
set_error_buf(error_buf, error_buf_size, "allocate memory failed");
157+
LOG_WARNING("Allocate memory failed");
167158
return NULL;
168159
}
169160

@@ -172,27 +163,32 @@ runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
172163
}
173164

174165
WASMSharedHeap *
175-
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args, char *error_buf,
176-
uint32 error_buf_size)
166+
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args)
177167
{
178168
uint64 heap_struct_size = sizeof(WASMSharedHeap);
179169
uint32 size = init_args->size;
180170
WASMSharedHeap *heap;
181171

182-
if (!(heap = runtime_malloc(heap_struct_size, error_buf, error_buf_size))) {
172+
if (size == 0) {
183173
goto fail1;
184174
}
175+
176+
if (!(heap = runtime_malloc(heap_struct_size))) {
177+
goto fail1;
178+
}
179+
185180
if (!(heap->heap_handle =
186-
runtime_malloc(mem_allocator_get_heap_struct_size(), error_buf,
187-
error_buf_size))) {
181+
runtime_malloc(mem_allocator_get_heap_struct_size()))) {
188182
goto fail2;
189183
}
184+
185+
size = align_uint(size, os_getpagesize());
186+
heap->size = size;
190187
heap->start_off_mem64 = UINT64_MAX - heap->size + 1;
191188
heap->start_off_mem32 = UINT32_MAX - heap->size + 1;
192189

193-
size = align_uint(size, os_getpagesize());
194190
if (size > APP_HEAP_SIZE_MAX || size < APP_HEAP_SIZE_MIN) {
195-
set_error_buf(error_buf, error_buf_size, "invalid size of shared heap");
191+
LOG_WARNING("Invalid size of shared heap");
196192
goto fail3;
197193
}
198194

@@ -201,7 +197,7 @@ wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args, char *error_buf,
201197
}
202198
if (!mem_allocator_create_with_struct_and_pool(
203199
heap->heap_handle, heap_struct_size, heap->base_addr, size)) {
204-
set_error_buf(error_buf, error_buf_size, "init share heap failed");
200+
LOG_WARNING("init share heap failed");
205201
goto fail4;
206202
}
207203

@@ -365,20 +361,25 @@ wasm_runtime_shared_heap_malloc(WASMModuleInstanceCommon *module_inst,
365361
WASMMemoryInstance *memory =
366362
wasm_get_default_memory((WASMModuleInstance *)module_inst);
367363
WASMSharedHeap *shared_heap = get_shared_heap(module_inst);
364+
void *native_addr = NULL;
368365

369366
if (!memory || !shared_heap)
370367
return 0;
371368

372-
*p_native_addr = mem_allocator_malloc(shared_heap->heap_handle, size);
373-
if (!*p_native_addr)
369+
native_addr = mem_allocator_malloc(shared_heap->heap_handle, size);
370+
if (!native_addr)
374371
return 0;
375372

373+
if (p_native_addr) {
374+
*p_native_addr = native_addr;
375+
}
376+
376377
if (memory->is_memory64)
377378
return shared_heap->start_off_mem64
378-
+ ((uint8 *)*p_native_addr - shared_heap->base_addr);
379+
+ ((uint8 *)native_addr - shared_heap->base_addr);
379380
else
380381
return shared_heap->start_off_mem32
381-
+ ((uint8 *)*p_native_addr - shared_heap->base_addr);
382+
+ ((uint8 *)native_addr - shared_heap->base_addr);
382383
}
383384

384385
void

core/iwasm/common/wasm_memory.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ SET_LINEAR_MEMORY_SIZE(WASMMemoryInstance *memory, uint64 size)
4343

4444
#if WASM_ENABLE_SHARED_HEAP != 0
4545
WASMSharedHeap *
46-
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args, char *error_buf,
47-
uint32 error_buf_size);
46+
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args);
4847

4948
bool
5049
wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst,

core/iwasm/common/wasm_runtime_common.c

+22-17
Original file line numberDiff line numberDiff line change
@@ -4498,6 +4498,11 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
44984498
uint32 *argv, uint32 argc, uint32 *argv_ret)
44994499
{
45004500
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
4501+
#if WASM_ENABLE_MEMORY64 != 0
4502+
WASMMemoryInstance *memory =
4503+
wasm_get_default_memory((WASMModuleInstance *)module);
4504+
bool is_memory64 = memory ? memory->is_memory64 : false;
4505+
#endif
45014506
typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *);
45024507
NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr;
45034508
uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64;
@@ -4525,11 +4530,11 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
45254530
#endif
45264531
{
45274532
*(uint32 *)argv_dst = arg_i32 = *argv_src++;
4528-
/* TODO: memory64 if future there is a way for supporting
4529-
* wasm64 and wasm32 in libc at the same time, remove the
4530-
* macro control */
4531-
#if WASM_ENABLE_MEMORY64 == 0
4532-
if (signature) {
4533+
if (signature
4534+
#if WASM_ENABLE_MEMORY64 != 0
4535+
&& !is_memory64
4536+
#endif
4537+
) {
45334538
if (signature[i + 1] == '*') {
45344539
/* param is a pointer */
45354540
if (signature[i + 2] == '~')
@@ -4558,7 +4563,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
45584563
module, (uint64)arg_i32);
45594564
}
45604565
}
4561-
#endif
45624566
break;
45634567
}
45644568
case VALUE_TYPE_I64:
@@ -4568,7 +4572,7 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
45684572
GET_I64_FROM_ADDR(argv_src));
45694573
argv_src += 2;
45704574
arg_i64 = *argv_dst;
4571-
if (signature) {
4575+
if (signature && is_memory64) {
45724576
/* TODO: memory64 pointer with length need a new symbol
45734577
* to represent type i64, with '~' still represent i32
45744578
* length */
@@ -4729,9 +4733,6 @@ wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
47294733
fail:
47304734
if (argv1 != argv_buf)
47314735
wasm_runtime_free(argv1);
4732-
#if WASM_ENABLE_MEMORY64 == 0
4733-
(void)arg_i64;
4734-
#endif
47354736
return ret;
47364737
}
47374738

@@ -5655,6 +5656,11 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
56555656
uint32 *argv_ret)
56565657
{
56575658
WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
5659+
#if WASM_ENABLE_MEMORY64 != 0
5660+
WASMMemoryInstance *memory =
5661+
wasm_get_default_memory((WASMModuleInstance *)module);
5662+
bool is_memory64 = memory ? memory->is_memory64 : false;
5663+
#endif
56585664
uint64 argv_buf[32] = { 0 }, *argv1 = argv_buf, *ints, *stacks, size,
56595665
arg_i64;
56605666
uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
@@ -5720,11 +5726,11 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
57205726
{
57215727
arg_i32 = *argv_src++;
57225728
arg_i64 = arg_i32;
5723-
/* TODO: memory64 if future there is a way for supporting
5724-
* wasm64 and wasm32 in libc at the same time, remove the
5725-
* macro control */
5726-
#if WASM_ENABLE_MEMORY64 == 0
5727-
if (signature) {
5729+
if (signature
5730+
#if WASM_ENABLE_MEMORY64 != 0
5731+
&& !is_memory64
5732+
#endif
5733+
) {
57285734
if (signature[i + 1] == '*') {
57295735
/* param is a pointer */
57305736
if (signature[i + 2] == '~')
@@ -5751,7 +5757,6 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
57515757
module, (uint64)arg_i32);
57525758
}
57535759
}
5754-
#endif
57555760
if (n_ints < MAX_REG_INTS)
57565761
ints[n_ints++] = arg_i64;
57575762
else
@@ -5763,7 +5768,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
57635768
{
57645769
arg_i64 = GET_I64_FROM_ADDR(argv_src);
57655770
argv_src += 2;
5766-
if (signature) {
5771+
if (signature && is_memory64) {
57675772
/* TODO: memory64 pointer with length need a new symbol
57685773
* to represent type i64, with '~' still represent i32
57695774
* length */

core/iwasm/include/wasm_export.h

+18-12
Original file line numberDiff line numberDiff line change
@@ -323,11 +323,9 @@ typedef enum {
323323
WASM_LOG_LEVEL_VERBOSE = 4
324324
} log_level_t;
325325

326-
#if WASM_ENABLE_SHARED_HEAP != 0
327326
typedef struct SharedHeapInitArgs {
328-
uint32 size;
327+
uint32_t size;
329328
} SharedHeapInitArgs;
330-
#endif
331329

332330
/**
333331
* Initialize the WASM runtime environment, and also initialize
@@ -2119,51 +2117,59 @@ wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env,
21192117
WASM_RUNTIME_API_EXTERN bool
21202118
wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module);
21212119

2122-
#if WASM_ENABLE_SHARED_HEAP != 0
21232120
/**
21242121
* Create a shared heap
2122+
*
21252123
* @param init_args the initialization arguments
2126-
* @param error_buf buffer to output the error info if failed
2127-
* @param error_buf_size the size of the error buffer
2124+
* @return the shared heap created
21282125
*/
21292126
WASM_RUNTIME_API_EXTERN wasm_shared_heap_t
2130-
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args, char *error_buf,
2131-
uint32 error_buf_size);
2127+
wasm_runtime_create_shared_heap(SharedHeapInitArgs *init_args);
21322128

21332129
/**
21342130
* Attach a shared heap to a module instance
2131+
*
21352132
* @param module_inst the module instance
21362133
* @param shared_heap the shared heap
2134+
* @return true if success, false if failed
21372135
*/
21382136
WASM_RUNTIME_API_EXTERN bool
21392137
wasm_runtime_attach_shared_heap(wasm_module_inst_t module_inst,
21402138
wasm_shared_heap_t shared_heap);
21412139

21422140
/**
21432141
* Detach a shared heap from a module instance
2142+
*
21442143
* @param module_inst the module instance
21452144
*/
21462145
WASM_RUNTIME_API_EXTERN void
21472146
wasm_runtime_detach_shared_heap(wasm_module_inst_t module_inst);
21482147

21492148
/**
21502149
* Allocate memory from a shared heap
2150+
*
21512151
* @param module_inst the module instance
21522152
* @param size required memory size
21532153
* @param p_native_addr native address of allocated memory
2154+
*
2155+
* @return return the allocated memory address, which re-uses part of the wasm
2156+
* address space and is in the range of [UINT32 - shared_heap_size + 1, UINT32]
2157+
* (when the wasm memory is 32-bit) or [UINT64 - shared_heap_size + 1, UINT64]
2158+
* (when the wasm memory is 64-bit). Note that it is not an absolute address.
2159+
* Return non-zero if success, zero if failed.
21542160
*/
2155-
WASM_RUNTIME_API_EXTERN uint64
2156-
wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64 size,
2161+
WASM_RUNTIME_API_EXTERN uint64_t
2162+
wasm_runtime_shared_heap_malloc(wasm_module_inst_t module_inst, uint64_t size,
21572163
void **p_native_addr);
21582164

21592165
/**
21602166
* Free the memory allocated from shared heap
2167+
*
21612168
* @param module_inst the module instance
21622169
* @param ptr the offset in wasm app
21632170
*/
21642171
WASM_RUNTIME_API_EXTERN void
2165-
wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64 ptr);
2166-
#endif
2172+
wasm_runtime_shared_heap_free(wasm_module_inst_t module_inst, uint64_t ptr);
21672173

21682174
#ifdef __cplusplus
21692175
}

core/iwasm/interpreter/wasm_runtime.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ typedef struct WASMSharedHeap {
9797
struct WASMSharedHeap *next;
9898
void *heap_handle;
9999
uint8 *base_addr;
100-
uint32 size;
100+
uint64 size;
101101
uint64 start_off_mem64;
102102
uint64 start_off_mem32;
103103
} WASMSharedHeap;

core/iwasm/libraries/shared-heap/shared_heap_wrapper.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ shared_free_wrapper(wasm_exec_env_t exec_env, void *ptr)
3131
{
3232
wasm_module_inst_t module_inst = get_module_inst(exec_env);
3333

34-
if (!validate_native_addr(ptr, (uint64)sizeof(uint32)))
34+
if (!validate_native_addr(ptr, (uint64)sizeof(uintptr_t))) {
35+
LOG_WARNING("Invalid app address");
3536
return;
37+
}
3638

3739
module_shared_free(addr_native_to_app(ptr));
3840
}

tests/unit/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ add_subdirectory(linux-perf)
5050
add_subdirectory(gc)
5151
add_subdirectory(memory64)
5252
add_subdirectory(tid-allocator)
53+
add_subdirectory(shared-heap)

tests/unit/shared-heap/CMakeLists.txt

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright (C) 2024 Xiaomi Corporation. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
cmake_minimum_required(VERSION 3.14)
5+
6+
project(test-shared-heap)
7+
8+
add_definitions(-DRUN_ON_LINUX)
9+
10+
set(WAMR_BUILD_APP_FRAMEWORK 0)
11+
set(WAMR_BUILD_AOT 0)
12+
set(WAMR_BUILD_INTERP 1)
13+
set(WAMR_BUILD_FAST_INTERP 1)
14+
set(WAMR_BUILD_JIT 0)
15+
set(WAMR_BUILD_MEMORY64 1)
16+
set(WAMR_BUILD_SHARED_HEAP 1)
17+
18+
# Compile wasm modules
19+
add_subdirectory(wasm-apps)
20+
21+
# if only load this CMake other than load it as subdirectory
22+
include(../unit_common.cmake)
23+
24+
set(LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
25+
26+
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
27+
message(FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
28+
endif ()
29+
30+
set(CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
31+
find_package(LLVM REQUIRED CONFIG)
32+
include_directories(${LLVM_INCLUDE_DIRS})
33+
add_definitions(${LLVM_DEFINITIONS})
34+
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
35+
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
36+
37+
include(${IWASM_DIR}/compilation/iwasm_compl.cmake)
38+
39+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
40+
41+
file(GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
42+
43+
set(UNIT_SOURCE ${source_all})
44+
45+
aux_source_directory(. SRC_LIST)
46+
47+
set(unit_test_sources
48+
${UNIT_SOURCE}
49+
${WAMR_RUNTIME_LIB_SOURCE}
50+
${UNCOMMON_SHARED_SOURCE}
51+
${SRC_LIST}
52+
)
53+
54+
# Now simply link against gtest or gtest_main as needed. Eg
55+
add_executable(shared_heap_test ${unit_test_sources})
56+
57+
target_link_libraries(shared_heap_test ${LLVM_AVAILABLE_LIBS} gtest_main)
58+
59+
gtest_discover_tests(shared_heap_test)

0 commit comments

Comments
 (0)