Skip to content

Commit 8ec0c74

Browse files
committed
refactor(allocator/vec): access len and cap fields via getters/setters (#11081)
Follow-on after #10884. Pure refactor. To make it explicit when we're converting `u32` to/from `usize`: * Make `RawVec`'s `len` field private. * Make all access to `len` and `cap` fields go via getter/setter methods. * Name those methods `*_u32` and `*_usize` so it's clear when a conversion is happening. I also renamed `cap_*` methods to `capacity_*` for consistency with `Vec::capacity`. I haven't used these methods in `RawVec` because there's some subtlety around when you want the "raw" `cap` value, and when you want the value `capacity` method returns, which is different when `T` is a ZST. Hopefully we can remove support for ZSTs, and remove this ambiguity.
1 parent c331ece commit 8ec0c74

File tree

2 files changed

+109
-64
lines changed

2 files changed

+109
-64
lines changed

crates/oxc_allocator/src/vec2/mod.rs

Lines changed: 71 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,18 @@ impl<'a, T: 'a> Vec<'a, T> {
706706
self.buf.len_usize()
707707
}
708708

709+
/// Get number of elements in the vector as a `usize`.
710+
#[inline]
711+
fn len_usize(&self) -> usize {
712+
self.buf.len_usize()
713+
}
714+
715+
/// Get number of elements in the vector as a `u32`.
716+
#[inline]
717+
fn len_u32(&self) -> u32 {
718+
self.buf.len_u32()
719+
}
720+
709721
/// Returns the number of elements the vector can hold without reallocating.
710722
///
711723
/// # Examples
@@ -719,7 +731,19 @@ impl<'a, T: 'a> Vec<'a, T> {
719731
/// ```
720732
#[inline]
721733
pub fn capacity(&self) -> usize {
722-
self.buf.cap_usize()
734+
self.buf.capacity_usize()
735+
}
736+
737+
/// Get capacity of the vector as a `usize`.
738+
#[inline]
739+
fn capacity_usize(&self) -> usize {
740+
self.buf.capacity_usize()
741+
}
742+
743+
/// Get capacity of the vector as a `u32`.
744+
#[inline]
745+
fn capacity_u32(&self) -> u32 {
746+
self.buf.capacity_u32()
723747
}
724748

725749
/// Sets the length of a vector.
@@ -798,7 +822,7 @@ impl<'a, T: 'a> Vec<'a, T> {
798822
// Caller guarantees `new_len <= u32::MAX`, so `new_len as u32` cannot truncate `new_len`
799823
#[expect(clippy::cast_possible_truncation)]
800824
let new_len = new_len as u32;
801-
self.buf.len = new_len;
825+
self.buf.set_len(new_len);
802826
}
803827

804828
/// Returns a shared reference to the allocator backing this `Vec`.
@@ -842,7 +866,7 @@ impl<'a, T: 'a> Vec<'a, T> {
842866
/// assert!(vec.capacity() >= 11);
843867
/// ```
844868
pub fn reserve(&mut self, additional: usize) {
845-
self.buf.reserve(self.buf.len, additional);
869+
self.buf.reserve(self.len_u32(), additional);
846870
}
847871

848872
/// Reserves the minimum capacity for exactly `additional` more elements to
@@ -869,7 +893,7 @@ impl<'a, T: 'a> Vec<'a, T> {
869893
/// assert!(vec.capacity() >= 11);
870894
/// ```
871895
pub fn reserve_exact(&mut self, additional: usize) {
872-
self.buf.reserve_exact(self.buf.len, additional);
896+
self.buf.reserve_exact(self.len_u32(), additional);
873897
}
874898

875899
/// Attempts to reserve capacity for at least `additional` more elements to be inserted
@@ -893,7 +917,7 @@ impl<'a, T: 'a> Vec<'a, T> {
893917
/// assert!(vec.capacity() >= 11);
894918
/// ```
895919
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
896-
self.buf.try_reserve(self.buf.len, additional)
920+
self.buf.try_reserve(self.len_u32(), additional)
897921
}
898922

