Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 107 additions & 110 deletions crates/oxc_allocator/src/vec2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,28 +689,24 @@ impl<'bump, T: 'bump> Vec<'bump, T> {
Vec { buf: RawVec::from_raw_parts_in(ptr, bump, capacity, length) }
}

/// Returns a shared reference to the allocator backing this `Vec`.
/// Returns the number of elements in the vector, also referred to as its 'length'.
///
/// # Examples
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// // uses the same allocator as the provided `Vec`
/// fn add_strings<'bump>(vec: &mut Vec<'bump, &'bump str>) {
/// for string in ["foo", "bar", "baz"] {
/// vec.push(vec.bump().alloc_str(string));
/// }
/// }
/// let b = Bump::new();
///
/// let a = bumpalo::vec![in &b; 1, 2, 3];
/// assert_eq!(a.len(), 3);
/// ```
#[inline]
#[must_use]
pub fn bump(&self) -> &'bump Bump {
self.buf.bump()
pub fn len(&self) -> usize {
self.buf.len_usize()
}

/// Returns the number of elements the vector can hold without
/// reallocating.
/// Returns the number of elements the vector can hold without reallocating.
///
/// # Examples
///
Expand All @@ -726,6 +722,105 @@ impl<'bump, T: 'bump> Vec<'bump, T> {
self.buf.cap_usize()
}

/// Sets the length of a vector.
///
/// This will explicitly set the size of the vector, without actually modifying its buffers,
/// so it is up to the caller to ensure that the vector is actually the specified size.
///
/// # Safety
///
/// * `new_len` must be less than or equal to `u32::MAX`.
/// * `new_len` must be less than or equal to [`capacity()`].
/// * The elements at `old_len..new_len` must be initialized.
///
/// [`capacity()`]: Vec::capacity
///
/// # Examples
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// use std::ptr;
///
/// let b = Bump::new();
///
/// let mut vec = bumpalo::vec![in &b; 'r', 'u', 's', 't'];
///
/// unsafe {
/// ptr::drop_in_place(&mut vec[3]);
/// vec.set_len(3);
/// }
/// assert_eq!(vec, ['r', 'u', 's']);
/// ```
///
/// In this example, there is a memory leak since the memory locations
/// owned by the inner vectors were not freed prior to the `set_len` call:
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// let b = Bump::new();
///
/// let mut vec = bumpalo::vec![in &b;
/// bumpalo::vec![in &b; 1, 0, 0],
/// bumpalo::vec![in &b; 0, 1, 0],
/// bumpalo::vec![in &b; 0, 0, 1]];
/// unsafe {
/// vec.set_len(0);
/// }
/// ```
///
/// In this example, the vector gets expanded from zero to four items
/// but we directly initialize uninitialized memory:
///
// TODO: rely upon `spare_capacity_mut`
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// let len = 4;
/// let b = Bump::new();
///
/// let mut vec: Vec<u8> = Vec::with_capacity_in(len, &b);
///
/// for i in 0..len {
/// // SAFETY: we initialize memory via `pointer::write`
/// unsafe { vec.as_mut_ptr().add(i).write(b'a') }
/// }
///
/// unsafe {
/// vec.set_len(len);
/// }
///
/// assert_eq!(b"aaaa", &*vec);
/// ```
#[inline]
pub unsafe fn set_len(&mut self, new_len: usize) {
// Caller guarantees `new_len <= u32::MAX`, so `new_len as u32` cannot truncate `new_len`
#[expect(clippy::cast_possible_truncation)]
let new_len = new_len as u32;
self.buf.len = new_len;
}

/// Returns a shared reference to the allocator backing this `Vec`.
///
/// # Examples
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// // uses the same allocator as the provided `Vec`
/// fn add_strings<'bump>(vec: &mut Vec<'bump, &'bump str>) {
/// for string in ["foo", "bar", "baz"] {
/// vec.push(vec.bump().alloc_str(string));
/// }
/// }
/// ```
#[inline]
#[must_use]
pub fn bump(&self) -> &'bump Bump {
self.buf.bump()
}

/// Reserves capacity for at least `additional` more elements to be inserted
/// in the given `Vec<'bump, T>`. The collection may reserve more space to avoid
/// frequent reallocations. After calling `reserve`, capacity will be
Expand Down Expand Up @@ -1087,86 +1182,6 @@ impl<'bump, T: 'bump> Vec<'bump, T> {
ptr
}

