wasmtime: Pass around more contexts instead of fields (#1486)

* wasmtime: Pass around more contexts instead of fields

This commit refactors some wasmtime internals to pass around more
context-style structures rather than individual fields of each
structure. The intention here is to make the addition of fields to a
structure easier to plumb throughout the internals of wasmtime.
Currently you need to edit lots of functions to pass lots of parameters,
but ideally after this you'll only need to edit one or two struct fields
and then relevant locations have access to the information already.

Updates in this commit are:

* `debug_info` configuration is now folded into `Tunables`. Additionally
  a `wasmtime::Config` now holds a `Tunables` directly and is passed
  into an internal `Compiler`. Eventually this should allow for direct
  configuration of the `Tunables` attributes from the `wasmtime` API,
  but no new configuration is exposed at this time.

* `ModuleTranslation` is now passed around as a whole rather than
  passing individual components to allow access to all the fields,
  including `Tunables`.

This was motivated by investigating what it would take to optionally
allow loops and such to get interrupted, but that sort of codegen
setting was currently relatively difficult to plumb all the way through
and now it's hoped to be largely just an addition to `Tunables`.

* Fix lightbeam compile
This commit is contained in:
Alex Crichton
2020-04-08 19:02:49 -05:00
committed by GitHub
parent e29c224f24
commit c4e90f729c
14 changed files with 112 additions and 180 deletions

View File

@@ -2,25 +2,22 @@
use crate::code_memory::CodeMemory;
use crate::instantiate::SetupError;
use crate::target_tunables::target_tunables;
use cranelift_codegen::ir::ExternalName;
use cranelift_codegen::ir::InstBuilder;
use cranelift_codegen::print_errors::pretty_error;
use cranelift_codegen::Context;
use cranelift_codegen::{binemit, ir};
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_wasm::ModuleTranslationState;
use std::collections::HashMap;
use std::convert::TryFrom;
use wasmtime_debug::{emit_debugsections_image, DebugInfoData};
use wasmtime_environ::entity::{EntityRef, PrimaryMap};
use wasmtime_environ::isa::{TargetFrontendConfig, TargetIsa};
use wasmtime_environ::wasm::{DefinedFuncIndex, DefinedMemoryIndex, MemoryIndex};
use wasmtime_environ::RelocationTarget;
use wasmtime_environ::{
CacheConfig, CompileError, CompiledFunction, CompiledFunctionUnwindInfo, Compiler as _C,
FunctionBodyData, Module, ModuleMemoryOffset, ModuleVmctxInfo, Relocation, Relocations, Traps,
Tunables, VMOffsets,
ModuleMemoryOffset, ModuleTranslation, ModuleVmctxInfo, Relocation, RelocationTarget,
Relocations, Traps, Tunables, VMOffsets,
};
use wasmtime_runtime::{
InstantiationError, SignatureRegistry, TrapRegistration, TrapRegistry, VMFunctionBody,
@@ -57,6 +54,7 @@ pub struct Compiler {
signatures: SignatureRegistry,
strategy: CompilationStrategy,
cache_config: CacheConfig,
tunables: Tunables,
}
impl Compiler {
@@ -65,6 +63,7 @@ impl Compiler {
isa: Box<dyn TargetIsa>,
strategy: CompilationStrategy,
cache_config: CacheConfig,
tunables: Tunables,
) -> Self {
Self {
isa,
@@ -73,6 +72,7 @@ impl Compiler {
strategy,
trap_registry: TrapRegistry::default(),
cache_config,
tunables,
}
}
}
@@ -95,16 +95,14 @@ impl Compiler {
}
/// Return the tunables in use by this engine.
pub fn tunables(&self) -> Tunables {
target_tunables(self.isa.triple())
pub fn tunables(&self) -> &Tunables {
&self.tunables
}
/// Compile the given function bodies.
pub(crate) fn compile<'data>(
&mut self,
module: &Module,
module_translation: &ModuleTranslationState,
function_body_inputs: PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
translation: &ModuleTranslation,
debug_data: Option<DebugInfoData>,
) -> Result<Compilation, SetupError> {
let (
@@ -120,22 +118,16 @@ impl Compiler {
// implementation.
CompilationStrategy::Auto | CompilationStrategy::Cranelift => {
wasmtime_environ::cranelift::Cranelift::compile_module(
module,
module_translation,
function_body_inputs,
translation,
&*self.isa,
debug_data.is_some(),
&self.cache_config,
)
}
#[cfg(feature = "lightbeam")]
CompilationStrategy::Lightbeam => {
wasmtime_environ::lightbeam::Lightbeam::compile_module(
module,
module_translation,
function_body_inputs,
translation,
&*self.isa,
debug_data.is_some(),
&self.cache_config,
)
}
@@ -164,7 +156,7 @@ impl Compiler {
let mut cx = FunctionBuilderContext::new();
let mut trampolines = HashMap::new();
let mut trampoline_relocations = HashMap::new();
for sig in module.local.signatures.values() {
for sig in translation.module.local.signatures.values() {
let index = self.signatures.register(sig);
if trampolines.contains_key(&index) {
continue;
@@ -190,7 +182,7 @@ impl Compiler {
// Translate debug info (DWARF) only if at least one function is present.
let dbg_image = if debug_data.is_some() && !finished_functions.is_empty() {
let target_config = self.isa.frontend_config();
let ofs = VMOffsets::new(target_config.pointer_bytes(), &module.local);
let ofs = VMOffsets::new(target_config.pointer_bytes(), &translation.module.local);
let mut funcs = Vec::new();
for (i, allocated) in finished_functions.into_iter() {

View File

@@ -63,7 +63,6 @@ impl<'data> RawCompiledModule<'data> {
fn new(
compiler: &mut Compiler,
data: &'data [u8],
debug_info: bool,
profiler: &dyn ProfilingAgent,
) -> Result<Self, SetupError> {
let environ = ModuleEnvironment::new(compiler.frontend_config(), compiler.tunables());
@@ -72,20 +71,13 @@ impl<'data> RawCompiledModule<'data> {
.translate(data)
.map_err(|error| SetupError::Compile(CompileError::Wasm(error)))?;
let debug_data = if debug_info {
let mut debug_data = None;
if compiler.tunables().debug_info {
// TODO Do we want to ignore invalid DWARF data?
let debug_data = read_debuginfo(&data)?;
Some(debug_data)
} else {
None
};
debug_data = Some(read_debuginfo(&data)?);
}
let compilation = compiler.compile(
&translation.module,
translation.module_translation.as_ref().unwrap(),
translation.function_body_inputs,
debug_data,
)?;
let compilation = compiler.compile(&translation, debug_data)?;
link_module(&translation.module, &compilation);
@@ -148,10 +140,9 @@ impl CompiledModule {
pub fn new<'data>(
compiler: &mut Compiler,
data: &'data [u8],
debug_info: bool,
profiler: &dyn ProfilingAgent,
) -> Result<Self, SetupError> {
let raw = RawCompiledModule::<'data>::new(compiler, data, debug_info, profiler)?;
let raw = RawCompiledModule::<'data>::new(compiler, data, profiler)?;
Ok(Self::from_parts(
raw.module,
@@ -282,12 +273,11 @@ pub unsafe fn instantiate(
compiler: &mut Compiler,
data: &[u8],
resolver: &mut dyn Resolver,
debug_info: bool,
is_bulk_memory: bool,
profiler: &dyn ProfilingAgent,
mem_creator: Option<&dyn RuntimeMemoryCreator>,
) -> Result<InstanceHandle, SetupError> {
let instance = CompiledModule::new(compiler, data, debug_info, profiler)?.instantiate(
let instance = CompiledModule::new(compiler, data, profiler)?.instantiate(
is_bulk_memory,
resolver,
compiler.signatures(),

View File

@@ -28,7 +28,6 @@ mod imports;
mod instantiate;
mod link;
mod resolver;
mod target_tunables;
pub mod native;
pub mod trampoline;
@@ -38,7 +37,6 @@ pub use crate::compiler::{make_trampoline, Compilation, CompilationStrategy, Com
pub use crate::instantiate::{instantiate, CompiledModule, SetupError};
pub use crate::link::link_module;
pub use crate::resolver::{NullResolver, Resolver};
pub use crate::target_tunables::target_tunables;
/// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

View File

@@ -1,22 +0,0 @@
use std::cmp::min;
use target_lexicon::{OperatingSystem, Triple};
use wasmtime_environ::Tunables;
/// Return a `Tunables` instance tuned for the given target platform.
pub fn target_tunables(triple: &Triple) -> Tunables {
let mut result = Tunables::default();
match triple.operating_system {
OperatingSystem::Windows => {
// For now, use a smaller footprint on Windows so that we don't
// don't outstrip the paging file.
// TODO: Make this configurable.
result.static_memory_bound = min(result.static_memory_bound, 0x100);
result.static_memory_offset_guard_size =
min(result.static_memory_offset_guard_size, 0x10000);
}
_ => {}
}
result
}