Skip to content

Commit

Permalink
Add support for multi-memory proposal in classic interpreter (bytecod…
Browse files Browse the repository at this point in the history
…ealliance#3742)

Implement multi-memory for classic-interpreter. Support core spec (and bulk memory) opcodes now,
and will support atomic opcodes, and add multi-memory export APIs in the future. 

PS: Multi-memory spec test patched a lot for linking test to adapt for multi-module implementation.
  • Loading branch information
wenyongh authored and LazyBoy-KK committed Oct 14, 2024
1 parent 7dc9c4b commit 5d2c06d
Show file tree
Hide file tree
Showing 22 changed files with 1,658 additions and 262 deletions.
44 changes: 36 additions & 8 deletions .github/workflows/compilation_on_android_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ env:
WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -S -b -P"
GC_TEST_OPTIONS: "-s spec -G -b -P"
MEMORY64_TEST_OPTIONS: "-s spec -W -b -P"
MULTI_MEMORY_TEST_OPTIONS: "-s spec -E -b -P"

jobs:
build_llvm_libraries_on_ubuntu_2204:
Expand Down Expand Up @@ -148,6 +149,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
]
os: [ubuntu-22.04]
platform: [android, linux]
Expand Down Expand Up @@ -206,11 +208,9 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
# Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform
# Memory64 only on CLASSIC INTERP and AOT mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
Expand All @@ -221,6 +221,21 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Multi memory only on CLASSIC INTERP mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
# Fast-JIT and Multi-Tier-JIT mode don't support android
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
platform: android
Expand Down Expand Up @@ -593,6 +608,7 @@ jobs:
$WASI_TEST_OPTIONS,
$GC_TEST_OPTIONS,
$MEMORY64_TEST_OPTIONS,
$MULTI_MEMORY_TEST_OPTIONS,
]
wasi_sdk_release:
[
Expand Down Expand Up @@ -640,18 +656,30 @@ jobs:
test_option: $MEMORY64_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $MEMORY64_TEST_OPTIONS
# aot, fast-interp, fast-jit, llvm-jit, multi-tier-jit don't support Multi Memory
- running_mode: "aot"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "fast-interp"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "fast-jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $MULTI_MEMORY_TEST_OPTIONS

steps:
- name: checkout
uses: actions/checkout@v4

- name: Set-up OCaml
uses: ocaml/setup-ocaml@v3
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
if: matrix.test_option == '$GC_TEST_OPTIONS'
with:
ocaml-compiler: 4.13

- name: Set-up Ocamlbuild
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
if: matrix.test_option == '$GC_TEST_OPTIONS'
run: opam install ocamlbuild dune menhir

- name: download and install wasi-sdk
Expand Down Expand Up @@ -717,13 +745,13 @@ jobs:

- name: run tests
timeout-minutes: 30
if: matrix.test_option != '$GC_TEST_OPTIONS' && matrix.test_option != '$MEMORY64_TEST_OPTIONS'
if: matrix.test_option != '$GC_TEST_OPTIONS'
run: ./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

- name: run gc or memory64 tests
- name: run gc tests
timeout-minutes: 20
if: matrix.test_option == '$GC_TEST_OPTIONS' || matrix.test_option == '$MEMORY64_TEST_OPTIONS'
if: matrix.test_option == '$GC_TEST_OPTIONS'
run: |
eval $(opam env)
./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
Expand Down
26 changes: 23 additions & 3 deletions .github/workflows/nightly_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
]
os: [ubuntu-20.04]
platform: [android, linux]
Expand Down Expand Up @@ -190,11 +191,9 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"
# Memory64 only on CLASSIC INTERP mode, and only on 64-bit platform
# Memory64 only on CLASSIC INTERP and AOT mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
Expand All @@ -205,6 +204,21 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Multi memory only on CLASSIC INTERP mode, and only on 64-bit platform
- make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
platform: android
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $MULTI_TIER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
# Fast-JIT and Multi-Tier-JIT mode don't support android
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
platform: android
Expand Down Expand Up @@ -289,6 +303,7 @@ jobs:
"-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_MEMORY64=1",
"-DWAMR_BUILD_MULTI_MEMORY=1",
]
exclude:
# incompatible feature and platform
Expand Down Expand Up @@ -322,6 +337,11 @@ jobs:
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MEMORY64=1"
# Memory64 only on CLASSIC INTERP mode
- make_options_run_mode: $FAST_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MEMORY=1"
steps:
- name: Install dependencies
run: |
Expand Down
5 changes: 5 additions & 0 deletions build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ if (WAMR_BUILD_MEMORY64 EQUAL 1)
set (WAMR_DISABLE_HW_BOUND_CHECK 1)
message (" Memory64 memory enabled")
endif ()
if (WAMR_BUILD_MULTI_MEMORY EQUAL 1)
add_definitions (-DWASM_ENABLE_MULTI_MEMORY=1)
message (" Multi memory enabled")
set (WAMR_BUILD_DEBUG_INTERP 0)
endif ()
if (WAMR_BUILD_THREAD_MGR EQUAL 1)
message (" Thread manager enabled")
endif ()
Expand Down
5 changes: 5 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,11 @@
#define WASM_ENABLE_MEMORY64 0
#endif

