From 5ab18f5c9fc2a9c71f521e33161ee1650b23eaac Mon Sep 17 00:00:00 2001 From: Dmitry Prudnikov Date: Sat, 6 Jun 2026 03:53:37 +0300 Subject: [PATCH] perf(decode): single-compare bounds check in exec_sequence_inline_avx2 Replace the per-sequence checked_add chain (total overflow check + tail + total + overshoot checked chain + two match branches) with one subtraction and one compare using plain arithmetic. lit_length and match_length are each bounded by the maximum FSE LL/ML code expansion (~131 KB), so total and total + overshoot cannot overflow usize even on 32-bit; tail <= cap holds on entry (from_slice starts at 0 and every prior sequence advanced tail only after the same check), so cap - tail cannot underflow. Cuts per-sequence overhead on the direct-decode hot path (exec_sequence_inline_avx2 = 15% self-time on z000033 decode). --- zstd/src/decoding/user_slice_buf.rs | 42 ++++++++++++----------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/zstd/src/decoding/user_slice_buf.rs b/zstd/src/decoding/user_slice_buf.rs index 50e14aee5..2dd8d421f 100644 --- a/zstd/src/decoding/user_slice_buf.rs +++ b/zstd/src/decoding/user_slice_buf.rs @@ -425,31 +425,23 @@ impl<'a> BufferBackend for UserSliceBackend<'a> { // this overshoot for well-formed frames. const MAX_WILDCOPY_OVERSHOOT: usize = 31; let cap = self.slice.len(); - let total = match lit_length.checked_add(match_length) { - Some(v) => v, - None => { - return Err(ExecuteSequencesError::OutputBufferOverflow { - tail: self.tail, - requested: usize::MAX, - capacity: cap, - }); - } - }; - let cap_required = self - .tail - .checked_add(total) - .and_then(|new_tail| new_tail.checked_add(MAX_WILDCOPY_OVERSHOOT)); - let cap_required = match cap_required { - Some(v) if v <= cap => v, - _ => { - return Err(ExecuteSequencesError::OutputBufferOverflow { - tail: self.tail, - requested: total, - capacity: cap, - }); - } - }; - let _ = cap_required; + // `lit_length` and `match_length` are each bounded by the maximum + // FSE LL/ML code expansion (~131 KB), so `total` and + // `total + MAX_WILDCOPY_OVERSHOOT` cannot overflow `usize` (even on + // 32-bit). `self.tail <= cap` holds on entry: `from_slice` starts at + // 0 and every prior sequence only advanced `tail` after passing the + // same check below (`total + overshoot <= cap - tail` ⇒ + // `new_tail < cap`), so `cap - self.tail` cannot underflow. This + // single subtraction + compare replaces a per-sequence `checked_add` + // chain (runs on every sequence on the decode hot path). + let total = lit_length + match_length; + if total + MAX_WILDCOPY_OVERSHOOT > cap - self.tail { + return Err(ExecuteSequencesError::OutputBufferOverflow { + tail: self.tail, + requested: total, + capacity: cap, + }); + } let new_tail = self.tail + total; debug_assert!(offset >= 1); debug_assert!(match_length >= 1);