For host VM code, we use plain reference counting, where cloning increments
the reference count, and dropping decrements it. We can avoid many of the
on-stack increment/decrement operations that typically plague the
performance of reference counting via Rust's ownership and borrowing system.
Moving a `VMExternRef` avoids mutating its reference count, and borrowing it
either avoids the reference count increment or delays it until if/when the
`VMExternRef` is cloned.
When passing a `VMExternRef` into compiled Wasm code, we don't want to do
reference count mutations for every compiled `local.{get,set}`, nor for
every function call. Therefore, we use a variation of **deferred reference
counting**, where we only mutate reference counts when storing
`VMExternRef`s somewhere that outlives the activation: into a global or
table. Simultaneously, we over-approximate the set of `VMExternRef`s that
are inside Wasm function activations. Periodically, we walk the stack at GC
safe points, and use stack map information to precisely identify the set of
`VMExternRef`s inside Wasm activations. Then we take the difference between
this precise set and our over-approximation, and decrement the reference
count for each of the `VMExternRef`s that are in our over-approximation but
not in the precise set. Finally, the over-approximation is replaced with the
precise set.
The `VMExternRefActivationsTable` implements the over-approximized set of
`VMExternRef`s referenced by Wasm activations. Calling a Wasm function and
passing it a `VMExternRef` moves the `VMExternRef` into the table, and the
compiled Wasm function logically "borrows" the `VMExternRef` from the
table. Similarly, `global.get` and `table.get` operations clone the gotten
`VMExternRef` into the `VMExternRefActivationsTable` and then "borrow" the
reference out of the table.
When a `VMExternRef` is returned to host code from a Wasm function, the host
increments the reference count (because the reference is logically
"borrowed" from the `VMExternRefActivationsTable` and the reference count
from the table will be dropped at the next GC).
For more general information on deferred reference counting, see *An
Examination of Deferred Reference Counting and Cycle Detection* by Quinane:
https://openresearch-repository.anu.edu.au/bitstream/1885/42030/2/hon-thesis.pdf
cc #929
Fixes #1804
93 lines
2.4 KiB
TOML
93 lines
2.4 KiB
TOML
[package]
|
|
name = "wasmtime-cli"
|
|
version = "0.18.0"
|
|
authors = ["The Wasmtime Project Developers"]
|
|
description = "Command-line interface for Wasmtime"
|
|
license = "Apache-2.0 WITH LLVM-exception"
|
|
documentation = "https://bytecodealliance.github.io/wasmtime/cli.html"
|
|
categories = ["wasm"]
|
|
keywords = ["webassembly", "wasm"]
|
|
repository = "https://github.com/bytecodealliance/wasmtime"
|
|
readme = "README.md"
|
|
edition = "2018"
|
|
default-run = "wasmtime"
|
|
|
|
[lib]
|
|
doctest = false
|
|
|
|
[[bin]]
|
|
name = "wasmtime"
|
|
path = "src/bin/wasmtime.rs"
|
|
doc = false
|
|
|
|
[dependencies]
|
|
# Enable all supported architectures by default.
|
|
wasmtime = { path = "crates/wasmtime", version = "0.18.0", default-features = false }
|
|
wasmtime-debug = { path = "crates/debug", version = "0.18.0" }
|
|
wasmtime-environ = { path = "crates/environ", version = "0.18.0" }
|
|
wasmtime-jit = { path = "crates/jit", version = "0.18.0" }
|
|
wasmtime-obj = { path = "crates/obj", version = "0.18.0" }
|
|
wasmtime-wast = { path = "crates/wast", version = "0.18.0" }
|
|
wasmtime-wasi = { path = "crates/wasi", version = "0.18.0" }
|
|
wasi-common = { path = "crates/wasi-common", version = "0.18.0" }
|
|
structopt = { version = "0.3.5", features = ["color", "suggestions"] }
|
|
object = { version = "0.19", default-features = false, features = ["write"] }
|
|
anyhow = "1.0.19"
|
|
target-lexicon = { version = "0.10.0", default-features = false }
|
|
pretty_env_logger = "0.4.0"
|
|
file-per-thread-logger = "0.1.1"
|
|
wat = "1.0.18"
|
|
libc = "0.2.60"
|
|
log = "0.4.8"
|
|
rayon = "1.2.1"
|
|
humantime = "1.3.0"
|
|
|
|
[dev-dependencies]
|
|
env_logger = "0.7.1"
|
|
filecheck = "0.5.0"
|
|
more-asserts = "0.2.1"
|
|
tempfile = "3.1.0"
|
|
test-programs = { path = "crates/test-programs" }
|
|
wasmtime-fuzzing = { path = "crates/fuzzing" }
|
|
wasmtime-runtime = { path = "crates/runtime" }
|
|
|
|
[build-dependencies]
|
|
anyhow = "1.0.19"
|
|
|
|
[profile.release.build-override]
|
|
opt-level = 0
|
|
|
|
[workspace]
|
|
members = [
|
|
"cranelift",
|
|
"crates/c-api",
|
|
"crates/fuzzing",
|
|
"crates/misc/run-examples",
|
|
"crates/misc/rust",
|
|
"crates/wiggle",
|
|
"examples/fib-debug/wasm",
|
|
"examples/wasi/wasm",
|
|
"fuzz",
|
|
]
|
|
|
|
[features]
|
|
default = ["jitdump", "wasmtime/wat"]
|
|
lightbeam = [
|
|
"wasmtime-environ/lightbeam",
|
|
"wasmtime-jit/lightbeam",
|
|
"wasmtime-wast/lightbeam",
|
|
"wasmtime/lightbeam",
|
|
]
|
|
jitdump = ["wasmtime/jitdump"]
|
|
vtune = ["wasmtime/vtune"]
|
|
|
|
[badges]
|
|
maintenance = { status = "actively-developed" }
|
|
|
|
[[test]]
|
|
name = "host_segfault"
|
|
harness = false
|
|
|
|
[patch.crates-io]
|
|
backtrace = { git = "https://github.com/rust-lang/backtrace-rs.git" }
|