/// Sets the length of a vector.
///
/// This will explicitly set the size of the vector, without actually
/// modifying its buffers, so it is up to the caller to ensure that the
/// vector is actually the specified size.
///
/// # Safety
///
/// - `new_len` must be less than or equal to `u32::MAX`.
/// - `new_len` must be less than or equal to [`capacity()`].
/// - The elements at `old_len..new_len` must be initialized.
///
/// [`capacity()`]: struct.Vec.html#method.capacity
///
/// # Examples
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// use std::ptr;
///
/// let b = Bump::new();
///
/// let mut vec = bumpalo::vec![in &b; 'r', 'u', 's', 't'];
///
/// unsafe {
/// ptr::drop_in_place(&mut vec[3]);
/// vec.set_len(3);
/// }
/// assert_eq!(vec, ['r', 'u', 's']);
/// ```
///
/// In this example, there is a memory leak since the memory locations
/// owned by the inner vectors were not freed prior to the `set_len` call:
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// let b = Bump::new();
///
/// let mut vec = bumpalo::vec![in &b;
/// bumpalo::vec![in &b; 1, 0, 0],
/// bumpalo::vec![in &b; 0, 1, 0],
/// bumpalo::vec![in &b; 0, 0, 1]];
/// unsafe {
/// vec.set_len(0);
/// }
/// ```
///
/// In this example, the vector gets expanded from zero to four items
/// but we directly initialize uninitialized memory:
///
// TODO: rely upon `spare_capacity_mut`
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// let len = 4;
/// let b = Bump::new();
///
/// let mut vec: Vec<u8> = Vec::with_capacity_in(len, &b);
///
/// for i in 0..len {
/// // SAFETY: we initialize memory via `pointer::write`
/// unsafe { vec.as_mut_ptr().add(i).write(b'a') }
/// }
///
/// unsafe {
/// vec.set_len(len);
/// }
///
/// assert_eq!(b"aaaa", &*vec);
/// ```
#[inline]
pub unsafe fn set_len(&mut self, new_len: usize) {
// Caller guarantees `new_len <= u32::MAX`, so `new_len as u32` cannot truncate `new_len`
#[expect(clippy::cast_possible_truncation)]
let new_len = new_len as u32;
self.buf.len = new_len;
}

/// Removes an element from the vector and returns it.
///
/// The removed element is replaced by the last element of the vector.
Expand Down Expand Up @@ -1749,24 +1764,6 @@ impl<'bump, T: 'bump> Vec<'bump, T> {
self.truncate(0)
}

/// Returns the number of elements in the vector, also referred to
/// as its 'length'.
///
/// # Examples
///
/// ```
/// use bumpalo::{Bump, collections::Vec};
///
/// let b = Bump::new();
///
/// let a = bumpalo::vec![in &b; 1, 2, 3];
/// assert_eq!(a.len(), 3);
/// ```
#[inline]
pub fn len(&self) -> usize {
self.buf.len_usize()
}

/// Returns `true` if the vector contains no elements.
///
/// # Examples
Expand Down
18 changes: 7 additions & 11 deletions crates/oxc_allocator/src/vec2/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@ impl<'a, T> RawVec<'a, T> {
RawVec { ptr, a, cap, len: 0 }
}
}
}

impl<'a, T> RawVec<'a, T> {
/// Reconstitutes a RawVec from a pointer, capacity, and allocator.
///
/// # SAFETY
Expand All @@ -147,16 +145,21 @@ impl<'a, T> RawVec<'a, T> {

RawVec { ptr, len, cap, a }
}
}

impl<'a, T> RawVec<'a, T> {
/// Gets a raw pointer to the start of the allocation. Note that this is
/// Unique::empty() if `cap = 0` or T is zero-sized. In the former case, you must
/// be careful.
pub fn ptr(&self) -> *mut T {
self.ptr.as_ptr()
}

/// Gets the usize number of elements.
pub fn len_usize(&self) -> usize {
// `self.len as usize` is safe because it's is `u32` so it must be
// less than `usize::MAX`.
self.len as usize
}

/// Gets the capacity of the allocation.
///
/// This will always be `u32::MAX` if `T` is zero-sized.
Expand All @@ -175,13 +178,6 @@ impl<'a, T> RawVec<'a, T> {
if mem::size_of::<T>() == 0 { !0 } else { self.cap as usize }
}

/// Gets the usize number of elements.
pub fn len_usize(&self) -> usize {
// `self.len as usize` is safe because it's is `u32` so it must be
// less than `usize::MAX`.
self.len as usize
}

/// Returns a shared reference to the allocator backing this RawVec.
pub fn bump(&self) -> &'a Bump {
self.a
Expand Down
Loading