22// Copyright 2023-2024 liuq19, ijl
33// adapted from sonic-rs' src/util/string.rs
44
5- use crate :: typeref:: PAGE_SIZE ;
65use core:: simd:: cmp:: { SimdPartialEq , SimdPartialOrd } ;
76
87macro_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 ) => {
109 $nb -= $cn;
10+ if $rotate == true {
11+ for _ in 0 ..$cn {
12+ $v = $v. rotate_elements_left:: <1 >( ) ;
13+ }
14+ }
1115 $dst = $dst. add( $cn) ;
1216 $src = $src. add( $cn) ;
1317 $omask >>= $cn;
1418 loop {
1519 $nb -= 1 ;
20+ if $rotate == true {
21+ $v = $v. rotate_elements_left:: <1 >( ) ;
22+ }
1623 $omask = $omask >> 1 ;
17-
1824 if * ( $src) == b'"' {
1925 core:: ptr:: copy_nonoverlapping( b"\\ \" " . as_ptr( ) , $dst, 2 ) ;
2026 $dst = $dst. add( 2 ) ;
@@ -48,46 +54,48 @@ macro_rules! impl_format_simd {
4854 * dptr = b'"' ;
4955 dptr = dptr. add( 1 ) ;
5056
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+ }
6473 }
6574 }
6675
67- let mut v = if unlikely!( is_cross_page!( sptr) ) {
76+ {
77+ const ROTATE : bool = true ;
6878 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+
7686 let mut mask = ( v. simd_eq( blash) | v. simd_eq( quote) | v. simd_lt( x20) ) . to_bitmask( )
7787 as u32
7888 & ( STRIDE_SATURATION >> ( 32 - STRIDE - nb) ) ;
7989
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 ) ;
9199 }
92100 }
93101 }
@@ -100,12 +108,6 @@ macro_rules! impl_format_simd {
100108 } ;
101109}
102110
103- macro_rules! is_cross_page {
104- ( $src: expr) => {
105- unsafe { ( ( $src as usize & ( PAGE_SIZE - 1 ) ) + STRIDE ) > PAGE_SIZE }
106- } ;
107- }
108-
109111#[ cold]
110112#[ inline( never) ]
111113fn write_unusual_escape ( sptr : * const u8 , dptr : * mut u8 ) -> * mut u8 {
0 commit comments