@@ -432,6 +432,20 @@ static zend_always_inline bool php_json_printable_ascii_escape(smart_str *buf, u
432
432
return true;
433
433
}
434
434
435
+ #ifdef __SSE2__
436
+ // TODO: may be unused
437
+ static zend_always_inline __m128i php_json_create_sse_escape_mask (int options )
438
+ {
439
+ const char sentinel = 1 ; /* outside of the printable range, so no false matches are possible */
440
+ const char amp = (options & PHP_JSON_HEX_AMP ) ? '&' : sentinel ;
441
+ const char apos = (options & PHP_JSON_HEX_APOS ) ? '\'' : sentinel ;
442
+ const char slash = !(options & PHP_JSON_UNESCAPED_SLASHES ) ? '/' : sentinel ;
443
+ const char tag1 = (options & PHP_JSON_HEX_TAG ) ? '<' : sentinel ;
444
+ const char tag2 = (options & PHP_JSON_HEX_TAG ) ? '>' : sentinel ;
445
+ return _mm_setr_epi8 ('"' , amp , apos , slash , tag1 , tag2 , '\\' , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 );
446
+ }
447
+ #endif
448
+
435
449
zend_result php_json_escape_string (
436
450
smart_str * buf , const char * s , size_t len ,
437
451
int options , php_json_encoder * encoder ) /* {{{ */
@@ -469,6 +483,11 @@ zend_result php_json_escape_string(
469
483
470
484
pos = 0 ;
471
485
486
+ #ifdef __SSE2__
487
+ const __m128i sse_escape_mask = php_json_create_sse_escape_mask (options );
488
+ (void ) sse_escape_mask ;
489
+ #endif
490
+
472
491
do {
473
492
static const uint32_t charmap [8 ] = {
474
493
0xffffffff , 0x500080c4 , 0x10000000 , 0x00000000 ,
@@ -487,7 +506,7 @@ zend_result php_json_escape_string(
487
506
break ;
488
507
}
489
508
490
- #if 1
509
+ #if 0
491
510
const __m128i result_34 = _mm_cmpeq_epi8 (input , _mm_set1_epi8 ('"' ));
492
511
const __m128i result_38 = _mm_cmpeq_epi8 (input , _mm_set1_epi8 ('&' ));
493
512
const __m128i result_39 = _mm_cmpeq_epi8 (input , _mm_set1_epi8 ('\'' ));
@@ -506,7 +525,7 @@ zend_result php_json_escape_string(
506
525
const __m128i result_individual_bytes = _mm_or_si128 (result_34_38_39_47 , result_60_62_92 );
507
526
int mask = _mm_movemask_epi8 (result_individual_bytes );
508
527
#else
509
- const __m128i result_individual_bytes = _mm_cmpistrm (_mm_setr_epi8 ( '"' , '&' , '\'' , '/' , '<' , '>' , '\\' , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) , input , _SIDD_SBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK );
528
+ const __m128i result_individual_bytes = _mm_cmpistrm (sse_escape_mask , input , _SIDD_SBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK );
510
529
int mask = _mm_cvtsi128_si32 (result_individual_bytes );
511
530
#endif
512
531
if (mask != 0 ) {
0 commit comments