Skip to content

Commit

Permalink
Add the "null" garbage collector (#9484)
Browse files Browse the repository at this point in the history
* Add the "null" garbage collector

The null collector does not actually collect any garbage, it simply
bump-allocates until the heap is exhausted, at which point further allocation
attempts will fail. It does not require any GC barriers.

Users can configure which collector to use via the `wasmtime::Config::collector`
method or the `-C collector=drc|null` CLI flag. The `wasmtime::Collector` enumeration,
similar to the `wasmtime::Strategy` enumeration but for choosing a collector
rather than a compiler, additionally has a table summarizing the properties and
characteristics of our current set of collector implementations.

Finally, we also run `.wast` tests that exercise GC types under both the DRC and
null collectors. I tried to avoid running tests that are not related to GC under
both configurations just to avoid a combinatorial blow up.

* cargo fmt

* fix +gc -gc-null -gc-drc build

* Fix some warnings in various cargo feature combo builds

* Fix some more warnings in certain build configs

* Fix unit tests for null GC

* Fill in some placeholder comments that I forgot to write

* Fix issues where we ask for a GC store when we don't actually need one

Which was causing test failures, since we no longer return a GC store with a
dummy heap.

* Add fuzzing config support for different collectors

* address review feedback

* fix cmake tests

* Fix test compilation after rebase

* Fix GC tests under MIRI
  • Loading branch information
fitzgen authored Oct 31, 2024
1 parent 7a49e44 commit 83bf774
Show file tree
Hide file tree
Showing 108 changed files with 3,818 additions and 611 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,12 @@ jobs:
-p wasmtime --no-default-features --features gc
-p wasmtime --no-default-features --features runtime,gc
-p wasmtime --no-default-features --features cranelift,gc
-p wasmtime --no-default-features --features gc-drc
-p wasmtime --no-default-features --features runtime,gc-drc
-p wasmtime --no-default-features --features cranelift,gc-drc
-p wasmtime --no-default-features --features gc-null
-p wasmtime --no-default-features --features runtime,gc-null
-p wasmtime --no-default-features --features cranelift,gc-null
-p wasmtime --no-default-features --features runtime
-p wasmtime --no-default-features --features threads
-p wasmtime --no-default-features --features runtime,threads
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ default = [
"component-model",
"threads",
"gc",
"gc-drc",
"gc-null",
"winch",

# Enable some nice features of clap by default, but they come at a binary size
Expand Down Expand Up @@ -441,7 +443,9 @@ coredump = ["wasmtime-cli-flags/coredump"]
addr2line = ["wasmtime/addr2line"]
debug-builtins = ["wasmtime/debug-builtins"]
threads = ["wasmtime-cli-flags/threads"]
gc = ["wasmtime-cli-flags/gc"]
gc = ["wasmtime-cli-flags/gc", "wasmtime/gc"]
gc-drc = ["gc", "wasmtime/gc-drc", "wasmtime-cli-flags/gc-drc"]
gc-null = ["gc", "wasmtime/gc-null", "wasmtime-cli-flags/gc-null"]

# CLI subcommands for the `wasmtime` executable. See `wasmtime $cmd --help`
# for more information on each subcommand.
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ addr2line = ["wasmtime/addr2line"]
demangle = ["wasmtime/demangle"]
threads = ["wasmtime/threads"]
gc = ["wasmtime/gc"]
gc-drc = ["wasmtime/gc-drc"]
gc-null = ["wasmtime/gc-null"]
cranelift = ['wasmtime/cranelift']
winch = ['wasmtime/winch']
# ... if you add a line above this be sure to change the other locations
Expand Down
4 changes: 4 additions & 0 deletions crates/c-api/artifact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ default = [
'demangle',
'threads',
'gc',
'gc-drc',
'gc-null',
'cranelift',
'winch',
# ... if you add a line above this be sure to change the other locations
Expand All @@ -52,6 +54,8 @@ demangle = ["wasmtime-c-api/demangle"]
wat = ["wasmtime-c-api/wat"]
threads = ["wasmtime-c-api/threads"]
gc = ["wasmtime-c-api/gc"]
gc-drc = ["wasmtime-c-api/gc-drc"]
gc-null = ["wasmtime-c-api/gc-null"]
cranelift = ["wasmtime-c-api/cranelift"]
winch = ["wasmtime-c-api/winch"]
# ... if you add a line above this be sure to read the comment at the end of
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const FEATURES: &[&str] = &[
"DEMANGLE",
"THREADS",
"GC",
"GC_DRC",
"GC_NULL",
"CRANELIFT",
"WINCH",
];
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/cmake/features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ feature(addr2line ON)
feature(demangle ON)
feature(threads ON)
feature(gc ON)
feature(gc-drc ON)
feature(gc-null ON)
feature(async ON)
feature(cranelift ON)
feature(winch ON)
Expand Down
2 changes: 2 additions & 0 deletions crates/c-api/include/wasmtime/conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#cmakedefine WASMTIME_FEATURE_DEMANGLE
#cmakedefine WASMTIME_FEATURE_THREADS
#cmakedefine WASMTIME_FEATURE_GC
#cmakedefine WASMTIME_FEATURE_GC_DRC
#cmakedefine WASMTIME_FEATURE_GC_NULL
#cmakedefine WASMTIME_FEATURE_ASYNC
#cmakedefine WASMTIME_FEATURE_CRANELIFT
#cmakedefine WASMTIME_FEATURE_WINCH
Expand Down
2 changes: 2 additions & 0 deletions crates/cli-flags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ logging = ["dep:file-per-thread-logger", "dep:tracing-subscriber"]
cranelift = ["wasmtime/cranelift"]
coredump = ["wasmtime/coredump"]
gc = ["wasmtime/gc"]
gc-drc = ["gc", "wasmtime/gc-drc"]
gc-null = ["gc", "wasmtime/gc-null"]
threads = ["wasmtime/threads"]
memory-protection-keys = ["wasmtime/memory-protection-keys"]
15 changes: 15 additions & 0 deletions crates/cli-flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ wasmtime_option_group! {
/// Currently only `cranelift` and `winch` are supported, but not all
/// builds of Wasmtime have both built in.
pub compiler: Option<wasmtime::Strategy>,
/// Which garbage collector to use: `drc` or `null`.
///
/// `drc` is the deferred reference-counting collector.
///
/// `null` is the null garbage collector, which does not collect any
/// garbage.
///
/// Note that not all builds of Wasmtime will have support for garbage
/// collection included.
pub collector: Option<wasmtime::Collector>,
/// Enable Cranelift's internal debug verifier (expensive)
pub cranelift_debug_verifier: Option<bool>,
/// Whether or not to enable caching of compiled modules.
Expand Down Expand Up @@ -535,6 +545,11 @@ impl CommonOptions {
strategy => config.strategy(strategy),
_ => err,
}
match_feature! {
["gc" : self.codegen.collector]
collector => config.collector(collector),
_ => err,
}
match_feature! {
["cranelift" : target]
target => config.target(target)?,
Expand Down
11 changes: 11 additions & 0 deletions crates/cli-flags/src/opt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,17 @@ impl WasmtimeOptionValue for wasmtime::Strategy {
}
}

impl WasmtimeOptionValue for wasmtime::Collector {
const VAL_HELP: &'static str = "=drc|null";
fn parse(val: Option<&str>) -> Result<Self> {
match String::parse(val)?.as_str() {
"drc" => Ok(wasmtime::Collector::DeferredReferenceCounting),
"null" => Ok(wasmtime::Collector::Null),
other => bail!("unknown collector `{other}` only `drc` and `null` accepted",),
}
}
}

impl WasmtimeOptionValue for WasiNnGraph {
const VAL_HELP: &'static str = "=<format>::<dir>";
fn parse(val: Option<&str>) -> Result<Self> {
Expand Down
2 changes: 2 additions & 0 deletions crates/cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ component-model = ["wasmtime-environ/component-model"]
incremental-cache = ["cranelift-codegen/incremental-cache"]
wmemcheck = ["wasmtime-environ/wmemcheck"]
gc = ["wasmtime-environ/gc"]
gc-drc = ["gc", "wasmtime-environ/gc-drc"]
gc-null = ["gc", "wasmtime-environ/gc-null"]
threads = ["wasmtime-environ/threads"]
5 changes: 3 additions & 2 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub struct FuncEnvironment<'module_environment> {
/// Offsets to struct fields accessed by JIT code.
pub(crate) offsets: VMOffsets<u8>,

tunables: &'module_environment Tunables,
pub(crate) tunables: &'module_environment Tunables,

/// A function-local variable which stores the cached value of the amount of
/// fuel remaining to execute. If used this is modified frequently so it's
Expand Down Expand Up @@ -1130,7 +1130,8 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
*builder.func.dfg.inst_results(call).first().unwrap()
}

fn vmshared_type_index_ty(&self) -> Type {
/// Get the `ir::Type` for a `VMSharedTypeIndex`.
pub(crate) fn vmshared_type_index_ty(&self) -> Type {
Type::int_with_byte_size(self.offsets.size_of_vmshared_type_index().into()).unwrap()
}

Expand Down
2 changes: 1 addition & 1 deletion crates/cranelift/src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use imp::*;

/// How to initialize a newly-allocated array's elements.
#[derive(Clone, Copy)]
#[cfg_attr(not(feature = "gc"), allow(dead_code))]
#[cfg_attr(not(any(feature = "gc-null", feature = "gc-drc")), allow(dead_code))]
pub enum ArrayInit<'a> {
/// Initialize the array's elements with the given values.
Elems(&'a [ir::Value]),
Expand Down
Loading

0 comments on commit 83bf774

Please sign in to comment.