From f4911924bc9778e80a08c2c601ec76b410e07352 Mon Sep 17 00:00:00 2001 From: Jef Date: Fri, 8 Feb 2019 11:59:31 +0100 Subject: [PATCH 1/5] Integrate lightbeam --- .gitmodules | 4 + Cargo.toml | 3 + lightbeam | 1 + spec_testsuite | 2 +- src/wasm2obj.rs | 4 +- wasmtime-environ/Cargo.toml | 1 + wasmtime-environ/src/compilation.rs | 62 ++++++++++-- wasmtime-environ/src/func_environ.rs | 136 ++++++++++++++++++++++++++- wasmtime-environ/src/lib.rs | 7 +- wasmtime-environ/src/lightbeam.rs | 51 ++++++++++ wasmtime-jit/Cargo.toml | 1 + wasmtime-jit/src/compiler.rs | 16 +++- 12 files changed, 274 insertions(+), 14 deletions(-) create mode 160000 lightbeam create mode 100644 wasmtime-environ/src/lightbeam.rs diff --git a/.gitmodules b/.gitmodules index 5e65dc7b8f8d..841205cbc97a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "spec_testsuite"] path = spec_testsuite url = https://github.com/WebAssembly/testsuite +[submodule "lightbeam"] + path = lightbeam + url = https://github.com/CraneStation/lightbeam.git + branch = master diff --git a/Cargo.toml b/Cargo.toml index e8fa5e9ac9ca..a20680395b42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,3 +41,6 @@ file-per-thread-logger = "0.1.1" wabt = "0.7" [workspace] + +[features] +lightbeam = ["wasmtime-environ/lightbeam", "wasmtime-jit/lightbeam"] diff --git a/lightbeam b/lightbeam new file mode 160000 index 000000000000..2a60d76bdc69 --- /dev/null +++ b/lightbeam @@ -0,0 +1 @@ +Subproject commit 2a60d76bdc69bee43de98f82d43a342eca2fee94 diff --git a/spec_testsuite b/spec_testsuite index 89cc463fa125..b2800641d6c6 160000 --- a/spec_testsuite +++ b/spec_testsuite @@ -1 +1 @@ -Subproject commit 89cc463fa1251449d7974086a34ef0dc100b1582 +Subproject commit b2800641d6c6b6a0c462f83e620843c414bea579 diff --git a/src/wasm2obj.rs b/src/wasm2obj.rs index c68ddb50b767..8b7b6de97f6c 100644 --- a/src/wasm2obj.rs +++ b/src/wasm2obj.rs @@ -49,7 +49,7 @@ use std::str; use std::str::FromStr; use target_lexicon::Triple; use wasmtime_debug::{emit_debugsections, read_debuginfo}; -use wasmtime_environ::{cranelift, ModuleEnvironment, Tunables}; +use wasmtime_environ::{Compiler, Cranelift, ModuleEnvironment, Tunables}; use wasmtime_obj::emit_module; const USAGE: &str = " @@ -159,7 +159,7 @@ fn handle_module( ) }; - let (compilation, relocations, address_transform) = cranelift::compile_module( + let (compilation, relocations, address_transform) = Cranelift::compile_module( &module, lazy_function_body_inputs, &*isa, diff --git a/wasmtime-environ/Cargo.toml b/wasmtime-environ/Cargo.toml index d7bd741e10ac..a130482a98d5 100644 --- a/wasmtime-environ/Cargo.toml +++ b/wasmtime-environ/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" cranelift-codegen = "0.30.0" cranelift-entity = "0.30.0" cranelift-wasm = "0.30.0" +lightbeam = { path = "../../lightbeam", optional = true } cast = { version = "0.2.2", default-features = false } failure = { version = "0.1.3", default-features = false } failure_derive = { version = "0.1.3", default-features = false } diff --git a/wasmtime-environ/src/compilation.rs b/wasmtime-environ/src/compilation.rs index d566051fef0a..dad710e958a2 100644 --- a/wasmtime-environ/src/compilation.rs +++ b/wasmtime-environ/src/compilation.rs @@ -1,25 +1,65 @@ //! A `Compilation` contains the compiled function bodies for a WebAssembly //! module. -use cranelift_codegen::binemit; -use cranelift_codegen::ir; -use cranelift_codegen::CodegenError; +use crate::module; +use cranelift_codegen::{binemit, ir, isa, CodegenError}; use cranelift_entity::PrimaryMap; use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError}; +use std::ops::Range; use std::vec::Vec; +type Functions = PrimaryMap>; + /// The result of compiling a WebAssembly module's functions. #[derive(Debug)] pub struct Compilation { /// Compiled machine code for the function bodies. - pub functions: PrimaryMap>, + functions: Functions, } impl Compilation { - /// Allocates the compilation result with the given function bodies. - pub fn new(functions: PrimaryMap>) -> Self { + /// Creates a compilation artifact from a contiguous function buffer and a set of ranges + pub fn new(functions: Functions) -> Self { Self { functions } } + + /// Allocates the compilation result with the given function bodies. + pub fn from_buffer(buffer: Vec, functions: impl IntoIterator>) -> Self { + Self::new(functions.into_iter().map(|range| buffer[range].to_vec()).collect()) + } + + /// Gets the bytes of a single function + pub fn get(&self, func: DefinedFuncIndex) -> &[u8] { + &self.functions[func] + } + + /// Gets the number of functions defined. + pub fn len(&self) -> usize { + self.functions.len() + } +} + +impl<'a> IntoIterator for &'a Compilation { + type IntoIter = Iter<'a>; + type Item = ::Item; + + fn into_iter(self) -> Self::IntoIter { + Iter { + iterator: self.functions.iter(), + } + } +} + +pub struct Iter<'a> { + iterator: <&'a Functions as IntoIterator>::IntoIter, +} + +impl<'a> Iterator for Iter<'a> { + type Item = &'a [u8]; + + fn next(&mut self) -> Option { + self.iterator.next().map(|(_, b)| &b[..]) + } } /// A record of a relocation to perform. @@ -95,3 +135,13 @@ pub struct FunctionAddressTransform { /// Function AddressTransforms collection. pub type AddressTransforms = PrimaryMap; + +/// An implementation of a compiler from parsed WebAssembly module to native code. +pub trait Compiler { + /// Compile a parsed module with the given `TargetIsa`. + fn compile_module<'data, 'module>( + module: &'module module::Module, + function_body_inputs: PrimaryMap, + isa: &dyn isa::TargetIsa, + ) -> Result<(Compilation, Relocations), CompileError>; +} diff --git a/wasmtime-environ/src/func_environ.rs b/wasmtime-environ/src/func_environ.rs index fefe07550161..57f55ab787e6 100644 --- a/wasmtime-environ/src/func_environ.rs +++ b/wasmtime-environ/src/func_environ.rs @@ -14,8 +14,8 @@ use cranelift_codegen::ir::{ use cranelift_codegen::isa::TargetFrontendConfig; use cranelift_entity::EntityRef; use cranelift_wasm::{ - self, FuncIndex, GlobalIndex, GlobalVariable, MemoryIndex, SignatureIndex, TableIndex, - WasmResult, + self, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex, + GlobalIndex, GlobalVariable, MemoryIndex, SignatureIndex, TableIndex, WasmResult, }; use std::vec::Vec; @@ -207,6 +207,138 @@ impl<'module_environment> FuncEnvironment<'module_environment> { } } +#[cfg(feature = "lightbeam")] +impl lightbeam::ModuleContext for FuncEnvironment<'_> { + type Signature = ir::Signature; + type GlobalType = ir::Type; + + fn func_index(&self, defined_func_index: u32) -> u32 { + self.module + .func_index(DefinedFuncIndex::from_u32(defined_func_index)) + .as_u32() + } + + fn defined_func_index(&self, func_index: u32) -> Option { + self.module + .defined_func_index(FuncIndex::from_u32(func_index)) + .map(|i| i.as_u32()) + } + + fn defined_global_index(&self, global_index: u32) -> Option { + self.module + .defined_global_index(GlobalIndex::from_u32(global_index)) + .map(|i| i.as_u32()) + } + + fn global_type(&self, global_index: u32) -> &Self::GlobalType { + &self.module.globals[GlobalIndex::from_u32(global_index)].ty + } + + fn func_type_index(&self, func_idx: u32) -> u32 { + self.module.functions[FuncIndex::from_u32(func_idx)].as_u32() + } + + fn signature(&self, index: u32) -> &Self::Signature { + &self.module.signatures[SignatureIndex::from_u32(index)] + } + + fn defined_table_index(&self, table_index: u32) -> Option { + self.module + .defined_table_index(TableIndex::from_u32(table_index)) + .map(|i| i.as_u32()) + } + + fn defined_memory_index(&self, memory_index: u32) -> Option { + self.module + .defined_memory_index(MemoryIndex::from_u32(memory_index)) + .map(|i| i.as_u32()) + } + + fn vmctx_vmfunction_import_body(&self, func_index: u32) -> u32 { + self.offsets + .vmctx_vmfunction_import_body(FuncIndex::from_u32(func_index)) + } + fn vmctx_vmfunction_import_vmctx(&self, func_index: u32) -> u32 { + self.offsets + .vmctx_vmfunction_import_vmctx(FuncIndex::from_u32(func_index)) + } + + fn vmctx_vmglobal_import_from(&self, global_index: u32) -> u32 { + self.offsets + .vmctx_vmglobal_import_from(GlobalIndex::from_u32(global_index)) + } + fn vmctx_vmglobal_definition(&self, defined_global_index: u32) -> u32 { + self.offsets + .vmctx_vmglobal_definition(DefinedGlobalIndex::from_u32(defined_global_index)) + } + fn vmctx_vmmemory_import_from(&self, memory_index: u32) -> u32 { + self.offsets + .vmctx_vmmemory_import_from(MemoryIndex::from_u32(memory_index)) + } + fn vmctx_vmmemory_definition(&self, defined_memory_index: u32) -> u32 { + self.offsets + .vmctx_vmmemory_definition(DefinedMemoryIndex::from_u32(defined_memory_index)) + } + fn vmctx_vmmemory_definition_base(&self, defined_memory_index: u32) -> u32 { + self.offsets + .vmctx_vmmemory_definition_base(DefinedMemoryIndex::from_u32(defined_memory_index)) + } + fn vmctx_vmmemory_definition_current_length(&self, defined_memory_index: u32) -> u32 { + self.offsets + .vmctx_vmmemory_definition_current_length(DefinedMemoryIndex::from_u32( + defined_memory_index, + )) + } + fn vmmemory_definition_base(&self) -> u8 { + self.offsets.vmmemory_definition_base() + } + fn vmmemory_definition_current_length(&self) -> u8 { + self.offsets.vmmemory_definition_current_length() + } + fn vmctx_vmtable_import_from(&self, table_index: u32) -> u32 { + self.offsets + .vmctx_vmtable_import_from(TableIndex::from_u32(table_index)) + } + fn vmctx_vmtable_definition(&self, defined_table_index: u32) -> u32 { + self.offsets + .vmctx_vmtable_definition(DefinedTableIndex::from_u32(defined_table_index)) + } + fn vmctx_vmtable_definition_base(&self, defined_table_index: u32) -> u32 { + self.offsets + .vmctx_vmtable_definition_base(DefinedTableIndex::from_u32(defined_table_index)) + } + fn vmctx_vmtable_definition_current_elements(&self, defined_table_index: u32) -> u32 { + self.offsets + .vmctx_vmtable_definition_current_elements(DefinedTableIndex::from_u32( + defined_table_index, + )) + } + fn vmtable_definition_base(&self) -> u8 { + self.offsets.vmtable_definition_base() + } + fn vmtable_definition_current_elements(&self) -> u8 { + self.offsets.vmtable_definition_current_elements() + } + fn vmcaller_checked_anyfunc_type_index(&self) -> u8 { + self.offsets.vmcaller_checked_anyfunc_type_index() + } + fn vmcaller_checked_anyfunc_func_ptr(&self) -> u8 { + self.offsets.vmcaller_checked_anyfunc_func_ptr() + } + fn vmcaller_checked_anyfunc_vmctx(&self) -> u8 { + self.offsets.vmcaller_checked_anyfunc_vmctx() + } + fn size_of_vmcaller_checked_anyfunc(&self) -> u8 { + self.offsets.size_of_vmcaller_checked_anyfunc() + } + fn vmctx_vmshared_signature_id(&self, signature_idx: u32) -> u32 { + self.offsets + .vmctx_vmshared_signature_id(SignatureIndex::from_u32(signature_idx)) + } + + // TODO: type of a global +} + impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> { fn target_config(&self) -> TargetFrontendConfig { self.target_config diff --git a/wasmtime-environ/src/lib.rs b/wasmtime-environ/src/lib.rs index e5cd6c664354..4da4b1482ad1 100644 --- a/wasmtime-environ/src/lib.rs +++ b/wasmtime-environ/src/lib.rs @@ -45,11 +45,16 @@ mod tunables; mod vmoffsets; pub mod cranelift; +#[cfg(feature = "lightbeam")] +pub mod lightbeam; pub use crate::compilation::{ - AddressTransforms, Compilation, CompileError, InstructionAddressTransform, Relocation, + AddressTransforms, Compilation, CompileError, Compiler, InstructionAddressTransform, Relocation, RelocationTarget, Relocations, }; +pub use crate::cranelift::Cranelift; +#[cfg(feature = "lightbeam")] +pub use crate::lightbeam::Lightbeam; pub use crate::module::{ Export, MemoryPlan, MemoryStyle, Module, TableElements, TablePlan, TableStyle, }; diff --git a/wasmtime-environ/src/lightbeam.rs b/wasmtime-environ/src/lightbeam.rs new file mode 100644 index 000000000000..afd2c88f3247 --- /dev/null +++ b/wasmtime-environ/src/lightbeam.rs @@ -0,0 +1,51 @@ +//! Support for compiling with Lightbeam. + +use crate::compilation::{Compilation, CompileError, Relocations}; +use crate::func_environ::FuncEnvironment; +use crate::module::Module; +// TODO: Put this in `compilation` +use crate::cranelift::RelocSink; +use cranelift_codegen::isa; +use cranelift_entity::PrimaryMap; +use cranelift_wasm::DefinedFuncIndex; +use lightbeam; + +/// A compiler that compiles a WebAssembly module with Lightbeam, directly translating the Wasm file. +pub struct Lightbeam; + +impl crate::compilation::Compiler for Lightbeam { + /// Compile the module using Cranelift, producing a compilation result with + /// associated relocations. + fn compile_module<'data, 'module>( + module: &'module Module, + function_body_inputs: PrimaryMap, + isa: &dyn isa::TargetIsa, + ) -> Result<(Compilation, Relocations), CompileError> { + let env = FuncEnvironment::new(isa.frontend_config(), module); + let mut relocations = PrimaryMap::new(); + let mut codegen_session: lightbeam::CodeGenSession<_> = + lightbeam::CodeGenSession::new(function_body_inputs.len() as u32, &env); + + for (i, function_body) in &function_body_inputs { + let mut reloc_sink = RelocSink::new(); + + lightbeam::translate_function( + &mut codegen_session, + &mut reloc_sink, + i.as_u32(), + &lightbeam::wasmparser::FunctionBody::new(0, function_body), + ) + .expect("Failed to translate function. TODO: Stop this from panicking"); + relocations.push(reloc_sink.func_relocs); + } + + let code_section = codegen_session + .into_translated_code_section() + .expect("Failed to generate output code. TODO: Stop this from panicking"); + + Ok(( + Compilation::from_buffer(code_section.buffer().to_vec(), code_section.funcs()), + relocations, + )) + } +} diff --git a/wasmtime-jit/Cargo.toml b/wasmtime-jit/Cargo.toml index 101501975902..644aee66f984 100644 --- a/wasmtime-jit/Cargo.toml +++ b/wasmtime-jit/Cargo.toml @@ -30,6 +30,7 @@ wasmparser = "0.29.2" default = ["std"] std = ["cranelift-codegen/std", "cranelift-wasm/std"] core = ["hashbrown/nightly", "cranelift-codegen/core", "cranelift-wasm/core", "wasmtime-environ/core"] +lightbeam = ["wasmtime-environ/lightbeam"] [badges] maintenance = { status = "experimental" } diff --git a/wasmtime-jit/src/compiler.rs b/wasmtime-jit/src/compiler.rs index 9f7084de0601..53f1243c09c1 100644 --- a/wasmtime-jit/src/compiler.rs +++ b/wasmtime-jit/src/compiler.rs @@ -17,7 +17,7 @@ use std::vec::Vec; use wasmtime_debug::{emit_debugsections_image, DebugInfoData}; use wasmtime_environ::cranelift; use wasmtime_environ::{ - Compilation, CompileError, FunctionBodyData, Module, Relocations, Tunables, + Compilation, CompileError, Compiler as _C, FunctionBodyData, Module, Relocations, Tunables, }; use wasmtime_runtime::{InstantiationError, SignatureRegistry, VMFunctionBody}; @@ -53,6 +53,11 @@ impl Compiler { } } +#[cfg(feature = "lightbeam")] +type DefaultCompiler = wasmtime_environ::lightbeam::Lightbeam; +#[cfg(not(feature = "lightbeam"))] +type DefaultCompiler = wasmtime_environ::cranelift::Cranelift; + impl Compiler { /// Return the target's frontend configuration settings. pub fn frontend_config(&self) -> TargetFrontendConfig { @@ -78,7 +83,7 @@ impl Compiler { ), SetupError, > { - let (compilation, relocations, address_transform) = cranelift::compile_module( + let (compilation, relocations, address_transform) = DefaultCompiler::compile_module( module, function_body_inputs, &*self.isa, @@ -252,6 +257,7 @@ fn allocate_functions( code_memory: &mut CodeMemory, compilation: &Compilation, ) -> Result, String> { +<<<<<<< HEAD:wasmtime-jit/src/compiler.rs // Allocate code for all function in one continuous memory block. // First, collect all function bodies into vector to pass to the // allocate_copy_of_byte_slices. @@ -266,6 +272,12 @@ fn allocate_functions( for i in 0..fat_ptrs.len() { let fat_ptr: *mut [VMFunctionBody] = fat_ptrs[i]; result.push(fat_ptr); +======= + let mut result = PrimaryMap::with_capacity(compilation.len()); + for body in &compilation { + let fatptr: *mut [VMFunctionBody] = code_memory.allocate_copy_of_byte_slice(body)?; + result.push(fatptr); +>>>>>>> Integrate lightbeam:lib/jit/src/compiler.rs } Ok(result) } From 9c547ecd501fef91b94a4d097d15ae7b905cff57 Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 26 Mar 2019 16:03:00 +0100 Subject: [PATCH 2/5] Fix for latest master --- wasmtime-environ/Cargo.toml | 2 +- wasmtime-environ/src/compilation.rs | 13 ++- wasmtime-environ/src/cranelift.rs | 128 +++++++++++++++------------- wasmtime-environ/src/lightbeam.rs | 14 +-- wasmtime-jit/src/compiler.rs | 15 +--- wasmtime-obj/src/function.rs | 4 +- 6 files changed, 92 insertions(+), 84 deletions(-) diff --git a/wasmtime-environ/Cargo.toml b/wasmtime-environ/Cargo.toml index a130482a98d5..c500d961cb96 100644 --- a/wasmtime-environ/Cargo.toml +++ b/wasmtime-environ/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" cranelift-codegen = "0.30.0" cranelift-entity = "0.30.0" cranelift-wasm = "0.30.0" -lightbeam = { path = "../../lightbeam", optional = true } +lightbeam = { path = "../lightbeam", optional = true } cast = { version = "0.2.2", default-features = false } failure = { version = "0.1.3", default-features = false } failure_derive = { version = "0.1.3", default-features = false } diff --git a/wasmtime-environ/src/compilation.rs b/wasmtime-environ/src/compilation.rs index dad710e958a2..c67a626876f6 100644 --- a/wasmtime-environ/src/compilation.rs +++ b/wasmtime-environ/src/compilation.rs @@ -2,6 +2,7 @@ //! module. use crate::module; +use crate::module_environ::FunctionBodyData; use cranelift_codegen::{binemit, ir, isa, CodegenError}; use cranelift_entity::PrimaryMap; use cranelift_wasm::{DefinedFuncIndex, FuncIndex, WasmError}; @@ -25,7 +26,12 @@ impl Compilation { /// Allocates the compilation result with the given function bodies. pub fn from_buffer(buffer: Vec, functions: impl IntoIterator>) -> Self { - Self::new(functions.into_iter().map(|range| buffer[range].to_vec()).collect()) + Self::new( + functions + .into_iter() + .map(|range| buffer[range].to_vec()) + .collect(), + ) } /// Gets the bytes of a single function @@ -141,7 +147,8 @@ pub trait Compiler { /// Compile a parsed module with the given `TargetIsa`. fn compile_module<'data, 'module>( module: &'module module::Module, - function_body_inputs: PrimaryMap, + function_body_inputs: PrimaryMap>, isa: &dyn isa::TargetIsa, - ) -> Result<(Compilation, Relocations), CompileError>; + generate_debug_info: bool, + ) -> Result<(Compilation, Relocations, AddressTransforms), CompileError>; } diff --git a/wasmtime-environ/src/cranelift.rs b/wasmtime-environ/src/cranelift.rs index 5c62be4f2595..976467dec048 100644 --- a/wasmtime-environ/src/cranelift.rs +++ b/wasmtime-environ/src/cranelift.rs @@ -21,9 +21,9 @@ use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use std::vec::Vec; /// Implementation of a relocation sink that just saves all the information for later -struct RelocSink { +pub struct RelocSink { /// Relocations recorded for the function. - func_relocs: Vec, + pub func_relocs: Vec, } impl binemit::RelocSink for RelocSink { @@ -109,69 +109,75 @@ fn get_address_transform( result } -/// Compile the module using Cranelift, producing a compilation result with -/// associated relocations. -pub fn compile_module<'data, 'module>( - module: &'module Module, - function_body_inputs: PrimaryMap>, - isa: &dyn isa::TargetIsa, - generate_debug_info: bool, -) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> { - let mut functions = PrimaryMap::with_capacity(function_body_inputs.len()); - let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len()); - let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len()); +/// A compiler that compiles a WebAssembly module with Cranelift, translating the Wasm to Cranelift IR, +/// optimizing it and then translating to assembly. +pub struct Cranelift; - function_body_inputs - .into_iter() - .collect::)>>() - .par_iter() - .map(|(i, input)| { - let func_index = module.func_index(*i); - let mut context = Context::new(); - context.func.name = get_func_name(func_index); - context.func.signature = module.signatures[module.functions[func_index]].clone(); +impl crate::compilation::Compiler for Cranelift { + /// Compile the module using Cranelift, producing a compilation result with + /// associated relocations. + fn compile_module<'data, 'module>( + module: &'module Module, + function_body_inputs: PrimaryMap>, + isa: &dyn isa::TargetIsa, + generate_debug_info: bool, + ) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> { + let mut functions = PrimaryMap::with_capacity(function_body_inputs.len()); + let mut relocations = PrimaryMap::with_capacity(function_body_inputs.len()); + let mut address_transforms = PrimaryMap::with_capacity(function_body_inputs.len()); - let mut trans = FuncTranslator::new(); - trans - .translate( - input.data, - input.module_offset, - &mut context.func, - &mut FuncEnvironment::new(isa.frontend_config(), module), - ) - .map_err(CompileError::Wasm)?; + function_body_inputs + .into_iter() + .collect::)>>() + .par_iter() + .map(|(i, input)| { + let func_index = module.func_index(*i); + let mut context = Context::new(); + context.func.name = get_func_name(func_index); + context.func.signature = module.signatures[module.functions[func_index]].clone(); - let mut code_buf: Vec = Vec::new(); - let mut reloc_sink = RelocSink::new(); - let mut trap_sink = binemit::NullTrapSink {}; - context - .compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) - .map_err(CompileError::Codegen)?; + let mut trans = FuncTranslator::new(); + trans + .translate( + input.data, + input.module_offset, + &mut context.func, + &mut FuncEnvironment::new(isa.frontend_config(), module), + ) + .map_err(CompileError::Wasm)?; - let address_transform = if generate_debug_info { - let body_len = code_buf.len(); - let at = get_address_transform(&context, isa); - Some(FunctionAddressTransform { - locations: at, - body_offset: 0, - body_len, - }) - } else { - None - }; + let mut code_buf: Vec = Vec::new(); + let mut reloc_sink = RelocSink::new(); + let mut trap_sink = binemit::NullTrapSink {}; + context + .compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut trap_sink) + .map_err(CompileError::Codegen)?; - Ok((code_buf, reloc_sink.func_relocs, address_transform)) - }) - .collect::, CompileError>>()? - .into_iter() - .for_each(|(function, relocs, address_transform)| { - functions.push(function); - relocations.push(relocs); - if let Some(address_transform) = address_transform { - address_transforms.push(address_transform); - } - }); + let address_transform = if generate_debug_info { + let body_len = code_buf.len(); + let at = get_address_transform(&context, isa); + Some(FunctionAddressTransform { + locations: at, + body_offset: 0, + body_len, + }) + } else { + None + }; + + Ok((code_buf, reloc_sink.func_relocs, address_transform)) + }) + .collect::, CompileError>>()? + .into_iter() + .for_each(|(function, relocs, address_transform)| { + functions.push(function); + relocations.push(relocs); + if let Some(address_transform) = address_transform { + address_transforms.push(address_transform); + } + }); - // TODO: Reorganize where we create the Vec for the resolved imports. - Ok((Compilation::new(functions), relocations, address_transforms)) + // TODO: Reorganize where we create the Vec for the resolved imports. + Ok((Compilation::new(functions), relocations, address_transforms)) + } } diff --git a/wasmtime-environ/src/lightbeam.rs b/wasmtime-environ/src/lightbeam.rs index afd2c88f3247..0edd8d9a2402 100644 --- a/wasmtime-environ/src/lightbeam.rs +++ b/wasmtime-environ/src/lightbeam.rs @@ -1,8 +1,9 @@ //! Support for compiling with Lightbeam. -use crate::compilation::{Compilation, CompileError, Relocations}; +use crate::compilation::{AddressTransforms, Compilation, CompileError, Relocations}; use crate::func_environ::FuncEnvironment; use crate::module::Module; +use crate::module_environ::FunctionBodyData; // TODO: Put this in `compilation` use crate::cranelift::RelocSink; use cranelift_codegen::isa; @@ -14,13 +15,15 @@ use lightbeam; pub struct Lightbeam; impl crate::compilation::Compiler for Lightbeam { - /// Compile the module using Cranelift, producing a compilation result with + /// Compile the module using Lightbeam, producing a compilation result with /// associated relocations. fn compile_module<'data, 'module>( module: &'module Module, - function_body_inputs: PrimaryMap, + function_body_inputs: PrimaryMap>, isa: &dyn isa::TargetIsa, - ) -> Result<(Compilation, Relocations), CompileError> { + // TODO + _generate_debug_info: bool, + ) -> Result<(Compilation, Relocations, AddressTransforms), CompileError> { let env = FuncEnvironment::new(isa.frontend_config(), module); let mut relocations = PrimaryMap::new(); let mut codegen_session: lightbeam::CodeGenSession<_> = @@ -33,7 +36,7 @@ impl crate::compilation::Compiler for Lightbeam { &mut codegen_session, &mut reloc_sink, i.as_u32(), - &lightbeam::wasmparser::FunctionBody::new(0, function_body), + &lightbeam::wasmparser::FunctionBody::new(0, function_body.data), ) .expect("Failed to translate function. TODO: Stop this from panicking"); relocations.push(reloc_sink.func_relocs); @@ -46,6 +49,7 @@ impl crate::compilation::Compiler for Lightbeam { Ok(( Compilation::from_buffer(code_section.buffer().to_vec(), code_section.funcs()), relocations, + AddressTransforms::new(), )) } } diff --git a/wasmtime-jit/src/compiler.rs b/wasmtime-jit/src/compiler.rs index 53f1243c09c1..08c9af1dfdf3 100644 --- a/wasmtime-jit/src/compiler.rs +++ b/wasmtime-jit/src/compiler.rs @@ -105,7 +105,7 @@ impl Compiler { let mut funcs = Vec::new(); for (i, allocated) in allocated_functions.into_iter() { let ptr = (*allocated) as *const u8; - let body_len = compilation.functions[i].len(); + let body_len = compilation.get(i).len(); funcs.push((ptr, body_len)); } let bytes = emit_debugsections_image( @@ -257,27 +257,18 @@ fn allocate_functions( code_memory: &mut CodeMemory, compilation: &Compilation, ) -> Result, String> { -<<<<<<< HEAD:wasmtime-jit/src/compiler.rs // Allocate code for all function in one continuous memory block. // First, collect all function bodies into vector to pass to the // allocate_copy_of_byte_slices. let bodies = compilation - .functions - .values() - .map(|body| body.as_slice()) + .into_iter() .collect::>(); let fat_ptrs = code_memory.allocate_copy_of_byte_slices(&bodies)?; // Second, create a PrimaryMap from result vector of pointers. - let mut result = PrimaryMap::with_capacity(compilation.functions.len()); + let mut result = PrimaryMap::with_capacity(compilation.len()); for i in 0..fat_ptrs.len() { let fat_ptr: *mut [VMFunctionBody] = fat_ptrs[i]; result.push(fat_ptr); -======= - let mut result = PrimaryMap::with_capacity(compilation.len()); - for body in &compilation { - let fatptr: *mut [VMFunctionBody] = code_memory.allocate_copy_of_byte_slice(body)?; - result.push(fatptr); ->>>>>>> Integrate lightbeam:lib/jit/src/compiler.rs } Ok(result) } diff --git a/wasmtime-obj/src/function.rs b/wasmtime-obj/src/function.rs index 246c5d6459f3..9cbe2ff0db49 100644 --- a/wasmtime-obj/src/function.rs +++ b/wasmtime-obj/src/function.rs @@ -38,11 +38,11 @@ pub fn emit_functions( .expect("Missing enable_verifier setting"); for (i, _function_relocs) in relocations.iter() { - let body = &compilation.functions[i]; + let body = compilation.get(i); let func_index = module.func_index(i); let string_name = format!("_wasm_function_{}", func_index.index()); - obj.define(string_name, body.clone()) + obj.define(string_name, body.to_vec()) .map_err(|err| format!("{}", err))?; } From 26eebf1805f61bed37096dc80d5ee58e509e4a1f Mon Sep 17 00:00:00 2001 From: Jef Date: Thu, 28 Mar 2019 10:15:05 +0100 Subject: [PATCH 3/5] Update lightbeam --- lightbeam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightbeam b/lightbeam index 2a60d76bdc69..a8bb9fd63401 160000 --- a/lightbeam +++ b/lightbeam @@ -1 +1 @@ -Subproject commit 2a60d76bdc69bee43de98f82d43a342eca2fee94 +Subproject commit a8bb9fd6340135517e8c2a7ba32d593279897525 From d372cf24f51d3f0b4f145533f53f3426221e9146 Mon Sep 17 00:00:00 2001 From: Jef Date: Thu, 28 Mar 2019 10:23:05 +0100 Subject: [PATCH 4/5] Update to latest lightbeam --- lightbeam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightbeam b/lightbeam index a8bb9fd63401..762cd3fb323a 160000 --- a/lightbeam +++ b/lightbeam @@ -1 +1 @@ -Subproject commit a8bb9fd6340135517e8c2a7ba32d593279897525 +Subproject commit 762cd3fb323a4755daa29c0282ee08f5e560a35b From 68ab2f329c0f1e52ea443f19e67129ebcf282f19 Mon Sep 17 00:00:00 2001 From: Jef Date: Thu, 28 Mar 2019 10:29:39 +0100 Subject: [PATCH 5/5] rustfmt --- wasmtime-environ/src/cranelift.rs | 2 +- wasmtime-environ/src/lib.rs | 4 ++-- wasmtime-jit/src/compiler.rs | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/wasmtime-environ/src/cranelift.rs b/wasmtime-environ/src/cranelift.rs index 976467dec048..4aadc354b801 100644 --- a/wasmtime-environ/src/cranelift.rs +++ b/wasmtime-environ/src/cranelift.rs @@ -113,7 +113,7 @@ fn get_address_transform( /// optimizing it and then translating to assembly. pub struct Cranelift; -impl crate::compilation::Compiler for Cranelift { +impl crate::compilation::Compiler for Cranelift { /// Compile the module using Cranelift, producing a compilation result with /// associated relocations. fn compile_module<'data, 'module>( diff --git a/wasmtime-environ/src/lib.rs b/wasmtime-environ/src/lib.rs index 4da4b1482ad1..4c0d214fbf50 100644 --- a/wasmtime-environ/src/lib.rs +++ b/wasmtime-environ/src/lib.rs @@ -49,8 +49,8 @@ pub mod cranelift; pub mod lightbeam; pub use crate::compilation::{ - AddressTransforms, Compilation, CompileError, Compiler, InstructionAddressTransform, Relocation, - RelocationTarget, Relocations, + AddressTransforms, Compilation, CompileError, Compiler, InstructionAddressTransform, + Relocation, RelocationTarget, Relocations, }; pub use crate::cranelift::Cranelift; #[cfg(feature = "lightbeam")] diff --git a/wasmtime-jit/src/compiler.rs b/wasmtime-jit/src/compiler.rs index 08c9af1dfdf3..e100684fd46c 100644 --- a/wasmtime-jit/src/compiler.rs +++ b/wasmtime-jit/src/compiler.rs @@ -260,9 +260,7 @@ fn allocate_functions( // Allocate code for all function in one continuous memory block. // First, collect all function bodies into vector to pass to the // allocate_copy_of_byte_slices. - let bodies = compilation - .into_iter() - .collect::>(); + let bodies = compilation.into_iter().collect::>(); let fat_ptrs = code_memory.allocate_copy_of_byte_slices(&bodies)?; // Second, create a PrimaryMap from result vector of pointers. let mut result = PrimaryMap::with_capacity(compilation.len());