From c58ec89b817cf40d7e7e219cdcb02f3fd8d69d51 Mon Sep 17 00:00:00 2001 From: overlookmotel <557937+overlookmotel@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:00:21 +0000 Subject: [PATCH] perf(data_structures): optimize `NonEmptyStack::pop` (#7021) Shave a few bytes off `NonEmptyStack::pop`. --- .../oxc_data_structures/src/stack/non_empty.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/oxc_data_structures/src/stack/non_empty.rs b/crates/oxc_data_structures/src/stack/non_empty.rs index 82754d7a7..63c83ee70 100644 --- a/crates/oxc_data_structures/src/stack/non_empty.rs +++ b/crates/oxc_data_structures/src/stack/non_empty.rs @@ -263,8 +263,22 @@ impl NonEmptyStack { /// Panics if the stack has only 1 entry on it. #[inline] pub fn pop(&mut self) -> T { - // Panic if trying to remove last entry from stack - assert!(self.cursor != self.start, "Cannot pop all entries"); + // Panic if trying to remove last entry from stack. + // + // Putting the panic in an `#[inline(never)]` + `#[cold]` function removes a 6-byte `lea` + // instruction vs `assert!(self.cursor != self.start, "Cannot pop all entries")`. + // This reduces this function on x86_64 from 32 bytes to 26 bytes. + // This function is commonly used, and we want it to be inlined, so every byte counts. + // https://godbolt.org/z/5587z99rM + #[inline(never)] + #[cold] + fn error() -> ! { + panic!("Cannot pop all entries"); + } + + if self.cursor == self.start { + error(); + } // SAFETY: Assertion above ensures stack has at least 2 entries unsafe { self.pop_unchecked() }