pub struct Allocator { /* private fields */ }Expand description
Arena allocator for Vize.
A per-compile allocation handle. Template structures, retained oxc ASTs and
arena strings all allocate from the same pool, so a &'a Allocator hands
out &'a references that share one lifetime, and Allocator::reset
clears all of them at once — nothing allocated here survives a compile
boundary.
§Example
use vize_l0::{Allocator, Box, Vec};
let allocator = Allocator::default();
let allocator = &allocator;
let s = allocator.alloc_str("hello");
assert_eq!(s, "hello");
let boxed = Box::new_in(42, &allocator);
assert_eq!(*boxed, 42);
let mut vec = Vec::new_in(&allocator);
vec.push(1);
assert_eq!(vec.len(), 1);Implementations§
Source§impl Allocator
impl Allocator
Sourcepub fn with_capacity(capacity: usize) -> Allocator
pub fn with_capacity(capacity: usize) -> Allocator
Creates a new allocator with the specified capacity reserved.
Sourcepub fn alloc_owned<T>(&self, value: T) -> &T
pub fn alloc_owned<T>(&self, value: T) -> &T
Parks an owned value for the rest of the compile and borrows it at the arena’s lifetime.
The only callers are the compile entry points that receive an owned
cross-compile summary (Croquis) by value and must hand the transform
a reference at the arena’s lifetime — a local cannot produce one,
because 'a is chosen by the caller and outlives the whole body.
P1-10 implemented this by parking a ManuallyDrop<T> in the arena
itself, reproducing what bumpalo::Bump::alloc did before: the arena
never runs destructors, so the summary’s own heap allocations were
never released. Per compile that is a leak, and P1-11’s batch pool
compiles thousands of files per process, so the leak became the peak-RSS
story. The value therefore lives in a Box owned by the allocator now:
the borrow still ends at the arena’s lifetime, and Allocator::reset
(and dropping the allocator) runs the real destructor.
Arena-resident nodes stay Drop-free — the container const
assertions in crate::Box / crate::Vec keep them that way — and
this entry point does not widen for them: the Any bound implies
'static, so a parked value cannot hold an arena reference in the
first place. It takes owned values built outside the arena, nothing
else.
Sourcepub fn as_oxc(&self) -> &Allocator
pub fn as_oxc(&self) -> &Allocator
Returns the arena oxc parses retained ASTs into.
Identical to the pool everything else uses; the accessor is kept
because oxc_parser takes &oxc_allocator::Allocator by name.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Resets the allocator, freeing all allocated memory.
This allows reusing the allocator for a new compilation without
deallocating the underlying memory — the batch pool (crate::pool)
resets between files instead of building a new arena per file.
Everything allocated since the last reset is invalidated: arena bytes
are recycled (oxc keeps the current chunk and returns the rest to the
global allocator) and every value parked by Allocator::alloc_owned
is dropped. Taking &mut self is what makes that sound — no
arena-backed borrow can be alive here — and in debug builds the arena’s
generation advances, so a stamp taken before this call
(Allocator::stamp) panics when validated afterwards.
Sourcepub fn allocated_bytes(&self) -> usize
pub fn allocated_bytes(&self) -> usize
Returns the number of bytes currently allocated.
Arena bytes only: values parked by Allocator::alloc_owned own heap
allocations outside the arena and are not counted.
Sourcepub fn stamp(&self) -> ArenaStamp
pub fn stamp(&self) -> ArenaStamp
Stamps the arena’s current identity and generation.
The stamp is the escape check for values that leave the borrow
checker’s sight (a pointer round-trip, an owned park, a handle stored
in a side table): validate it with Allocator::assert_stamp_current
before reading, and a value that outlived a Allocator::reset panics
instead of returning another file’s bytes. Carries no data in release
builds, where validation is a no-op.
Sourcepub fn assert_stamp_current(&self, stamp: ArenaStamp)
pub fn assert_stamp_current(&self, stamp: ArenaStamp)
Panics when stamp did not come from this arena’s current generation.
No-op in release builds. See Allocator::stamp.
Methods from Deref<Target = Allocator>§
Sourcepub fn alloc_slice_copy<T>(&self, src: &[T]) -> &mut [T]where
T: Copy,
pub fn alloc_slice_copy<T>(&self, src: &[T]) -> &mut [T]where
T: Copy,
Sourcepub fn alloc_layout(&self, layout: Layout) -> NonNull<u8>
pub fn alloc_layout(&self, layout: Layout) -> NonNull<u8>
Allocate space for an object with the given Layout.
The returned pointer points at uninitialized memory, and should be initialized with
std::ptr::write.
§Panics
Panics if reserving space matching layout fails.
Sourcepub fn alloc_concat_strs_array<'a, const N: usize>(
&'a self,
strings: [&str; N],
) -> &'a str
pub fn alloc_concat_strs_array<'a, const N: usize>( &'a self, strings: [&str; N], ) -> &'a str
Create new &str from a fixed-size array of &strs concatenated together,
allocated in the given allocator.
§Panics
Panics if the sum of length of all strings exceeds isize::MAX.
§Example
use oxc_allocator::Allocator;
let allocator = Allocator::new();
let s = allocator.alloc_concat_strs_array(["hello", " ", "world", "!"]);
assert_eq!(s, "hello world!");Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Calculate the total capacity of this Allocator including all chunks, in bytes.
Note: This is the total amount of memory the Allocator owns NOT the total size of data
that’s been allocated in it. If you want the latter, use used_bytes instead.
§Examples
use oxc_allocator::Allocator;
let capacity = 64 * 1024; // 64 KiB
let mut allocator = Allocator::with_capacity(capacity);
allocator.alloc(123u64); // 8 bytes
// Result is the capacity (64 KiB), not the size of allocated data (8 bytes).
// `Allocator::with_capacity` may allocate a bit more than requested.
assert!(allocator.capacity() >= capacity);Sourcepub fn used_bytes(&self) -> usize
pub fn used_bytes(&self) -> usize
Calculate the total size of data used in this Allocator, in bytes.
This is the total amount of memory that has been used in the Allocator, NOT the amount of
memory the Allocator owns. If you want the latter, use capacity instead.
The result includes:
- Padding bytes between objects which have been allocated to preserve alignment of types where they have different alignments or have larger-than-typical alignment.
- Excess capacity in
Vecs,StringBuilders andHashMaps. - Objects which were allocated but later dropped.
Allocatordoes not re-use allocations, so anything which is allocated into arena continues to take up “dead space”, even after it’s no longer referenced anywhere. - “Dead space” left over where a
Vec,StringBuilderorHashMaphas grown and had to make a new allocation to accommodate its new larger size. Its old allocation continues to take up “dead” space in the allocator, unless it was the most recent allocation.
In practice, this almost always means that the result returned from this function will be an over-estimate vs the amount of “live” data in the arena.
However, if you are using the result of this method to create a new Allocator to clone
an AST into, it is theoretically possible (though very unlikely) that it may be a slight
under-estimate of the capacity required in new allocator to clone the AST into, depending
on the order that &strs were allocated into arena in parser vs the order they get allocated
during cloning. The order allocations are made in affects the amount of padding bytes required.
§Examples
use oxc_allocator::{Allocator, Vec};
let capacity = 64 * 1024; // 64 KiB
let mut allocator = Allocator::with_capacity(capacity);
allocator.alloc(1u8); // 1 byte with alignment 1
allocator.alloc(2u8); // 1 byte with alignment 1
allocator.alloc(3u64); // 8 bytes with alignment 8
// Only 10 bytes were allocated, but 16 bytes were used, in order to align `3u64` on 8
assert_eq!(allocator.used_bytes(), 16);
allocator.reset();
let mut vec = Vec::<u64>::with_capacity_in(2, &&allocator);
// Allocate something else, so `vec`'s allocation is not the most recent
allocator.alloc(123u64);
// `vec` has to grow beyond it's initial capacity
vec.extend([1, 2, 3, 4]);
// `vec` takes up 32 bytes, and `123u64` takes up 8 bytes = 40 total.
// But there's an additional 16 bytes consumed for `vec`'s original capacity of 2,
// which is still using up space
assert_eq!(allocator.used_bytes(), 56);Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Allocator
impl !RefUnwindSafe for Allocator
impl !Sync for Allocator
impl !UnwindSafe for Allocator
impl Send for Allocator
impl Unpin for Allocator
impl UnsafeUnpin for Allocator
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more