@@ -621,24 +621,25 @@ pub unsafe fn escape_sse2(bytes: &[u8], result: &mut Vec<u8>) {
621621
622622 if mask != 0 {
623623 let at = sub ( ptr, start_ptr) ;
624- let mut cur = mask. trailing_zeros ( ) as usize ;
625- loop {
626- let c = * ptr. add ( cur) ;
624+ let first_escape = mask. trailing_zeros ( ) as usize ;
625+
626+ // Copy everything before the first escape
627+ let i = at + first_escape;
628+ if start < i {
629+ result. extend_from_slice ( & bytes[ start..i] ) ;
630+ }
631+
632+ // Process bytes sequentially from the first escape position
633+ for pos in first_escape..remaining {
634+ let c = * ptr. add ( pos) ;
627635 let escape_byte = ESCAPE [ c as usize ] ;
628636 if escape_byte != 0 {
629- let i = at + cur;
630- if start < i {
631- result. extend_from_slice ( & bytes[ start..i] ) ;
632- }
633637 write_escape ( result, escape_byte, c) ;
634- start = i + 1 ;
635- }
636- mask ^= 1 << cur;
637- if mask == 0 {
638- break ;
638+ } else {
639+ result. push ( c) ;
639640 }
640- cur = mask. trailing_zeros ( ) as usize ;
641641 }
642+ start = at + remaining;
642643 }
643644 }
644645
@@ -665,26 +666,32 @@ unsafe fn process_mask_avx(
665666 let ptr = ptr. add ( offset) ;
666667 let at = sub ( ptr, start_ptr) ;
667668
668- // Process mask bits using bit manipulation
669- let mut remaining = mask as u32 ;
670- while remaining != 0 {
671- let cur = remaining. trailing_zeros ( ) as usize ;
672- let c = * ptr. add ( cur) ;
669+ // Find the first escape position
670+ let first_escape = ( mask as u32 ) . trailing_zeros ( ) as usize ;
671+
672+ // Copy everything before the first escape
673+ let i = at + first_escape;
674+ if * start < i {
675+ result. extend_from_slice ( & bytes[ * start..i] ) ;
676+ }
677+
678+ // Process bytes sequentially from the first escape position
679+ let mut pos = first_escape;
680+ let end = at + M256_VECTOR_SIZE ;
681+
682+ while pos < M256_VECTOR_SIZE {
683+ let c = * ptr. add ( pos) ;
673684 let escape_byte = ESCAPE [ c as usize ] ;
674- debug_assert ! ( escape_byte != 0 ) ;
675685
676- let i = at + cur ;
677- // Copy unescaped portion if needed
678- if * start < i {
679- result. extend_from_slice ( & bytes [ * start..i ] ) ;
686+ if escape_byte != 0 {
687+ write_escape ( result , escape_byte , c ) ;
688+ } else {
689+ result. push ( c ) ;
680690 }
681- // Write escape sequence
682- write_escape ( result, escape_byte, c) ;
683- * start = i + 1 ;
684-
685- // Clear the lowest set bit
686- remaining &= remaining - 1 ;
691+ pos += 1 ;
687692 }
693+
694+ * start = end;
688695}
689696
690697#[ inline( always) ]
@@ -704,26 +711,32 @@ unsafe fn process_mask_avx512(
704711 let ptr = ptr. add ( offset) ;
705712 let at = sub ( ptr, start_ptr) ;
706713
707- // Process mask bits using bit manipulation
708- let mut remaining = mask;
709- while remaining != 0 {
710- let cur = remaining. trailing_zeros ( ) as usize ;
711- let c = * ptr. add ( cur) ;
714+ // Find the first escape position
715+ let first_escape = mask. trailing_zeros ( ) as usize ;
716+
717+ // Copy everything before the first escape
718+ let i = at + first_escape;
719+ if * start < i {
720+ result. extend_from_slice ( & bytes[ * start..i] ) ;
721+ }
722+
723+ // Process bytes sequentially from the first escape position
724+ let mut pos = first_escape;
725+ let end = at + M512_VECTOR_SIZE ;
726+
727+ while pos < M512_VECTOR_SIZE {
728+ let c = * ptr. add ( pos) ;
712729 let escape_byte = ESCAPE [ c as usize ] ;
713- debug_assert ! ( escape_byte != 0 ) ;
714730
715- let i = at + cur ;
716- // Copy unescaped portion if needed
717- if * start < i {
718- result. extend_from_slice ( & bytes [ * start..i ] ) ;
731+ if escape_byte != 0 {
732+ write_escape ( result , escape_byte , c ) ;
733+ } else {
734+ result. push ( c ) ;
719735 }
720- // Write escape sequence
721- write_escape ( result, escape_byte, c) ;
722- * start = i + 1 ;
723-
724- // Clear the lowest set bit
725- remaining &= remaining - 1 ;
736+ pos += 1 ;
726737 }
738+
739+ * start = end;
727740}
728741
729742#[ inline( always) ]
0 commit comments