Skip to content

Commit

Permalink
Implement GC (Garbage Collection) feature for interpreter, AOT and LL…
Browse files Browse the repository at this point in the history
…VM-JIT (bytecodealliance#3125)

Implement the GC (Garbage Collection) feature for interpreter mode,
AOT mode and LLVM-JIT mode, and support most features of the latest
spec proposal, and also enable the stringref feature.

Use `cmake -DWAMR_BUILD_GC=1/0` to enable/disable the feature,
and `wamrc --enable-gc` to generate the AOT file with GC supported.

And update the AOT file version from 2 to 3 since there are many AOT
ABI breaks, including the changes of AOT file format, the changes of
AOT module/memory instance layouts, the AOT runtime APIs for the
AOT code to invoke and so on.
  • Loading branch information
wenyongh authored Feb 6, 2024
1 parent 5931aaa commit 16a4d71
Show file tree
Hide file tree
Showing 98 changed files with 38,252 additions and 7,942 deletions.
44 changes: 39 additions & 5 deletions .github/workflows/compilation_on_android_ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ env:
THREADS_TEST_OPTIONS: "-s spec -b -p -P"
X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P"
WASI_TEST_OPTIONS: "-s wasi_certification -w"
WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -b -P"
WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -S -b -P"
GC_TEST_OPTIONS: "-s spec -G -b -P"

jobs:
build_llvm_libraries_on_ubuntu_2204:
Expand Down Expand Up @@ -484,6 +485,7 @@ jobs:
$SIMD_TEST_OPTIONS,
$THREADS_TEST_OPTIONS,
$WASI_TEST_OPTIONS,
$GC_TEST_OPTIONS,
]
wasi_sdk_release:
[
Expand Down Expand Up @@ -517,10 +519,25 @@ jobs:
test_option: $MULTI_MODULES_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $SIMD_TEST_OPTIONS
# fast-jit and multi-tier-jit don't support GC
- running_mode: "fast-jit"
test_option: $GC_TEST_OPTIONS
- running_mode: "multi-tier-jit"
test_option: $GC_TEST_OPTIONS
steps:
- name: checkout
uses: actions/checkout@v4

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

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

- name: download and install wasi-sdk
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: |
Expand All @@ -545,9 +562,9 @@ jobs:

- name: set env variable(if x86_32 test needed)
if: >
(matrix.test_option == '$DEFAULT_TEST_OPTIONS' || matrix.test_option == '$THREADS_TEST_OPTIONS'
|| matrix.test_option == '$WASI_TEST_OPTIONS')
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit'
((matrix.test_option == '$DEFAULT_TEST_OPTIONS' || matrix.test_option == '$THREADS_TEST_OPTIONS'
|| matrix.test_option == '$WASI_TEST_OPTIONS' || matrix.test_option == '$GC_TEST_OPTIONS')
&& matrix.running_mode != 'fast-jit' && matrix.running_mode != 'jit' && matrix.running_mode != 'multi-tier-jit')
run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV

#only download llvm libraries in jit and aot mode
Expand Down Expand Up @@ -584,9 +601,18 @@ jobs:

- name: run tests
timeout-minutes: 30
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 tests
timeout-minutes: 20
if: matrix.test_option == '$GC_TEST_OPTIONS'
run: |
eval $(opam env)
./test_wamr.sh ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

#only install x32 support libraries when to run x86_32 cases
- name: install x32 support libraries
if: env.TEST_ON_X86_32 == 'true'
Expand All @@ -600,10 +626,18 @@ jobs:

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

- name: run gc tests x86_32
timeout-minutes: 20
if: env.TEST_ON_X86_32 == 'true' && matrix.test_option == '$GC_TEST_OPTIONS'
run: |
eval $(opam env)
./test_wamr.sh ${{ env.X86_32_TARGET_TEST_OPTIONS }} ${{ matrix.test_option }} -t ${{ matrix.running_mode }}
working-directory: ./tests/wamr-test-suites

test-wamr-ide:
needs:
[
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/compilation_on_sgx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ concurrency:
cancel-in-progress: true

env:
AOT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
# ref types enabled in wamrc by default, so we need to enable it for iwasm in AOT mode
AOT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0 -DWAMR_BUILD_REF_TYPES=1"
CLASSIC_INTERP_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_INTERP_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=0 -DWAMR_BUILD_FAST_INTERP=1 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=0"
FAST_JIT_BUILD_OPTIONS: "-DWAMR_BUILD_AOT=1 -DWAMR_BUILD_FAST_INTERP=0 -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_FAST_JIT=1 -DWAMR_BUILD_JIT=0 -DWAMR_BUILD_LAZY_JIT=1"
Expand Down
67 changes: 50 additions & 17 deletions .github/workflows/spec_test_on_nuttx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ on:
- synchronize
paths:
- ".github/workflows/spec_test_on_nuttx.yml"

- "core/**"
- "!core/deps/**"
- "product-mini/**"
- "!samples/workload/**"
- "tests/wamr-test-suites/**"
- "wamr-compiler/**"
- "wamr-sdk/**"
schedule:
- cron: '0 0 * * *'

Expand All @@ -20,21 +26,21 @@ env:
LLVM_CACHE_SUFFIX: "build-llvm_libraries_ex"
WASI_SDK_PATH: "/opt/wasi-sdk"
WAMR_COMMON_OPTION:
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=32768\\nCONFIG_INTERPRETERS_WAMR_LOG=y\\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\\nCONFIG_EOL_IS_LF=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\\nCONFIG_FS_HOSTFS=y\\nCONFIG_LIBC_FLOATINGPOINT=y\\n"
"CONFIG_INTERPRETERS_WAMR=y\\nCONFIG_INTERPRETERS_WAMR_STACKSIZE=327680\\nCONFIG_INTERPRETERS_WAMR_LOG=y\\nCONFIG_INTERPRETERS_WAMR_LIBC_BUILTIN=y\\nCONFIG_INTERPRETERS_WAMR_REF_TYPES=y\\nCONFIG_INTERPRETERS_WAMR_ENABLE_SPEC_TEST=y\\nCONFIG_INTERPRETERS_WAMR_SHARED_MEMORY=y\\nCONFIG_INTERPRETERS_WAMR_BULK_MEMORY=y\\nCONFIG_EOL_IS_LF=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS=y\\nCONFIG_ARM_SEMIHOSTING_HOSTFS_CACHE_COHERENCE=y\\nCONFIG_RISCV_SEMIHOSTING_HOSTFS=y\\nCONFIG_FS_HOSTFS=y\\nCONFIG_LIBC_FLOATINGPOINT=y\\n"

jobs:
build_llvm_libraries:
uses: ./.github/workflows/build_llvm_libraries.yml
with:
os: "ubuntu-22.04"
arch: "ARM RISCV AArch64"
container_image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:d9261eacf6c6ebe656c571757751c803e8f04c3ae9b820320a5ea5dd57b7205a
container_image: ghcr.io/no1wudi/nuttx/apache-nuttx-ci-linux@sha256:8c4e00b607d4d6d66ba8f51c4544819a616eac69d3a2ac669e2af2150e2eb0f9

spec_test_on_qemu:
runs-on: ubuntu-latest
needs: [build_llvm_libraries]
container:
image: ghcr.io/apache/nuttx/apache-nuttx-ci-linux@sha256:d9261eacf6c6ebe656c571757751c803e8f04c3ae9b820320a5ea5dd57b7205a
image: ghcr.io/no1wudi/nuttx/apache-nuttx-ci-linux@sha256:8c4e00b607d4d6d66ba8f51c4544819a616eac69d3a2ac669e2af2150e2eb0f9
strategy:
matrix:
target_config: [
Expand Down Expand Up @@ -75,20 +81,25 @@ jobs:
mode: "-t aot",
option: "CONFIG_INTERPRETERS_WAMR_AOT=y\\n"
},
{
mode: "-t aot -X",
option: "CONFIG_INTERPRETERS_WAMR_AOT=y\\n"
},
{
mode: "-t classic-interp",
option: "CONFIG_INTERPRETERS_WAMR_CLASSIC=y\\n"
},
{
mode: "-t fast-interp",
option: "CONFIG_INTERPRETERS_WAMR_FAST=y\\n"
},
# {
# mode: "-t aot -X",
# option: "CONFIG_INTERPRETERS_WAMR_AOT=y\\n"
# },
# {
# mode: "-t classic-interp",
# option: "CONFIG_INTERPRETERS_WAMR_CLASSIC=y\\n"
# },
# {
# mode: "-t fast-interp",
# option: "CONFIG_INTERPRETERS_WAMR_FAST=y\\n"
# },
]

wamr_feature_option:
# Empty option for default
- { option: "", mode: "" }
- { option: "CONFIG_INTERPRETERS_WAMR_GC=y\\nCONFIG_INTERPRETERS_WAMR_AOT_STACK_FRAME=y\\n", mode: "-G" }

exclude:
# XIP is not fully supported yet on RISCV64, some relocations can not be resolved
- target_config: { config: "boards/risc-v/qemu-rv/rv-virt/configs/nsh64" }
Expand Down Expand Up @@ -136,6 +147,23 @@ jobs:
if: contains(matrix.wamr_test_option.mode, 'aot')
run: cp -r core/deps/llvm apps/interpreters/wamr/wamr/core/deps/llvm

# Inject the config option to NuttX
# TODO: Merge this into NuttX once GC is generally available
- name: Modify Kconfig
run: |
echo "\n" >> apps/interpreters/wamr/Kconfig
echo "config INTERPRETERS_WAMR_GC" >> apps/interpreters/wamr/Kconfig
echo "\tbool \"Enable GC\"" >> apps/interpreters/wamr/Kconfig
echo "\tdefault n" >> apps/interpreters/wamr/Kconfig
echo "\n" >> apps/interpreters/wamr/Kconfig
echo "config INTERPRETERS_WAMR_AOT_STACK_FRAME" >> apps/interpreters/wamr/Kconfig
echo "\tbool \"Enable AOT stack frame\"" >> apps/interpreters/wamr/Kconfig
echo "\tdefault n" >> apps/interpreters/wamr/Kconfig
echo "\n" >> apps/interpreters/wamr/Kconfig
echo "config INTERPRETERS_WAMR_TAIL_CALL" >> apps/interpreters/wamr/Kconfig
echo "\tbool \"Enable Tail Call\"" >> apps/interpreters/wamr/Kconfig
echo "\tdefault y" >> apps/interpreters/wamr/Kconfig
- name: Enable WAMR for NuttX
run: |
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ env.WAMR_COMMON_OPTION }}'
Expand All @@ -144,6 +172,11 @@ jobs:
run: |
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ matrix.wamr_test_option.option }}'
- name: Enable WAMR Feature for NuttX
if: matrix.wamr_feature_option.option != ''
run: |
find nuttx/boards -name defconfig | xargs sed -i '$a\${{ matrix.wamr_feature_option.option }}'
- name: Disable FPU for NuttX
if: matrix.target_config.fpu_type == 'none'
run: |
Expand Down Expand Up @@ -172,4 +205,4 @@ jobs:
- name: Test
run: |
cd apps/interpreters/wamr/wamr/tests/wamr-test-suites
./test_wamr.sh -s spec ${{ matrix.wamr_test_option.mode }} -m ${{ matrix.target_config.target }} -b -Q -P -F ${{ steps.build_firmware.outputs.firmware }}
./test_wamr.sh -s spec ${{ matrix.wamr_test_option.mode }} -m ${{ matrix.target_config.target }} -b -Q -P -F ${{ steps.build_firmware.outputs.firmware }} ${{ matrix.wamr_feature_option.mode}}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*.obj
*.a
*.so
.clangd
.DS_Store