899923
/// Attempts to reserve the minimum capacity for exactly `additional` more elements to
@@ -920,7 +944,7 @@ impl<'a, T: 'a> Vec<'a, T> {
920944
/// assert!(vec.capacity() >= 11);
921945
/// ```
922946
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
923-
self.buf.try_reserve_exact(self.buf.len, additional)
947+
self.buf.try_reserve_exact(self.len_u32(), additional)
924948
}
925949

926950
/// Shrinks the capacity of the vector as much as possible.
@@ -942,8 +966,8 @@ impl<'a, T: 'a> Vec<'a, T> {
942966
/// assert!(vec.capacity() >= 3);
943967
/// ```
944968
pub fn shrink_to_fit(&mut self) {
945-
if self.buf.cap() != self.buf.len {
946-
self.buf.shrink_to_fit(self.buf.len);
969+
if self.len_u32() != self.capacity_u32() {
970+
self.buf.shrink_to_fit(self.len_u32());
947971
}
948972
}
949973

@@ -963,7 +987,7 @@ impl<'a, T: 'a> Vec<'a, T> {
963987
pub fn into_bump_slice(self) -> &'a [T] {
964988
unsafe {
965989
let ptr = self.as_ptr();
966-
let len = self.len();
990+
let len = self.len_usize();
967991
// Don't need `mem::forget(self)` here, because `Vec` does not implement `Drop`.
968992
slice::from_raw_parts(ptr, len)
969993
}
@@ -988,7 +1012,7 @@ impl<'a, T: 'a> Vec<'a, T> {
9881012
/// ```
9891013
pub fn into_bump_slice_mut(mut self) -> &'a mut [T] {
9901014
let ptr = self.as_mut_ptr();
991-
let len = self.len();
1015+
let len = self.len_usize();
9921016
// Don't need `mem::forget(self)` here, because `Vec` does not implement `Drop`.
9931017

9941018
unsafe { slice::from_raw_parts_mut(ptr, len) }
@@ -1049,7 +1073,7 @@ impl<'a, T: 'a> Vec<'a, T> {
10491073
/// [`clear`]: #method.clear
10501074
/// [`drain`]: #method.drain
10511075
pub fn truncate(&mut self, len: usize) {
1052-
let current_len = self.buf.len_usize();
1076+
let current_len = self.len_usize();
10531077
if len < current_len {
10541078
// SAFETY: `len` is less than current len, so cannot be greater than `u32::MAX`,
10551079
// and cannot be greater than `self.capacity()`.
@@ -1214,8 +1238,8 @@ impl<'a, T: 'a> Vec<'a, T> {
12141238
// bounds check on hole succeeds there must be a last element (which
12151239
// can be self[index] itself).
12161240
let hole: *mut T = &mut self[index];
1217-
let last = ptr::read(self.get_unchecked(self.buf.len_usize() - 1));
1218-
self.buf.len -= 1;
1241+
let last = ptr::read(self.get_unchecked(self.len_usize() - 1));
1242+
self.buf.decrease_len(1);
12191243
ptr::replace(hole, last)
12201244
}
12211245
}
@@ -1241,11 +1265,11 @@ impl<'a, T: 'a> Vec<'a, T> {
12411265
/// assert_eq!(vec, [1, 4, 2, 3, 5]);
12421266
/// ```
12431267
pub fn insert(&mut self, index: usize, element: T) {
1244-
let len = self.buf.len_usize();
1268+
let len = self.len_usize();
12451269
assert!(index <= len);
12461270

12471271
// space for the new element
1248-
if self.buf.len == self.buf.cap() {
1272+
if self.len_u32() == self.capacity_u32() {
12491273
self.buf.grow_one();
12501274
}
12511275

@@ -1261,7 +1285,7 @@ impl<'a, T: 'a> Vec<'a, T> {
12611285
// element.
12621286
ptr::write(p, element);
12631287
}
1264-
self.buf.len += 1;
1288+
self.buf.increase_len(1);
12651289
}
12661290
}
12671291

