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 #929Fixes#1804
* Pin nightlies to previous night
Fixes some upstream breakage in rust-lang/rust which should get fixed
tomorrow.
* fix-0.65
Co-authored-by: Yury Delendik <ydelendik@mozilla.com>
* Moves CodeMemory, VMInterrupts and SignatureRegistry from Compiler
* CompiledModule holds CodeMemory and GdbJitImageRegistration
* Store keeps track of its JIT code
* Makes "jit_int.rs" stuff Send+Sync
* Adds the threads example.
This avoids the set uniqueness (hashing) test, reduces memory
churn when re-mapping virtual register onto real registers, and is
generally more memory-efficient.
* Minor code tidying.
* Document that `Linker::iter`'s iteration order is arbitrary.
* Add a few more tests for `wasmtime::Linker`.
* Refactor `Linker::compute_imports`.
- Extract the error message generation into a separate function.
- In the error message, sort the candidates.
* Fix a typo in a comment.
* Add `__rtti_base` to the list of allowed but deprecated exports.
* Don't print an Error message when a program exits normally.
* Update comments to reflect the current code.
* Also allow "table" as an exported table, which is used by AssemblyScript.
This ports all of the identity, no-op, simplification, and canonicalization
related optimizations over from being hand-coded to the `peepmatic` DSL. This
does not handle the branch-to-branch optimizations or most of the
divide-by-constant optimizations.
SmallVec<[Value; 1]>, not as a Vec<Value>. This isn't a useful change for any
non-developer use of Cranelift, but it does significantly reduce the amount of
allocation "noise" seen when tuning the new backend pipeline as driven by
clif-util reading .clif files. In one case the number of malloc calls
declined by about 20% with this change.
This resolves the work started in https://github.com/bytecodealliance/cranelift/pull/1231 and https://github.com/bytecodealliance/wasmtime/pull/1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results:
- `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value
- `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout
To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see 3b7cb6ee64/crates/api/src/func.rs (L510-L526), 3b7cb6ee64/crates/jit/src/compiler.rs (L260)). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
* Implement trap info in Lightbeam
* Start using wasm-reader instead of wasmparser for parsing operators
* Update to use wasm-reader, some reductions in allocation, support source location tracking for traps, start to support multi-value
The only thing that still needs to be supported for multi-value is stack returns, but we need to make it compatible with Cranelift.
* Error when running out of registers (although we'd hope it should be impossible) instead of panicking
* WIP: Update Lightbeam to work with latest Wasmtime
* WIP: Update Lightbeam to use current wasmtime
* WIP: Migrate to new system for builtin functions
* WIP: Update Lightbeam to work with latest Wasmtime
* Remove multi_mut
* Format
* Fix some bugs around arguments, add debuginfo offset tracking
* Complete integration with new Wasmtime
* Remove commented code
* Fix formatting
* Fix warnings, remove unused dependencies
* Fix `iter` if there are too many elements, fix compilation for latest wasmtime
* Fix float arguments on stack
* Remove wasm-reader and trap info work
* Allocate stack space _before_ passing arguments, fail if we can't zero a xmm reg
* Fix stack argument offset calculation
* Fix stack arguments in Lightbeam
* Re-add WASI because it somehow got removed during rebase
* Workaround for apparent `type_alias_impl_trait`-related bug in rustdoc
* Fix breakages caused by rebase, remove module offset info as it is unrelated to wasmtime integration PR and was broken by rebase
* Add TODO comment explaining `lightbeam::ModuleContext` trait
This PR updates Cranelift to use the new version of regalloc.rs
(bytecodealliance/regalloc.rs#55) that provides dense vreg->rreg maps to
the `map_reg()` function for each instruction, rather than the earlier
hashmap-based approach.
In one test (regex-rs.wasm), this PR results in a 15% reduction in
memory allocations (1245MB -> 1060MB) as measured by DHAT on `clif-util
wasm` runs.