Skip to content

Commit 66c5e3f

Browse files
committed
Reduce the size of panics in RawVec
Create one canonical location which panics with "capacity overflow" instead of having many. This reduces the size of a `panic!("{}", 1)` binary on wasm from 34k to 17k.
1 parent c3a5d6b commit 66c5e3f

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

src/liballoc/raw_vec.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ impl<T, A: Alloc> RawVec<T, A> {
8585
unsafe {
8686
let elem_size = mem::size_of::<T>();
8787

88-
let alloc_size = cap.checked_mul(elem_size).expect("capacity overflow");
89-
alloc_guard(alloc_size).expect("capacity overflow");
88+
let alloc_size = cap.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
89+
alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());
9090

9191
// handles ZSTs and `cap = 0` alike
9292
let ptr = if alloc_size == 0 {
@@ -309,7 +309,7 @@ impl<T, A: Alloc> RawVec<T, A> {
309309
// `from_size_align_unchecked`.
310310
let new_cap = 2 * self.cap;
311311
let new_size = new_cap * elem_size;
312-
alloc_guard(new_size).expect("capacity overflow");
312+
alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
313313
let ptr_res = self.a.realloc(NonNull::from(self.ptr).as_opaque(),
314314
cur,
315315
new_size);
@@ -368,7 +368,7 @@ impl<T, A: Alloc> RawVec<T, A> {
368368
// overflow and the alignment is sufficiently small.
369369
let new_cap = 2 * self.cap;
370370
let new_size = new_cap * elem_size;
371-
alloc_guard(new_size).expect("capacity overflow");
371+
alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
372372
match self.a.grow_in_place(NonNull::from(self.ptr).as_opaque(), old_layout, new_size) {
373373
Ok(_) => {
374374
// We can't directly divide `size`.
@@ -440,7 +440,7 @@ impl<T, A: Alloc> RawVec<T, A> {
440440

441441
pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) {
442442
match self.try_reserve_exact(used_cap, needed_extra_cap) {
443-
Err(CapacityOverflow) => panic!("capacity overflow"),
443+
Err(CapacityOverflow) => capacity_overflow(),
444444
Err(AllocErr) => self.a.oom(),
445445
Ok(()) => { /* yay */ }
446446
}
@@ -550,7 +550,7 @@ impl<T, A: Alloc> RawVec<T, A> {
550550
/// The same as try_reserve, but errors are lowered to a call to oom().
551551
pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) {
552552
match self.try_reserve(used_cap, needed_extra_cap) {
553-
Err(CapacityOverflow) => panic!("capacity overflow"),
553+
Err(CapacityOverflow) => capacity_overflow(),
554554
Err(AllocErr) => self.a.oom(),
555555
Ok(()) => { /* yay */ }
556556
}
@@ -591,15 +591,15 @@ impl<T, A: Alloc> RawVec<T, A> {
591591
}
592592

593593
let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)
594-
.expect("capacity overflow");
594+
.unwrap_or_else(|_| capacity_overflow());
595595

596596
// Here, `cap < used_cap + needed_extra_cap <= new_cap`
597597
// (regardless of whether `self.cap - used_cap` wrapped).
598598
// Therefore we can safely call grow_in_place.
599599

600600
let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
601601
// FIXME: may crash and burn on over-reserve
602-
alloc_guard(new_layout.size()).expect("capacity overflow");
602+
alloc_guard(new_layout.size()).unwrap_or_else(|_| capacity_overflow());
603603
match self.a.grow_in_place(
604604
NonNull::from(self.ptr).as_opaque(), old_layout, new_layout.size(),
605605
) {
@@ -731,6 +731,13 @@ fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
731731
}
732732
}
733733

734+
// One central function responsible for reporting capacity overflows. This'll
735+
// ensure that the code generation related to these panics is minimal as there's
736+
// only one location which panics rather than a bunch throughout the module.
737+
fn capacity_overflow() -> ! {
738+
panic!("capacity overflow")
739+
}
740+
734741
#[cfg(test)]
735742
mod tests {
736743
use super::*;

0 commit comments

Comments
 (0)