/* Disable multi-memory by default */
#ifndef WASM_ENABLE_MULTI_MEMORY
#define WASM_ENABLE_MULTI_MEMORY 0
#endif

#ifndef WASM_TABLE_MAX_SIZE
#define WASM_TABLE_MAX_SIZE 1024
#endif
Expand Down
7 changes: 7 additions & 0 deletions core/iwasm/aot/aot_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,13 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
return wasm_enlarge_memory(module_inst, inc_page_count);
}

bool
aot_enlarge_memory_with_idx(AOTModuleInstance *module_inst,
uint32 inc_page_count, uint32 memidx)
{
return wasm_enlarge_memory_with_idx(module_inst, inc_page_count, memidx);
}

bool
aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
uint32 *argv)
Expand Down
4 changes: 4 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,10 @@ aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
bool
aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count);

bool
aot_enlarge_memory_with_idx(AOTModuleInstance *module_inst,
uint32 inc_page_count, uint32 memidx);

/**
* Invoke native function from aot code
*/
Expand Down
38 changes: 36 additions & 2 deletions core/iwasm/common/wasm_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,16 @@ wasm_get_default_memory(WASMModuleInstance *module_inst)
return NULL;
}

WASMMemoryInstance *
wasm_get_memory_with_idx(WASMModuleInstance *module_inst, uint32 index)
{
bh_assert(index < module_inst->memory_count);
if (module_inst->memories)
return module_inst->memories[index];
else
return NULL;
}

void
wasm_runtime_set_mem_bound_check_bytes(WASMMemoryInstance *memory,
uint64 memory_data_size)
Expand Down Expand Up @@ -747,9 +757,14 @@ wasm_mmap_linear_memory(uint64_t map_size, uint64 commit_size)
}

bool
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count,
uint32 memidx)
{
#if WASM_ENABLE_MULTI_MEMORY != 0
WASMMemoryInstance *memory = wasm_get_memory_with_idx(module, memidx);
#else
WASMMemoryInstance *memory = wasm_get_default_memory(module);
#endif
uint8 *memory_data_old, *memory_data_new, *heap_data_old;
uint32 num_bytes_per_page, heap_size;
uint32 cur_page_count, max_page_count, total_page_count;
Expand Down Expand Up @@ -960,7 +975,7 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
if (module->memory_count > 0)
shared_memory_lock(module->memories[0]);
#endif
ret = wasm_enlarge_memory_internal(module, inc_page_count);
ret = wasm_enlarge_memory_internal(module, inc_page_count, 0);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (module->memory_count > 0)
shared_memory_unlock(module->memories[0]);
Expand All @@ -969,6 +984,25 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
return ret;
}

