@@ -10,43 +10,36 @@ const CHUNK: usize = 64;
10
10
pub fn encode_str < S : AsRef < str > > ( input : S ) -> String {
11
11
let s = input. as_ref ( ) ;
12
12
let mut out = Vec :: with_capacity ( s. len ( ) + 2 ) ;
13
- let b = s. as_bytes ( ) ;
14
- let n = b . len ( ) ;
13
+ let bytes = s. as_bytes ( ) ;
14
+ let n = bytes . len ( ) ;
15
15
out. push ( b'"' ) ;
16
16
17
17
unsafe {
18
18
let tbl = vld1q_u8_x4 ( ESCAPE . as_ptr ( ) ) ; // first 64 B of the escape table
19
19
let slash = vdupq_n_u8 ( b'\\' ) ;
20
20
let mut i = 0 ;
21
+ let mut placeholder: [ u8 ; 16 ] = core:: mem:: zeroed ( ) ;
21
22
22
23
while i + CHUNK <= n {
23
- let ptr = b . as_ptr ( ) . add ( i) ;
24
+ let ptr = bytes . as_ptr ( ) . add ( i) ;
24
25
25
26
/* ---- L1 prefetch: CHUNK size ahead ---- */
26
27
core:: arch:: asm!( "prfm pldl1keep, [{0}, #64]" , in( reg) ptr) ;
27
28
/* ------------------------------------------ */
28
29
29
30
// load 64 B (four q-regs)
30
31
let a = vld1q_u8 ( ptr) ;
31
- let m1 = vqtbl4q_u8 ( tbl, a) ;
32
- let m2 = vceqq_u8 ( slash, a) ;
33
32
34
- let b2 = vld1q_u8 ( ptr. add ( 16 ) ) ;
35
- let m3 = vqtbl4q_u8 ( tbl, b2) ;
36
- let m4 = vceqq_u8 ( slash, b2) ;
33
+ let b = vld1q_u8 ( ptr. add ( 16 ) ) ;
37
34
38
35
let c = vld1q_u8 ( ptr. add ( 32 ) ) ;
39
- let m5 = vqtbl4q_u8 ( tbl, c) ;
40
- let m6 = vceqq_u8 ( slash, c) ;
41
36
42
37
let d = vld1q_u8 ( ptr. add ( 48 ) ) ;
43
- let m7 = vqtbl4q_u8 ( tbl, d) ;
44
- let m8 = vceqq_u8 ( slash, d) ;
45
38
46
- let mask_1 = vorrq_u8 ( m1 , m2 ) ;
47
- let mask_2 = vorrq_u8 ( m3 , m4 ) ;
48
- let mask_3 = vorrq_u8 ( m5 , m6 ) ;
49
- let mask_4 = vorrq_u8 ( m7 , m8 ) ;
39
+ let mask_1 = vorrq_u8 ( vqtbl4q_u8 ( tbl , a ) , vceqq_u8 ( slash , a ) ) ;
40
+ let mask_2 = vorrq_u8 ( vqtbl4q_u8 ( tbl , b ) , vceqq_u8 ( slash , b ) ) ;
41
+ let mask_3 = vorrq_u8 ( vqtbl4q_u8 ( tbl , c ) , vceqq_u8 ( slash , c ) ) ;
42
+ let mask_4 = vorrq_u8 ( vqtbl4q_u8 ( tbl , d ) , vceqq_u8 ( slash , d ) ) ;
50
43
51
44
let mask_r_1 = vmaxvq_u8 ( mask_1) ;
52
45
let mask_r_2 = vmaxvq_u8 ( mask_2) ;
@@ -59,40 +52,27 @@ pub fn encode_str<S: AsRef<str>>(input: S) -> String {
59
52
i += CHUNK ;
60
53
continue ;
61
54
}
62
- let mut tmp: [ u8 ; 16 ] = core:: mem:: zeroed ( ) ;
63
55
64
- if mask_r_1 == 0 {
65
- out. extend_from_slice ( std:: slice:: from_raw_parts ( ptr, 16 ) ) ;
66
- } else {
67
- vst1q_u8 ( tmp. as_mut_ptr ( ) , mask_1) ;
68
- handle_block ( & b[ i..i + 16 ] , & tmp, & mut out) ;
56
+ macro_rules! handle {
57
+ ( $mask: expr, $mask_r: expr, $off: expr) => {
58
+ if $mask_r == 0 {
59
+ out. extend_from_slice( std:: slice:: from_raw_parts( ptr. add( $off) , 16 ) ) ;
60
+ } else {
61
+ vst1q_u8( placeholder. as_mut_ptr( ) , $mask) ;
62
+ handle_block( & bytes[ i + $off..i + $off + 16 ] , & placeholder, & mut out) ;
63
+ }
64
+ } ;
69
65
}
70
66
71
- if mask_r_2 == 0 {
72
- out. extend_from_slice ( std:: slice:: from_raw_parts ( ptr. add ( 16 ) , 16 ) ) ;
73
- } else {
74
- vst1q_u8 ( tmp. as_mut_ptr ( ) , mask_2) ;
75
- handle_block ( & b[ i + 16 ..i + 32 ] , & tmp, & mut out) ;
76
- }
77
-
78
- if mask_r_3 == 0 {
79
- out. extend_from_slice ( std:: slice:: from_raw_parts ( ptr. add ( 32 ) , 16 ) ) ;
80
- } else {
81
- vst1q_u8 ( tmp. as_mut_ptr ( ) , mask_3) ;
82
- handle_block ( & b[ i + 32 ..i + 48 ] , & tmp, & mut out) ;
83
- }
84
-
85
- if mask_r_4 == 0 {
86
- out. extend_from_slice ( std:: slice:: from_raw_parts ( ptr. add ( 48 ) , 16 ) ) ;
87
- } else {
88
- vst1q_u8 ( tmp. as_mut_ptr ( ) , mask_4) ;
89
- handle_block ( & b[ i + 48 ..i + 64 ] , & tmp, & mut out) ;
90
- }
67
+ handle ! ( mask_1, mask_r_1, 0 ) ;
68
+ handle ! ( mask_2, mask_r_2, 16 ) ;
69
+ handle ! ( mask_3, mask_r_3, 32 ) ;
70
+ handle ! ( mask_4, mask_r_4, 48 ) ;
91
71
92
72
i += CHUNK ;
93
73
}
94
74
if i < n {
95
- encode_str_inner ( & b [ i..] , & mut out) ;
75
+ encode_str_inner ( & bytes [ i..] , & mut out) ;
96
76
}
97
77
}
98
78
out. push ( b'"' ) ;
0 commit comments