From 556140f19ea70f62b6a62d8545601d0700c81dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:31:41 +0900 Subject: [PATCH 01/21] We need benchmark --- crates/swc_allocator/benches/bench.rs | 1 + 1 file changed, 1 insertion(+) create mode 100644 crates/swc_allocator/benches/bench.rs diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/crates/swc_allocator/benches/bench.rs @@ -0,0 +1 @@ + From 850599412e2eb4b7f339d86dd99b5ecdd1e6cf10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:35:55 +0900 Subject: [PATCH 02/21] harness --- crates/swc_allocator/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/swc_allocator/Cargo.toml b/crates/swc_allocator/Cargo.toml index 621eb8d27c07..5c6713d5ba90 100644 --- a/crates/swc_allocator/Cargo.toml +++ b/crates/swc_allocator/Cargo.toml @@ -24,3 +24,8 @@ rkyv = { workspace = true, optional = true } scoped-tls = { workspace = true } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } + + +[[bench]] +harness = false +name = "bench" From da135c3b3e202ba5f0cd562809943a2ca5d84956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:37:28 +0900 Subject: [PATCH 03/21] dev deps --- crates/swc_allocator/Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/swc_allocator/Cargo.toml b/crates/swc_allocator/Cargo.toml index 5c6713d5ba90..6b2bc274fcea 100644 --- a/crates/swc_allocator/Cargo.toml +++ b/crates/swc_allocator/Cargo.toml @@ -26,6 +26,13 @@ serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } +[dev-dependencies] +criterion = { workspace = true } + +codspeed-criterion-compat = { workspace = true } +swc_malloc = { version = "0.5.10", path = "../swc_malloc" } + + [[bench]] harness = false name = "bench" From bf25548111f63d61cacffc9ceedfe8ac5b6b84ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:37:33 +0900 Subject: [PATCH 04/21] cargo lockfile --- Cargo.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index de37a4f3b5c2..50cd341075cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3702,11 +3702,14 @@ version = "0.1.1" dependencies = [ "allocator-api2", "bumpalo", + "codspeed-criterion-compat", + "criterion", "ptr_meta", "rkyv", "scoped-tls", "serde", "serde_derive", + "swc_malloc", ] [[package]] From ac33e713a5ea71c67ec43fc840faaf5bfd65c6d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:39:16 +0900 Subject: [PATCH 05/21] direct alloc --- crates/swc_allocator/benches/bench.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 8b137891791f..8b63fa7eb328 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -1 +1,21 @@ +extern crate swc_malloc; +use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; + +fn bench_alloc(c: &mut Criterion) { + fn direct_alloc(b: &mut Bencher, times: usize) { + b.iter(|| { + for _ in 0..times { + let _: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(1234))); + } + }) + } + + c.bench_function("common/allocator/alloc/1000", |b| { + direct_alloc(b, 1000 * 1000 * 1000) + }); +} + +criterion_group!(benches, bench_alloc); +criterion_main!(benches); From a76514329c1014e65050e2afd1c3ecbb770e28fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:39:25 +0900 Subject: [PATCH 06/21] rename --- crates/swc_allocator/benches/bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 8b63fa7eb328..ab3f19189403 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -12,7 +12,7 @@ fn bench_alloc(c: &mut Criterion) { }) } - c.bench_function("common/allocator/alloc/1000", |b| { + c.bench_function("common/allocator/alloc/1000_000_000", |b| { direct_alloc(b, 1000 * 1000 * 1000) }); } From 7b59bdcd8b086076765aa12db855209c53029377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:40:37 +0900 Subject: [PATCH 07/21] bench --- crates/swc_allocator/benches/bench.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index ab3f19189403..e80106b7a80b 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -1,6 +1,7 @@ extern crate swc_malloc; use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; +use swc_allocator::Allocator; fn bench_alloc(c: &mut Criterion) { fn direct_alloc(b: &mut Bencher, times: usize) { @@ -12,9 +13,25 @@ fn bench_alloc(c: &mut Criterion) { }) } - c.bench_function("common/allocator/alloc/1000_000_000", |b| { + fn direct_alloc_in_scope(b: &mut Bencher, times: usize) { + b.iter(|| { + let allocator = Allocator::default(); + + allocator.scope(|| { + for _ in 0..times { + let _: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(1234))); + } + }); + }) + } + + c.bench_function("common/allocator/alloc/no-scope/1000_000_000", |b| { direct_alloc(b, 1000 * 1000 * 1000) }); + c.bench_function("common/allocator/alloc/scoped/1000_000_000", |b| { + direct_alloc_in_scope(b, 1000 * 1000 * 1000) + }); } criterion_group!(benches, bench_alloc); From 1200f987b770a924d883c440a8f39bfa973baa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:41:44 +0900 Subject: [PATCH 08/21] bench --- crates/swc_allocator/benches/bench.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index e80106b7a80b..986e6c485be3 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -26,11 +26,11 @@ fn bench_alloc(c: &mut Criterion) { }) } - c.bench_function("common/allocator/alloc/no-scope/1000_000_000", |b| { - direct_alloc(b, 1000 * 1000 * 1000) + c.bench_function("common/allocator/alloc/no-scope/1000", |b| { + direct_alloc(b, 1000) }); - c.bench_function("common/allocator/alloc/scoped/1000_000_000", |b| { - direct_alloc_in_scope(b, 1000 * 1000 * 1000) + c.bench_function("common/allocator/alloc/scoped/1000", |b| { + direct_alloc_in_scope(b, 1000) }); } From 47c0b18da1bc2fa761284df76be783a656c78953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:42:31 +0900 Subject: [PATCH 09/21] bench --- crates/swc_allocator/benches/bench.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 986e6c485be3..0b368b563b9f 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -4,7 +4,15 @@ use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Benc use swc_allocator::Allocator; fn bench_alloc(c: &mut Criterion) { - fn direct_alloc(b: &mut Bencher, times: usize) { + fn direct_alloc_std(b: &mut Bencher, times: usize) { + b.iter(|| { + for _ in 0..times { + let _: std::boxed::Box = black_box(std::boxed::Box::new(black_box(1234))); + } + }) + } + + fn direct_alloc_no_scope(b: &mut Bencher, times: usize) { b.iter(|| { for _ in 0..times { let _: swc_allocator::boxed::Box = @@ -26,8 +34,11 @@ fn bench_alloc(c: &mut Criterion) { }) } + c.bench_function("common/allocator/alloc/std/1000", |b| { + direct_alloc_std(b, 1000) + }); c.bench_function("common/allocator/alloc/no-scope/1000", |b| { - direct_alloc(b, 1000) + direct_alloc_no_scope(b, 1000) }); c.bench_function("common/allocator/alloc/scoped/1000", |b| { direct_alloc_in_scope(b, 1000) From 89413d1a0ba278619f60744a48635f613302d070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:44:33 +0900 Subject: [PATCH 10/21] vec --- crates/swc_allocator/benches/bench.rs | 35 ++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 0b368b563b9f..88828b986ebd 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -6,17 +6,21 @@ use swc_allocator::Allocator; fn bench_alloc(c: &mut Criterion) { fn direct_alloc_std(b: &mut Bencher, times: usize) { b.iter(|| { - for _ in 0..times { - let _: std::boxed::Box = black_box(std::boxed::Box::new(black_box(1234))); + let mut buf = std::vec::Vec::new(); + for i in 0..times { + let item: std::boxed::Box = black_box(std::boxed::Box::new(black_box(i))); + buf.push(item); } }) } fn direct_alloc_no_scope(b: &mut Bencher, times: usize) { b.iter(|| { - for _ in 0..times { - let _: swc_allocator::boxed::Box = - black_box(swc_allocator::boxed::Box::new(black_box(1234))); + let mut vec = swc_allocator::vec::Vec::new(); + for i in 0..times { + let item: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(i))); + vec.push(item); } }) } @@ -25,23 +29,26 @@ fn bench_alloc(c: &mut Criterion) { b.iter(|| { let allocator = Allocator::default(); + let mut vec = swc_allocator::vec::Vec::new(); + allocator.scope(|| { - for _ in 0..times { - let _: swc_allocator::boxed::Box = - black_box(swc_allocator::boxed::Box::new(black_box(1234))); + for i in 0..times { + let item: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(i))); + vec.push(item); } }); }) } - c.bench_function("common/allocator/alloc/std/1000", |b| { - direct_alloc_std(b, 1000) + c.bench_function("common/allocator/alloc/std/100000", |b| { + direct_alloc_std(b, 100000) }); - c.bench_function("common/allocator/alloc/no-scope/1000", |b| { - direct_alloc_no_scope(b, 1000) + c.bench_function("common/allocator/alloc/no-scope/100000", |b| { + direct_alloc_no_scope(b, 100000) }); - c.bench_function("common/allocator/alloc/scoped/1000", |b| { - direct_alloc_in_scope(b, 1000) + c.bench_function("common/allocator/alloc/scoped/100000", |b| { + direct_alloc_in_scope(b, 100000) }); } From 93d9b1e3ebf2a367b180eeb5bc1ab37d26d9b7c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 13:45:20 +0900 Subject: [PATCH 11/21] fix --- crates/swc_allocator/benches/bench.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 88828b986ebd..c3cf091e91bf 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -29,9 +29,9 @@ fn bench_alloc(c: &mut Criterion) { b.iter(|| { let allocator = Allocator::default(); - let mut vec = swc_allocator::vec::Vec::new(); - allocator.scope(|| { + let mut vec = swc_allocator::vec::Vec::new(); + for i in 0..times { let item: swc_allocator::boxed::Box = black_box(swc_allocator::boxed::Box::new(black_box(i))); From 3b42ad47e54dfbb21c13514249c5252212ab4923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 14:38:05 +0900 Subject: [PATCH 12/21] Add an assertion --- crates/swc_allocator/src/alloc.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/swc_allocator/src/alloc.rs b/crates/swc_allocator/src/alloc.rs index 4d80a5fa935f..69a16d19ec08 100644 --- a/crates/swc_allocator/src/alloc.rs +++ b/crates/swc_allocator/src/alloc.rs @@ -33,6 +33,10 @@ fn mark_ptr_as_arena_mode(ptr: NonNull<[u8]>) -> NonNull<[u8]> { raw_ptr = (raw_ptr as usize | 1) as *mut (); + debug_assert!(is_ptr_in_arena_mode(unsafe { + NonNull::new_unchecked(raw_ptr as *mut u8) + })); + unsafe { // Safety: NonNull::new_unchecked(ptr_meta::from_raw_parts_mut(raw_ptr, metadata)) From a9ab8fbcb99dd6efe0de6896363d7d3b1c39958e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 14:44:08 +0900 Subject: [PATCH 13/21] fix --- crates/swc_allocator/src/alloc.rs | 41 +++++++++++---------------- crates/swc_allocator/src/boxed/mod.rs | 10 +++++-- crates/swc_allocator/src/vec/mod.rs | 10 +++++-- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/crates/swc_allocator/src/alloc.rs b/crates/swc_allocator/src/alloc.rs index 69a16d19ec08..f135698679a8 100644 --- a/crates/swc_allocator/src/alloc.rs +++ b/crates/swc_allocator/src/alloc.rs @@ -7,8 +7,18 @@ use crate::Allocator; scoped_thread_local!(pub(crate) static ALLOC: Allocator); -#[derive(Debug, Clone, Copy, Default)] -pub struct SwcAlloc; +#[derive(Debug, Clone, Copy)] +pub struct SwcAlloc { + is_arena_mode: bool, +} + +impl Default for SwcAlloc { + fn default() -> Self { + SwcAlloc { + is_arena_mode: ALLOC.is_set(), + } + } +} impl SwcAlloc { /// `true` is passed to `f` if the box is allocated with a custom allocator. @@ -27,25 +37,8 @@ impl SwcAlloc { } } -/// Set the last bit to 1 fn mark_ptr_as_arena_mode(ptr: NonNull<[u8]>) -> NonNull<[u8]> { - let (mut raw_ptr, metadata) = ptr_meta::PtrExt::to_raw_parts(ptr.as_ptr()); - - raw_ptr = (raw_ptr as usize | 1) as *mut (); - - debug_assert!(is_ptr_in_arena_mode(unsafe { - NonNull::new_unchecked(raw_ptr as *mut u8) - })); - - unsafe { - // Safety: - NonNull::new_unchecked(ptr_meta::from_raw_parts_mut(raw_ptr, metadata)) - } -} - -fn is_ptr_in_arena_mode(ptr: NonNull) -> bool { - let ptr = ptr.as_ptr() as usize; - ptr & 1 == 1 + ptr } unsafe impl allocator_api2::alloc::Allocator for SwcAlloc { @@ -77,7 +70,7 @@ unsafe impl allocator_api2::alloc::Allocator for SwcAlloc { } unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { - if is_ptr_in_arena_mode(ptr) { + if self.is_arena_mode { debug_assert!( ALLOC.is_set(), "Deallocating a pointer allocated with arena mode with a non-arena mode allocator" @@ -100,7 +93,7 @@ unsafe impl allocator_api2::alloc::Allocator for SwcAlloc { old_layout: Layout, new_layout: Layout, ) -> Result, allocator_api2::alloc::AllocError> { - if is_ptr_in_arena_mode(ptr) { + if self.is_arena_mode { debug_assert!( ALLOC.is_set(), "Growing a pointer allocated with arena mode with a non-arena mode allocator" @@ -118,7 +111,7 @@ unsafe impl allocator_api2::alloc::Allocator for SwcAlloc { old_layout: Layout, new_layout: Layout, ) -> Result, allocator_api2::alloc::AllocError> { - if is_ptr_in_arena_mode(ptr) { + if self.is_arena_mode { debug_assert!( ALLOC.is_set(), "Growing a pointer allocated with arena mode with a non-arena mode allocator" @@ -136,7 +129,7 @@ unsafe impl allocator_api2::alloc::Allocator for SwcAlloc { old_layout: Layout, new_layout: Layout, ) -> Result, allocator_api2::alloc::AllocError> { - if is_ptr_in_arena_mode(ptr) { + if self.is_arena_mode { debug_assert!( ALLOC.is_set(), "Shrinking a pointer allocated with arena mode with a non-arena mode allocator" diff --git a/crates/swc_allocator/src/boxed/mod.rs b/crates/swc_allocator/src/boxed/mod.rs index 09e7ce5346bd..3e05e5e54de9 100644 --- a/crates/swc_allocator/src/boxed/mod.rs +++ b/crates/swc_allocator/src/boxed/mod.rs @@ -54,7 +54,10 @@ impl Box { /// See [`std::boxed::Box::new`]. #[inline(always)] pub fn new(value: T) -> Self { - Self(allocator_api2::boxed::Box::new_in(value, SwcAlloc)) + Self(allocator_api2::boxed::Box::new_in( + value, + SwcAlloc::default(), + )) } /// Moves the value out of the box. @@ -106,7 +109,10 @@ impl Box { /// [memory layout]: self#memory-layout /// [`Layout`]: crate::Layout pub unsafe fn from_raw(raw: *mut T) -> Self { - Self(allocator_api2::boxed::Box::from_raw_in(raw, SwcAlloc)) + Self(allocator_api2::boxed::Box::from_raw_in( + raw, + SwcAlloc::default(), + )) } /// Consumes the `Box`, returning a wrapped raw pointer. diff --git a/crates/swc_allocator/src/vec/mod.rs b/crates/swc_allocator/src/vec/mod.rs index 9b3adbca19d7..fbea86417593 100644 --- a/crates/swc_allocator/src/vec/mod.rs +++ b/crates/swc_allocator/src/vec/mod.rs @@ -20,7 +20,8 @@ impl Vec { pub fn with_capacity(capacity: usize) -> Self { Self(allocator_api2::vec::Vec::with_capacity_in( - capacity, SwcAlloc, + capacity, + SwcAlloc::default(), )) } @@ -163,7 +164,10 @@ impl Vec { /// ``` pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { Self(allocator_api2::vec::Vec::from_raw_parts_in( - ptr, length, capacity, SwcAlloc, + ptr, + length, + capacity, + SwcAlloc::default(), )) } } @@ -184,7 +188,7 @@ impl DerefMut for Vec { impl Default for Vec { fn default() -> Self { - Self(allocator_api2::vec::Vec::new_in(SwcAlloc)) + Self(allocator_api2::vec::Vec::new_in(SwcAlloc::default())) } } From e6a2e8ece9ca41907585328d491c7fd828cc7a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 14:56:33 +0900 Subject: [PATCH 14/21] LTO --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ae8f45d1ca9d..d026af7976c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,7 +141,7 @@ resolver = "2" wasmer-wasix = { version = "0.18.0", default-features = false } [profile.release] -# lto = true +lto = true # We use CARGO_PROFILE_RELEASE_LTO for production builds # lto = "fat" @@ -151,7 +151,7 @@ resolver = "2" [profile.bench] debug = true -# lto = true +lto = true # Optimize for iteration [profile.dev.build-override] From 764d4b7c61cab4026badb14189b1f6426618cad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 14:58:20 +0900 Subject: [PATCH 15/21] test --- crates/swc_allocator/tests/apis.rs | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/swc_allocator/tests/apis.rs b/crates/swc_allocator/tests/apis.rs index 8b137891791f..377251cd50f2 100644 --- a/crates/swc_allocator/tests/apis.rs +++ b/crates/swc_allocator/tests/apis.rs @@ -1 +1,36 @@ +use criterion::black_box; +use swc_allocator::Allocator; +#[test] +fn direct_alloc_std() { + let mut buf = std::vec::Vec::new(); + for i in 0..1000 { + let item: std::boxed::Box = black_box(std::boxed::Box::new(black_box(i))); + buf.push(item); + } +} + +#[test] +fn direct_alloc_no_scope() { + let mut vec = swc_allocator::vec::Vec::new(); + for i in 0..1000 { + let item: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(i))); + vec.push(item); + } +} + +#[test] +fn direct_alloc_in_scope() { + let allocator = Allocator::default(); + + allocator.scope(|| { + let mut vec = swc_allocator::vec::Vec::new(); + + for i in 0..1000 { + let item: swc_allocator::boxed::Box = + black_box(swc_allocator::boxed::Box::new(black_box(i))); + vec.push(item); + } + }); +} From 53939c301cf44913979166d2f3505c8e1ffb228a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:02:37 +0900 Subject: [PATCH 16/21] Revert "LTO" This reverts commit e6a2e8ece9ca41907585328d491c7fd828cc7a2a. --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d026af7976c5..ae8f45d1ca9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,7 +141,7 @@ resolver = "2" wasmer-wasix = { version = "0.18.0", default-features = false } [profile.release] -lto = true +# lto = true # We use CARGO_PROFILE_RELEASE_LTO for production builds # lto = "fat" @@ -151,7 +151,7 @@ lto = true [profile.bench] debug = true -lto = true +# lto = true # Optimize for iteration [profile.dev.build-override] From e4f57ea648c169d8133e008078d4cf5a59072be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:14:13 +0900 Subject: [PATCH 17/21] Rename --- crates/swc_allocator/src/alloc.rs | 14 +++++++++++--- crates/swc_allocator/src/boxed/mod.rs | 8 +++++++- crates/swc_allocator/src/lib.rs | 24 +++++++++++++++++++----- crates/swc_allocator/src/vec/mod.rs | 15 ++++++++++++++- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/crates/swc_allocator/src/alloc.rs b/crates/swc_allocator/src/alloc.rs index f135698679a8..934eabbc9e05 100644 --- a/crates/swc_allocator/src/alloc.rs +++ b/crates/swc_allocator/src/alloc.rs @@ -3,13 +3,21 @@ use std::{alloc::Layout, ptr::NonNull}; use allocator_api2::alloc::Global; use scoped_tls::scoped_thread_local; -use crate::Allocator; +use crate::{FastAlloc, MemorySpace}; -scoped_thread_local!(pub(crate) static ALLOC: Allocator); +scoped_thread_local!(pub(crate) static ALLOC: MemorySpace); #[derive(Debug, Clone, Copy)] pub struct SwcAlloc { - is_arena_mode: bool, + pub(crate) is_arena_mode: bool, +} + +impl Default for FastAlloc { + fn default() -> Self { + Self { + is_arena_mode: ALLOC.is_set(), + } + } } impl Default for SwcAlloc { diff --git a/crates/swc_allocator/src/boxed/mod.rs b/crates/swc_allocator/src/boxed/mod.rs index 3e05e5e54de9..2748adb6caba 100644 --- a/crates/swc_allocator/src/boxed/mod.rs +++ b/crates/swc_allocator/src/boxed/mod.rs @@ -7,7 +7,7 @@ use std::{ pin::Pin, }; -use crate::alloc::SwcAlloc; +use crate::{alloc::SwcAlloc, FastAlloc}; #[cfg(feature = "rkyv")] mod rkyv; @@ -627,3 +627,9 @@ where self.0.len() } } + +impl FastAlloc { + pub fn alloc(self, t: T) -> Box { + Box(allocator_api2::boxed::Box::new_in(t, self.swc_alloc())) + } +} diff --git a/crates/swc_allocator/src/lib.rs b/crates/swc_allocator/src/lib.rs index 27728c2b4792..f45ba6568c12 100644 --- a/crates/swc_allocator/src/lib.rs +++ b/crates/swc_allocator/src/lib.rs @@ -4,6 +4,7 @@ #![allow(clippy::needless_doctest_main)] +use alloc::SwcAlloc; use std::ops::{Deref, DerefMut}; use bumpalo::Bump; @@ -14,12 +15,25 @@ mod alloc; pub mod boxed; pub mod vec; +#[derive(Debug, Clone, Copy)] +pub struct FastAlloc { + is_arena_mode: bool, +} + +impl FastAlloc { + fn swc_alloc(self) -> SwcAlloc { + SwcAlloc { + is_arena_mode: self.is_arena_mode, + } + } +} + #[derive(Default)] -pub struct Allocator { +pub struct MemorySpace { alloc: Bump, } -impl Allocator { +impl MemorySpace { /// Invokes `f` in a scope where the allocations are done in this allocator. #[inline(always)] pub fn scope(&self, f: F) -> R @@ -30,13 +44,13 @@ impl Allocator { } } -impl From for Allocator { +impl From for MemorySpace { fn from(alloc: Bump) -> Self { Self { alloc } } } -impl Deref for Allocator { +impl Deref for MemorySpace { type Target = Bump; fn deref(&self) -> &Bump { @@ -44,7 +58,7 @@ impl Deref for Allocator { } } -impl DerefMut for Allocator { +impl DerefMut for MemorySpace { fn deref_mut(&mut self) -> &mut Bump { &mut self.alloc } diff --git a/crates/swc_allocator/src/vec/mod.rs b/crates/swc_allocator/src/vec/mod.rs index fbea86417593..3ca69557b399 100644 --- a/crates/swc_allocator/src/vec/mod.rs +++ b/crates/swc_allocator/src/vec/mod.rs @@ -3,7 +3,7 @@ use std::ops::{Deref, DerefMut}; #[cfg(feature = "rkyv")] mod rkyv; -use crate::{alloc::SwcAlloc, boxed::Box}; +use crate::{alloc::SwcAlloc, boxed::Box, FastAlloc}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] @@ -243,3 +243,16 @@ impl Extend for Vec { self.0.extend(iter) } } + +impl FastAlloc { + pub fn vec(self) -> Vec { + Vec(allocator_api2::vec::Vec::new_in(self.swc_alloc())) + } + + pub fn vec_with_capacity(self, capacity: usize) -> Vec { + Vec(allocator_api2::vec::Vec::with_capacity_in( + capacity, + self.swc_alloc(), + )) + } +} From 0be7c20b7e95328ae4d73d6a89ca6f16215770b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:14:32 +0900 Subject: [PATCH 18/21] More bench --- crates/swc_allocator/benches/bench.rs | 44 ++++++++++++++++++++++++--- crates/swc_allocator/tests/apis.rs | 4 +-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index c3cf091e91bf..9c692c6e2a14 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -1,7 +1,7 @@ extern crate swc_malloc; use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion}; -use swc_allocator::Allocator; +use swc_allocator::{FastAlloc, MemorySpace}; fn bench_alloc(c: &mut Criterion) { fn direct_alloc_std(b: &mut Bencher, times: usize) { @@ -25,9 +25,22 @@ fn bench_alloc(c: &mut Criterion) { }) } - fn direct_alloc_in_scope(b: &mut Bencher, times: usize) { + fn fast_alloc_no_scope(b: &mut Bencher, times: usize) { b.iter(|| { - let allocator = Allocator::default(); + let allocator = FastAlloc::default(); + + let mut vec = allocator.vec(); + for i in 0..times { + let item: swc_allocator::boxed::Box = + black_box(allocator.alloc(black_box(i))); + vec.push(item); + } + }) + } + + fn direct_alloc_scoped(b: &mut Bencher, times: usize) { + b.iter(|| { + let allocator = MemorySpace::default(); allocator.scope(|| { let mut vec = swc_allocator::vec::Vec::new(); @@ -41,6 +54,22 @@ fn bench_alloc(c: &mut Criterion) { }) } + fn fast_alloc_scoped(b: &mut Bencher, times: usize) { + b.iter(|| { + MemorySpace::default().scope(|| { + let allocator = FastAlloc::default(); + + let mut vec = allocator.vec(); + + for i in 0..times { + let item: swc_allocator::boxed::Box = + black_box(allocator.alloc(black_box(i))); + vec.push(item); + } + }); + }) + } + c.bench_function("common/allocator/alloc/std/100000", |b| { direct_alloc_std(b, 100000) }); @@ -48,7 +77,14 @@ fn bench_alloc(c: &mut Criterion) { direct_alloc_no_scope(b, 100000) }); c.bench_function("common/allocator/alloc/scoped/100000", |b| { - direct_alloc_in_scope(b, 100000) + direct_alloc_scoped(b, 100000) + }); + + c.bench_function("common/allocator/alloc/cached-no-scope/100000", |b| { + fast_alloc_no_scope(b, 100000) + }); + c.bench_function("common/allocator/alloc/cached-scoped/100000", |b| { + fast_alloc_scoped(b, 100000) }); } diff --git a/crates/swc_allocator/tests/apis.rs b/crates/swc_allocator/tests/apis.rs index 377251cd50f2..5a796d9ad4cd 100644 --- a/crates/swc_allocator/tests/apis.rs +++ b/crates/swc_allocator/tests/apis.rs @@ -1,5 +1,5 @@ use criterion::black_box; -use swc_allocator::Allocator; +use swc_allocator::MemorySpace; #[test] fn direct_alloc_std() { @@ -22,7 +22,7 @@ fn direct_alloc_no_scope() { #[test] fn direct_alloc_in_scope() { - let allocator = Allocator::default(); + let allocator = MemorySpace::default(); allocator.scope(|| { let mut vec = swc_allocator::vec::Vec::new(); From f2c22f03f3204e80ee2211f37fac9aa78f81a690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:18:55 +0900 Subject: [PATCH 19/21] fix perf bug --- crates/swc_allocator/src/alloc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/swc_allocator/src/alloc.rs b/crates/swc_allocator/src/alloc.rs index 934eabbc9e05..7d109734bdd8 100644 --- a/crates/swc_allocator/src/alloc.rs +++ b/crates/swc_allocator/src/alloc.rs @@ -34,7 +34,7 @@ impl SwcAlloc { &self, f: impl FnOnce(&dyn allocator_api2::alloc::Allocator, bool) -> T, ) -> T { - if ALLOC.is_set() { + if self.is_arena_mode { ALLOC.with(|a| { // f(&&**a as &dyn allocator_api2::alloc::Allocator, true) From f11fbfbd9fb90a84aaec9cc354bbbde0c20cdc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:21:20 +0900 Subject: [PATCH 20/21] Make benchmark more reliable --- crates/swc_allocator/benches/bench.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/swc_allocator/benches/bench.rs b/crates/swc_allocator/benches/bench.rs index 9c692c6e2a14..6b27b4bf26d7 100644 --- a/crates/swc_allocator/benches/bench.rs +++ b/crates/swc_allocator/benches/bench.rs @@ -70,21 +70,21 @@ fn bench_alloc(c: &mut Criterion) { }) } - c.bench_function("common/allocator/alloc/std/100000", |b| { - direct_alloc_std(b, 100000) + c.bench_function("common/allocator/alloc/std/1000000", |b| { + direct_alloc_std(b, 1000000) }); - c.bench_function("common/allocator/alloc/no-scope/100000", |b| { - direct_alloc_no_scope(b, 100000) + c.bench_function("common/allocator/alloc/no-scope/1000000", |b| { + direct_alloc_no_scope(b, 1000000) }); - c.bench_function("common/allocator/alloc/scoped/100000", |b| { - direct_alloc_scoped(b, 100000) + c.bench_function("common/allocator/alloc/scoped/1000000", |b| { + direct_alloc_scoped(b, 1000000) }); - c.bench_function("common/allocator/alloc/cached-no-scope/100000", |b| { - fast_alloc_no_scope(b, 100000) + c.bench_function("common/allocator/alloc/cached-no-scope/1000000", |b| { + fast_alloc_no_scope(b, 1000000) }); - c.bench_function("common/allocator/alloc/cached-scoped/100000", |b| { - fast_alloc_scoped(b, 100000) + c.bench_function("common/allocator/alloc/cached-scoped/1000000", |b| { + fast_alloc_scoped(b, 1000000) }); } From 0efee47e669b254545acc4f2985389347a71425c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4=20=28Donny=29?= Date: Sun, 14 Jul 2024 15:57:32 +0900 Subject: [PATCH 21/21] ubuntu --- .github/workflows/CI.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 84d4a00fa283..9be94394bd23 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -330,6 +330,7 @@ jobs: tool: cargo-hack@0.5.29 - name: Check compilation + if: matrix.settings.os == 'ubuntu-latest' run: | ./scripts/github/run-cargo-hack.sh ${{ matrix.settings.crate }}