bool
wasm_enlarge_memory_with_idx(WASMModuleInstance *module, uint32 inc_page_count,
uint32 memidx)
{
bool ret = false;

#if WASM_ENABLE_SHARED_MEMORY != 0
if (memidx < module->memory_count)
shared_memory_lock(module->memories[memidx]);
#endif
ret = wasm_enlarge_memory_internal(module, inc_page_count, memidx);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (memidx < module->memory_count)
shared_memory_unlock(module->memories[memidx]);
#endif

return ret;
}

void
wasm_deallocate_linear_memory(WASMMemoryInstance *memory_inst)
{
Expand Down
50 changes: 26 additions & 24 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,36 @@ static RunningMode runtime_running_mode = Mode_Default;
of signal handler */
static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;

static bool
is_sig_addr_in_guard_pages(void *sig_addr, WASMModuleInstance *module_inst)
{
WASMMemoryInstance *memory_inst;
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
uint32 i;

for (i = 0; i < module_inst->memory_count; ++i) {
/* To be compatible with multi memory, get the ith memory instance */
memory_inst = wasm_get_memory_with_idx(module_inst, i);
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
if (mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr) {
/* The address which causes segmentation fault is inside
the memory instance's guard regions */
return true;
}
}

return false;
}

#ifndef BH_PLATFORM_WINDOWS
static void
runtime_signal_handler(void *sig_addr)
{
WASMModuleInstance *module_inst;
WASMMemoryInstance *memory_inst;
WASMJmpBuf *jmpbuf_node;
uint8 *mapped_mem_start_addr = NULL;
uint8 *mapped_mem_end_addr = NULL;
uint32 page_size = os_getpagesize();
#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
uint8 *stack_min_addr;
Expand All @@ -201,23 +222,13 @@ runtime_signal_handler(void *sig_addr)
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
/* Get mapped mem info of current instance */
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
/* Get the default memory instance */
memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst) {
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
}

#if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
/* Get stack info of current thread */
stack_min_addr = os_thread_get_stack_boundary();
#endif

if (memory_inst
&& (mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr)) {
/* The address which causes segmentation fault is inside
the memory instance's guard regions */
if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) {
wasm_set_exception(module_inst, "out of bounds memory access");
os_longjmp(jmpbuf_node->jmpbuf, 1);
}
Expand Down Expand Up @@ -340,16 +351,7 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
&& (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
/* Get the default memory instance */
memory_inst = wasm_get_default_memory(module_inst);
if (memory_inst) {
mapped_mem_start_addr = memory_inst->memory_data;
mapped_mem_end_addr =
memory_inst->memory_data + 8 * (uint64)BH_GB;
}

if (memory_inst && mapped_mem_start_addr <= (uint8 *)sig_addr
&& (uint8 *)sig_addr < mapped_mem_end_addr) {
if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) {
/* The address which causes segmentation fault is inside
the memory instance's guard regions.
Set exception and let the wasm func continue to run, when
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/compilation/aot.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ aot_create_comp_data(WASMModule *module, const char *target_arch,
/* TODO: create import memories */

/* Allocate memory for memory array, reserve one AOTMemory space at least */
/* TODO: multi-memory */
if (!comp_data->memory_count)
comp_data->memory_count = 1;

Expand Down
1 change: 1 addition & 0 deletions core/iwasm/compilation/aot_emit_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,7 @@ aot_compile_op_memory_grow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)

POP_PAGE_COUNT(delta);

/* TODO: multi-memory aot_enlarge_memory_with_idx() */
/* Function type of aot_enlarge_memory() */
param_types[0] = INT8_PTR_TYPE;
param_types[1] = I32_TYPE;
Expand Down
1 change: 1 addition & 0 deletions core/iwasm/fast-jit/fe/jit_emit_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ jit_compile_op_memory_grow(JitCompContext *cc, uint32 mem_idx)
args[0] = get_module_inst_reg(cc->jit_frame);
args[1] = inc_page_count;

/* TODO: multi-memory wasm_enlarge_memory_with_idx() */
if (!jit_emit_callnative(cc, wasm_enlarge_memory, grow_res, args, 2)) {
goto fail;
}
Expand Down
Loading

0 comments on commit 5d2c06d

Please sign in to comment.