Added parallel compilation (#209)

This commit is contained in:
Syrus Akbary 2019-02-25 12:03:48 -08:00 committed by Lachlan Sneff
parent 82eef13f41
commit c5c967da00
5 changed files with 45 additions and 18 deletions

1
Cargo.lock generated
View File

@ -1220,6 +1220,7 @@ dependencies = [
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.85 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -19,6 +19,7 @@ wasmparser = "0.23.0"
byteorder = "1" byteorder = "1"
nix = "0.13.0" nix = "0.13.0"
libc = "0.2.48" libc = "0.2.48"
rayon = "1.0"
# Dependencies for caching. # Dependencies for caching.
[dependencies.serde] [dependencies.serde]

View File

@ -24,6 +24,7 @@ use wasmer_runtime_core::{
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate rayon;
extern crate serde; extern crate serde;
use wasmparser::{self, WasmDecoder}; use wasmparser::{self, WasmDecoder};

View File

@ -7,6 +7,7 @@ use crate::{
}, },
signal::HandlerData, signal::HandlerData,
}; };
use rayon::prelude::*;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
use cranelift_codegen::{ir, isa, Context}; use cranelift_codegen::{ir, isa, Context};
@ -92,25 +93,45 @@ impl FuncResolverBuilder {
function_bodies: Map<LocalFuncIndex, ir::Function>, function_bodies: Map<LocalFuncIndex, ir::Function>,
info: &ModuleInfo, info: &ModuleInfo,
) -> CompileResult<(Self, HandlerData)> { ) -> CompileResult<(Self, HandlerData)> {
let mut compiled_functions: Vec<Vec<u8>> = Vec::with_capacity(function_bodies.len()); let num_func_bodies = function_bodies.len();
let mut local_relocs = Map::with_capacity(function_bodies.len()); let mut compiled_functions: Vec<(Vec<u8>, RelocSink)> = Vec::with_capacity(num_func_bodies);
let mut external_relocs = Map::new(); let mut local_relocs = Map::with_capacity(num_func_bodies);
let mut external_relocs = Map::with_capacity(num_func_bodies);
let mut trap_sink = TrapSink::new(); let mut trap_sink = TrapSink::new();
let compiled_functions: Result<Vec<(Vec<u8>, (RelocSink, LocalTrapSink))>, CompileError> =
function_bodies
.into_vec()
.par_iter()
.map_init(
|| Context::new(),
|ctx, func| {
let mut code_buf = Vec::new();
ctx.func = func.to_owned();
let mut reloc_sink = RelocSink::new();
let mut local_trap_sink = LocalTrapSink::new(); let mut local_trap_sink = LocalTrapSink::new();
let mut ctx = Context::new(); ctx.compile_and_emit(
let mut total_size = 0; isa,
&mut code_buf,
for (_, func) in function_bodies { &mut reloc_sink,
ctx.func = func; &mut local_trap_sink,
let mut code_buf = Vec::new(); )
let mut reloc_sink = RelocSink::new();
ctx.compile_and_emit(isa, &mut code_buf, &mut reloc_sink, &mut local_trap_sink)
.map_err(|e| CompileError::InternalError { msg: e.to_string() })?; .map_err(|e| CompileError::InternalError { msg: e.to_string() })?;
ctx.clear(); ctx.clear();
Ok((code_buf, (reloc_sink, local_trap_sink)))
},
)
.collect();
let compiled_functions = compiled_functions?;
let mut total_size = 0;
// We separate into two iterators, one iterable and one into iterable
let (code_bufs, sinks): (Vec<Vec<u8>>, Vec<(RelocSink, LocalTrapSink)>) =
compiled_functions.into_iter().unzip();
for (code_buf, (reloc_sink, mut local_trap_sink)) in code_bufs.iter().zip(sinks.into_iter())
{
// Clear the local trap sink and consolidate all trap info // Clear the local trap sink and consolidate all trap info
// into a single location. // into a single location.
trap_sink.drain_local(total_size, &mut local_trap_sink); trap_sink.drain_local(total_size, &mut local_trap_sink);
@ -118,7 +139,6 @@ impl FuncResolverBuilder {
// Round up each function's size to pointer alignment. // Round up each function's size to pointer alignment.
total_size += round_up(code_buf.len(), mem::size_of::<usize>()); total_size += round_up(code_buf.len(), mem::size_of::<usize>());
compiled_functions.push(code_buf);
local_relocs.push(reloc_sink.local_relocs.into_boxed_slice()); local_relocs.push(reloc_sink.local_relocs.into_boxed_slice());
external_relocs.push(reloc_sink.external_relocs.into_boxed_slice()); external_relocs.push(reloc_sink.external_relocs.into_boxed_slice());
} }
@ -145,10 +165,10 @@ impl FuncResolverBuilder {
*i = 0xCC; *i = 0xCC;
} }
let mut map = Map::with_capacity(compiled_functions.len()); let mut map = Map::with_capacity(num_func_bodies);
let mut previous_end = 0; let mut previous_end = 0;
for compiled in compiled_functions.iter() { for compiled in code_bufs.iter() {
let new_end = previous_end + round_up(compiled.len(), mem::size_of::<usize>()); let new_end = previous_end + round_up(compiled.len(), mem::size_of::<usize>());
unsafe { unsafe {
memory.as_slice_mut()[previous_end..previous_end + compiled.len()] memory.as_slice_mut()[previous_end..previous_end + compiled.len()]

View File

@ -56,6 +56,10 @@ where
pub fn into_boxed_map(self) -> BoxedMap<K, V> { pub fn into_boxed_map(self) -> BoxedMap<K, V> {
BoxedMap::new(self.elems.into_boxed_slice()) BoxedMap::new(self.elems.into_boxed_slice())
} }
pub fn into_vec(self) -> Vec<V> {
self.elems
}
} }
impl<K, V> Map<K, V> impl<K, V> Map<K, V>