@@ -526,6 +526,57 @@ impl FromJSValConvertible for f64 {
526
526
}
527
527
}
528
528
529
+ #[ cfg( all(
530
+ any( target_arch = "x86" , target_arch = "x86_64" ) ,
531
+ any( target_feature = "avx" , target_feature = "sse2" )
532
+ ) ) ]
533
+ /// Copies chars to the string using simd instructions
534
+ pub unsafe fn fast_copy ( chars : & [ u8 ] ) -> String {
535
+ use std:: arch:: x86_64;
536
+
537
+ let mut s = String :: with_capacity ( chars. len ( ) ) ;
538
+ let mut count = 0 ;
539
+ let num_iter = chars. len ( ) / 32 ;
540
+ let v = s. as_mut_vec ( ) ;
541
+ ( 0 ..num_iter) . for_each ( |i| {
542
+ if cfg ! ( target_feature = "avx" ) {
543
+ let simd =
544
+ x86_64:: _mm256_loadu_si256 ( chars. as_ptr ( ) . add ( i * 32 ) as * const x86_64:: __m256i ) ;
545
+ x86_64:: _mm256_storeu_si256 ( v. as_ptr ( ) . add ( i * 32 ) as * mut x86_64:: __m256i , simd) ;
546
+ count += 32 ;
547
+ } else {
548
+ let simd = x86_64:: _mm_load_si128 ( chars. as_ptr ( ) . add ( i * 16 ) as * const x86_64:: __m128i ) ;
549
+ x86_64:: _mm_store_si128 ( v. as_ptr ( ) . add ( i * 16 ) as * mut x86_64:: __m128i , simd) ;
550
+ count += 16 ;
551
+ }
552
+ } ) ;
553
+
554
+ // bytes that do not fit into the simd instruction
555
+ for i in count..chars. len ( ) {
556
+ chars. as_ptr ( ) . add ( i) . copy_to ( v. as_mut_ptr ( ) . add ( i) , 1 ) ;
557
+ count += 1 ;
558
+ }
559
+ v. set_len ( count) ;
560
+ s
561
+ }
562
+
563
+ #[ cfg( not( any(
564
+ all(
565
+ any( target_arch = "x86" , target_arch = "x86_64" ) ,
566
+ any( target_feature = "avx" , target_feature = "sse" ) ,
567
+ ) ,
568
+ all( any( target_arch = "arm" , target_arch = "aarch64" ) )
569
+ ) ) ) ]
570
+ /// Copies chars to the string using a slower method instructions
571
+ pub unsafe fn fast_copy ( chars : & [ u8 ] ) -> String {
572
+ let mut v = Vec :: with_capacity ( chars. len ( ) * 2 ) ;
573
+ v. set_len ( chars. len ( ) * 2 ) ;
574
+ let real_size = encoding_rs:: mem:: convert_latin1_to_utf8 ( chars, v. as_mut_slice ( ) ) ;
575
+
576
+ v. truncate ( real_size) ;
577
+ String :: from_utf8_unchecked ( v)
578
+ }
579
+
529
580
/// Converts a `JSString`, encoded in "Latin1" (i.e. U+0000-U+00FF encoded as 0x00-0xFF) into a
530
581
/// `String`.
531
582
pub unsafe fn latin1_to_string ( cx : * mut JSContext , s : * mut JSString ) -> String {
@@ -536,12 +587,7 @@ pub unsafe fn latin1_to_string(cx: *mut JSContext, s: *mut JSString) -> String {
536
587
assert ! ( !chars. is_null( ) ) ;
537
588
538
589
let chars = slice:: from_raw_parts ( chars, length as usize ) ;
539
- let mut v = Vec :: with_capacity ( length * 2 ) ;
540
- v. set_len ( length * 2 ) ;
541
-
542
- let real_size = encoding_rs:: mem:: convert_latin1_to_utf8 ( chars, v. as_mut_slice ( ) ) ;
543
- v. truncate ( real_size) ;
544
- String :: from_utf8_unchecked ( v)
590
+ fast_copy ( chars)
545
591
}
546
592
547
593
/// Converts a `JSString` into a `String`, regardless of used encoding.
0 commit comments