From 48a6be87a006dedde5c5e6c457e68ccd8a1631c2 Mon Sep 17 00:00:00 2001 From: Sergey Shulepov Date: Mon, 9 Aug 2021 16:09:52 +0200 Subject: [PATCH] Plumb parallel_compilation config to compilation --- crates/cache/src/lib.rs | 3 +- crates/cache/src/tests.rs | 40 ++++++++++----------- crates/jit/src/compiler.rs | 8 +++-- crates/jit/src/instantiate.rs | 26 ++++++++++---- crates/jit/src/lib.rs | 19 ++++++---- crates/wasmtime/src/engine.rs | 2 ++ crates/wasmtime/src/module.rs | 18 ++++++++-- crates/wasmtime/src/module/serialization.rs | 2 ++ 8 files changed, 79 insertions(+), 39 deletions(-) diff --git a/crates/cache/src/lib.rs b/crates/cache/src/lib.rs index f29dd21056c9..69ab9be50807 100644 --- a/crates/cache/src/lib.rs +++ b/crates/cache/src/lib.rs @@ -43,10 +43,11 @@ impl<'config> ModuleCacheEntry<'config> { } /// Gets cached data if state matches, otherwise calls the `compute`. - pub fn get_data(&self, state: T, compute: fn(T) -> Result) -> Result + pub fn get_data(&self, state: T, compute: F) -> Result where T: Hash, U: Serialize + for<'a> Deserialize<'a>, + F: FnOnce(T) -> Result, { let inner = match &self.0 { Some(inner) => inner, diff --git a/crates/cache/src/tests.rs b/crates/cache/src/tests.rs index 4362aaba2222..3e09201461cd 100644 --- a/crates/cache/src/tests.rs +++ b/crates/cache/src/tests.rs @@ -65,28 +65,28 @@ fn test_write_read_cache() { let entry1 = ModuleCacheEntry::from_inner(ModuleCacheEntryInner::new(compiler1, &cache_config)); let entry2 = ModuleCacheEntry::from_inner(ModuleCacheEntryInner::new(compiler2, &cache_config)); - entry1.get_data::<_, i32, i32>(1, |_| Ok(100)).unwrap(); - entry1.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| Ok(100)).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(2, |_| Ok(100)).unwrap(); - entry1.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(2, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(2, |_| Ok(100)).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(2, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(3, |_| Ok(100)).unwrap(); - entry1.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(2, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(3, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(3, |_| Ok(100)).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(2, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(3, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(4, |_| Ok(100)).unwrap(); - entry1.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(2, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(3, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(4, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(4, |_| Ok(100)).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(2, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(3, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(4, |_| panic!()).unwrap(); - entry2.get_data::<_, i32, i32>(1, |_| Ok(100)).unwrap(); - entry1.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(2, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(3, |_| panic!()).unwrap(); - entry1.get_data::<_, i32, i32>(4, |_| panic!()).unwrap(); - entry2.get_data::<_, i32, i32>(1, |_| panic!()).unwrap(); + entry2.get_data::<_, i32, i32, _>(1, |_| Ok(100)).unwrap(); + entry1.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(2, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(3, |_| panic!()).unwrap(); + entry1.get_data::<_, i32, i32, _>(4, |_| panic!()).unwrap(); + entry2.get_data::<_, i32, i32, _>(1, |_| panic!()).unwrap(); } diff --git a/crates/jit/src/compiler.rs b/crates/jit/src/compiler.rs index 6d2fc7caf27f..5a855eb2bda1 100644 --- a/crates/jit/src/compiler.rs +++ b/crates/jit/src/compiler.rs @@ -134,11 +134,12 @@ impl Compiler { &self, translation: &mut ModuleTranslation, types: &TypeTables, + #[cfg(feature = "parallel-compilation")] parallel_compilation: bool, ) -> Result { let functions = mem::take(&mut translation.function_body_inputs); let functions = functions.into_iter().collect::>(); - let funcs = maybe_parallel!(functions.(into_iter | into_par_iter)) - .map(|(index, func)| { + let funcs = maybe_parallel!(parallel_compilation, functions.(into_iter | into_par_iter), iter => { + iter.map(|(index, func)| { self.compiler.compile_function( translation, index, @@ -150,7 +151,8 @@ impl Compiler { }) .collect::, _>>()? .into_iter() - .collect::(); + .collect::() + }); let dwarf_sections = if self.tunables.generate_native_debuginfo && !funcs.is_empty() { transform_dwarf_data( diff --git a/crates/jit/src/instantiate.rs b/crates/jit/src/instantiate.rs index 70894bdfebd5..6320c8dbec3c 100644 --- a/crates/jit/src/instantiate.rs +++ b/crates/jit/src/instantiate.rs @@ -99,10 +99,15 @@ impl CompilationArtifacts { /// The `use_paged_init` argument controls whether or not an attempt is made to /// organize linear memory initialization data as entire pages or to leave /// the memory initialization data as individual segments. + /// + /// The `prefer_parallel_compilation` is used to control whether compilation should be performed + /// using multiple threads or not. This has only an effect if the feature `parallel-compilation` + /// is enabled. pub fn build( compiler: &Compiler, data: &[u8], use_paged_mem_init: bool, + #[cfg(feature = "parallel-compilation")] parallel_compilation: bool, ) -> Result<(usize, Vec, TypeTables), SetupError> { let (main_module, translations, types) = ModuleEnvironment::new( compiler.frontend_config(), @@ -112,13 +117,18 @@ impl CompilationArtifacts { .translate(data) .map_err(|error| SetupError::Compile(CompileError::Wasm(error)))?; - let list = maybe_parallel!(translations.(into_iter | into_par_iter)) - .map(|mut translation| { + let list = maybe_parallel!(parallel_compilation, translations.(into_iter | into_par_iter), iter => { + iter.map(|mut translation| { let Compilation { obj, unwind_info, funcs, - } = compiler.compile(&mut translation, &types)?; + } = compiler.compile( + &mut translation, + &types, + #[cfg(feature = "parallel-compilation")] + parallel_compilation, + )?; let ModuleTranslation { mut module, @@ -160,7 +170,8 @@ impl CompilationArtifacts { has_unparsed_debuginfo, }) }) - .collect::, SetupError>>()?; + .collect::, SetupError>>()? + }); Ok(( main_module, list, @@ -226,10 +237,11 @@ impl CompiledModule { artifacts: Vec, isa: &dyn TargetIsa, profiler: &dyn ProfilingAgent, + #[cfg(feature = "parallel-compilation")] parallel_compilation: bool, ) -> Result>, SetupError> { - maybe_parallel!(artifacts.(into_iter | into_par_iter)) - .map(|a| CompiledModule::from_artifacts(a, isa, profiler)) - .collect() + maybe_parallel!(parallel_compilation, artifacts.(into_iter | into_par_iter), iter => { + iter.map(|a| CompiledModule::from_artifacts(a, isa, profiler)).collect() + }) } /// Creates `CompiledModule` directly from `CompilationArtifacts`. diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 12329ea266d7..7ced995bb1e6 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -22,16 +22,23 @@ #[cfg(feature = "parallel-compilation")] macro_rules! maybe_parallel { - ($e:ident.($serial:ident | $parallel:ident)) => { - $e.$parallel() - }; + ($condition:ident, $e:ident.($serial:ident | $parallel:ident), $iter_name:ident => { $body:expr }) => {{ + if $condition { + let $iter_name = $e.$parallel(); + $body + } else { + let $iter_name = $e.$serial(); + $body + } + }}; } #[cfg(not(feature = "parallel-compilation"))] macro_rules! maybe_parallel { - ($e:ident.($serial:ident | $parallel:ident)) => { - $e.$serial() - }; + ($condition:ident, $e:ident.($serial:ident | $parallel:ident), $iter_name:ident => { $body:expr }) => {{ + let $iter_name = $e.$serial(); + $body + }}; } mod code_memory; diff --git a/crates/wasmtime/src/engine.rs b/crates/wasmtime/src/engine.rs index f0c615fb2dae..4b9c5bf770e8 100644 --- a/crates/wasmtime/src/engine.rs +++ b/crates/wasmtime/src/engine.rs @@ -144,6 +144,8 @@ impl Engine { &self.inner.compiler, &bytes, USE_PAGED_MEM_INIT, + #[cfg(feature = "parallel-compilation")] + self.inner.config.parallel_compilation, )?; crate::module::SerializedModule::from_artifacts(&self.inner.compiler, &artifacts, &types) diff --git a/crates/wasmtime/src/module.rs b/crates/wasmtime/src/module.rs index 2a9168f8f8c1..47948134d34c 100644 --- a/crates/wasmtime/src/module.rs +++ b/crates/wasmtime/src/module.rs @@ -300,11 +300,23 @@ impl Module { engine.cache_config(), ) .get_data((engine.compiler(), binary), |(compiler, binary)| { - CompilationArtifacts::build(compiler, binary, USE_PAGED_MEM_INIT) + CompilationArtifacts::build( + compiler, + binary, + USE_PAGED_MEM_INIT, + #[cfg(feature = "parallel-compilation")] + engine.config().parallel_compilation, + ) })?; } else { let (main_module, artifacts, types) = - CompilationArtifacts::build(engine.compiler(), binary, USE_PAGED_MEM_INIT)?; + CompilationArtifacts::build( + engine.compiler(), + binary, + USE_PAGED_MEM_INIT, + #[cfg(feature = "parallel-compilation")] + engine.config().parallel_compilation, + )?; } }; @@ -312,6 +324,8 @@ impl Module { artifacts, engine.compiler().isa(), &*engine.config().profiler, + #[cfg(feature = "parallel-compilation")] + engine.config().parallel_compilation, )?; Self::from_parts(engine, modules, main_module, Arc::new(types), &[]) diff --git a/crates/wasmtime/src/module/serialization.rs b/crates/wasmtime/src/module/serialization.rs index 8dedf6803f8d..c59999824c28 100644 --- a/crates/wasmtime/src/module/serialization.rs +++ b/crates/wasmtime/src/module/serialization.rs @@ -291,6 +291,8 @@ impl<'a> SerializedModule<'a> { .collect(), engine.compiler().isa(), &*engine.config().profiler, + #[cfg(feature = "parallel-compilation")] + engine.config().parallel_compilation, )?; assert!(!modules.is_empty());