Commit Graph

1563 Commits

Author SHA1 Message Date
Nick Fitzgerald
2a32567871 Merge pull request #2821 from alexcrichton/faster-vmoffsets
Precompute fields in `VMOffsets`
2021-04-08 14:17:11 -07:00
Alex Crichton
18dd82ba7d Improve signature lookup happening during instantiation (#2818)
This commit is intended to be a perf improvement for instantiation of
modules with lots of functions. Previously the `lookup_shared_signature`
callback was showing up quite high in profiles as part of instantiation.

As some background, this callback is used to translate from a module's
`SignatureIndex` to a `VMSharedSignatureIndex` which the instance
stores. This callback is called for two reasons, one is to translate all
of the module's own types into `VMSharedSignatureIndex` for the purposes
of `call_indirect` (the translation of that loads from this table to
compare indices). The second reason is that a `VMCallerCheckedAnyfunc`
is prepared for all functions and this embeds a `VMSharedSignatureIndex`
inside of it.

The slow part today is that the lookup callback was called
once-per-function and each lookup involved hashing a full
`WasmFuncType`. Albeit our hash algorithm is still Rust's default
SipHash algorithm which is quite slow, but we also shouldn't need to
re-hash each signature if we see it multiple times anyway.

The fix applied in this commit is to change this lookup callback to an
`enum` where one variant is that there's a table to lookup from. This
table is a `PrimaryMap` which means that lookup is quite fast. The only
thing we need to do is to prepare the table ahead of time. Currently
this happens on the instantiation path because in my measurments the
creation of the table is quite fast compared to the rest of
instantiation. If this becomes an issue, though, we can look into
creating the table as part of `SigRegistry::register_module` and caching
it somewhere (I'm not entirely sure where but I'm sure we can figure it
out).

There's in generally not a ton of efficiency around the `SigRegistry`
type. I'm hoping though that this fixes the next-lowest-hanging-fruit in
terms of performance without complicating the implementation too much. I
tried a few variants and this change seemed like the best balance
between simplicity and still a nice performance gain.

Locally I measured an improvement in instantiation time for a large-ish
module by reducing the time from ~3ms to ~2.6ms per instance.
2021-04-08 15:04:18 -05:00
Alex Crichton
c91e14d83f Precompute fields in VMOffsets
This commit updates the implementation of `VMOffsets` to frontload all
checked arithmetic on construction of the `VMOffsets` which allows
eliding all checked arithmetic when accessing the fields of `VMOffsets`.
For testing and such this adds a new constructor as well from a new
`VMOffsetsFields` structure which is a clone of the old definition.

This should help speed up some profile hot spots I've been seeing where
with all the checked arithmetic on field sizes this was slowing down the
various accessors during instantiation (which uses `VMOffsets` to
initialize various fields of the `VMContext`).
2021-04-08 12:46:17 -07:00
Alex Crichton
c77ea0c5c7 Add some more #[inline] annotations for trivial functions (#2817)
Looking at some profiles these or their related functions were all
showing up, so this commit adds `#[inline]` to allow cross-crate
inlining by default.
2021-04-08 12:23:54 -05:00
Alex Crichton
5c4c03d278 Don't hash for the cache if it's disabled (#2816)
This fixes an issue where even if the wasmtime cache was disabled we're
still calculating the sha256 of modules for the hash key. This hash
was then simply discarded if the cache was disabled!
2021-04-08 11:48:24 -05:00
Peter Huene
2ca97ed7e4 Merge pull request #2814 from fitzgen/inline-vm-offsets
wasmtime-environ: Mark all VM offset functions as `#[inline]`
2021-04-07 18:16:29 -07:00
Peter Huene
45a500701f Merge pull request #2811 from peterhuene/improve-store-registration
Refactor store frame information.
2021-04-07 18:16:10 -07:00
Peter Huene
ad9fa11d48 Code review feedback.
* Remove `once-cell` dependency.
* Remove function address `BTreeMap` from `CompiledModule` in favor of binary
  searching finished functions directly.
* Use `with_capacity` when populating `CompiledModule` finished functions and
  trampolines.
2021-04-07 16:37:04 -07:00
Nick Fitzgerald
ed31f28158 wasmtime-environ: Mark all VM offset functions as #[inline]
Otherwise they won't get inlined across crates unless we enable LTO, and much of
the usage of these function is across crates (eg from the `wasmtime-runtime`
crate).
2021-04-07 16:17:26 -07:00
Peter Huene
875cb92cf0 Refactor store frame information.
This commit refactors the store frame information to eliminate the copying of
data out from `CompiledModule`.

It also moves the population of a `BTreeMap` out of the frame information and
into `CompiledModule` where it is only ever calculated once rather than at
every new module instantiation into a `Store`. The map is also lazy-initialized
so the cost of populating the map is incurred only when a trap occurs.

This should help improve instantiation time of modules with a large number of
functions and functions with lots of instructions.
2021-04-07 12:47:04 -07:00
Alex Crichton
195bf0e29a Fully support multiple returns in Wasmtime (#2806)
* Fully support multiple returns in Wasmtime

For quite some time now Wasmtime has "supported" multiple return values,
but only in the mose bare bones ways. Up until recently you couldn't get
a typed version of functions with multiple return values, and never have
you been able to use `Func::wrap` with functions that return multiple
values. Even recently where `Func::typed` can call functions that return
multiple values it uses a double-indirection by calling a trampoline
which calls the real function.

The underlying reason for this lack of support is that cranelift's ABI
for returning multiple values is not possible to write in Rust. For
example if a wasm function returns two `i32` values there is no Rust (or
C!) function you can write to correspond to that. This commit, however
fixes that.

This commit adds two new ABIs to Cranelift: `WasmtimeSystemV` and
`WasmtimeFastcall`. The intention is that these Wasmtime-specific ABIs
match their corresponding ABI (e.g. `SystemV` or `WindowsFastcall`) for
everything *except* how multiple values are returned. For multiple
return values we simply define our own version of the ABI which Wasmtime
implements, which is that for N return values the first is returned as
if the function only returned that and the latter N-1 return values are
returned via an out-ptr that's the last parameter to the function.

These custom ABIs provides the ability for Wasmtime to bind these in
Rust meaning that `Func::wrap` can now wrap functions that return
multiple values and `Func::typed` no longer uses trampolines when
calling functions that return multiple values. Although there's lots of
internal changes there's no actual changes in the API surface area of
Wasmtime, just a few more impls of more public traits which means that
more types are supported in more places!

Another change made with this PR is a consolidation of how the ABI of
each function in a wasm module is selected. The native `SystemV` ABI,
for example, is more efficient at returning multiple values than the
wasmtime version of the ABI (since more things are in more registers).
To continue to take advantage of this Wasmtime will now classify some
functions in a wasm module with the "fast" ABI. Only functions that are
not reachable externally from the module are classified with the fast
ABI (e.g. those not exported, used in tables, or used with `ref.func`).
This should enable purely internal functions of modules to have a faster
calling convention than those which might be exposed to Wasmtime itself.

Closes #1178

* Tweak some names and add docs

* "fix" lightbeam compile

* Fix TODO with dummy environ

* Unwind info is a property of the target, not the ABI

* Remove lightbeam unused imports

* Attempt to fix arm64

* Document new ABIs aren't stable

* Fix filetests to use the right target

* Don't always do 64-bit stores with cranelift

This was overwriting upper bits when 32-bit registers were being stored
into return values, so fix the code inline to do a sized store instead
of one-size-fits-all store.

* At least get tests passing on the old backend

* Fix a typo

* Add some filetests with mixed abi calls

* Get `multi` example working

* Fix doctests on old x86 backend

* Add a mixture of wasmtime/system_v tests
2021-04-07 12:34:26 -05:00
Benjamin Bouvier
7588565078 Tweaks some tests for Mac aarch64
- some tests don't pass because of bad interactions with the system's
libunwind; ignore them for now.
- the page size on mac aarch64 is 16K, not 4K; tweak some tests which
were expecting 4K or multiples of 4K pages to use a multiple of host page size
instead.
- a cranelift-native test needed an update for the new calling convention.
2021-04-07 14:54:50 +02:00
Chris Fallin
6bec13da04 Bump versions: Wasmtime to 0.26.0, Cranelift to 0.73.0. 2021-04-05 10:48:42 -07:00
Chris Fallin
8d78212a15 Merge pull request #2718 from cfallin/new-backend
Switch default to new x86_64 backend.
2021-04-05 09:38:08 -07:00
Alex Crichton
04bf6e5bbb Move some scopes around to fix a leak on raising a trap (#2803)
Some recent refactorings accidentally had a local `Store` on the stack
when a longjmp was initiated, bypassing its destructor and causing
`Store` to leak.

Closes #2802
2021-04-05 10:29:18 -05:00
Peter Huene
37bb7af454 Fix incorrect range in ininitialize_instance.
This commit fixes a bug where the wrong destination range was used when copying
data from the module's memory initialization upon instance initialization.

This affects the on-demand allocator only when using the `uffd` feature on
Linux and when the Wasm page being initialized is not the last in the module's
initial pages.

Fixes #2784.
2021-04-02 16:27:22 -07:00
Chris Fallin
cb48ea406e Switch default to new x86_64 backend.
This PR switches the default backend on x86, for both the
`cranelift-codegen` crate and for Wasmtime, to the new
(`MachInst`-style, `VCode`-based) backend that has been under
development and testing for some time now.

The old backend is still available by default in builds with the
`old-x86-backend` feature, or by requesting `BackendVariant::Legacy`
from the appropriate APIs.

As part of that switch, it adds some more runtime-configurable plumbing
to the testing infrastructure so that tests can be run using the
appropriate backend. `clif-util test` is now capable of parsing a
backend selector option from filetests and instantiating the correct
backend.

CI has been updated so that the old x86 backend continues to run its
tests, just as we used to run the new x64 backend separately.

At some point, we will remove the old x86 backend entirely, once we are
satisfied that the new backend has not caused any unforeseen issues and
we do not need to revert.
2021-04-02 11:35:53 -07:00
Peter Huene
0ddfe97a09 Change how flags are stored in serialized modules.
This commit changes how both the shared flags and ISA flags are stored in the
serialized module to detect incompatibilities when a serialized module is
instantiated.

It improves the error reporting when a compiled module has mismatched shared
flags.
2021-04-01 21:39:57 -07:00
Peter Huene
4ad0099da4 Update wat crate.
Update the `wat` crate to latest version and use `Error::set_path` in
`Module::from_file` to properly record the path associated with errors.
2021-04-01 20:11:26 -07:00
Peter Huene
3da03bcfcf Code review feedback.
* Expand doc comment on `Engine::precompile_module`.
* Add FIXME comment regarding a future ISA flag compatibility check before
  doing a JIT from `Module::from_binary`.
* Remove no-longer-needed CLI groups from the `compile` command.
2021-04-01 19:38:20 -07:00
Peter Huene
d1313b1291 Code review feedback.
* Move `Module::compile` to `Engine::precompile_module`.
* Remove `Module::deserialize` method.
* Make `Module::serialize` the same format as `Engine::precompile_module`.
* Make `Engine::precompile_module` return a `Vec<u8>`.
* Move the remaining serialization-related code to `serialization.rs`.
2021-04-01 19:38:19 -07:00
Peter Huene
abf3bf29f9 Add a wasmtime settings command to print Cranelift settings.
This commit adds the `wasmtime settings` command to print out available
Cranelift settings for a target (defaults to the host).

The compile command has been updated to remove the Cranelift ISA options in
favor of encouraging users to use `wasmtime settings` to discover what settings
are available.  This will reduce the maintenance cost for syncing the compile
command with Cranelift ISA flags.
2021-04-01 19:38:19 -07:00
Peter Huene
a474524d3b Code review feedback.
* Removed `Config::cranelift_clear_cpu_flags`.
* Renamed `Config::cranelift_other_flag` to `Config::cranelift::flag_set`.
* Renamed `--cranelift-flag` to `--cranelift-set`.
* Renamed `--cranelift-preset` to `--cranelift-enable`.
2021-04-01 19:38:19 -07:00
Peter Huene
1ce2a87149 Code review feedback.
* Remove `Config::for_target` in favor of setter `Config::target`.
* Remove explicit setting of Cranelift flags in `Config::new` in favor of
  calling the `Config` methods that do the same thing.
* Serialize the package version independently of the data when serializing a
  module.
* Use struct deconstructing in module serialization to ensure tunables and
  features aren't missed.
* Move common log initialization in the CLI into `CommonOptions`.
2021-04-01 19:38:19 -07:00
Peter Huene
273597903b Fix spelling error. 2021-04-01 19:38:18 -07:00
Peter Huene
7e02940c72 Add Wasmtime to AOT header.
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
2021-04-01 19:38:18 -07:00
Peter Huene
29d366db7b Add a compile command to Wasmtime.
This commit adds a `compile` command to the Wasmtime CLI.

The command can be used to Ahead-Of-Time (AOT) compile WebAssembly modules.

With the `all-arch` feature enabled, AOT compilation can be performed for
non-native architectures (i.e. cross-compilation).

The `Module::compile` method has been added to perform AOT compilation.

A few of the CLI flags relating to "on by default" Wasm features have been
changed to be "--disable-XYZ" flags.

A simple example of using the `wasmtime compile` command:

```text
$ wasmtime compile input.wasm
$ wasmtime input.cwasm
```
2021-04-01 19:38:18 -07:00
Alex Crichton
90aa5cf49f Daily update of wasm-smith (#2798)
Because apparently it's daily now!
2021-04-01 15:05:38 -05:00
Pat Hickey
0508394c62 Revert "wiggle: generate a span that is present at all levels"
This reverts commit 0466f47cb4.
2021-04-01 09:33:37 -07:00
Alex Crichton
dfffc69150 Update wasm-smith again (#2794)
More fuzz tweaks!
2021-03-31 15:39:37 -05:00
Alex Crichton
6748dfa43a Disable module linking in spectest fuzzing
Module linking implicitly enables multiple tables but that isn't
supported by the spec tests today.
2021-03-31 07:20:22 -07:00
Nick Fitzgerald
27ce383306 Merge pull request #2792 from alexcrichton/update-wasm-smith
Update wasm-smith dependency
2021-03-30 10:33:11 -07:00
Alex Crichton
e0440eebb7 Update wasm-smith dependency
Brings in a fuzzing bug fix!
2021-03-30 07:13:10 -07:00
Alex Crichton
a301202b7d Remove the type-driven ability for duplicates in a Linker (#2789)
When `Linker` was first created it was attempted to be created with the
ability to instantiate any wasm modules, including those with duplicate
import strings of different types. In an effort to support this a
`Linker` supports defining the same names twice so long as they're
defined with differently-typed values.

This ended up causing wast testsuite failures module linking is enabled,
however, because the wrong error message is returned. While it would be
possible to fix this there's already the possibility for confusing error
messages today due to the `Linker` trying to take on this type-level
complexity. In a way this is yet-another type checker for wasm imports,
but sort of a bad one because it only supports things like
globals/functions, and otherwise you can only define one `Memory`, for
example, with a particular name.

This commit completely removes this feature from `Linker` to simplify
the implementation and make error messages more straightforward. This
means that any error message coming from a `Linker` is purely "this
thing wasn't defined" rather than a hybrid of "maybe the types didn't
match?". I think this also better aligns with the direction that we see
conventional wasm modules going which is that duplicate imports are not
ever present.
2021-03-29 17:26:02 -05:00
Pat Hickey
e38166ac3f wiggle::async_trait is defined as async_trait::async_trait(?Send)
async methods used by wiggle currently need to Not have the Send
constraint, so rather than make all use sites pass the argument
to the re-exported async_trait macro, define a new macro that
applies the argument.
2021-03-29 10:04:42 -07:00
Alex Crichton
b1a3c9047f Actually make spectest fuzzing deterministic
Turns out #2106 missed the actual sorting operation. Silly me!
2021-03-29 09:12:16 -07:00
Pat Hickey
0a255c19de Merge pull request #2782 from bytecodealliance/pch/wiggle_tracing_span_fix
wiggle: generate a span that is present at all levels
2021-03-28 15:04:33 -07:00
Pat Hickey
3c00440b0e Merge pull request #2785 from bytecodealliance/pch/bugfix_wiggle_wasmtime_async
wiggle-wasmtime: use fully qualified Rc, RefCell in expansion
2021-03-28 15:03:42 -07:00
Pat Hickey
3abc29e279 Merge pull request #2776 from bytecodealliance/pch/wasmtime_wasi_usability
`wasmtime-wasi` usability: re-exports of common siblings
2021-03-26 17:36:44 -07:00
Pat Hickey
8da3de6756 wiggle-wasmtime: use fully qualified std::rc::Rc<std::cell::RefCell<>> in expansion 2021-03-26 17:21:51 -07:00
Pat Hickey
0466f47cb4 wiggle: generate a span that is present at all levels
The code I wrote here prior was incorrect: a span is present at the
level specified and below; previously I thought it was present at the
level specified and above. So, previously, a TRACE-level event inside
this span would be associated with the module and function name provided
here. Now all events inside this span should be associated with it.
2021-03-26 14:25:10 -07:00
Alex Crichton
550c774c1d fuzz: Allow incompatible import types in instantiation (#2778)
Yesterday fuzzing was switched to using a `Linker` to improve coverage
when using module linking since we can fake instance imports with
definitions of each individual item. Using a `Linker`, however, means
that we can't necessarily instantiate all modules, such as

    (module
      (import "" "" (memory (;0;) 0 1))
      (import "" "" (memory (;1;) 2)))

As a result this just allows these sorts of "incompatible import type"
errors when fuzzing to not trigger crashes.
2021-03-26 14:38:34 -05:00
Alex Crichton
7d8931c517 Compile fewer trampolines with module linking (#2774)
Previously each module in a module-linking-using-module would compile
all the trampolines for all signatures for all modules. In forest-like
situations with lots of modules this would cause quite a few trampolines
to get compiled. The original intention was to have one global list of
trampolines for all modules in the module-linking graph that they could
all share. With the current design of module linking, however, the
intention is for modules to be relatively isolated from one another
which would make achieving this difficult.

In lieu of total sharing (which would be good for the global scope
anyway but we also don't do that right now) this commit implements an
alternative strategy where each module simply compiles its own
trampolines that it itself can reach. This should mean that
module-linking modules behave more similarly to standalone modules in
terms of trampoline duplication. If we ever do global trampoline
deduplication we can likely batch this all together into one, but for
now this should fix the performance issues seen in fuzzing.

Closes #2525
2021-03-25 19:11:02 -05:00
Pat Hickey
af7030197d wasmtime-cli: drop direct dep on cap_std by using re-export 2021-03-25 17:05:04 -07:00
Pat Hickey
07245a8763 wasi-cap-std-sync: re-export Dir while we're at it 2021-03-25 17:05:02 -07:00
Pat Hickey
183ee9d6d8 wasmtime cli: use wasmtime_wasi's re-exports more deliberately
this drops the direct dep on wasi-cap-std-sync and wasi-common.
2021-03-25 17:04:10 -07:00
Pat Hickey
19a802549f wasmtime-wasi: re-export wasi-cap-std-sync 2021-03-25 17:04:10 -07:00
Alex Crichton
211731b876 Update wasm-tools crates (#2773)
Brings in some fuzzing-related bug-fixes
2021-03-25 18:44:31 -05:00
Alex Crichton
654156714c Deduplicate function signatures in wasm modules (#2772)
Currently wasmtime will generate a `SignatureIndex`-per-type in the
module itself, even if the module itself declares the same type multiple
times. To make matters worse if the same type is declared across
multiple modules used in a module-linking-using-module then the
signature will be recorded each time it's declared.

This commit adds a simple map to module translation to deduplicate these
function types. This should improve the performance of module-linking
graphs where the same function type may be declared in a number of
modules. For modules that don't use module linking this adds an extra
map that's not used too often, but the time spent managing it should be
dwarfed by other compile tasks.
2021-03-25 18:44:22 -05:00
Alex Crichton
516a97b3f3 A few more small fuzzing fixes (#2770)
* Increase allowances for values when fuzzing

The wasm-smith limits for generating modules are a bit higher than what
we specify, so sync those up to avoid getting too many false positives
with limits getting blown.

* Ensure fuzzing `*.wat` files are in sync

I keep looking at `*.wat` files that are actually stale, so remove stale
files if we write out a `*.wasm` file and can't disassemble it.

* Enable shadowing in dummy_linker

Fixes an issues where the same name is imported twice and we generated
two values for that. We don't mind the error here, we just want to
ignore the shadowing errors.
2021-03-25 18:44:04 -05:00