From 6fe75aad6da55e7ce473109e219fdc80bf3b7a51 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 19 Jun 2017 10:07:11 +0300 Subject: [PATCH] Optimization for fast path. --- ext/json/json_encoder.c | 163 ++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 80 deletions(-) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index f0d02bfbd0..9d480bcc90 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -329,90 +329,93 @@ static int php_json_escape_string( smart_str_appendc(buf, digits[(us & 0xf0) >> 4]); smart_str_appendc(buf, digits[(us & 0xf)]); } else { - pos++; - - switch (us) { - case '"': - if (options & PHP_JSON_HEX_QUOT) { - smart_str_appendl(buf, "\\u0022", 6); - } else { - smart_str_appendl(buf, "\\\"", 2); - } - break; - - case '\\': - smart_str_appendl(buf, "\\\\", 2); - break; - - case '/': - if (options & PHP_JSON_UNESCAPED_SLASHES) { - smart_str_appendc(buf, '/'); - } else { - smart_str_appendl(buf, "\\/", 2); - } - break; - - case '\b': - smart_str_appendl(buf, "\\b", 2); - break; - - case '\f': - smart_str_appendl(buf, "\\f", 2); - break; - - case '\n': - smart_str_appendl(buf, "\\n", 2); - break; - - case '\r': - smart_str_appendl(buf, "\\r", 2); - break; - - case '\t': - smart_str_appendl(buf, "\\t", 2); - break; - - case '<': - if (options & PHP_JSON_HEX_TAG) { - smart_str_appendl(buf, "\\u003C", 6); - } else { - smart_str_appendc(buf, '<'); - } - break; - - case '>': - if (options & PHP_JSON_HEX_TAG) { - smart_str_appendl(buf, "\\u003E", 6); - } else { - smart_str_appendc(buf, '>'); - } - break; + static const uint32_t charmap[4] = { + 0xffffffff, 0x500080c4, 0x10000000, 0x00000000}; - case '&': - if (options & PHP_JSON_HEX_AMP) { - smart_str_appendl(buf, "\\u0026", 6); - } else { - smart_str_appendc(buf, '&'); - } - break; - - case '\'': - if (options & PHP_JSON_HEX_APOS) { - smart_str_appendl(buf, "\\u0027", 6); - } else { - smart_str_appendc(buf, '\''); - } - break; - - default: - if (us >= ' ') { - smart_str_appendc(buf, (unsigned char) us); - } else { + pos++; + if (EXPECTED(!(charmap[us >> 5] & (1 << (us & 0x1f))))) { + smart_str_appendc(buf, (unsigned char) us); + } else { + switch (us) { + case '"': + if (options & PHP_JSON_HEX_QUOT) { + smart_str_appendl(buf, "\\u0022", 6); + } else { + smart_str_appendl(buf, "\\\"", 2); + } + break; + + case '\\': + smart_str_appendl(buf, "\\\\", 2); + break; + + case '/': + if (options & PHP_JSON_UNESCAPED_SLASHES) { + smart_str_appendc(buf, '/'); + } else { + smart_str_appendl(buf, "\\/", 2); + } + break; + + case '\b': + smart_str_appendl(buf, "\\b", 2); + break; + + case '\f': + smart_str_appendl(buf, "\\f", 2); + break; + + case '\n': + smart_str_appendl(buf, "\\n", 2); + break; + + case '\r': + smart_str_appendl(buf, "\\r", 2); + break; + + case '\t': + smart_str_appendl(buf, "\\t", 2); + break; + + case '<': + if (options & PHP_JSON_HEX_TAG) { + smart_str_appendl(buf, "\\u003C", 6); + } else { + smart_str_appendc(buf, '<'); + } + break; + + case '>': + if (options & PHP_JSON_HEX_TAG) { + smart_str_appendl(buf, "\\u003E", 6); + } else { + smart_str_appendc(buf, '>'); + } + break; + + case '&': + if (options & PHP_JSON_HEX_AMP) { + smart_str_appendl(buf, "\\u0026", 6); + } else { + smart_str_appendc(buf, '&'); + } + break; + + case '\'': + if (options & PHP_JSON_HEX_APOS) { + smart_str_appendl(buf, "\\u0027", 6); + } else { + smart_str_appendc(buf, '\''); + } + break; + + default: + ZEND_ASSERT(us < ' '); smart_str_appendl(buf, "\\u00", sizeof("\\u00")-1); smart_str_appendc(buf, digits[(us & 0xf0) >> 4]); smart_str_appendc(buf, digits[(us & 0xf)]); - } - break; + break; + } } } } while (pos < len); -- 2.40.0