Commit Graph

2130 Commits

Author SHA1 Message Date
Alex Crichton
25d3fa4d7b Remove spec interpreter fuzz target temporarily (#3399)
This commit removes the `differential_spec` fuzz target for now,
although this removal is intended to be temporary. We have #3251 to
track re-enabling the spec interpreter in a way that it won't time out,
and additionally the spec interpreter is also failing to build with
ocaml on oss-fuzz so that will also need to be investigated when
re-enabling.
2021-09-30 13:09:19 -05:00
Chris Fallin
937b319e2d Merge pull request #3009 from bjorn3/bye_x86_backend
[RFC] Remove the old x86 backend
2021-09-30 09:20:14 -07:00
Dan Gohman
e5ebef1b94 Use empty() instead of NONE with rsix flags types.
`empty()` is provided by all `bitflags` types, so it's more idiomatic
than having `NONE` values.
2021-09-30 08:14:13 -07:00
Alex Crichton
49767c7379 Validate functions in parallel in Module::validate (#3394)
We already validate wasm functions in parallel when compiling a module,
but the same parallelism wasn't available to the `Module::validate` API.
This commit peforms a minor tweak to the validate-the-whole-module API
to validate all functions in parallel in the same manner that module
compilation does.
2021-09-30 09:09:12 -05:00
bjorn3
9e34df33b9 Remove the old x86 backend 2021-09-29 16:13:46 +02:00
Alex Crichton
1ee2af0098 Remove the lightbeam backend (#3390)
This commit removes the Lightbeam backend from Wasmtime as per [RFC 14].
This backend hasn't received maintenance in quite some time, and as [RFC
14] indicates this doesn't meet the threshold for keeping the code
in-tree, so this commit removes it.

A fast "baseline" compiler may still be added in the future. The
addition of such a backend should be in line with [RFC 14], though, with
the principles we now have for stable releases of Wasmtime. I'll close
out Lightbeam-related issues once this is merged.

[RFC 14]: https://github.com/bytecodealliance/rfcs/pull/14
2021-09-27 12:27:19 -05:00
Alex Crichton
bfdbd10a13 Add *_unchecked variants of Func APIs for the C API (#3350)
* Add `*_unchecked` variants of `Func` APIs for the C API

This commit is what is hopefully going to be my last installment within
the saga of optimizing function calls in/out of WebAssembly modules in
the C API. This is yet another alternative approach to #3345 (sorry) but
also contains everything necessary to make the C API fast. As in #3345
the general idea is just moving checks out of the call path in the same
style of `TypedFunc`.

This new strategy takes inspiration from previously learned attempts
effectively "just" exposes how we previously passed `*mut u128` through
trampolines for arguments/results. This storage format is formalized
through a new `ValRaw` union that is exposed from the `wasmtime` crate.
By doing this it made it relatively easy to expose two new APIs:

* `Func::new_unchecked`
* `Func::call_unchecked`

These are the same as their checked equivalents except that they're
`unsafe` and they work with `*mut ValRaw` rather than safe slices of
`Val`. Working with these eschews type checks and such and requires
callers/embedders to do the right thing.

These two new functions are then exposed via the C API with new
functions, enabling C to have a fast-path of calling/defining functions.
This fast path is akin to `Func::wrap` in Rust, although that API can't
be built in C due to C not having generics in the same way that Rust
has.

For some benchmarks, the benchmarks here are:

* `nop` - Call a wasm function from the host that does nothing and
  returns nothing.
* `i64` - Call a wasm function from the host, the wasm function calls a
  host function, and the host function returns an `i64` all the way out to
  the original caller.
* `many` - Call a wasm function from the host, the wasm calls
   host function with 5 `i32` parameters, and then an `i64` result is
   returned back to the original host
* `i64` host - just the overhead of the wasm calling the host, so the
  wasm calls the host function in a loop.
* `many` host - same as `i64` host, but calling the `many` host function.

All numbers in this table are in nanoseconds, and this is just one
measurement as well so there's bound to be some variation in the precise
numbers here.

| Name      | Rust | C (before) | C (after) |
|-----------|------|------------|-----------|
| nop       | 19   | 112        | 25        |
| i64       | 22   | 207        | 32        |
| many      | 27   | 189        | 34        |
| i64 host  | 2    | 38         | 5         |
| many host | 7    | 75         | 8         |

The main conclusion here is that the C API is significantly faster than
before when using the `*_unchecked` variants of APIs. The Rust
implementation is still the ceiling (or floor I guess?) for performance
The main reason that C is slower than Rust is that a little bit more has
to travel through memory where on the Rust side of things we can
monomorphize and inline a bit more to get rid of that. Overall though
the costs are way way down from where they were originally and I don't
plan on doing a whole lot more myself at this time. There's various
things we theoretically could do I've considered but implementation-wise
I think they'll be much more weighty.

* Tweak `wasmtime_externref_t` API comments
2021-09-24 14:05:45 -05:00
Alex Crichton
476d0bee96 Allow another trap mismatch with v8
If Wasmtime thinks a module stack-overflows and v8 says that it does
something else that's ok. This means that the limits on v8 and Wasmtime
are different which is expected and not something we want fuzz-bugs
about.
2021-09-23 08:48:11 -07:00
Olivier Lemasle
b5e289d319 Add license file to wasmtime-types
The LICENSE file is missing in wasmtime-types crate.
As per the Apache 2.0 license, the license file itself
should be redistributed with the source code.
2021-09-22 22:08:35 +02:00
Alex Crichton
1a5a2c7c5d Fix a merge conflict on main (#3378)
This commit fixes a "merge conflict" with #3319 being merged into
`main`, causing CI failures on merge.
2021-09-21 15:30:07 -05:00
Alex Crichton
bcf3544924 Optimize Func::call and its C API (#3319)
* Optimize `Func::call` and its C API

This commit is an alternative to #3298 which achieves effectively the
same goal of optimizing the `Func::call` API as well as its C API
sibling of `wasmtime_func_call`. The strategy taken here is different
than #3298 though where a new API isn't created, rather a small tweak to
an existing API is done. Specifically this commit handles the major
sources of slowness with `Func::call` with:

* Looking up the type of a function, to typecheck the arguments with and
  use to guide how the results should be loaded, no longer hits the
  rwlock in the `Engine` but instead each `Func` contains its own
  `FuncType`. This can be an unnecessary allocation for funcs not used
  with `Func::call`, so this is a downside of this implementation
  relative to #3298. A mitigating factor, though, is that instance
  exports are loaded lazily into the `Store` and in theory not too many
  funcs are active in the store as `Func` objects.

* Temporary storage is amortized with a long-lived `Vec` in the `Store`
  rather than allocating a new vector on each call. This is basically
  the same strategy as #3294 only applied to different types in
  different places. Specifically `wasmtime::Store` now retains a
  `Vec<u128>` for `Func::call`, and the C API retains a `Vec<Val>` for
  calling `Func::call`.

* Finally, an API breaking change is made to `Func::call` and its type
  signature (as well as `Func::call_async`). Instead of returning
  `Box<[Val]>` as it did before this function now takes a
  `results: &mut [Val]` parameter. This allows the caller to manage the
  allocation and we can amortize-remove it in `wasmtime_func_call` by
  using space after the parameters in the `Vec<Val>` we're passing in.
  This change is naturally a breaking change and we'll want to consider
  it carefully, but mitigating factors are that most embeddings are
  likely using `TypedFunc::call` instead and this signature taking a
  mutable slice better aligns with `Func::new` which receives a mutable
  slice for the results.

Overall this change, in the benchmark of "call a nop function from the C
API" is not quite as good as #3298. It's still a bit slower, on the
order of 15ns, because there's lots of capacity checks around vectors
and the type checks are slightly less optimized than before. Overall
though this is still significantly better than today because allocations
and the rwlock to acquire the type information are both avoided. I
personally feel that this change is the best to do because it has less
of an API impact than #3298.

* Rebase issues
2021-09-21 14:07:05 -05:00
Alex Crichton
38463d11ed Load generated trampolines into jitdump when profiling (#3344)
* Load generated trampolines into jitdump when profiling

This commit updates the jitdump profiler to generate JIT profiling
records for generated trampolines in a wasm module in addition to the
functions already in a module. It's also updated to learn about
trampolines generated via `Func::new` and friends. These trampolines
were all not previously registered meaning that stack traces with these
pc values would be confusing to see in the profile output. While the
names aren't the best it should at least be more clear than before if a
function is hot!

* Fix more builds
2021-09-21 13:05:31 -05:00
Alex Crichton
fc6328ae06 Temporarily disable SIMD fuzzing on CI (#3376)
We've got a large crop of fuzz-bugs from fuzzing with enabled-with-SIMD
on oss-fuzz but at this point the fuzz stats from oss-fuzz say that the
fuzzers like v8 are spending less than 50% of its time actually fuzzing
and presumably mostly hitting crashes and such. While we fix the other
issues this disables simd for fuzzing with v8 so we can try to see if we
can weed out other issues.
2021-09-20 14:17:19 -05:00
Advance Software
a8467d0824 Exports symbols to be shared with external GDB/JIT debugging interfac… (#3373)
* Exports symbols to be shared with external GDB/JIT debugging interface tools.
Windows O/S specific requirement.

* Moved comments into platform specific compiler directive sections.
2021-09-20 12:33:20 -05:00
Dan Gohman
87ff24a4aa Use __builtin_setjmp instead of sigsetjmp. (#3360)
* Use `__builtin_setjmp` instead of `sigsetjmp`.

Use [`__builtin_setjmp`] instead of `sigsetjmp`, as it is implemented in
the compiler, performed inline, and saves much less state. This speeds up
calls into wasm by about 8% on my machine.

[`__builtin_setjmp`]: https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html

* Add a comment confirming that 5 really is the documented size.

* Add a comment about callee-saved state and __builtin_setjmp.

* On clang on aarch64, use sigsetjmp.

* Fix a stray `#endif`.
2021-09-20 09:14:52 -05:00
Ulrich Weigand
51131a3acc Fix s390x regressions (#3330)
- Add relocation handling needed after PR #3275
- Fix incorrect handling of signed constants detected by PR #3056 test
- Fix LabelUse max pos/neg ranges; fix overflow in buffers.rs
- Disable fuzzing tests that require pre-built v8 binaries
- Disable cranelift test that depends on i128
- Temporarily disable memory64 tests
2021-09-20 09:12:36 -05:00
Dan Gohman
47490b4383 Use rsix to make system calls in Wasmtime. (#3355)
* Use rsix to make system calls in Wasmtime.

`rsix` is a system call wrapper crate that we use in `wasi-common`,
which can provide the following advantages in the rest of Wasmtime:

 - It eliminates some `unsafe` blocks in Wasmtime's code. There's
   still an `unsafe` block in the library, but this way, the `unsafe`
   is factored out and clearly scoped.

 - And, it makes error handling more consistent, factoring out code for
   checking return values and `io::Error::last_os_error()`, and code that
   does `errno::set_errno(0)`.

This doesn't cover *all* system calls; `rsix` doesn't implement
signal-handling APIs, and this doesn't cover calls made through `std` or
crates like `userfaultfd`, `rand`, and `region`.
2021-09-17 15:28:56 -07:00
Nick Fitzgerald
0d3153c16b Fix a warning about unnecessary mut in AutoAssertNoGc 2021-09-17 11:07:56 -07:00
Nick Fitzgerald
b32130d0aa Fix table_ops fuzz generator test's expected results 2021-09-17 11:07:56 -07:00
Nick Fitzgerald
72f38617ca Fix links between docs 2021-09-17 11:07:56 -07:00
Nick Fitzgerald
a1f4b46f64 Bump Wasmtime to version 0.30.0; cranelift to 0.77.0 2021-09-17 10:33:50 -07:00
Nick Fitzgerald
833c93b25c use public accessors, not private fields for WasmFuncType params/returns 2021-09-17 10:31:13 -07:00
Nick Fitzgerald
b39f087414 Merge pull request from GHSA-q879-9g95-56mx
Add an assertion that a `HostFunc`'s `store` agrees on engines
2021-09-17 10:29:35 -07:00
Nick Fitzgerald
398a73f0dd Merge pull request from GHSA-4873-36h9-wv49
Stop doing fuzzy search for stack maps
2021-09-17 10:28:50 -07:00
Nick Fitzgerald
101998733b Merge pull request from GHSA-v4cp-h94r-m7xf
Fix a use-after-free bug when passing `ExternRef`s to Wasm
2021-09-17 10:27:29 -07:00
Dan Gohman
e56312e61a Add "cargo:rerun-if-changed=build.rs" to some build.rs files.
Add "cargo:rerun-if-changed=build.rs" in some build.rs files to tell
cargo that it doesn't need to scan the whole package. See the
[Cargo docs] for more info.

[Cargo docs]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed
2021-09-16 11:52:21 -07:00
Pat Hickey
faa117cac4 Merge pull request #3349 from bytecodealliance/pch/limiter
add a hook to ResourceLimiter to detect memory grow failure
2021-09-15 18:04:31 -07:00
Pat Hickey
bb7f58d936 add a hook to ResourceLimiter to detect memory grow failure.
* allow the ResourceLimiter to reject a memory grow before the
memory's own maximum.
* add a hook so a ResourceLimiter can detect any reason that
a memory grow fails, including if the OS denies additional memory
* add tests for this new functionality. I only took the time to
test the OS denial on Linux, it should be possible on Mac OS
as well but I don't have a test setup. I have no idea how to
do this on windows.
2021-09-15 11:50:23 -07:00
Alex Crichton
b31a4ea16b Add Store::consume_fuel to manually consume fuel (#3352)
This can be useful for host functions that want to consume fuel to
reflect their relative cost. Additionally it's a relatively easy
addition to have and someone's asking for it!

Closes #3315
2021-09-15 13:10:11 -05:00
Alex Crichton
9db418cfd9 Improve linking-related error messages (#3353)
Include more contextual information about why the link failed related to
why the types didn't match.

Closes #3172
2021-09-15 11:42:45 -05:00
Nick Fitzgerald
d2ce1ac753 Fix a use-after-free bug when passing ExternRefs to Wasm
We _must not_ trigger a GC when moving refs from host code into
Wasm (e.g. returned from a host function or passed as arguments to a Wasm
function). After insertion into the table, this reference is no longer
rooted. If multiple references are being sent from the host into Wasm and we
allowed GCs during insertion, then the following events could happen:

* Reference A is inserted into the activations table. This does not trigger a
  GC, but does fill the table to capacity.

* The caller's reference to A is removed. Now the only reference to A is from
  the activations table.

* Reference B is inserted into the activations table. Because the table is at
  capacity, a GC is triggered.

* A is reclaimed because the only reference keeping it alive was the activation
  table's reference (it isn't inside any Wasm frames on the stack yet, so stack
  scanning and stack maps don't increment its reference count).

* We transfer control to Wasm, giving it A and B. Wasm uses A. That's a use
  after free.

To prevent uses after free, we cannot GC when moving refs into the
`VMExternRefActivationsTable` because we are passing them from the host to Wasm.

On the other hand, when we are *cloning* -- as opposed to moving -- refs from
the host to Wasm, then it is fine to GC while inserting into the activations
table, because the original referent that we are cloning from is still alive and
rooting the ref.
2021-09-14 14:23:42 -07:00
Alex Crichton
eb4089e212 Fix a typo 2021-09-14 14:09:14 -07:00
Alex Crichton
b759514124 Allow wasmtime/v8 to differ on errors slightly (#3348)
I'm not sure why when run repeatedly v8 has different limits on
call-stack-size but it's not particularly interesting to assert exact
matches here, so this should fix a fuzz-bug-failure found on oss-fuzz.
2021-09-14 10:40:24 -05:00
Dan Gohman
d1fce1e836 Modify the poll_oneoff_files test tolerate OS differences. (#3346)
Modify the `poll_oneoff_files` test to avoid assuming that `poll_oneoff`
returns all pending events, as it may sometimes return only a subset of
events. When multiple events are expected, use a loop, and loop until
all events have been recorded.
2021-09-13 14:59:50 -05:00
Nick Fitzgerald
ec4e48d4cb Stop doing fuzzy search for stack maps
The new backends will not emit a stack map for a safepoint if there are zero
live references. Our fuzzy search for stack maps, which was necessary for the
old backend, caused us to use the wrong stack map for some PCs which would in
turn cause us to treat arbitrary stack slots as reference types pointers.
2021-09-13 10:41:26 -07:00
Dan Gohman
4d86f0ca10 Update to cap-std 0.19.0 and rsix 0.22.4. (#3331)
This pulls in the s390x fix needed by #3330.

Also a small `rsix` API update; `PollFdVec` has been removed in favor of
just using `Vec<PollFd>`.
2021-09-11 12:28:30 -05:00
Dan Gohman
256e942aa0 Tidy up redundant use declarations. (#3333)
This is just a minor code cleanup.
2021-09-11 12:26:54 -05:00
Nick Fitzgerald
4b256ab968 Place unwind info directly after the text section, even when debug info is enabled
When debug info was enabled, we would put the debug info sections in between the
text section and the unwind info section. But the unwind info is encoded in a
position-independent manner (so that we don't need relocs for it) that relies on
it directly following the text section. The result of the misplacement was some
crashes inside the unwinder.
2021-09-09 13:39:30 -07:00
Nick Fitzgerald
0499cca2fa Name unwind info .eh_frame in the Wasmtime's compiled ELF artifact
We were previously using `_wasmtime_eh_frame` but there is no good reason to
add the prefix Wasmtime-specific prefix. Using the standard name allows for
better inspection with standard tools like `dwarfdump`.
2021-09-09 12:54:49 -07:00
Nick Fitzgerald
dd0bc3237e Do not write a DWARF section if it is empty
There is no point in writing an empty DWARF section, and this will make our ELF
files a tiny bit smaller.
2021-09-09 12:54:13 -07:00
Alex Crichton
e26b91e890 Remove unnecessary annotations on Module::get_export (#3318)
I think these were historically needed but nowadays not necessary!
2021-09-09 11:54:50 -07:00
Pat Hickey
bd19f43f84 rewrite Store::{entering,exiting}_native_code_hook into Store::call_hook (#3313)
which provides additional detail on what state transition is being made
2021-09-09 09:20:45 -05:00
Alex Crichton
bcb1dc90d6 Add an assertion that a HostFunc's store agrees on engines
This commit adds an assertion which was previously forgotten when
inserting a `HostFunc` into a `Store`. This can happen when a `Linker`
is defined with one engine but it's used to interoperate with a store
defined within a different engine.

A function contains type information that's only valid relative to the
engine that it was defined within. This means that if a function is used
within a different engine then type information may look valid when in
fact it is not. For example it's otherwise possible to insert a function
into an engine with one type and call it in a different engine with a
different type.

Similar to how `Store` misuse is a panic throughout `wasmtime`'s API
this commit also turns this behavior into panic, so there's no API
impact. Documentation has been updated accordingly to indicate that
various functions on `Linker` will panic if a `store` is provided that's
connected to a different `Engine`.
2021-09-08 14:42:02 -07:00
Alex Crichton
c73673559b Avoid vector allocations in wasm->host calls (#3294)
This commit improves the runtime support for wasm-to-host invocations
for functions created with `Func::new` or `wasmtime_func_new` in the C
API. Previously a `Vec` (sometimes a `SmallVec`) would be dynamically
allocated on each host call to store the arguments that are coming from
wasm and going to the host. In the case of the `wasmtime` crate we need
to decode the `u128`-stored values, and in the case of the C API we need
to decode the `Val` into the C API's `wasmtime_val_t`.

The technique used in this commit is to store a singular `Vec<T>` inside
the "store", be it the literal `Store<T>` or within the `T` in the case
of the C API, which can be reused across wasm->host calls. This means
that we're unlikely to actually perform dynamic memory allocation and
instead we should hit a faster path where the `Vec` always has enough
capacity.

Note that this is just a mild improvement for `Func::new`-based
functions. It's still the case that `Func::wrap` is much faster, but
unfortunately the C API doesn't have access to `Func::wrap`, so the main
motivation here is accelerating the C API.
2021-09-03 15:14:21 -05:00
Alex Crichton
ca3947911e Refactor the internals of Store<T> (#3291)
* Refactor the internals of `Store<T>`

This commit is an overdue refactoring and renaming of some internals of
the `Store` type in Wasmtime. The actual implementation of `Store<T>`
has evolved from the original implementation to the point where some of
the aspects of how things are structured no longer makes sense. There's
also always been a lot of unnecessary gymnastics when trying to get
access to various store pieces depending on where you are in `wasmtime`.

This refactoring aims to simplify all this and make the internals much
easier to read/write. The following changes were made:

* The `StoreOpaque<'_>` type is deleted, along with the `opaque()`
  method.

* The `StoreInnermost` type was renamed to `StoreOpaque`.
  `StoreOpaque<'_>` is dead. Long live `StoreOpaque`. This renaming
  and a few small tweaks means that this type now suffices for all
  consumers.

* The `AsContextMut` and `AsContext` traits are now implemented for
  `StoreInner<T>`.

These changes, while subtly small, help clean up a lot of the internals
of `wasmtime`. There's a lot less verbose `&mut
store.as_context_mut().opaque()` now. Additionally many methods can
simply start with `let store = store.as_context_mut().0;` and use things
internally. One of the nicer aspects of using references directly is
that the compiler automatically reborrows references as necessary
meaning there's lots of less manual reborrowing.

The main motivation for this change was actually somewhat roundabout
where I found that when `StoreOpaque<'_>` was being captured in closures
and iterators it's 3 pointers wide which is a lot of data to move
around. Now things capture over `&mut StoreOpaque` which is just one
nice and small pointer to move around. In any case though I've long
wanted to revisit the design of these internals to improve the
ergonomics. It's not expected that this change alone will really have
all that much impact on the performance of `wasmtime`.

Finally a doc comment was added to `store.rs` to try to explain all the
`Store`-related types since there are a nontrivial amount.

* Rustfmt
2021-09-03 13:55:18 -05:00
Alex Crichton
50ce19a4a4 Remove an indirect function call in Func::new (#3293)
This commit optimizes the runtime execution of `Func::new` by removing
an indirect function call that happens whenever a host function is
called. This indirection was generally done to prevent monomoprhizing a
lot into consumer code but the few extra functions this makes
monomorphic are fairly small, and in general wasm->host call performance
is pretty important.

While not a massive win this is expected to improve codegen, especially
because with the indirect call removed the compiler should now be able
to prove more often when a `Func::new` closure doesn't panic or return
an error.
2021-09-03 13:40:51 -05:00
Alex Crichton
c33700087d Align order of wasm types/values across Wasmtime (#3292)
Wasmtime has a few representations of `Val` and `ValType` across the
internal crates, the `wasmtime` crate, and the C API. These were
previously sometimes mentioned in different orders which means that
converting between the two took a little extra code than before. This
commit is a micro-optimization to align the types across the various
places we define these to help reduce the codegen burden when converting
between these types.

This is not expected to have a major impact on performance, rather it's
a small cleanup which should be easy-ish to preserve I've noticed while
staring at assembly.
2021-09-03 11:43:56 -05:00
Nick Fitzgerald
dd71acd7e3 Merge pull request #3281 from alexcrichton/small-opts
Some small optimizations for calling wasm functions
2021-09-02 15:06:42 -07:00
Pat Hickey
fa15adfdd0 Merge pull request #3271 from bytecodealliance/pch/flexible_ser_module_versioning
More flexible versioning for module serialization
2021-09-02 12:51:03 -07:00
Alex Crichton
37b9fc5333 Fix async build 2021-09-02 07:38:29 -07:00