From f3da3499c5b2a2a58bdc85f33dd5886f49704932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 8 Mar 2022 07:36:06 +0900 Subject: [PATCH] perf(es): Add fast memory deallocator (#3910) --- Cargo.lock | 8 ++ crates/fastmem/Cargo.toml | 14 +++ crates/fastmem/src/fast_drop.rs | 97 ++++++++++++++++++++ crates/fastmem/src/lib.rs | 14 +++ crates/swc_ecma_parser/scripts/instrument.sh | 2 +- crates/swc_node_base/Cargo.toml | 1 + 6 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 crates/fastmem/Cargo.toml create mode 100644 crates/fastmem/src/fast_drop.rs create mode 100644 crates/fastmem/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 310f879ed36..111caa64934 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -773,6 +773,13 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastmem" +version = "0.1.0" +dependencies = [ + "rayon", +] + [[package]] name = "fixedbitset" version = "0.2.0" @@ -3574,6 +3581,7 @@ dependencies = [ name = "swc_node_base" version = "0.5.1" dependencies = [ + "fastmem", "mimalloc-rust", ] diff --git a/crates/fastmem/Cargo.toml b/crates/fastmem/Cargo.toml new file mode 100644 index 00000000000..6b233d94e1f --- /dev/null +++ b/crates/fastmem/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["강동윤 "] +description = "Configurable utilities for fast memory operations" +edition = "2021" +license = "Apache-2.0" +name = "fastmem" +repository = "https://github.com/swc-project/swc.git" +version = "0.1.0" + +[features] +enable = ["rayon"] + +[dependencies] +rayon = {version = "1", optional = true} diff --git a/crates/fastmem/src/fast_drop.rs b/crates/fastmem/src/fast_drop.rs new file mode 100644 index 00000000000..e147e6fed63 --- /dev/null +++ b/crates/fastmem/src/fast_drop.rs @@ -0,0 +1,97 @@ +use std::ops::{Deref, DerefMut}; + +pub fn drop_fast(v: T) +where + T: Send + 'static, +{ + FastDrop::new(v); +} + +/// Utility type to deallocate memory in another thread. +/// +/// +/// +/// If ths feature `enable` is turned on, the value will be deallocated in other +/// thread. +/// +/// This type uses [rayon::spawn] +#[repr(transparent)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FastDrop +where + T: Send + 'static, +{ + value: Option, +} + +impl Default for FastDrop +where + T: Send + 'static, + T: Default, +{ + #[inline(always)] + fn default() -> Self { + Self::new(T::default()) + } +} + +impl FastDrop +where + T: Send, +{ + #[inline(always)] + pub fn new(value: T) -> Self { + let value = Some(value); + Self { value } + } +} + +impl From for FastDrop +where + T: Send, +{ + #[inline(always)] + fn from(value: T) -> Self { + Self::new(value) + } +} + +impl Deref for FastDrop +where + T: Send, +{ + type Target = T; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + debug_assert!(self.value.is_some()); + // Safety: self.value can be None only if drop is called. + unsafe { self.value.as_ref().unwrap_unchecked() } + } +} + +impl DerefMut for FastDrop +where + T: Send, +{ + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + debug_assert!(self.value.is_some()); + // Safety: self.value can be None only if drop is called. + unsafe { self.value.as_mut().unwrap_unchecked() } + } +} + +impl Drop for FastDrop +where + T: Send, +{ + fn drop(&mut self) { + #[cfg(feature = "enable")] + if let Some(value) = self.value.take() { + rayon::spawn(move || { + std::mem::drop(value); + }); + } + } +} diff --git a/crates/fastmem/src/lib.rs b/crates/fastmem/src/lib.rs new file mode 100644 index 00000000000..fe6d07af04d --- /dev/null +++ b/crates/fastmem/src/lib.rs @@ -0,0 +1,14 @@ +//! Utilities to unblock main thread. +//! +//! # Cargo Features +//! +//! ## `enable` +//! +//! This enables fast-mode of this crate. + +#![deny(clippy::all)] +#![deny(unused)] + +pub use self::fast_drop::*; + +mod fast_drop; diff --git a/crates/swc_ecma_parser/scripts/instrument.sh b/crates/swc_ecma_parser/scripts/instrument.sh index bc6c85399a7..8b8c35fd582 100755 --- a/crates/swc_ecma_parser/scripts/instrument.sh +++ b/crates/swc_ecma_parser/scripts/instrument.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash set -eu -cargo profile instruments --release -t time --features tracing/release_max_level_info --features swc_common/concurrent --features swc_common/parking_lot --bench parser -- --bench \ No newline at end of file +cargo profile instruments --release -t time --features tracing/release_max_level_info --features swc_common/concurrent --features swc_common/parking_lot --bench parser -- --bench diff --git a/crates/swc_node_base/Cargo.toml b/crates/swc_node_base/Cargo.toml index f5ee4963e2a..93c1f45a874 100644 --- a/crates/swc_node_base/Cargo.toml +++ b/crates/swc_node_base/Cargo.toml @@ -11,6 +11,7 @@ version = "0.5.1" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +fastmem = {version = "0.1.0", path = "../fastmem", features = ["enable"]} [target.'cfg(not(all(target_os = "linux", target_arch = "aarch64", target_env = "musl")))'.dependencies] mimalloc-rust = "=0.1.5"