1
1
// This code is very hot and uses lots of arithmetic, avoid overflow checks for performance.
2
2
// See https://github.com/rust-lang/rust/pull/119440#issuecomment-1874255727
3
+ use std:: mem:: MaybeUninit ;
4
+
3
5
use crate :: int_overflow:: DebugStrictAdd ;
4
6
use crate :: opaque:: MemDecoder ;
5
7
use crate :: serialize:: Decoder ;
@@ -18,20 +20,23 @@ pub const fn largest_max_leb128_len() -> usize {
18
20
macro_rules! impl_write_unsigned_leb128 {
19
21
( $fn_name: ident, $int_ty: ty) => {
20
22
#[ inline]
21
- pub fn $fn_name( out: & mut [ u8 ; max_leb128_len:: <$int_ty>( ) ] , mut value: $int_ty) -> usize {
23
+ pub fn $fn_name(
24
+ out: & mut [ MaybeUninit <u8 >; max_leb128_len:: <$int_ty>( ) ] ,
25
+ mut value: $int_ty,
26
+ ) -> usize {
22
27
let mut i = 0 ;
23
28
24
29
loop {
25
30
if value < 0x80 {
26
31
unsafe {
27
- * out. get_unchecked_mut( i) = value as u8 ;
32
+ out. get_unchecked_mut( i) . write ( value as u8 ) ;
28
33
}
29
34
30
35
i = i. debug_strict_add( 1 ) ;
31
36
break ;
32
37
} else {
33
38
unsafe {
34
- * out. get_unchecked_mut( i) = ( ( value & 0x7f ) | 0x80 ) as u8 ;
39
+ out. get_unchecked_mut( i) . write ( ( ( value & 0x7f ) | 0x80 ) as u8 ) ;
35
40
}
36
41
37
42
value >>= 7 ;
@@ -87,7 +92,10 @@ impl_read_unsigned_leb128!(read_usize_leb128, usize);
87
92
macro_rules! impl_write_signed_leb128 {
88
93
( $fn_name: ident, $int_ty: ty) => {
89
94
#[ inline]
90
- pub fn $fn_name( out: & mut [ u8 ; max_leb128_len:: <$int_ty>( ) ] , mut value: $int_ty) -> usize {
95
+ pub fn $fn_name(
96
+ out: & mut [ MaybeUninit <u8 >; max_leb128_len:: <$int_ty>( ) ] ,
97
+ mut value: $int_ty,
98
+ ) -> usize {
91
99
let mut i = 0 ;
92
100
93
101
loop {
@@ -101,7 +109,7 @@ macro_rules! impl_write_signed_leb128 {
101
109
}
102
110
103
111
unsafe {
104
- * out. get_unchecked_mut( i) = byte;
112
+ out. get_unchecked_mut( i) . write ( byte) ;
105
113
}
106
114
107
115
i = i. debug_strict_add( 1 ) ;
0 commit comments