-
Notifications
You must be signed in to change notification settings - Fork 728
Description
GC (Gargbage Collection) AOT support
Motivation
In recent days we had refactored the WAMR GC interpreter implementation to support most features of the latest GC MVP spec proposal, and support the bytecodes generate by the binaryen toolchain as its bytecode definition is a little different from the definition of GC MVP, so as to run the workloads compiled by the ts2wasm compiler, which uses binaryen as its backend. To gain better performance and to reduce the footprint, we started to enable the GC AOT support.
Design Goals
- Support platform linux, macos, windows, android, linux-sgx, nuttx and so on
- Support target x86-64, x86-32, aarch64, arm32, thumb, riscv64, riscv32
- Support the same functionalities as interpreter
- Support the bytecode definition of both GC MVP and GC binaryen
- Pass the spec cases and the cases compiled by ts2wasm compiler
- Support GC multi-threading
- Export necessary GC APIs
- Standardize the interface between runtime and GC allocator
Non Design Goals now
- Improve the performance of GC allocator and GC reclaim process, and resolve the fragment issue of GC heap
There may be some shortcomings of the current ems heap allocator, we hope we can replace it with other GC heap allocator in the feature. And the interfaces between runtime and GC allocator will be standardized, so we can easily integrate a new GC allocator into runtime.
Changes of the AOT file format
There will be many changes in the AOT file format, after discussion, some decisions were made:
- The AOT file version will be upgraded from 1 to 2
- The new version won’t be compatible with the old version since it is complex and difficult to main the compatibility with old version, in other words, the AOT file generated by the old wamrc won’t be able to be run by the new AOT runtime.
- Remove the current handles to keep the compatibility in AOT runtime, so as to make the code clear and concise
- Consider the support for multiple memories, exception handling and component model
- Strings in the AOT file are always terminated by ‘\0’, so runtime can directly use them and doesn’t need to create a copy
Some detail changes
- Enable feature flags, each bit denotes whether a feature is support or not
- Extend the structures which have value type field, add extra heap type field if the value type is a reference type that requires heap type info
- Extend the function type to function/struct/array/sub/sub_final/recursive types, and add a flag to specify which defined type it is
- Extend the initializer expression to support more const expression (like struct.new_xxx, array.new_xxx) and support a piece of bytecode to do the initialization
Changes of the AOT compiler
- Add
--enable-gcoption for wamrc - Support build wamrc for GC MVP version and GC binaryen version, by default the GC MVP version is built, and when
cmake -DWAMR_BUILD_GC_BINARYEN=1is used, the GC binaryen version is built.
Changes of AOT module instance layout
- The value of element in the table instance is changed from the function index of uint32 type to the function object pointer of WASMFunctionObjRef type. The impacts the instantiation of table instance and how to access it.
AOT stack frame process
Current AOT doesn’t operate on the stack frame except in the feature of dumping call stack, memory profiling and performance profiling, since the operations of the function local variables and stack operators have been optimized to the operations of registers and native stack by the LLVM codegen. Since GC requires to add the GC objects into the rootset during garbage collection, we need to enable the stack frame operation for GC AOT:
- Create a frame before calling a function, and release it after returning from a function
- Commit operators from registers into stack frame when needed
Export GC runtime APIs
See PR #2143, the runtime APIs are exported in core/iwasm/include/gc_export.h
GC multi-threding support
Need to enhance the thread suspend/resume mechanism to support the GC reclaim process for multi-thread: a thread can require to suspend the world if needed, or suspend other threads (wait until all other threads are suspended), and resume them after a job is finished. This mechanism is also helpful to the linear memory info synchronization when memory.grow opcode is exectued, see the discussion in #2078. Another scenario may be the source debugger for multi-threading: when a thread enters into break pointer, it may ask other threads to suspend, and resume them when it continues to run.
Standardize the interface between runtime and GC heap allocator
Better define the interface between runtime and GC heap allocator so that we can easily integrate a new GC heap allocator into runtime.
References
- WAMR GC development branch
https://github.com/bytecodealliance/wasm-micro-runtime/tree/dev/gc_refactor - GC MVP spec proposal
https://github.com/WebAssembly/gc/blob/master/proposals/gc/MVP.md - Binaryen toolchain
https://github.com/WebAssembly/binaryen - ts2wasm compiler
Compiling TypeScript to WebAssembly #2037