a2d356d45ebb1465399f000c047db11d0b7557ee
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9b896d2a70 |
Resolve libcall relocations for older CPUs (#5567)
* Resolve libcall relocations for older CPUs Long ago Wasmtime used to have logic for resolving relocations post-compilation for libcalls which I ended up removing during refactorings last year. As #5563 points out, however, it's possible to get Wasmtime to panic by disabling SSE features which forces Cranelift to use libcalls for some floating-point operations instead. Note that this also requires disabling SIMD because SIMD support has a baseline of SSE 4.2. This commit pulls back the old implementations of various libcalls and reimplements logic necessary to have them work on CPUs without SSE 4.2 Closes #5563 * Fix log message in `wast` support * Fix offset listed in relocations Be sure to factor in the offset of the function itself * Review comments |
||
|
|
08d44e3746 |
Change how wasm DWARF is inserted into artifacts (#5358)
This commit fixes a bug with components by changing how DWARF information from a wasm binary is copied over to the final compiled artifact. Note that this is not the Wasmtime-generated DWARF but rather the native wasm DWARF itself used in backtraces. Previously the wasm dwarf was inserted into sections `.*.wasm` where `*` was `debug_info`, `debug_str`, etc -- one per `gimli::SectionId` as found in the original wasm module. This does not work with components, however, where modules did not correctly separate their debug information into separate sections or otherwise disambiguate. The fix in this commit is to instead smash all the debug information together into one large section and store offsets into that giant section. This is similar to the `name`-section scraping or the trap metadata section where one section contains all the data for all the modules in a component. This simplifies the object file parsing by only looking for one section name and doesn't add all that much complexity to serializing and looking up dwarf information as well. |
||
|
|
cd53bed898 |
Implement AOT compilation for components (#5160)
* Pull `Module` out of `ModuleTextBuilder` This commit is the first in what will likely be a number towards preparing for serializing a compiled component to bytes, a precompiled artifact. To that end my rough plan is to merge all of the compiled artifacts for a component into one large object file instead of having lots of separate object files and lots of separate mmaps to manage. To that end I plan on eventually using `ModuleTextBuilder` to build one large text section for all core wasm modules and trampolines, meaning that `ModuleTextBuilder` is no longer specific to one module. I've extracted out functionality such as function name calculation as well as relocation resolving (now a closure passed in) in preparation for this. For now this just keeps tests passing, and the trajectory for this should become more clear over the following commits. * Remove component-specific object emission This commit removes the `ComponentCompiler::emit_obj` function in favor of `Compiler::emit_obj`, now renamed `append_code`. This involved significantly refactoring code emission to take a flat list of functions into `append_code` and the caller is responsible for weaving together various "families" of functions and un-weaving them afterwards. * Consolidate ELF parsing in `CodeMemory` This commit moves the ELF file parsing and section iteration from `CompiledModule` into `CodeMemory` so one location keeps track of section ranges and such. This is in preparation for sharing much of this code with components which needs all the same sections to get tracked but won't be using `CompiledModule`. A small side benefit from this is that the section parsing done in `CodeMemory` and `CompiledModule` is no longer duplicated. * Remove separately tracked traps in components Previously components would generate an "always trapping" function and the metadata around which pc was allowed to trap was handled manually for components. With recent refactorings the Wasmtime-standard trap section in object files is now being generated for components as well which means that can be reused instead of custom-tracking this metadata. This commit removes the manual tracking for the `always_trap` functions and plumbs the necessary bits around to make components look more like modules. * Remove a now-unnecessary `Arc` in `Module` Not expected to have any measurable impact on performance, but complexity-wise this should make it a bit easier to understand the internals since there's no longer any need to store this somewhere else than its owner's location. * Merge compilation artifacts of components This commit is a large refactoring of the component compilation process to produce a single artifact instead of multiple binary artifacts. The core wasm compilation process is refactored as well to share as much code as necessary with the component compilation process. This method of representing a compiled component necessitated a few medium-sized changes internally within Wasmtime: * A new data structure was created, `CodeObject`, which represents metadata about a single compiled artifact. This is then stored as an `Arc` within a component and a module. For `Module` this is always uniquely owned and represents a shuffling around of data from one owner to another. For a `Component`, however, this is shared amongst all loaded modules and the top-level component. * The "module registry" which is used for symbolicating backtraces and for trap information has been updated to account for a single region of loaded code holding possibly multiple modules. This involved adding a second-level `BTreeMap` for now. This will likely slow down instantiation slightly but if it poses an issue in the future this should be able to be represented with a more clever data structure. This commit additionally solves a number of longstanding issues with components such as compiling only one host-to-wasm trampoline per signature instead of possibly once-per-module. Additionally the `SignatureCollection` registration now happens once-per-component instead of once-per-module-within-a-component. * Fix compile errors from prior commits * Support AOT-compiling components This commit adds support for AOT-compiled components in the same manner as `Module`, specifically adding: * `Engine::precompile_component` * `Component::serialize` * `Component::deserialize` * `Component::deserialize_file` Internally the support for components looks quite similar to `Module`. All the prior commits to this made adding the support here (unsurprisingly) easy. Components are represented as a single object file as are modules, and the functions for each module are all piled into the same object file next to each other (as are areas such as data sections). Support was also added here to quickly differentiate compiled components vs compiled modules via the `e_flags` field in the ELF header. * Prevent serializing exported modules on components The current representation of a module within a component means that the implementation of `Module::serialize` will not work if the module is exported from a component. The reason for this is that `serialize` doesn't actually do anything and simply returns the underlying mmap as a list of bytes. The mmap, however, has `.wasmtime.info` describing component metadata as opposed to this module's metadata. While rewriting this section could be implemented it's not so easy to do so and is otherwise seen as not super important of a feature right now anyway. * Fix windows build * Fix an unused function warning * Update crates/environ/src/compilation.rs Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> |
||
|
|
87c33c2969 |
Remove wasmtime-environ's dependency on cranelift-codegen (#3199)
* Move `CompiledFunction` into wasmtime-cranelift This commit moves the `wasmtime_environ::CompiledFunction` type into the `wasmtime-cranelift` crate. This type has lots of Cranelift-specific pieces of compilation and doesn't need to be generated by all Wasmtime compilers. This replaces the usage in the `Compiler` trait with a `Box<Any>` type that each compiler can select. Each compiler must still produce a `FunctionInfo`, however, which is shared information we'll deserialize for each module. The `wasmtime-debug` crate is also folded into the `wasmtime-cranelift` crate as a result of this commit. One possibility was to move the `CompiledFunction` commit into its own crate and have `wasmtime-debug` depend on that, but since `wasmtime-debug` is Cranelift-specific at this time it didn't seem like it was too too necessary to keep it separate. If `wasmtime-debug` supports other backends in the future we can recreate a new crate, perhaps with it refactored to not depend on Cranelift. * Move wasmtime_environ::reference_type This now belongs in wasmtime-cranelift and nowhere else * Remove `Type` reexport in wasmtime-environ One less dependency on `cranelift-codegen`! * Remove `types` reexport from `wasmtime-environ` Less cranelift! * Remove `SourceLoc` from wasmtime-environ Change the `srcloc`, `start_srcloc`, and `end_srcloc` fields to a custom `FilePos` type instead of `ir::SourceLoc`. These are only used in a few places so there's not much to lose from an extra abstraction for these leaf use cases outside of cranelift. * Remove wasmtime-environ's dep on cranelift's `StackMap` This commit "clones" the `StackMap` data structure in to `wasmtime-environ` to have an independent representation that that chosen by Cranelift. This allows Wasmtime to decouple this runtime dependency of stack map information and let the two evolve independently, if necessary. An alternative would be to refactor cranelift's implementation into a separate crate and have wasmtime depend on that but it seemed a bit like overkill to do so and easier to clone just a few lines for this. * Define code offsets in wasmtime-environ with `u32` Don't use Cranelift's `binemit::CodeOffset` alias to define this field type since the `wasmtime-environ` crate will be losing the `cranelift-codegen` dependency soon. * Commit to using `cranelift-entity` in Wasmtime This commit removes the reexport of `cranelift-entity` from the `wasmtime-environ` crate and instead directly depends on the `cranelift-entity` crate in all referencing crates. The original reason for the reexport was to make cranelift version bumps easier since it's less versions to change, but nowadays we have a script to do that. Otherwise this encourages crates to use whatever they want from `cranelift-entity` since we'll always depend on the whole crate. It's expected that the `cranelift-entity` crate will continue to be a lean crate in dependencies and suitable for use at both runtime and compile time. Consequently there's no need to avoid its usage in Wasmtime at runtime, since "remove Cranelift at compile time" is primarily about the `cranelift-codegen` crate. * Remove most uses of `cranelift-codegen` in `wasmtime-environ` There's only one final use remaining, which is the reexport of `TrapCode`, which will get handled later. * Limit the glob-reexport of `cranelift_wasm` This commit removes the glob reexport of `cranelift-wasm` from the `wasmtime-environ` crate. This is intended to explicitly define what we're reexporting and is a transitionary step to curtail the amount of dependencies taken on `cranelift-wasm` throughout the codebase. For example some functions used by debuginfo mapping are better imported directly from the crate since they're Cranelift-specific. Note that this is intended to be a temporary state affairs, soon this reexport will be gone entirely. Additionally this commit reduces imports from `cranelift_wasm` and also primarily imports from `crate::wasm` within `wasmtime-environ` to get a better sense of what's imported from where and what will need to be shared. * Extract types from cranelift-wasm to cranelift-wasm-types This commit creates a new crate called `cranelift-wasm-types` and extracts type definitions from the `cranelift-wasm` crate into this new crate. The purpose of this crate is to be a shared definition of wasm types that can be shared both by compilers (like Cranelift) as well as wasm runtimes (e.g. Wasmtime). This new `cranelift-wasm-types` crate doesn't depend on `cranelift-codegen` and is the final step in severing the unconditional dependency from Wasmtime to `cranelift-codegen`. The final refactoring in this commit is to then reexport this crate from `wasmtime-environ`, delete the `cranelift-codegen` dependency, and then update all `use` paths to point to these new types. The main change of substance here is that the `TrapCode` enum is mirrored from Cranelift into this `cranelift-wasm-types` crate. While this unfortunately results in three definitions (one more which is non-exhaustive in Wasmtime itself) it's hopefully not too onerous and ideally something we can patch up in the future. * Get lightbeam compiling * Remove unnecessary dependency * Fix compile with uffd * Update publish script * Fix more uffd tests * Rename cranelift-wasm-types to wasmtime-types This reflects the purpose a bit more where it's types specifically intended for Wasmtime and its support. * Fix publish script |
||
|
|
e8aa7bb53b |
Reimplement how unwind information is stored (#3180)
* Reimplement how unwind information is stored This commit is a major refactoring of how unwind information is stored after compilation of a function has finished. Previously we would store the raw `UnwindInfo` as a result of compilation and this would get serialized/deserialized alongside the rest of the ELF object that compilation creates. Whenever functions were registered with `CodeMemory` this would also result in registering unwinding information dynamically at runtime, which in the case of Unix, for example, would dynamically created FDE/CIE entries on-the-fly. Eventually I'd like to support compiling Wasmtime without Cranelift, but this means that `UnwindInfo` wouldn't be easily available to decode into and create unwinding information from. To solve this I've changed the ELF object created to have the unwinding information encoded into it ahead-of-time so loading code into memory no longer needs to create unwinding tables. This change has two different implementations for Windows/Unix: * On Windows the implementation was much easier. The unwinding information on Windows is already stored after the function itself in the text section. This was actually slightly duplicated in object building and in code memory allocation. Now the object building continues to do the same, recording unwinding information after functions, and code memory no longer manually tracks this. Additionally Wasmtime will emit a special custom section in the object file with unwinding information which is the list of `RUNTIME_FUNCTION` structures that `RtlAddFunctionTable` expects. This means that the object file has all the information precompiled into it and registration at runtime is simply passing a few pointers around to the runtime. * Unix was a little bit more difficult than Windows. Today a `.eh_frame` section is created on-the-fly with offsets in FDEs specified as the absolute address that functions are loaded at. This absolute address hindered the ability to precompile the FDE into the object file itself. I've switched how addresses are encoded, though, to using `DW_EH_PE_pcrel` which means that FDE addresses are now specified relative to the FDE itself. This means that we can maintain a fixed offset between the `.eh_frame` loaded in memory and the beginning of code memory. When doing so this enables precompiling the `.eh_frame` section into the object file and at runtime when loading an object no further construction of unwinding information is needed. The overall result of this commit is that unwinding information is no longer stored in its cranelift-data-structure form on disk. This means that this unwinding information format is only present during compilation, which will make it that much easier to compile out cranelift in the future. This commit also significantly refactors `CodeMemory` since the way unwinding information is handled is not much different from before. Previously `CodeMemory` was suitable for incrementally adding more and more functions to it, but nowadays a `CodeMemory` either lives per module (in which case all functions are known up front) or it's created once-per-`Func::new` with two trampolines. In both cases we know all functions up front so the functionality of incrementally adding more and more segments is no longer needed. This commit removes the ability to add a function-at-a-time in `CodeMemory` and instead it can now only load objects in their entirety. A small helper function is added to build a small object file for trampolines in `Func::new` to handle allocation there. Finally, this commit also folds the `wasmtime-obj` crate directly into the `wasmtime-cranelift` crate and its builder structure to be more amenable to this strategy of managing unwinding tables. It is not intentional to have any real functional change as a result of this commit. This might accelerate loading a module from cache slightly since less work is needed to manage the unwinding information, but that's just a side benefit from the main goal of this commit which is to remove the dependence on cranelift unwinding information being available at runtime. * Remove isa reexport from wasmtime-environ * Trim down reexports of `cranelift-codegen` Remove everything non-essential so that only the bits which will need to be refactored out of cranelift remain. * Fix debug tests * Review comments |