Skip to content

Commit df0117e

Browse files
committed
test
1 parent 57efb3a commit df0117e

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

ext/json/json_encoder.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
379379
/* }}} */
380380

381381
/* Specialization of smart_str_appendl() to avoid performance loss due to code bloat */
382-
static zend_always_inline void php_json_append(smart_str *dest, const char *src, size_t len)
382+
static void php_json_append(smart_str *dest, const char *src, size_t len)
383383
{
384384
/* smart_str has a minimum size of the input length,
385385
* this avoids generating initial allocation code */
@@ -542,7 +542,12 @@ typedef enum php_json_simd_result {
542542
} php_json_simd_result;
543543

544544
static zend_always_inline php_json_simd_result php_json_process_simd_block(
545-
smart_str *buf, const __m128i sse_escape_mask, const char **s, size_t *pos, size_t *len, int options
545+
smart_str *buf,
546+
const __m128i sse_escape_mask,
547+
const char **s,
548+
size_t *restrict pos,
549+
size_t *restrict len,
550+
int options
546551
)
547552
{
548553
while (*len >= sizeof(__m128i)) {
@@ -584,20 +589,24 @@ static zend_always_inline php_json_simd_result php_json_process_simd_block(
584589
/* Note that we shift the input forward, so we have to shift the mask as well,
585590
* beyond the to-be-escaped character */
586591
int len = zend_ulong_ntz(mask);
587-
mask >>= len + 1;
592+
mask >>= len;
588593

589594
php_json_append(buf, *s, len);
590595

591-
unsigned char us = (unsigned char)(*s)[len];
592-
*s += len + 1; /* skip 'us' too */
596+
*s += len; /* skip 'us' too */
593597

594-
bool handled = php_json_printable_ascii_escape(buf, us, options);
595-
ZEND_ASSERT(handled == true);
598+
/* Mitigate long run performance */
599+
do {
600+
unsigned char us = (unsigned char)(*s)[0];
601+
(*s)++;
602+
bool handled = php_json_printable_ascii_escape(buf, us, options);
603+
ZEND_ASSERT(handled == true);
604+
} while ((mask >>= 1) & 1);
596605
} while (mask != 0);
597606

598607
*pos = sizeof(__m128i) - (*s - s_backup);
599608
} else {
600-
if (UNEXPECTED(max_shift < sizeof(__m128i))) {
609+
if (/*UNEXPECTED*/(max_shift < sizeof(__m128i))) {
601610
*pos += max_shift;
602611
*len -= max_shift;
603612
return PHP_JSON_SLOW;
@@ -608,7 +617,7 @@ static zend_always_inline php_json_simd_result php_json_process_simd_block(
608617
*len -= sizeof(__m128i);
609618
}
610619

611-
return !*len ? PHP_JSON_STOP : PHP_JSON_SLOW;
620+
return UNEXPECTED(!*len) ? PHP_JSON_STOP : PHP_JSON_SLOW;
612621
}
613622
#endif
614623

@@ -660,8 +669,9 @@ zend_result php_json_escape_string(
660669
0xffffffff, 0x500080c4, 0x10000000, 0x00000000,
661670
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
662671

672+
php_json_simd_result result = PHP_JSON_SLOW;
663673
#ifdef JSON_USE_SIMD
664-
php_json_simd_result result = php_json_process_simd_block(buf, sse_escape_mask, &s, &pos, &len, options);
674+
result = php_json_process_simd_block(buf, sse_escape_mask, &s, &pos, &len, options);
665675
if (UNEXPECTED(result == PHP_JSON_STOP)) {
666676
break;
667677
}
@@ -721,6 +731,8 @@ zend_result php_json_escape_string(
721731
s += pos;
722732
pos = 0;
723733

734+
ZEND_ASSERT(buf->s);
735+
724736
/* From http://en.wikipedia.org/wiki/UTF16 */
725737
if (us >= 0x10000) {
726738
unsigned int next_us;

0 commit comments

Comments
 (0)