Shared heap enhancements for Interpreter and AOT (#4400)

Propose two enhancements:

- Shared heap created from preallocated memory buffer: The user can create a shared heap from a pre-allocated buffer and see that memory region as one large chunk; there's no need to dynamically manage it(malloc/free). The user needs to make sure the native address and size of that memory region are valid.
- Introduce shared heap chain: The user can create a shared heap chain, from the wasm app point of view, it's still a continuous memory region in wasm app's point of view while in the native it can consist of multiple shared heaps (each of which is a continuous memory region). For example, one 500MB shared heap 1 and one 500 MB shared heap 2 form a chain, in Wasm's point of view, it's one 1GB shared heap.

After these enhancements, the data sharing between wasm apps, and between hosts can be more efficient and flexible. Admittedly shared heap management can be more complex for users, but it's similar to the zero-overhead principle. No overhead will be imposed for the users who don't use the shared heap enhancement or don't use the shared heap at all.
This commit is contained in:
TianlongLiang
2025-07-04 10:44:51 +08:00
committed by GitHub
parent ee056d8076
commit 8a55a1e7a1
35 changed files with 2792 additions and 657 deletions

View File

@ -19,8 +19,15 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
if(WAMR_BUILD_TARGET STREQUAL "X86_32")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
# 1) Force -m32
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32" CACHE STRING "" FORCE)
# 2) Make CMake prefer i386 libraries
set(CMAKE_SYSTEM_PROCESSOR i386 CACHE STRING "" FORCE)
set(CMAKE_LIBRARY_ARCHITECTURE "i386-linux-gnu" CACHE STRING "" FORCE)
endif()
# Prevent overriding the parent project's compiler/linker
@ -29,12 +36,21 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Fetch Google test
include (FetchContent)
FetchContent_Declare (
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24")
FetchContent_Declare (
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable (googletest)
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
else()
FetchContent_Declare (
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
endif()
FetchContent_MakeAvailable(googletest)
SET(GOOGLETEST_INCLUDED 1)

View File

@ -12,12 +12,20 @@ set(WAMR_BUILD_AOT 1)
set(WAMR_BUILD_INTERP 1)
set(WAMR_BUILD_FAST_INTERP 1)
set(WAMR_BUILD_JIT 0)
set(WAMR_BUILD_MEMORY64 1)
if(WAMR_BUILD_TARGET STREQUAL "X86_32")
set(WAMR_BUILD_MEMORY64 0)
else()
set(WAMR_BUILD_MEMORY64 1)
endif()
set(WAMR_BUILD_SHARED_HEAP 1)
# Compile wasm modules
add_subdirectory(wasm-apps)
if (WAMR_BUILD_MEMORY64 EQUAL 1)
add_subdirectory(wasm-apps/memory64)
endif ()
# if only load this CMake other than load it as subdirectory
include(../unit_common.cmake)
@ -56,4 +64,4 @@ add_executable(shared_heap_test ${unit_test_sources})
target_link_libraries(shared_heap_test ${LLVM_AVAILABLE_LIBS} gtest_main)
gtest_discover_tests(shared_heap_test)
gtest_discover_tests(shared_heap_test)

File diff suppressed because it is too large Load Diff

View File

@ -29,44 +29,81 @@ set(CMAKE_EXE_LINKER_FLAGS
-Wl,--allow-undefined"
)
if (WAMR_BUILD_TARGET STREQUAL "X86_32")
set (WAMR_COMPILER_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-heap --target=i386)
set (WAMR_COMPILER_CHAIN_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-chain --target=i386)
else ()
set (WAMR_COMPILER_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-heap)
set (WAMR_COMPILER_CHAIN_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-chain)
endif ()
function(copy_wasm TARGET_NAME)
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Copy ${TARGET_NAME} to the same directory of google test"
)
endfunction()
function(compile_and_copy_aot_from TARGET_NAME)
string(REPLACE ".wasm" ".aot" AOT_TARGET ${TARGET_NAME})
string(REPLACE ".wasm" "_chain.aot" AOT_CHAIN_TARGET ${TARGET_NAME})
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_FLAGS}
-o ${AOT_TARGET}
${TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${AOT_TARGET}
${CMAKE_CURRENT_BINARY_DIR}/../
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_CHAIN_FLAGS}
-o ${AOT_CHAIN_TARGET}
${TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${AOT_CHAIN_TARGET}
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Compile and copy ${AOT_TARGET} to the same directory of google test"
)
endfunction()
add_executable(test.wasm test.c)
target_link_libraries(test.wasm)
add_custom_command(TARGET test.wasm POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/test.wasm
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Copy test.wasm to the same directory of google test"
)
add_custom_command(TARGET test.wasm POST_BUILD
COMMAND ${WAMRC_ROOT_DIR}/wamrc --opt-level=0 --enable-shared-heap --bounds-checks=1
-o
test.aot
test.wasm
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/test.aot
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Copy test.aot to the same directory of google test"
)
copy_wasm(test.wasm)
compile_and_copy_aot_from(test.wasm)
add_executable(test_addr_conv.wasm test_addr_conv.c)
target_link_libraries(test.wasm)
target_link_libraries(test_addr_conv.wasm)
copy_wasm(test_addr_conv.wasm)
compile_and_copy_aot_from(test_addr_conv.wasm)
add_custom_command(TARGET test_addr_conv.wasm POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/test_addr_conv.wasm
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Copy test_addr_conv.wasm to the same directory of google test"
)
# copy and compile aot for bulk memory test
set(SOURCE_WASM ${CMAKE_CURRENT_SOURCE_DIR}/bulk-memory/test_bulk_memory.wasm)
set(BUILD_WASM ${CMAKE_CURRENT_BINARY_DIR}/../test_bulk_memory.wasm)
set(OUTPUT_AOT ${CMAKE_CURRENT_BINARY_DIR}/../test_bulk_memory.aot)
set(OUTPUT_CHAIN_AOT ${CMAKE_CURRENT_BINARY_DIR}/../test_bulk_memory_chain.aot)
add_custom_command(TARGET test_addr_conv.wasm POST_BUILD
COMMAND ${WAMRC_ROOT_DIR}/wamrc --opt-level=0 --enable-shared-heap --bounds-checks=1
-o
test_addr_conv.aot
test_addr_conv.wasm
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/test_addr_conv.aot
${CMAKE_CURRENT_BINARY_DIR}/../
COMMENT "Copy test_addr_conv.aot to the same directory of google test"
)
add_custom_command(
OUTPUT ${BUILD_WASM}
COMMAND ${CMAKE_COMMAND} -E copy
${SOURCE_WASM}
${BUILD_WASM}
DEPENDS ${SOURCE_WASM}
COMMENT "Copying bulk memory WASM to build directory"
)
add_custom_command(
OUTPUT ${OUTPUT_AOT}
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_FLAGS}
-o ${OUTPUT_AOT}
${BUILD_WASM}
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_CHAIN_FLAGS}
-o ${OUTPUT_CHAIN_AOT}
${BUILD_WASM}
DEPENDS ${BUILD_WASM}
COMMENT "Compiling bulk memory AOT from copied WASM"
)
add_custom_target(compile_bulk_memory_aot ALL
DEPENDS ${OUTPUT_AOT}
)

