Skip to content

Commit 6ff6643

Browse files
committed
refactor(allocator): add error type to RawVec (#12204)
Add an error type `AllocError`, instead of using `bumpalo`'s error types. This is preparation for replacing `bumpalo` with our own allocator.
1 parent a9482f2 commit 6ff6643

File tree

2 files changed

+28
-26
lines changed

2 files changed

+28
-26
lines changed

crates/oxc_allocator/src/vec2/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,12 @@ use core::slice;
124124
// #[cfg(feature = "std")]
125125
// use std::io;
126126

127-
use bumpalo::collections::CollectionAllocErr;
128-
129127
use oxc_data_structures::assert_unchecked;
130128

131129
use crate::alloc::Alloc;
132130

133131
mod raw_vec;
134-
use raw_vec::RawVec;
132+
use raw_vec::{AllocError, RawVec};
135133

136134
unsafe fn arith_offset<T>(p: *const T, offset: isize) -> *const T {
137135
p.offset(offset)
@@ -921,7 +919,7 @@ impl<'a, T: 'a, A: Alloc> Vec<'a, T, A> {
921919
/// vec.try_reserve(10).unwrap();
922920
/// assert!(vec.capacity() >= 11);
923921
/// ```
924-
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
922+
pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
925923
self.buf.try_reserve(self.len_u32(), additional)
926924
}
927925

@@ -948,7 +946,7 @@ impl<'a, T: 'a, A: Alloc> Vec<'a, T, A> {
948946
/// vec.try_reserve_exact(10).unwrap();
949947
/// assert!(vec.capacity() >= 11);
950948
/// ```
951-
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
949+
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), AllocError> {
952950
self.buf.try_reserve_exact(self.len_u32(), additional)
953951
}
954952

crates/oxc_allocator/src/vec2/raw_vec.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ use core::cmp;
2828
use core::mem;
2929
use core::ptr::{self, NonNull};
3030

31-
use bumpalo::collections::CollectionAllocErr::{self, AllocErr, CapacityOverflow};
32-
3331
use crate::alloc::Alloc;
3432

33+
/// Error type for fallible methods:
34+
/// [`RawVec::try_reserve`], [`RawVec::try_reserve_exact`].
35+
pub enum AllocError {
36+
AllocErr,
37+
CapacityOverflow,
38+
}
39+
3540
// use boxed::Box;
3641

