@@ -8,14 +8,6 @@ use bumpalo::Bump;
88
99use oxc_data_structures:: assert_unchecked;
1010
11- #[ cfg( feature = "track_allocations" ) ]
12- use std:: sync:: atomic:: {
13- AtomicUsize ,
14- Ordering :: { Relaxed , SeqCst } ,
15- } ;
16- #[ cfg( feature = "track_allocations" ) ]
17- static NUM_ALLOC : AtomicUsize = AtomicUsize :: new ( 0 ) ;
18-
1911/// A bump-allocated memory arena.
2012///
2113/// # Anatomy of an Allocator
@@ -222,7 +214,20 @@ static NUM_ALLOC: AtomicUsize = AtomicUsize::new(0);
222214/// [`HashMap::new_in`]: crate::HashMap::new_in
223215#[ derive( Default ) ]
224216pub struct Allocator {
217+ #[ cfg( not( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ) ]
225218 bump : Bump ,
219+ // NOTE: We need to expose `bump` publicly here for calculating its field offset in memory.
220+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
221+ #[ doc( hidden) ]
222+ pub bump : Bump ,
223+ /// Used to track the total number of allocations made in this allocator when the `track_allocations` feature is enabled.
224+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
225+ #[ doc( hidden) ]
226+ pub num_alloc : std:: sync:: atomic:: AtomicUsize ,
227+ /// Used to track the total number of re-allocations made in this allocator when the `track_allocations` feature is enabled.
228+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
229+ #[ doc( hidden) ]
230+ pub num_realloc : std:: sync:: atomic:: AtomicUsize ,
226231}
227232
228233impl Allocator {
@@ -249,7 +254,13 @@ impl Allocator {
249254 #[ expect( clippy:: inline_always) ]
250255 #[ inline( always) ]
251256 pub fn new ( ) -> Self {
252- Self { bump : Bump :: new ( ) }
257+ Self {
258+ bump : Bump :: new ( ) ,
259+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
260+ num_alloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
261+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
262+ num_realloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
263+ }
253264 }
254265
255266 /// Create a new [`Allocator`] with specified capacity.
@@ -260,7 +271,13 @@ impl Allocator {
260271 #[ expect( clippy:: inline_always) ]
261272 #[ inline( always) ]
262273 pub fn with_capacity ( capacity : usize ) -> Self {
263- Self { bump : Bump :: with_capacity ( capacity) }
274+ Self {
275+ bump : Bump :: with_capacity ( capacity) ,
276+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
277+ num_alloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
278+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
279+ num_realloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
280+ }
264281 }
265282
266283 /// Allocate an object in this [`Allocator`] and return an exclusive reference to it.
@@ -284,10 +301,9 @@ impl Allocator {
284301 pub fn alloc < T > ( & self , val : T ) -> & mut T {
285302 const { assert ! ( !std:: mem:: needs_drop:: <T >( ) , "Cannot allocate Drop type in arena" ) } ;
286303
287- #[ cfg( feature = "track_allocations" ) ]
288- {
289- NUM_ALLOC . fetch_add ( 1 , Relaxed ) ;
290- }
304+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
305+ self . num_alloc . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
306+
291307 self . bump . alloc ( val)
292308 }
293309
@@ -309,10 +325,9 @@ impl Allocator {
309325 #[ expect( clippy:: inline_always) ]
310326 #[ inline( always) ]
311327 pub fn alloc_str < ' alloc > ( & ' alloc self , src : & str ) -> & ' alloc str {
312- #[ cfg( feature = "track_allocations" ) ]
313- {
314- NUM_ALLOC . fetch_add ( 1 , Relaxed ) ;
315- }
328+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
329+ self . num_alloc . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
330+
316331 self . bump . alloc_str ( src)
317332 }
318333
@@ -333,10 +348,9 @@ impl Allocator {
333348 #[ expect( clippy:: inline_always) ]
334349 #[ inline( always) ]
335350 pub fn alloc_slice_copy < T : Copy > ( & self , src : & [ T ] ) -> & mut [ T ] {
336- #[ cfg( feature = "track_allocations" ) ]
337- {
338- NUM_ALLOC . fetch_add ( 1 , Relaxed ) ;
339- }
351+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
352+ self . num_alloc . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
353+
340354 self . bump . alloc_slice_copy ( src)
341355 }
342356
@@ -349,10 +363,9 @@ impl Allocator {
349363 ///
350364 /// Panics if reserving space matching `layout` fails.
351365 pub fn alloc_layout ( & self , layout : Layout ) -> NonNull < u8 > {
352- #[ cfg( feature = "track_allocations" ) ]
353- {
354- NUM_ALLOC . fetch_add ( 1 , Relaxed ) ;
355- }
366+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
367+ self . num_alloc . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
368+
356369 self . bump . alloc_layout ( layout)
357370 }
358371
@@ -403,10 +416,8 @@ impl Allocator {
403416 "attempted to create a string longer than `isize::MAX` bytes"
404417 ) ;
405418
406- #[ cfg( feature = "track_allocations" ) ]
407- {
408- NUM_ALLOC . fetch_add ( 1 , Relaxed ) ;
409- }
419+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
420+ self . num_alloc . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
410421
411422 // Create actual `&str` in a separate function, to ensure that `alloc_concat_strs_array`
412423 // is inlined, so that compiler has knowledge to remove the overflow checks above.
@@ -500,10 +511,12 @@ impl Allocator {
500511 #[ expect( clippy:: inline_always) ]
501512 #[ inline( always) ]
502513 pub fn reset ( & mut self ) {
503- #[ cfg( feature = "track_allocations" ) ]
514+ #[ cfg( all ( feature = "track_allocations" , not ( feature = "disable_track_allocations" ) ) ) ]
504515 {
505- NUM_ALLOC . store ( 0 , SeqCst ) ;
516+ self . num_alloc . store ( 0 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
517+ self . num_realloc . store ( 0 , std:: sync:: atomic:: Ordering :: SeqCst ) ;
506518 }
519+
507520 self . bump . reset ( ) ;
508521 }
509522
@@ -604,12 +617,6 @@ impl Allocator {
604617 bytes
605618 }
606619
607- /// Returns the total number of allocations that have been made in this [`Allocator`] instance.
608- #[ cfg( feature = "track_allocations" ) ]
609- pub fn num_alloc ( ) -> usize {
610- NUM_ALLOC . load ( SeqCst )
611- }
612-
613620 /// Get inner [`bumpalo::Bump`].
614621 ///
615622 /// This method is not public. We don't want to expose `Bump` to user.
@@ -631,7 +638,13 @@ impl Allocator {
631638 #[ expect( clippy:: inline_always) ]
632639 #[ inline( always) ]
633640 pub ( crate ) fn from_bump ( bump : Bump ) -> Self {
634- Self { bump }
641+ Self {
642+ bump,
643+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
644+ num_alloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
645+ #[ cfg( all( feature = "track_allocations" , not( feature = "disable_track_allocations" ) ) ) ]
646+ num_realloc : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
647+ }
635648 }
636649}
637650
0 commit comments