View File

@ -0,0 +1,12 @@
(module
(memory 1)
(func $memory_fill_test (param $dst i32) (param $val i32) (param $len i32)
local.get $dst
local.get $val
local.get $len
memory.fill
)
(export "memory_fill_test" (func $memory_fill_test))
)

View File

@ -0,0 +1,68 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.14)
project(wasm-apps-wasm64)
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
set(WAMRC_ROOT_DIR ${WAMR_ROOT_DIR}/wamr-compiler/build)
set(CMAKE_SYSTEM_PROCESSOR wasm64)
set(CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot)
if (NOT DEFINED WASI_SDK_DIR)
set(WASI_SDK_DIR "/opt/wasi-sdk")
endif ()
set(CMAKE_C_FLAGS "-nostdlib -pthread -Qunused-arguments")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -z stack-size=8192 -nostdlib -O0 --target=wasm64")
set(CMAKE_C_COMPILER_TARGET "wasm64")
set(CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
set(DEFINED_SYMBOLS
"${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt")
set(CMAKE_EXE_LINKER_FLAGS
"-Wl,--no-entry \
-Wl,--initial-memory=65536 \
-Wl,--export-all \
-Wl,--allow-undefined"
)
set (WAMR_COMPILER_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-heap)
set (WAMR_COMPILER_CHAIN_FLAGS --opt-level=3 --bounds-checks=1 --enable-shared-chain)
function(copy_wasm TARGET_NAME)
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
${CMAKE_CURRENT_BINARY_DIR}/../../
COMMENT "Copy ${TARGET_NAME} to the same directory of google test"
)
endfunction()
function(compile_and_copy_aot_from TARGET_NAME)
string(REPLACE ".wasm" ".aot" AOT_TARGET ${TARGET_NAME})
string(REPLACE ".wasm" "_chain.aot" AOT_CHAIN_TARGET ${TARGET_NAME})
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_FLAGS}
-o ${AOT_TARGET}
${TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${AOT_TARGET}
${CMAKE_CURRENT_BINARY_DIR}/../../
COMMAND ${WAMRC_ROOT_DIR}/wamrc ${WAMR_COMPILER_CHAIN_FLAGS}
-o ${AOT_CHAIN_TARGET}
${TARGET_NAME}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${AOT_CHAIN_TARGET}
${CMAKE_CURRENT_BINARY_DIR}/../../
COMMENT "Compile and copy ${AOT_TARGET} ${AOT_CHAIN_TARGET} to the same directory of google test"
)
endfunction()
add_executable(test64.wasm ../test.c)
target_link_libraries(test64.wasm)
copy_wasm(test64.wasm)
compile_and_copy_aot_from(test64.wasm)

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#define NULL 0
extern void *
shared_heap_malloc(int size);
@ -32,3 +32,31 @@ test_malloc_fail()
shared_heap_free(ptr);
return 0;
}
void *
my_shared_heap_malloc(int size)
{
return shared_heap_malloc(size);
}
void
my_shared_heap_free(void *addr)
{
shared_heap_free(addr);
}
char
read_modify_write_8(char *addr, char value)
{
char original_value = *addr;
*addr = value;
return original_value;
}
short
read_modify_write_16(short *addr, short value)
{
short original_value = *addr;
*addr = value;
return original_value;
}

View File

@ -30,3 +30,17 @@ test()
shared_heap_free(ptr);
return 1;
}
int
test_preallocated(void *app_addr)
{
int *ptr = (int *)app_addr;
int *ptr2 = NULL;
ptr2 = test_addr_conv(ptr);
if (ptr2 != ptr) {
return 0;
}
return 1;
}