@@ -51,35 +51,42 @@ macro_rules! impl_read_unsigned_leb128 {
5151 ( $fn_name: ident, $int_ty: ty) => {
5252 #[ inline]
5353 pub fn $fn_name( slice: & [ u8 ] , position: & mut usize ) -> $int_ty {
54+ #[ inline( never) ]
55+ fn slow_path( slice: & [ u8 ] , position: & mut usize ) -> Option <$int_ty> {
56+ let mut result = 0 ;
57+ let mut shift = 0 ;
58+ for consumed in 0 ..20 {
59+ let byte = slice[ * position + consumed] ;
60+ result |= ( ( byte & 0x7F ) as $int_ty) << shift;
61+ if ( byte & 0x80 ) == 0 {
62+ * position += consumed + 1 ;
63+ return Some ( result) ;
64+ }
65+ shift += 7 ;
66+ }
67+ None
68+ }
69+
5470 #[ inline]
55- fn inner ( slice: & [ u8 ] , position: & mut usize ) -> Option <$int_ty> {
56- let mut pos = * position;
71+ fn fast_path ( slice: & [ u8 ] , position: & mut usize ) -> Option <$int_ty> {
72+ let pos = * position;
5773 // The first iteration of this loop is unpeeled. This is a
5874 // performance win because this code is hot and integer values less
5975 // than 128 are very common, typically occurring 50-80% or more of
6076 // the time, even for u64 and u128.
61- let byte = * slice. get( pos) ?;
62- pos += 1 ;
63- if ( byte & 0x80 ) == 0 {
64- * position = pos;
65- return Some ( byte as $int_ty) ;
66- }
67- let mut result = ( byte & 0x7F ) as $int_ty;
68- let mut shift = 7 ;
69- loop {
70- let byte = * slice. get( pos) ?;
71- pos += 1 ;
72- if ( byte & 0x80 ) == 0 {
73- result |= ( byte as $int_ty) << shift;
74- * position = pos;
75- return Some ( result) ;
76- } else {
77- result |= ( ( byte & 0x7F ) as $int_ty) << shift;
78- }
79- shift += 7 ;
77+ if * slice. get( pos) ? & 0x80 == 0 {
78+ * position += 1 ;
79+ Some ( slice[ pos] as $int_ty)
80+ } else if * slice. get( pos + 1 ) ? & 0x80 == 0 {
81+ * position += 2 ;
82+ Some ( ( ( slice[ pos] & 0x7F ) as $int_ty) | ( slice[ pos + 1 ] as $int_ty << 7 ) )
83+
84+ } else {
85+ slow_path( slice, position)
8086 }
8187 }
82- inner( slice, position) . unwrap( )
88+
89+ fast_path( slice, position) . unwrap( )
8390 }
8491 } ;
8592}
0 commit comments