core/deps/**
Expand Down
33 changes: 33 additions & 0 deletions build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ if (WAMR_BUILD_SIMD EQUAL 1)
message (" SIMD disabled due to not supported on target RISCV64")
endif ()
endif ()
if (WAMR_BUILD_AOT_STACK_FRAME EQUAL 1)
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
message (" AOT stack frame enabled")
endif ()
if (WAMR_BUILD_MEMORY_PROFILING EQUAL 1)
add_definitions (-DWASM_ENABLE_MEMORY_PROFILING=1)
message (" Memory profiling enabled")
Expand Down Expand Up @@ -329,6 +333,35 @@ if (WAMR_BUILD_REF_TYPES EQUAL 1)
else ()
message (" Reference types disabled")
endif ()
if (WAMR_BUILD_GC EQUAL 1)
message (" GC enabled")
if (WAMR_TEST_GC EQUAL 1)
message(" GC testing enabled")
endif()
endif ()
if (WAMR_BUILD_GC EQUAL 1 AND WAMR_BUILD_GC_PERF_PROFILING EQUAL 1)
add_definitions (-DWASM_ENABLE_GC_PERF_PROFILING=1)
message (" GC performance profiling enabled")
else ()
message (" GC performance profiling disabled")
endif ()
if (WAMR_BUILD_STRINGREF EQUAL 1)
message (" Stringref enabled")
if (NOT DEFINED WAMR_STRINGREF_IMPL_SOURCE)
message (" Using WAMR builtin implementation for stringref")
else ()
message (" Using custom implementation for stringref")
endif()
endif ()
if (WAMR_BUILD_PERF_PROFILING EQUAL 1 OR
WAMR_BUILD_DUMP_CALL_STACK EQUAL 1 OR
WAMR_BUILD_GC EQUAL 1)
# Enable AOT/JIT stack frame when perf-profiling, dump-call-stack
# or GC is enabled
if (WAMR_BUILD_AOT EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
endif ()
endif ()
if (WAMR_BUILD_EXCE_HANDLING EQUAL 1)
add_definitions (-DWASM_ENABLE_EXCE_HANDLING=1)
add_definitions (-DWASM_ENABLE_TAGS=1)
Expand Down
11 changes: 11 additions & 0 deletions build-scripts/runtime_lib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ if (WAMR_BUILD_AOT EQUAL 1)
include (${IWASM_DIR}/aot/iwasm_aot.cmake)
endif ()

if (WAMR_BUILD_STRINGREF EQUAL 1)
set (WAMR_BUILD_GC 1)
endif ()

if (WAMR_BUILD_GC EQUAL 1)
include (${IWASM_DIR}/common/gc/iwasm_gc.cmake)
# Enable the dependent feature if GC is enabled
set (WAMR_BUILD_REF_TYPES 1)
endif ()

if (WAMR_BUILD_APP_FRAMEWORK EQUAL 1)
include (${APP_FRAMEWORK_DIR}/app_framework.cmake)
include (${SHARED_DIR}/coap/lib_coap.cmake)
Expand Down Expand Up @@ -189,6 +199,7 @@ set (source_all
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${IWASM_FAST_JIT_SOURCE}
${IWASM_GC_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
${NATIVE_INTERFACE_SOURCE}
${APP_MGR_SOURCE}
Expand Down
4 changes: 4 additions & 0 deletions core/app-mgr/app-manager/module_wasm_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,8 +1230,12 @@ wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
uint8 section_type = ch;
#if WASM_ENABLE_BULK_MEMORY == 0
uint8 section_type_max = SECTION_TYPE_DATA;
#else
#if WASM_ENABLE_STRINGREF != 0
uint8 section_type_max = SECTION_TYPE_STRINGREF;
#else
uint8 section_type_max = SECTION_TYPE_DATACOUNT;
#endif /* end of WASM_ENABLE_STRINGREF != 0 */
#endif
if (section_type <= section_type_max) {
wasm_section_t *new_section;
Expand Down
45 changes: 45 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,11 @@
#define WASM_ENABLE_SIMD 0
#endif

/* GC performance profiling */
#ifndef WASM_ENABLE_GC_PERF_PROFILING
#define WASM_ENABLE_GC_PERF_PROFILING 0
#endif

/* Memory profiling */
#ifndef WASM_ENABLE_MEMORY_PROFILING
#define WASM_ENABLE_MEMORY_PROFILING 0
Expand All @@ -325,6 +330,11 @@
#define WASM_ENABLE_DUMP_CALL_STACK 0
#endif

/* AOT stack frame */
#ifndef WASM_ENABLE_AOT_STACK_FRAME
#define WASM_ENABLE_AOT_STACK_FRAME 0
#endif

/* Heap verification */
#ifndef BH_ENABLE_GC_VERIFY
#define BH_ENABLE_GC_VERIFY 0
Expand Down Expand Up @@ -388,6 +398,13 @@
#define APP_HEAP_SIZE_MIN (256)
#define APP_HEAP_SIZE_MAX (512 * 1024 * 1024)

/* Default min/max gc heap size of each app */
#ifndef GC_HEAP_SIZE_DEFAULT
#define GC_HEAP_SIZE_DEFAULT (128 * 1024)
#endif
#define GC_HEAP_SIZE_MIN (4 * 1024)
#define GC_HEAP_SIZE_MAX (1024 * 1024 * 1024)

/* Default wasm stack size of each app */
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#define DEFAULT_WASM_STACK_SIZE (16 * 1024)
Expand Down Expand Up @@ -461,6 +478,30 @@
#define WASM_ENABLE_REF_TYPES 0
#endif

#ifndef WASM_ENABLE_GC
#define WASM_ENABLE_GC 0
#endif

#ifndef WASM_CONST_EXPR_STACK_SIZE
#if WASM_ENABLE_GC != 0
#define WASM_CONST_EXPR_STACK_SIZE 8
#else
#define WASM_CONST_EXPR_STACK_SIZE 4
#endif
#endif

#ifndef WASM_ENABLE_STRINGREF
#define WASM_ENABLE_STRINGREF 0
#endif

#ifndef GC_REFTYPE_MAP_SIZE_DEFAULT
#define GC_REFTYPE_MAP_SIZE_DEFAULT 64
#endif

#ifndef GC_RTTOBJ_MAP_SIZE_DEFAULT
#define GC_RTTOBJ_MAP_SIZE_DEFAULT 64
#endif

#ifndef WASM_ENABLE_EXCE_HANDLING
#define WASM_ENABLE_EXCE_HANDLING 0
#endif
Expand Down Expand Up @@ -525,4 +566,8 @@
#define WASM_ENABLE_QUICK_AOT_ENTRY 1
#endif

#ifndef WASM_TABLE_MAX_SIZE
#define WASM_TABLE_MAX_SIZE 1024
#endif

#endif /* end of _CONFIG_H_ */
Loading

0 comments on commit 16a4d71

Please sign in to comment.