From 69f33e52b70e44d20ff8a91f62b38d2102885da4 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 2 Apr 2023 17:35:34 -0400 Subject: [PATCH] Optimize integer decoding a bit --- compiler/rustc_serialize/src/leb128.rs | 45 +++++++++++++++----------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index 7dad9aa01fafd..9841edca012cf 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -51,28 +51,35 @@ macro_rules! impl_read_unsigned_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty { - // The first iteration of this loop is unpeeled. This is a - // performance win because this code is hot and integer values less - // than 128 are very common, typically occurring 50-80% or more of - // the time, even for u64 and u128. - let byte = slice[*position]; - *position += 1; - if (byte & 0x80) == 0 { - return byte as $int_ty; - } - let mut result = (byte & 0x7F) as $int_ty; - let mut shift = 7; - loop { - let byte = slice[*position]; - *position += 1; + #[inline] + fn inner(slice: &[u8], position: &mut usize) -> Option<$int_ty> { + let mut pos = *position; + // The first iteration of this loop is unpeeled. This is a + // performance win because this code is hot and integer values less + // than 128 are very common, typically occurring 50-80% or more of + // the time, even for u64 and u128. + let byte = *slice.get(pos)?; + pos += 1; if (byte & 0x80) == 0 { - result |= (byte as $int_ty) << shift; - return result; - } else { - result |= ((byte & 0x7F) as $int_ty) << shift; + *position = pos; + return Some(byte as $int_ty); + } + let mut result = (byte & 0x7F) as $int_ty; + let mut shift = 7; + loop { + let byte = *slice.get(pos)?; + pos += 1; + if (byte & 0x80) == 0 { + result |= (byte as $int_ty) << shift; + *position = pos; + return Some(result); + } else { + result |= ((byte & 0x7F) as $int_ty) << shift; + } + shift += 7; } - shift += 7; } + inner(slice, position).unwrap() } }; }