From 9512ea31ff1bb0c70f4f96a620b429fa01f48e0c Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Wed, 28 Jun 2023 18:56:55 -0700 Subject: [PATCH] feat(plugin/runner): Share runtime `Engine` (#7590) --- crates/swc_plugin_runner/src/cache.rs | 9 ++-- .../src/plugin_module_bytes.rs | 31 +------------ crates/swc_plugin_runner/src/wasix_runtime.rs | 46 ++++++++++++++++++- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/crates/swc_plugin_runner/src/cache.rs b/crates/swc_plugin_runner/src/cache.rs index eeae10a424d..5e57ad65803 100644 --- a/crates/swc_plugin_runner/src/cache.rs +++ b/crates/swc_plugin_runner/src/cache.rs @@ -19,8 +19,9 @@ use wasmer::{Module, Store}; #[cfg(all(not(target_arch = "wasm32"), feature = "filesystem_cache"))] use wasmer_cache::{Cache as WasmerCache, FileSystemCache, Hash}; -use crate::plugin_module_bytes::{ - CompiledPluginModuleBytes, PluginModuleBytes, RawPluginModuleBytes, +use crate::{ + plugin_module_bytes::{CompiledPluginModuleBytes, PluginModuleBytes, RawPluginModuleBytes}, + wasix_runtime::new_store, }; /// Version for bytecode cache stored in local filesystem. @@ -114,7 +115,7 @@ impl PluginModuleCacheInner { // If FilesystemCache is available, store serialized bytes into fs. if let Some(fs_cache_store) = &mut self.fs_cache_store { let module_bytes_hash = Hash::generate(&raw_module_bytes); - let store = crate::plugin_module_bytes::new_store(); + let store = new_store(); let module = Module::new(&store, raw_module_bytes.clone()) .context("Cannot compile plugin binary")?; fs_cache_store.store(module_bytes_hash, &module)?; @@ -154,7 +155,7 @@ impl PluginModuleCacheInner { #[cfg(all(not(target_arch = "wasm32"), feature = "filesystem_cache"))] if let Some(fs_cache_store) = &self.fs_cache_store { let hash = self.fs_cache_hash_store.get(key)?; - let store = crate::plugin_module_bytes::new_store(); + let store = new_store(); let module = unsafe { fs_cache_store.load(&store, *hash) }; if let Ok(module) = module { return Some(Box::new(CompiledPluginModuleBytes::new( diff --git a/crates/swc_plugin_runner/src/plugin_module_bytes.rs b/crates/swc_plugin_runner/src/plugin_module_bytes.rs index 594011b8649..de9e2f87f4b 100644 --- a/crates/swc_plugin_runner/src/plugin_module_bytes.rs +++ b/crates/swc_plugin_runner/src/plugin_module_bytes.rs @@ -2,36 +2,7 @@ use anyhow::Error; use serde::{Deserialize, Serialize}; use wasmer::{Module, Store}; -/// Creates an instnace of [Store]. -/// -/// This function exists because we need to disable simd. -#[cfg(not(target_arch = "wasm32"))] -#[allow(unused_mut)] -pub(crate) fn new_store() -> Store { - // Use empty enumset to disable simd. - use enumset::EnumSet; - use wasmer::{BaseTunables, CompilerConfig, EngineBuilder, Target, Triple}; - let mut set = EnumSet::new(); - - // [TODO]: Should we use is_x86_feature_detected! macro instead? - #[cfg(target_arch = "x86_64")] - set.insert(wasmer::CpuFeature::SSE2); - let target = Target::new(Triple::host(), set); - - let config = wasmer_compiler_cranelift::Cranelift::default(); - let mut engine = EngineBuilder::new(Box::new(config) as Box) - .set_target(Some(target)) - .engine(); - let tunables = BaseTunables::for_target(engine.target()); - engine.set_tunables(tunables); - - Store::new(engine) -} - -#[cfg(target_arch = "wasm32")] -fn new_store() -> Store { - Store::default() -} +use crate::wasix_runtime::new_store; // A trait abstracts plugin's wasm compilation and instantiation. // Depends on the caller, this could be a simple clone from existing module, or diff --git a/crates/swc_plugin_runner/src/wasix_runtime.rs b/crates/swc_plugin_runner/src/wasix_runtime.rs index d0a884c7349..368dcde27b4 100644 --- a/crates/swc_plugin_runner/src/wasix_runtime.rs +++ b/crates/swc_plugin_runner/src/wasix_runtime.rs @@ -1,7 +1,36 @@ use std::{path::PathBuf, sync::Arc}; +use parking_lot::Mutex; +use swc_common::sync::{Lazy, OnceCell}; +use wasmer::Store; use wasmer_wasix::Runtime; +/// A shared instance to plugin runtime engine. +/// ref: https://github.com/wasmerio/wasmer/issues/3793#issuecomment-1607117480 +static ENGINE: Lazy> = Lazy::new(|| { + // Use empty enumset to disable simd. + use enumset::EnumSet; + use wasmer::{BaseTunables, CompilerConfig, EngineBuilder, Target, Triple}; + let mut set = EnumSet::new(); + + // [TODO]: Should we use is_x86_feature_detected! macro instead? + #[cfg(target_arch = "x86_64")] + set.insert(wasmer::CpuFeature::SSE2); + let target = Target::new(Triple::host(), set); + + let config = wasmer_compiler_cranelift::Cranelift::default(); + let mut engine = EngineBuilder::new(Box::new(config) as Box) + .set_target(Some(target)) + .engine(); + let tunables = BaseTunables::for_target(engine.target()); + engine.set_tunables(tunables); + parking_lot::Mutex::new(wasmer::Engine::from(engine)) +}); + +/// Dummy http client for wasix runtime to avoid instantiation failure for the +/// default pluggable runtime. We don't support network in the host runtime +/// anyway (we init vnet instead), and for the default runtime mostly it's for +/// the wapm registry which is redundant for the plugin. #[derive(Debug)] struct StubHttpClient; @@ -38,11 +67,10 @@ pub fn build_wasi_runtime( SharedCache::default().with_fallback(wasmer_wasix::runtime::module_cache::in_memory()); let dummy_loader = BuiltinPackageLoader::new_with_client(".", Arc::new(StubHttpClient)); - let rt = PluggableRuntime { rt: Arc::new(TokioTaskManager::shared()), networking: Arc::new(virtual_net::UnsupportedVirtualNetworking::default()), - engine: Some(wasmer::Engine::default()), + engine: Some(ENGINE.lock().clone()), tty: None, source: Arc::new(MultiSource::new()), module_cache: Arc::new(cache), @@ -52,3 +80,17 @@ pub fn build_wasi_runtime( Some(Arc::new(rt)) } + +/// Creates an instnace of [Store] with custom engine instead of default one to +/// disable simd for certain platform targets +#[cfg(not(target_arch = "wasm32"))] +#[allow(unused_mut)] +pub(crate) fn new_store() -> Store { + let engine = ENGINE.lock().clone(); + Store::new(engine) +} + +#[cfg(target_arch = "wasm32")] +pub(crate) fn new_store() -> Store { + Store::default() +}