3742
/// A low-level utility for more ergonomically allocating, reallocating, and deallocating
@@ -353,11 +358,7 @@ impl<'a, T, A: Alloc> RawVec<'a, T, A> {
353358
*/
354359

355360
/// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
356-
pub fn try_reserve_exact(
357-
&mut self,
358-
len: u32,
359-
additional: usize,
360-
) -> Result<(), CollectionAllocErr> {
361+
pub fn try_reserve_exact(&mut self, len: u32, additional: usize) -> Result<(), AllocError> {
361362
if self.needs_to_grow(len, additional) {
362363
self.grow_exact(len, additional)?
363364
}
@@ -393,7 +394,7 @@ impl<'a, T, A: Alloc> RawVec<'a, T, A> {
393394
}
394395

395396
/// The same as `reserve`, but returns on errors instead of panicking or aborting.
396-
pub fn try_reserve(&mut self, len: u32, additional: usize) -> Result<(), CollectionAllocErr> {
397+
pub fn try_reserve(&mut self, len: u32, additional: usize) -> Result<(), AllocError> {
397398
if self.needs_to_grow(len, additional) {
398399
self.grow_amortized(len, additional)?;
399400
}
@@ -637,7 +638,7 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
637638

638639
/// Helper method to reserve additional space, reallocating the backing memory.
639640
/// The caller is responsible for confirming that there is not already enough space available.
640-
fn grow_exact(&mut self, len: u32, additional: usize) -> Result<(), CollectionAllocErr> {
641+
fn grow_exact(&mut self, len: u32, additional: usize) -> Result<(), AllocError> {
641642
unsafe {
642643
// NOTE: we don't early branch on ZSTs here because we want this
643644
// to actually catch "asking for more than u32::MAX" in that case.
@@ -646,8 +647,10 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
646647

647648
// `len as usize` is safe because `len` is `u32`, so it must be
648649
// less than `usize::MAX`.
649-
let new_cap = (len as usize).checked_add(additional).ok_or(CapacityOverflow)?;
650-
let new_layout = Layout::array::<T>(new_cap).map_err(|_| CapacityOverflow)?;
650+
let new_cap =
651+
(len as usize).checked_add(additional).ok_or(AllocError::CapacityOverflow)?;
652+
let new_layout =
653+
Layout::array::<T>(new_cap).map_err(|_| AllocError::CapacityOverflow)?;
651654

652655
self.ptr = self.finish_grow(new_layout)?.cast();
653656

@@ -663,7 +666,7 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
663666

664667
/// Helper method to reserve additional space, reallocating the backing memory.
665668
/// The caller is responsible for confirming that there is not already enough space available.
666-
fn grow_amortized(&mut self, len: u32, additional: usize) -> Result<(), CollectionAllocErr> {
669+
fn grow_amortized(&mut self, len: u32, additional: usize) -> Result<(), AllocError> {
667670
unsafe {
668671
// NOTE: we don't early branch on ZSTs here because we want this
669672
// to actually catch "asking for more than u32::MAX" in that case.
@@ -673,7 +676,8 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
673676
// Nothing we can really do about these checks, sadly.
674677
// `len as usize` is safe because `len` is `u32`, so it must be
675678
// less than `usize::MAX`.
676-
let required_cap = (len as usize).checked_add(additional).ok_or(CapacityOverflow)?;
679+
let required_cap =
680+
(len as usize).checked_add(additional).ok_or(AllocError::CapacityOverflow)?;
677681

678682
// This guarantees exponential growth. The doubling cannot overflow
679683
// because `cap <= isize::MAX` and the type of `cap` is `u32`.
@@ -707,7 +711,7 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
707711
// }
708712
// let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap);
709713

710-
let new_layout = Layout::array::<T>(cap).map_err(|_| CapacityOverflow)?;
714+
let new_layout = Layout::array::<T>(cap).map_err(|_| AllocError::CapacityOverflow)?;
711715

712716
self.ptr = self.finish_grow(new_layout)?.cast();
713717

@@ -723,7 +727,7 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
723727

724728
// Given a new layout, completes the grow operation.
725729
#[inline]
726-
fn finish_grow(&self, new_layout: Layout) -> Result<NonNull<u8>, CollectionAllocErr> {
730+
fn finish_grow(&self, new_layout: Layout) -> Result<NonNull<u8>, AllocError> {
727731
alloc_guard(new_layout.size())?;
728732

729733
let new_ptr = match self.current_layout() {
@@ -772,13 +776,13 @@ impl<T, A: Alloc> RawVec<'_, T, A> {
772776
// running on a platform which can use all 4GB in user-space. e.g. PAE or x32
773777

774778
#[inline]
775-
fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
779+
fn alloc_guard(alloc_size: usize) -> Result<(), AllocError> {
776780
if mem::size_of::<usize>() < 8 {
777781
if alloc_size > ::core::isize::MAX as usize {
778-
return Err(CapacityOverflow);
782+
return Err(AllocError::CapacityOverflow);
779783
}
780784
} else if alloc_size > u32::MAX as usize {
781-
return Err(CapacityOverflow);
785+
return Err(AllocError::CapacityOverflow);
782786
}
783787
Ok(())
784788
}
@@ -796,11 +800,11 @@ fn capacity_overflow() -> ! {
796800
// to make the call site function as small as possible, so it can be inlined.
797801
#[inline(never)]
798802
#[cold]
799-
fn handle_error(error: CollectionAllocErr) -> ! {
803+
fn handle_error(error: AllocError) -> ! {
800804
match error {
801-
CapacityOverflow => capacity_overflow(),
805+
AllocError::CapacityOverflow => capacity_overflow(),
802806
// TODO: call `handle_alloc_error` instead of `panic!` once the AllocErr stored a Layout,
803-
AllocErr => panic!("encountered allocation error"),
807+
AllocError::AllocErr => panic!("encountered allocation error"),
804808
}
805809
}
806810

0 commit comments

Comments
 (0)