@@ -1284,7 +1308,7 @@ impl<'a, T: 'a> Vec<'a, T> {
12841308
/// assert_eq!(v, [1, 3]);
12851309
/// ```
12861310
pub fn remove(&mut self, index: usize) -> T {
1287-
let len = self.len();
1311+
let len = self.len_usize();
12881312
assert!(index < len);
12891313
unsafe {
12901314
// infallible
@@ -1365,7 +1389,7 @@ impl<'a, T: 'a> Vec<'a, T> {
13651389
where
13661390
F: FnMut(&mut T) -> bool,
13671391
{
1368-
let original_len = self.len();
1392+
let original_len = self.len_usize();
13691393

13701394
if original_len == 0 {
13711395
// Empty case: explicit return allows better optimization, vs letting compiler infer it
@@ -1482,7 +1506,7 @@ impl<'a, T: 'a> Vec<'a, T> {
14821506
where
14831507
F: FnMut(&mut T) -> bool,
14841508
{
1485-
let old_len = self.len();
1509+
let old_len = self.len_usize();
14861510

14871511
// Guard against us getting leaked (leak amplification)
14881512
unsafe {
@@ -1573,13 +1597,13 @@ impl<'a, T: 'a> Vec<'a, T> {
15731597
pub fn push(&mut self, value: T) {
15741598
// This will panic or abort if we would allocate > isize::MAX bytes
15751599
// or if the length increment would overflow for zero-sized types.
1576-
if self.buf.len == self.buf.cap() {
1600+
if self.len_u32() == self.capacity_u32() {
15771601
self.buf.grow_one();
15781602
}
15791603
unsafe {
1580-
let end = self.buf.ptr().add(self.buf.len_usize());
1604+
let end = self.buf.ptr().add(self.len_usize());
15811605
ptr::write(end, value);
1582-
self.buf.len += 1;
1606+
self.buf.increase_len(1);
15831607
}
15841608
}
15851609

@@ -1601,12 +1625,12 @@ impl<'a, T: 'a> Vec<'a, T> {
16011625
/// ```
16021626
#[inline]
16031627
pub fn pop(&mut self) -> Option<T> {
1604-
if self.buf.len == 0 {
1628+
if self.len_u32() == 0 {
16051629
None
16061630
} else {
16071631
unsafe {
1608-
self.buf.len -= 1;
1609-
Some(ptr::read(self.as_ptr().add(self.len())))
1632+
self.buf.decrease_len(1);
1633+
Some(ptr::read(self.as_ptr().add(self.len_usize())))
16101634
}
16111635
}
16121636
}
@@ -1654,15 +1678,15 @@ impl<'a, T: 'a> Vec<'a, T> {
16541678
#[allow(clippy::needless_borrow, clippy::allow_attributes)]
16551679
let count = (&*other).len();
16561680
self.reserve(count);
1657-
let len = self.len();
1681+
let len = self.len_usize();
16581682
ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
16591683
// `count` cannot be `> u32::MAX`, so `count as u32` cannot truncate `count`.
16601684
// `self.buf.len + count` cannot be `> u32::MAX`.
16611685
// If either of these conditions was violated, `self.reserve(count)` above would have panicked.
16621686
// So this addition cannot wrap around.
16631687
#[expect(clippy::cast_possible_truncation)]
16641688
let count = count as u32;
1665-
self.buf.len += count;
1689+
self.buf.increase_len(count);
16661690
}
16671691

16681692
/// Creates a draining iterator that removes the specified range in the vector
@@ -1712,7 +1736,7 @@ impl<'a, T: 'a> Vec<'a, T> {
17121736
// When finished, remaining tail of the vec is copied back to cover
17131737
// the hole, and the vector length is restored to the new length.
17141738
//
1715-
let len = self.len();
1739+
let len = self.len_usize();
17161740
let start = match range.start_bound() {
17171741
Included(&n) => n,
17181742
Excluded(&n) => n + 1,
@@ -1780,7 +1804,7 @@ impl<'a, T: 'a> Vec<'a, T> {
17801804
/// assert!(!v.is_empty());
17811805
/// ```
17821806
pub fn is_empty(&self) -> bool {
1783-
self.len() == 0
1807+
self.len_u32() == 0
17841808
}
17851809

17861810
/// Splits the collection into two at the given index.
@@ -1808,17 +1832,17 @@ impl<'a, T: 'a> Vec<'a, T> {
18081832
/// ```
18091833
#[inline]
18101834
pub fn split_off(&mut self, at: usize) -> Self {
1811-
assert!(at <= self.len(), "`at` out of bounds");
1835+
assert!(at <= self.len_usize(), "`at` out of bounds");
18121836

1813-
let other_len = self.buf.len_usize() - at;
1837+
let other_len = self.len_usize() - at;
18141838
let mut other = Vec::with_capacity_in(other_len, self.buf.bump());
18151839

18161840
// Unsafely `set_len` and copy items to `other`.
18171841
unsafe {
18181842
self.set_len(at);
18191843
other.set_len(other_len);
18201844

1821-
ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len());
1845+
ptr::copy_nonoverlapping(self.as_ptr().add(at), other.as_mut_ptr(), other.len_usize());
18221846
}
18231847
other
18241848
}
@@ -1889,7 +1913,7 @@ impl<'a, T: 'a + Clone> Vec<'a, T> {
18891913
/// [`Default`]: https://doc.rust-lang.org/std/default/trait.Default.html
18901914
/// [`resize_with`]: #method.resize_with
18911915
pub fn resize(&mut self, new_len: usize, value: T) {
1892-
let len = self.len();
1916+
let len = self.len_usize();
18931917

18941918
if new_len > len {
18951919
self.extend_with(new_len - len, ExtendElement(value))
@@ -1935,8 +1959,8 @@ impl<'a, T: 'a + Copy> Vec<'a, T> {
19351959
/// capacity to store `other.len()` more items.
19361960
/// * guaranteeing that `self` and `other` do not overlap.
19371961
unsafe fn extend_from_slice_copy_unchecked(&mut self, other: &[T]) {
1938-
let old_len = self.len();
1939-
debug_assert!(old_len + other.len() <= self.capacity());
1962+
let old_len = self.len_usize();
1963+
debug_assert!(old_len + other.len() <= self.capacity_usize());
19401964

19411965
// SAFETY:
19421966
// * `src` is valid for reads of `other.len()` values by virtue of being a `&[T]`.
@@ -2078,7 +2102,7 @@ impl<'a, T: 'a> Vec<'a, T> {
20782102
// so they get dropped when the `Vec` is dropped.
20792103
// But our `Vec` requires that `T` is not `Drop`, so we don't need to worry about that.
20802104
unsafe {
2081-
let mut ptr = self.as_mut_ptr().add(self.len());
2105+
let mut ptr = self.as_mut_ptr().add(self.len_usize());
20822106

20832107
// Write all elements except the last one
20842108
for _ in 1..n {
@@ -2095,7 +2119,7 @@ impl<'a, T: 'a> Vec<'a, T> {
20952119
// would have panicked. So `n as u32` cannot truncate `n`, and `len + n` cannot wrap.
20962120
#[expect(clippy::cast_possible_truncation)]
20972121
let n = n as u32;
2098-
self.buf.len += n;
2122+
self.buf.increase_len(n);
20992123
}
21002124
}
21012125
}
@@ -2132,7 +2156,7 @@ impl<'a, T: 'a + PartialEq> Vec<'a, T> {
21322156
impl<'a, T: 'a + Clone> Clone for Vec<'a, T> {
21332157
#[cfg(not(test))]
21342158
fn clone(&self) -> Vec<'a, T> {
2135-
let mut v = Vec::with_capacity_in(self.len(), self.buf.bump());
2159+
let mut v = Vec::with_capacity_in(self.len_usize(), self.buf.bump());
21362160
v.extend(self.iter().cloned());
21372161
v
21382162
}
@@ -2185,7 +2209,7 @@ impl<'a, T: 'a> ops::Deref for Vec<'a, T> {
21852209
unsafe {
21862210
let p = self.buf.ptr();
21872211
// assume(!p.is_null());
2188-
slice::from_raw_parts(p, self.buf.len_usize())
2212+
slice::from_raw_parts(p, self.len_usize())
21892213
}
21902214
}
21912215
}
@@ -2195,7 +2219,7 @@ impl<'a, T: 'a> ops::DerefMut for Vec<'a, T> {
21952219
unsafe {
21962220
let ptr = self.buf.ptr();
21972221
// assume(!ptr.is_null());
2198-
slice::from_raw_parts_mut(ptr, self.buf.len_usize())
2222+
slice::from_raw_parts_mut(ptr, self.len_usize())
21992223
}
22002224
}
22012225
}
@@ -2227,9 +2251,9 @@ impl<'a, T: 'a> IntoIterator for Vec<'a, T> {
22272251
let begin = self.as_mut_ptr();
22282252
// assume(!begin.is_null());
22292253
let end = if mem::size_of::<T>() == 0 {
2230-
arith_offset(begin as *const i8, self.len() as isize) as *const T
2254+
arith_offset(begin as *const i8, self.len_u32() as isize) as *const T
22312255
} else {
2232-
begin.add(self.len()) as *const T
2256+
begin.add(self.len_usize()) as *const T
22332257
};
22342258
IntoIter { phantom: PhantomData, ptr: begin, end }
22352259
}
@@ -2275,8 +2299,8 @@ impl<'a, T: 'a> Vec<'a, T> {
22752299
// self.push(item);
22762300
// }
22772301
while let Some(element) = iterator.next() {
2278-
let len = self.len();
2279-
if len == self.capacity() {
2302+
let len = self.len_usize();
2303+
if len == self.capacity_usize() {
22802304
// This reallocation path is rarely taken, especially with prior reservation,
22812305
// so mark it `#[cold]` and `#[inline(never)]` helps the compiler optimize the
22822306
// common case, and prevents this cold path from being inlined to the `while` loop,
@@ -2685,7 +2709,7 @@ impl<T> Drop for Drain<'_, '_, T> {
26852709
unsafe {
26862710
let source_vec = self.vec.as_mut();
26872711
// memmove back untouched tail, update to new length
2688-
let start = source_vec.len();
2712+
let start = source_vec.len_usize();
26892713
let tail = self.tail_start;
26902714
if tail != start {
26912715
let src = source_vec.as_ptr().add(tail);
@@ -2782,15 +2806,15 @@ impl<T> Drain<'_, '_, T> {
27822806
/// Return whether we filled the entire range. (`replace_with.next()` didn’t return `None`.)
27832807
unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
27842808
let vec = self.vec.as_mut();
2785-
let range_start = vec.buf.len_usize();
2809+
let range_start = vec.len_usize();
27862810
let range_end = self.tail_start;
27872811
let range_slice =
27882812
slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start);
27892813

27902814
for place in range_slice {
27912815
if let Some(new_item) = replace_with.next() {
27922816
ptr::write(place, new_item);
2793-
vec.buf.len += 1;
2817+
vec.buf.increase_len(1);
27942818
} else {
27952819
return false;
27962820
}

0 commit comments

Comments
 (0)