* Enable jitdump profiling support by default
This the result of some of the investigation I was doing for #1017. I've
done a number of refactorings here which culminated in a number of
changes that all amount to what I think should result in jitdump support being
enabled by default:
* Pass in a list of finished functions instead of just a range to
ensure that we're emitting jit dump data for a specific module rather
than a whole `CodeMemory` which may have other modules.
* Define `ProfilingStrategy` in the `wasmtime` crate to have everything
locally-defined
* Add support to the C API to enable profiling
* Documentation added for profiling with jitdump to the book
* Split out supported/unsupported files in `jitdump.rs` to avoid having
lots of `#[cfg]`.
* Make dependencies optional that are only used for `jitdump`.
* Move initialization up-front to `JitDumpAgent::new()` instead of
deferring it to the first module.
* Pass around `Arc<dyn ProfilingAgent>` instead of
`Option<Arc<Mutex<Box<dyn ProfilingAgent>>>>`
The `jitdump` Cargo feature is now enabled by default which means that
our published binaries, C API artifacts, and crates will support
profiling at runtime by default. The support I don't think is fully
fleshed out and working but I think it's probably in a good enough spot
we can get users playing around with it!
* Handle select relocations while generating trampolines
Trampoline generation for all function signatures exposed a preexisting
bug in wasmtime where trampoline generation occasionally does have
relocations, but it's asserted that trampolines don't generate
relocations, causing a panic. The relocation is currently primarily the
probestack function which happens when functions might have a huge
number of parameters, but not so huge as to blow the wasmparser limit of
how many parameters are allowed.
This commit fixes the issue by handling relocations for trampolines in
the same manner as the rest of the code. Note that dynamically-generated
trampolines via the `Func` API still panic if they have too many
arguments and generate a relocation, but it seems like we can try to fix
that later if the need truly arises.
Closes#1322
* Log trampoline relocations
Until #1306 is resolved (some spilling/regalloc issue with larger FPR register banks), this removes FPR32 support. Only Wasm's `i64x2.mul` was using this register class and that instruction is predicated on AVX512 support; for the time being, that instruction will have to make do with the 16 FPR registers.
* Exit with a more severe error code if the program traps.
Previously, the wasmtime CLI would return with a regular failure
error code, such as 1 on Unix. However, a program trap indicates a bug
in the program, which can be useful to distinguish from a simple error
status. Check for the trap case, and return an appropriate OS-specific
exit status.
* Use a loop to iterate over the error causes to find Traps.
* Use anyhow's `chain()` iterator.
* For completeness, handle non-Unix and non-Windows platforms too.
* Add a CLI test for a trapping program.
* Replace a manual `.cause` loop with a `.is` call.
* Correct the expected exit status on Windows.
* Use assert_eq/assert_ne so that if these fail, it prints the output.
* add a lifetime to the wiggle_runtime::GuestErrorType trait, wiggle_tests::WasiCtx struct
* wiggle-generate: make config parsing public so it can be reused in lucet
This patch updates or removes all references to the Cranelift repository. It affects links in README documents, issues that were transferred to the Wasmtime repository, CI badges, and a small bunch of sundry items.
* wiggle-runtime: add as_raw method for [T]
* add trivial borrow checker back in
* integrate runtime borrow checker with as_raw methods
* handle pointer arith overflow correctly in as_raw, create PtrOverflow error
* runtime: add validation back to GuestType
* generate: impl validate for enums, flags, handles, ints
* oops! make validate its own method on trait GuestTypeTransparent
* fix transparent impls for enum, flag, handle, int
* some structs are transparent. fix tests.
* tests: define byte_slice_strat and friends
* wiggle-tests: i believe my allocator is working now
* some type juggling around memset for ease of use
* make GuestTypeTransparent an unsafe trait
* delete redundant validation of pointer align
* fix doc
* wiggle_test: aha, you cant use sets to track memory areas
* add multi-string test
which exercises the runtime borrow checker against
HostMemory::byte_slice_strat
* oops left debug panic in
* remove redundant (& incorrect, since unchecked) length calc
* redesign validate again, and actually hook to as_raw
* makr all validate impls as inline
this should hopefully allow as_raw's check loop to be unrolled to a
no-op in most cases!
* code review fixes
This commit rewrites the runtime crate to provide safety in the face
of recursive calls to the guest. The basic principle is that
`GuestMemory` is now a trait which dynamically returns the
pointer/length pair. This also has an implicit contract (hence the
`unsafe` trait) that the pointer/length pair point to a valid list of
bytes in host memory "until something is reentrant".
After this changes the various suite of `Guest*` types were rewritten.
`GuestRef` and `GuestRefMut` were both removed since they cannot safely
exist. The `GuestPtrMut` type was removed for simplicity, and the final
`GuestPtr` type subsumes `GuestString` and `GuestArray`. This means
that there's only one guest pointer type, `GuestPtr<'a, T>`, where `'a`
is the borrow into host memory, basically borrowing the `GuestMemory`
trait object itself.
Some core utilities are exposed on `GuestPtr`, but they're all 100%
safe. Unsafety is now entirely contained within a few small locations:
* Implementations of the `GuestType` for primitive types (e.g. `i8`,
`u8`, etc) use `unsafe` to read/write memory. The `unsafe` trait of
`GuestMemory` though should prove that they're safe.
* `GuestPtr<'_, str>` has a method which validates utf-8 contents, and
this requires `unsafe` internally to read all the bytes. This is
guaranteed to be safe however given the contract of `GuestMemory`.
And that's it! Everything else is a bunch of safe combinators all built
up on the various utilities provided by `GuestPtr`. The general idioms
are roughly the same as before, with various tweaks here and there. A
summary of expected idioms are:
* For small values you'd `.read()` or `.write()` very quickly. You'd
pass around the type itself.
* For strings, you'd pass `GuestPtr<'_, str>` down to the point where
it's actually consumed. At that moment you'd either decide to copy it
out (a safe operation) or you'd get a raw view to the string (an
unsafe operation) and assert that you won't call back into wasm while
you're holding that pointer.
* Arrays are similar to strings, passing around `GuestPtr<'_, [T]>`.
Arrays also have a `iter()` method which yields an iterator of
`GuestPtr<'_, T>` for convenience.
Overall there's still a lot of missing documentation on the runtime
crate specifically around the safety of the `GuestMemory` trait as well
as how the utilities/methods are expected to be used. Additionally
there's utilities which aren't currently implemented which would be easy
to implement. For example there's no method to copy out a string or a
slice, although that would be pretty easy to add.
In any case I'm curious to get feedback on this approach and see what
y'all think!
This commit puts context object, i.e., the implementor of the
WASI snapshot, behind a reference `&self` rather than a mutable
reference `&mut self`. As suggested by @alexcrichton, this gives
the implementor the possibility to determine how it handles its
interior mutability.
* Add WASI spec (minus unions)
* Fill in all WASI shims
* Clean up derives and fix noncopy struct write method
This commit does three things:
* it uses the full, current snapshot1 WASI spec as a compilation test
* it fixes noncopy struct write method (which was incorrectly resolved
in certain cases to the inherent method of the `GuestPtrMut` rather
than the interface method `GuestType::write`
* it cleans up derives for structs and unions which should not auto-derive
`PartialEq`, `Eq`, or `Hash` since their members are not guaranteed to
be compatible
this allows us to reuse the code in wiggle-generate elsewhere, because
a proc-macro=true lib can only export a #[proc_macro] and not ordinary
functions.
In lucet, I will depend on wiggle-generate to define a proc macro that
glues wiggle to the specifics of the runtime.
This commit refactors trait system for guest types. Namely, as
discussed offline on zulip, `GuestType` now includes `GuestTypeClone`,
whereas `GuestTypeCopy` has been renamed to `GuestTypeTransparent`.
Essentially, table and memory out of bounds errors are no longer link errors,
but traps after linking. This means that the partail writes / inits are visible.
This adds support for the `table.copy` instruction from the bulk memory
proposal. It also supports multiple tables, which were introduced by the
reference types proposal.
Part of #928
these names were artifacts of some early confusion / bad design i made
in the traits. read and write are much simpler names!
also, change a ptr_mut to ptr where we just read the contents in the
argument marshalling for structs. this has no effect, but it is more
correct.
* Allow returning structs if copy
This commit does three things:
1. enables marshalling of structs as return args from interface funcs
but so far *only* for the case when the struct itself is copy
2. puts bits that use `std::convert::TryInto` in a local scope to avoid
multiple reimports
3. for added clarity, we now print for which `tref` type the marshalling
of results is unimplemented
The first case (1.) is required to make `fd_fdstat_get` WASI interface
func work which returns `Fdstat` struct (which is copy). The second
case (2.) caused me some grief somewhere along the lines when I was
playing with snapshot1. Putting the code that requires it inside a local
scope fixed all the issues
* Add proptests for returing struct if copyable
* Use write_ptr_to_guest to marshal value to guest
* Successfully return non-copy struct
* Optimize generated code via the CLI by default
This commit updates the behavior of the CLI and adds a new flag. It
first enables the `--optimize` flag by default, ensuring that usage of
the `wasmtime` CLI will enable cranelift optimizations by default. Next
it also adds a `--opt-level` flag which is similar to Rust's
`-Copt-level` where it takes a string argument of how to optimize. This
is updates to support 0/1/2/s, where 1 is currently the same as 2 but
added for consistency with other compilers. The default setting is
`--opt-level=2`.
When the `-O` flag is not passed the `--opt-level` flag is used,
otherwise `-O` takes precedent in the sense that it implies
`--opt-level=2` which is the highest optimization level. The thinking is
that these flags will in general select the highest optimization level
specified as the final optimization level.
* Add inline docs
* fix a test
* Implement fmt::Display for enums
`wasi_common` relies on `strerror` to nicely format error messages.
`strerror` is autoimplemented in `wig`. I thought it might be useful
to provide a Rust-idiomatic alternative which boils down to autoimplementing
`fmt::Display` for all enums.
* Implement fmt::Display for flags
* Implement fmt::Display for ints
* atoms in one test unit
* factor out pointers test
* factor structs into separate test unit
* factor out arrays, flags
* finally, separate into strings and ints
* Draft out IntDatatype in wiggle-generate
This commit drafts out basic layout for `IntDatatype` structure in
`wiggle`. As it currently stands, an `Int` type is represented as
a one-element tuple struct much like `FlagDatatype`, however, with
this difference that we do not perform any checks on the input
underlying representation since any value for the prescribed type
is legal.
* Finish drafting IntDatatype support in wiggle
This commit adds necessary marshal stubs to properly pass `IntDatatype`
in and out of interface functions. It also adds a basic proptest.
* Add basic GuestString support to wiggle
This commit adds basic `GuestString` support to `wiggle`. `GuestString`
is a wrapper around `GuestArray<'_, u8>` array type which itself can
be made into either an owned (cloned) Rust `String` or borrowed as
a reference `&str`. In both cases, `GuestString` ensures that the
underlying bytes are valid Unicode code units, throwing a `InvalidUtf8`
error if not.
This commit adds support *only* for passing in strings as arguments
in WASI. Marshalling of the return arg has not yet been implemented.
I'm not even sure it's possible without multi-value return args
feature of Wasm. It's not a major setback especially since the WASI
spec (and this includes even the `ephemeral` snapshot) doesn't
return strings anywhere. They are only ever passed in as arguments
to interface functions.
It should be noted that error returned in case of invalid UTF-8
requires a lot more love as it doesn't include anything besides
flagging an event that the string contained an invalid Unicode code unit.
* Borrow all of string's memory including nul-byte
Borrow all of string's underlying memory including the nul-byte.
This perhaps might not have a tremendous impact on anything, but
since the nul-byte is technically part of the WASI string, we should
include it in the borrow as well.
* Fill in wiggle-generate blanks for strings
* Print to screen passed string in proptest
* Strings are PointerLengthPairs!
* Fix generation of strings in compound types
* Update test with simple string strategy
* Generate better test strings
* Finalise proptest for strings
* Fix formatting
* Update crates/runtime/src/memory/string.rs
Removes unnecessary comment in code
* Apply Pat's suggestion to wrap Utf8Error as error
* merge GuestTypePtr and GuestTypeClone into a single GuestTypeClone<'a> trait
* GuestArray can derive Clone (but not impl GuestTypeClone)
* fix array tests
* Fix GuestTypeClone for flags
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Patch adds support for the perf jitdump file specification.
With this patch it should be possible to see profile data for code
generated and maped at runtime. Specifically the patch adds support
for the JIT_CODE_LOAD and the JIT_DEBUG_INFO record as described in
the specification. Dumping jitfiles is enabled with the --jitdump
flag. When the -g flag is also used there is an attempt to dump file
and line number information where this option would be most useful
when the WASM file already includes DWARF debug information.
The generation of the jitdump files has been tested on only a few wasm
files. This patch is expected to be useful/serviceable where currently
there is no means for jit profiling, but future patches may benefit
line mapping and add support for additional jitdump record types.
Usage Example:
Record
sudo perf record -k 1 -e instructions:u target/debug/wasmtime -g
--jitdump test.wasm
Combine
sudo perf inject -v -j -i perf.data -o perf.jit.data
Report
sudo perf report -i perf.jit.data -F+period,srcline
* Adds support for flags datatype
This commit adds support for `FlagsDatatype`. In WASI, flags are
represented as bitfields/bitflags, therefore, it is important
for the type to have bitwise operations implemented, and some
way of checking whether the current set of flags contains some
other set (i.e., they intersect). Thus, this commit automatically
derives `BitAnd`, etc. for the derived flags datatype. It also
automatically provides an `ALL_FLAGS` value which corresponds to
a bitwise-or of all flag values present and is provided for
convenience.
* Simplify read_from_guest
In preparation for landing `string` support in `wiggle`, I've
revisited `GuestArray` and the deref mechanics, and decided to
scrap the current approach in favour of the previous. Namely, for
`T: GuestTypeCopy` we provide `GuestArray::as_ref` which then can
be derefed directly to `&[T]` since the guest and host types have
matching representation, and for other types (thinking here of
our infamous arrays of pointers), I've instead added a way to
iterate over the pointers. Then, it is up to the `wiggle`'s client
to know whether they can deref whatever the pointer stored in array
is pointing at.
* Add array generation to wiggle-generate crate
This commit:
* adds array generation to `wiggle-generate` crate which implies
that we can now generate arrays from `witx` files
* introduces two test interface functions `foo::reduce_excuses` and
`foo::populate_excuses`, and adds matching prop-tests
* adds an out-of-boundary check to `HostMemory::mem_area_strat` since
now, given we're generating arrays for testing with an arbitrary
but bounded number of elements, it is possible to violate the boundary
* refactors `Region::extend` to a new signature `extend(times: u32)`
which multiplies the current pointer `len` by `times`
* fixes bug in `GuestArray::as_ref` and `GuestArrayMut::as_ref_mut` methods
where we were not validating the first element (we always started the
validation from the second element)
* Fix generation of arrays in witx
This commit fixes how `arrays` are auto-generated from `witx` files.
In particular, the changes include:
* Since by design every `array` in `witx` represents an immutable
slab of memory, we will only ever operate on `GuestArray` in which
case I've gone ahead and removed `GuestArrayMut` so as to unclutter
the code somewhat. If we find ourselves in need for it in the future,
I reckon it will be better to write it from scratch (since the codebase
will inevitably evolve by then considerably) rather than maintaining an
unused implementation.
* I've rewritten `GuestArrayRef<T>` to be a wrapper for `Vec<GuestRef<T>>`.
Also, `GuestArray::as_ref` now borrows each underlying "element" of the
array one-by-one rather than borrowing the entire chunk of memory at once.
This change is motivated by the inability to coerce type parameter `T` in
`GuestArray<T>` in more complicated cases such as arrays of guest pointers
`GuestPtr<T>` to `*const T` for reuse in `std::slice::from_raw_parts` call.
(In general, the size of Wasm32 pointer is 4 bytes, while
```
std::mem::size_of::<T>() == std::mem::size_of::<GuestPtr<S>>() == 16
```
which is problematic; i.e., I can't see how I could properly extract guest
pointers from slices of 4 bytes and at the same time not allocate.)
* I've augmented fuzz tests by (re-)defining two `array` types:
```
(typename $const_excuse_array (array (@witx const_pointer $excuse)))
(typename $excuse_array (array (@witx pointer $excuse)))
```
This should hopefully emulate and test the `iovec` and `ciovec` arrays
present in WASI spec.