2
2
// Copyright 2023-2024 liuq19, ijl
3
3
// adapted from sonic-rs' src/util/string.rs
4
4
5
- use crate :: typeref:: PAGE_SIZE ;
6
5
use core:: simd:: cmp:: { SimdPartialEq , SimdPartialOrd } ;
7
6
8
7
macro_rules! impl_escape_unchecked {
9
- ( $src: expr, $dst: expr, $nb: expr, $omask: expr, $cn: expr) => {
8
+ ( $src: expr, $dst: expr, $nb: expr, $omask: expr, $cn: expr, $v : expr , $rotate : expr ) => {
10
9
$nb -= $cn;
10
+ if $rotate == true {
11
+ for _ in 0 ..$cn {
12
+ $v = $v. rotate_elements_left:: <1 >( ) ;
13
+ }
14
+ }
11
15
$dst = $dst. add( $cn) ;
12
16
$src = $src. add( $cn) ;
13
17
$omask >>= $cn;
14
18
loop {
15
19
$nb -= 1 ;
20
+ if $rotate == true {
21
+ $v = $v. rotate_elements_left:: <1 >( ) ;
22
+ }
16
23
$omask = $omask >> 1 ;
17
-
18
24
if * ( $src) == b'"' {
19
25
core:: ptr:: copy_nonoverlapping( b"\\ \" " . as_ptr( ) , $dst, 2 ) ;
20
26
$dst = $dst. add( 2 ) ;
@@ -48,46 +54,48 @@ macro_rules! impl_format_simd {
48
54
* dptr = b'"' ;
49
55
dptr = dptr. add( 1 ) ;
50
56
51
- while nb >= STRIDE {
52
- let v = StrVector :: from_slice( core:: slice:: from_raw_parts( sptr, STRIDE ) ) ;
53
- v. copy_to_slice( core:: slice:: from_raw_parts_mut( dptr, STRIDE ) ) ;
54
- let mut mask =
55
- ( v. simd_eq( blash) | v. simd_eq( quote) | v. simd_lt( x20) ) . to_bitmask( ) as u32 ;
56
-
57
- if likely!( mask == 0 ) {
58
- nb -= STRIDE ;
59
- dptr = dptr. add( STRIDE ) ;
60
- sptr = sptr. add( STRIDE ) ;
61
- } else {
62
- let cn = mask. trailing_zeros( ) as usize ;
63
- impl_escape_unchecked!( sptr, dptr, nb, mask, cn) ;
57
+ {
58
+ const ROTATE : bool = false ;
59
+ while nb >= STRIDE {
60
+ let mut v = StrVector :: from_slice( core:: slice:: from_raw_parts( sptr, STRIDE ) ) ;
61
+ let mut mask =
62
+ ( v. simd_eq( blash) | v. simd_eq( quote) | v. simd_lt( x20) ) . to_bitmask( ) as u32 ;
63
+ v. copy_to_slice( core:: slice:: from_raw_parts_mut( dptr, STRIDE ) ) ;
64
+
65
+ if likely!( mask == 0 ) {
66
+ nb -= STRIDE ;
67
+ dptr = dptr. add( STRIDE ) ;
68
+ sptr = sptr. add( STRIDE ) ;
69
+ } else {
70
+ let cn = mask. trailing_zeros( ) as usize ;
71
+ impl_escape_unchecked!( sptr, dptr, nb, mask, cn, v, ROTATE ) ;
72
+ }
64
73
}
65
74
}
66
75
67
- let mut v = if unlikely!( is_cross_page!( sptr) ) {
76
+ {
77
+ const ROTATE : bool = true ;
68
78
let mut v = StrVector :: default ( ) ;
69
- v . as_mut_array ( ) [ ..nb ] . copy_from_slice ( core :: slice :: from_raw_parts ( sptr , nb ) ) ;
70
- v
71
- } else {
72
- StrVector :: from_slice ( core:: slice :: from_raw_parts ( sptr , STRIDE ) )
73
- } ;
74
- while nb > 0 {
75
- v . copy_to_slice ( core :: slice :: from_raw_parts_mut ( dptr , STRIDE ) ) ;
79
+ {
80
+ let vec_ptr = v . as_mut_array ( ) . as_mut_ptr ( ) ;
81
+ for idx in 0 ..nb {
82
+ core:: ptr :: write ( vec_ptr . add ( idx ) , * sptr . add ( idx ) ) ;
83
+ }
84
+ }
85
+
76
86
let mut mask = ( v. simd_eq( blash) | v. simd_eq( quote) | v. simd_lt( x20) ) . to_bitmask( )
77
87
as u32
78
88
& ( STRIDE_SATURATION >> ( 32 - STRIDE - nb) ) ;
79
89
80
- if likely!( mask == 0 ) {
81
- dptr = dptr. add( nb) ;
82
- break ;
83
- } else {
84
- let cn = mask. trailing_zeros( ) as usize ;
85
- let nb_start = nb;
86
- impl_escape_unchecked!( sptr, dptr, nb, mask, cn) ;
87
- let mut consumed = nb_start - nb;
88
- while consumed != 0 {
89
- v = v. rotate_elements_left:: <1 >( ) ;
90
- consumed -= 1 ;
90
+ while nb > 0 {
91
+ v. copy_to_slice( core:: slice:: from_raw_parts_mut( dptr, STRIDE ) ) ;
92
+
93
+ if likely!( mask == 0 ) {
94
+ dptr = dptr. add( nb) ;
95
+ break ;
96
+ } else {
97
+ let cn = mask. trailing_zeros( ) as usize ;
98
+ impl_escape_unchecked!( sptr, dptr, nb, mask, cn, v, ROTATE ) ;
91
99
}
92
100
}
93
101
}
@@ -100,12 +108,6 @@ macro_rules! impl_format_simd {
100
108
} ;
101
109
}
102
110
103
- macro_rules! is_cross_page {
104
- ( $src: expr) => {
105
- unsafe { ( ( $src as usize & ( PAGE_SIZE - 1 ) ) + STRIDE ) > PAGE_SIZE }
106
- } ;
107
- }
108
-
109
111
#[ cold]
110
112
#[ inline( never) ]
111
113
fn write_unusual_escape ( sptr : * const u8 , dptr : * mut u8 ) -> * mut u8 {
0 commit comments