@@ -51,35 +51,42 @@ macro_rules! impl_read_unsigned_leb128 {
51
51
( $fn_name: ident, $int_ty: ty) => {
52
52
#[ inline]
53
53
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
+
54
70
#[ 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;
57
73
// The first iteration of this loop is unpeeled. This is a
58
74
// performance win because this code is hot and integer values less
59
75
// than 128 are very common, typically occurring 50-80% or more of
60
76
// 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)
80
86
}
81
87
}
82
- inner( slice, position) . unwrap( )
88
+
89
+ fast_path( slice, position) . unwrap( )
83
90
}
84
91
} ;
85
92
}
0 commit comments