perf(es/helpers): Use bool instead of AtomicBool (#9321)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/9222
This commit is contained in:
Donny/강동윤 2024-07-23 15:47:17 +09:00 committed by GitHub
parent 279ea910e0
commit 8107e985e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 84 additions and 26 deletions

View File

@ -0,0 +1,6 @@
---
swc_bundler: patch
swc_ecma_transforms_base: patch
---
perf(es/helpers): Use `bool` instead of `AtomicBool`

View File

@ -9,6 +9,7 @@ use swc_common::{
FileName, SyntaxContext, DUMMY_SP, FileName, SyntaxContext, DUMMY_SP,
}; };
use swc_ecma_ast::*; use swc_ecma_ast::*;
use swc_ecma_transforms_base::helpers::Helpers;
use swc_ecma_utils::{find_pat_ids, prepend_stmt, private_ident, quote_ident, ExprFactory}; use swc_ecma_utils::{find_pat_ids, prepend_stmt, private_ident, quote_ident, ExprFactory};
use swc_ecma_visit::{VisitMut, VisitMutWith}; use swc_ecma_visit::{VisitMut, VisitMutWith};
use EdgeDirection::Outgoing; use EdgeDirection::Outgoing;
@ -104,7 +105,18 @@ where
let deps = all_deps_of_entry.iter().map(|id| { let deps = all_deps_of_entry.iter().map(|id| {
let dep_info = self.scope.get_module(*id).unwrap(); let dep_info = self.scope.get_module(*id).unwrap();
entry_info.helpers.extend(&dep_info.helpers); entry_info.helpers.extend(&dep_info.helpers);
entry_info.swc_helpers.extend_from(&dep_info.swc_helpers);
{
let helpers = *entry_info.swc_helpers.lock();
let dep_helpers = *dep_info.swc_helpers.lock();
let helpers = Helpers::from_data(helpers);
let dep_helpers = Helpers::from_data(dep_helpers);
helpers.extend_from(&dep_helpers);
*entry_info.swc_helpers.lock() = helpers.data();
}
if *id == entry_id { if *id == entry_id {
return Modules::empty(injected_ctxt); return Modules::empty(injected_ctxt);

View File

@ -6,7 +6,7 @@ use swc_common::{collections::AHashMap, util::move_map::MoveMap, FileName, Mark,
use swc_ecma_ast::*; use swc_ecma_ast::*;
use swc_ecma_transforms_base::{ use swc_ecma_transforms_base::{
fixer::fixer, fixer::fixer,
helpers::{inject_helpers, HELPERS}, helpers::{inject_helpers, Helpers, HELPERS},
hygiene::hygiene, hygiene::hygiene,
}; };
use swc_ecma_utils::{contains_top_level_await, find_pat_ids, private_ident, ExprFactory}; use swc_ecma_utils::{contains_top_level_await, find_pat_ids, private_ident, ExprFactory};
@ -48,15 +48,16 @@ where
{ {
// Inject swc helpers // Inject swc helpers
let swc_helpers = self let swc_helpers = *self
.scope .scope
.get_module(bundle.id) .get_module(bundle.id)
.expect("module should exist at this point") .expect("module should exist at this point")
.swc_helpers; .swc_helpers
.lock();
let module = bundle.module; let module = bundle.module;
bundle.module = HELPERS.set(&swc_helpers, || { bundle.module = HELPERS.set(&Helpers::from_data(swc_helpers), || {
module.fold_with(&mut inject_helpers(unresolved_mark)) module.fold_with(&mut inject_helpers(unresolved_mark))
}); });
} }

View File

@ -4,7 +4,10 @@ use anyhow::{Context, Error};
use is_macro::Is; use is_macro::Is;
#[cfg(feature = "rayon")] #[cfg(feature = "rayon")]
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use swc_common::{sync::Lrc, FileName, SourceFile, SyntaxContext}; use swc_common::{
sync::{Lock, Lrc},
FileName, SourceFile, SyntaxContext,
};
use swc_ecma_ast::{ use swc_ecma_ast::{
CallExpr, Callee, Expr, Ident, ImportDecl, ImportSpecifier, MemberExpr, MemberProp, Module, CallExpr, Callee, Expr, Ident, ImportDecl, ImportSpecifier, MemberExpr, MemberProp, Module,
ModuleDecl, ModuleExportName, Str, SuperProp, SuperPropExpr, ModuleDecl, ModuleExportName, Str, SuperProp, SuperPropExpr,
@ -38,7 +41,7 @@ pub(crate) struct TransformedModule {
/// Used helpers /// Used helpers
pub helpers: Lrc<Helpers>, pub helpers: Lrc<Helpers>,
pub swc_helpers: Lrc<swc_ecma_transforms_base::helpers::Helpers>, pub swc_helpers: Lrc<Lock<swc_ecma_transforms_base::helpers::HelperData>>,
local_ctxt: SyntaxContext, local_ctxt: SyntaxContext,
export_ctxt: SyntaxContext, export_ctxt: SyntaxContext,
@ -208,7 +211,7 @@ where
exports: Lrc::new(exports), exports: Lrc::new(exports),
is_es6, is_es6,
helpers: Default::default(), helpers: Default::default(),
swc_helpers: Lrc::new(data.helpers), swc_helpers: Lrc::new(Lock::new(data.helpers.data())),
local_ctxt: SyntaxContext::empty().apply_mark(local_mark), local_ctxt: SyntaxContext::empty().apply_mark(local_mark),
export_ctxt: SyntaxContext::empty().apply_mark(export_mark), export_ctxt: SyntaxContext::empty().apply_mark(export_mark),
}, },

View File

@ -1,7 +1,4 @@
use std::{ use std::{cell::RefCell, mem::replace};
mem::replace,
sync::atomic::{AtomicBool, Ordering},
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@ -52,7 +49,7 @@ macro_rules! add_to {
parse(&code) parse(&code)
}); });
let enable = $b.load(Ordering::Relaxed); let enable = $b;
if enable { if enable {
$buf.extend(STMTS.iter().cloned().map(|mut stmt| { $buf.extend(STMTS.iter().cloned().map(|mut stmt| {
stmt.visit_mut_with(&mut Marker { stmt.visit_mut_with(&mut Marker {
@ -69,7 +66,7 @@ macro_rules! add_to {
macro_rules! add_import_to { macro_rules! add_import_to {
($buf:expr, $name:ident, $b:expr, $mark:expr) => {{ ($buf:expr, $name:ident, $b:expr, $mark:expr) => {{
let enable = $b.load(Ordering::Relaxed); let enable = $b;
if enable { if enable {
let ctxt = SyntaxContext::empty().apply_mark($mark); let ctxt = SyntaxContext::empty().apply_mark($mark);
let s = ImportSpecifier::Named(ImportNamedSpecifier { let s = ImportSpecifier::Named(ImportNamedSpecifier {
@ -103,6 +100,13 @@ better_scoped_tls::scoped_tls!(
/// Tracks used helper methods. (e.g. __extends) /// Tracks used helper methods. (e.g. __extends)
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Helpers { pub struct Helpers {
external: bool,
mark: HelperMark,
inner: RefCell<Inner>,
}
#[derive(Debug, Clone, Copy)]
pub struct HelperData {
external: bool, external: bool,
mark: HelperMark, mark: HelperMark,
inner: Inner, inner: Inner,
@ -124,6 +128,22 @@ impl Helpers {
pub const fn external(&self) -> bool { pub const fn external(&self) -> bool {
self.external self.external
} }
pub fn data(&self) -> HelperData {
HelperData {
inner: *self.inner.borrow(),
external: self.external,
mark: self.mark,
}
}
pub fn from_data(data: HelperData) -> Self {
Helpers {
external: data.external,
mark: data.mark,
inner: RefCell::new(data.inner),
}
}
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -140,15 +160,15 @@ macro_rules! define_helpers {
$( $name:ident : ( $( $dep:ident ),* ), )* $( $name:ident : ( $( $dep:ident ),* ), )*
} }
) => { ) => {
#[derive(Debug,Default)] #[derive(Debug,Default, Clone, Copy)]
struct Inner { struct Inner {
$( $name: AtomicBool, )* $( $name: bool, )*
} }
impl Helpers { impl Helpers {
$( $(
pub fn $name(&self) { pub fn $name(&self) {
self.inner.$name.store(true, Ordering::Relaxed); self.inner.borrow_mut().$name = true;
if !self.external { if !self.external {
$( $(
@ -159,11 +179,14 @@ macro_rules! define_helpers {
)* )*
} }
impl Helpers { impl Helpers {
pub fn extend_from(&self, other: &Self) { pub fn extend_from(&self, other: &Self) {
let other = other.inner.borrow();
let mut me = self.inner.borrow_mut();
$( $(
if other.inner.$name.load(Ordering::SeqCst) { if other.$name {
self.inner.$name.store(true, Ordering::Relaxed); me.$name = true;
} }
)* )*
} }
@ -173,8 +196,9 @@ macro_rules! define_helpers {
fn is_helper_used(&self) -> bool{ fn is_helper_used(&self) -> bool{
HELPERS.with(|helpers|{ HELPERS.with(|helpers|{
let inner = helpers.inner.borrow();
false $( false $(
|| helpers.inner.$name.load(Ordering::Relaxed) || inner.$name
)* )*
}) })
} }
@ -184,8 +208,9 @@ macro_rules! define_helpers {
HELPERS.with(|helpers|{ HELPERS.with(|helpers|{
debug_assert!(!helpers.external); debug_assert!(!helpers.external);
let inner = helpers.inner.borrow();
$( $(
add_to!(buf, $name, helpers.inner.$name, helpers.mark.0); add_to!(buf, $name, inner.$name, helpers.mark.0);
)* )*
}); });
@ -196,9 +221,10 @@ macro_rules! define_helpers {
let mut buf = Vec::new(); let mut buf = Vec::new();
HELPERS.with(|helpers|{ HELPERS.with(|helpers|{
let inner = helpers.inner.borrow();
debug_assert!(helpers.external); debug_assert!(helpers.external);
$( $(
add_import_to!(buf, $name, helpers.inner.$name, helpers.mark.0); add_import_to!(buf, $name, inner.$name, helpers.mark.0);
)* )*
}); });
@ -209,8 +235,9 @@ macro_rules! define_helpers {
let mut buf = Vec::new(); let mut buf = Vec::new();
HELPERS.with(|helpers|{ HELPERS.with(|helpers|{
debug_assert!(helpers.external); debug_assert!(helpers.external);
let inner = helpers.inner.borrow();
$( $(
let enable = helpers.inner.$name.load(Ordering::Relaxed); let enable = inner.$name;
if enable { if enable {
buf.push(self.build_reqire(stringify!($name), helpers.mark.0)) buf.push(self.build_reqire(stringify!($name), helpers.mark.0))
} }

View File

@ -5,6 +5,7 @@ use swc_ecma_ast::*;
pub use swc_ecma_utils::parallel::*; pub use swc_ecma_utils::parallel::*;
use swc_ecma_visit::{Fold, FoldWith, Visit, VisitMut, VisitMutWith, VisitWith}; use swc_ecma_visit::{Fold, FoldWith, Visit, VisitMut, VisitMutWith, VisitWith};
use crate::helpers::Helpers;
#[cfg(feature = "concurrent")] #[cfg(feature = "concurrent")]
use crate::helpers::HELPERS; use crate::helpers::HELPERS;
@ -52,14 +53,18 @@ where
if nodes.len() >= threshold { if nodes.len() >= threshold {
GLOBALS.with(|globals| { GLOBALS.with(|globals| {
HELPERS.with(|helpers| { HELPERS.with(|helpers| {
let helpers = helpers.data();
HANDLER.with(|handler| { HANDLER.with(|handler| {
use rayon::prelude::*; use rayon::prelude::*;
let visitor = nodes let visitor = nodes
.into_par_iter() .into_par_iter()
.map(|node| { .map(|node| {
let helpers = Helpers::from_data(helpers);
GLOBALS.set(globals, || { GLOBALS.set(globals, || {
HELPERS.set(helpers, || { HELPERS.set(&helpers, || {
HANDLER.set(handler, || { HANDLER.set(handler, || {
let mut visitor = Parallel::create(&*self); let mut visitor = Parallel::create(&*self);
node.visit_with(&mut visitor); node.visit_with(&mut visitor);
@ -110,14 +115,16 @@ where
if nodes.len() >= threshold { if nodes.len() >= threshold {
GLOBALS.with(|globals| { GLOBALS.with(|globals| {
HELPERS.with(|helpers| { HELPERS.with(|helpers| {
let helpers = helpers.data();
HANDLER.with(|handler| { HANDLER.with(|handler| {
use rayon::prelude::*; use rayon::prelude::*;
let visitor = nodes let visitor = nodes
.into_par_iter() .into_par_iter()
.map(|node| { .map(|node| {
let helpers = Helpers::from_data(helpers);
GLOBALS.set(globals, || { GLOBALS.set(globals, || {
HELPERS.set(helpers, || { HELPERS.set(&helpers, || {
HANDLER.set(handler, || { HANDLER.set(handler, || {
let mut visitor = Parallel::create(&*self); let mut visitor = Parallel::create(&*self);
node.visit_mut_with(&mut visitor); node.visit_mut_with(&mut visitor);
@ -170,12 +177,14 @@ where
let (visitor, nodes) = GLOBALS.with(|globals| { let (visitor, nodes) = GLOBALS.with(|globals| {
HELPERS.with(|helpers| { HELPERS.with(|helpers| {
let helpers = helpers.data();
HANDLER.with(|handler| { HANDLER.with(|handler| {
nodes nodes
.into_par_iter() .into_par_iter()
.map(|node| { .map(|node| {
let helpers = Helpers::from_data(helpers);
GLOBALS.set(globals, || { GLOBALS.set(globals, || {
HELPERS.set(helpers, || { HELPERS.set(&helpers, || {
HANDLER.set(handler, || { HANDLER.set(handler, || {
let mut visitor = Parallel::create(&*self); let mut visitor = Parallel::create(&*self);
let node = node.fold_with(&mut visitor); let node = node.fold_with(&mut visitor);