Skip to content

Commit fe4a3fe

Browse files
authored
Micro-optimisations to perform better on JSON and String processing (#1280)
1 parent 2868a65 commit fe4a3fe

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

quickjs.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20185,7 +20185,7 @@ typedef struct JSFunctionDef {
2018520185
bool need_home_object : 1;
2018620186
bool use_short_opcodes : 1; /* true if short opcodes are used in byte_code */
2018720187
bool has_await : 1; /* true if await is used (used in module eval) */
20188-
20188+
2018920189
JSFunctionKindEnum func_kind : 8;
2019020190
JSParseFunctionEnum func_type : 7;
2019120191
uint8_t is_strict_mode : 1;
@@ -20344,6 +20344,21 @@ static const JSOpCode opcode_info[OP_COUNT + (OP_TEMP_END - OP_TEMP_START)] = {
2034420344
opcode_info[(op) >= OP_TEMP_START ? \
2034520345
(op) + (OP_TEMP_END - OP_TEMP_START) : (op)]
2034620346

20347+
static void json_free_token(JSParseState *s, JSToken *token) {
20348+
// Only free actual allocated values
20349+
switch(token->val) {
20350+
case TOK_NUMBER:
20351+
JS_FreeValue(s->ctx, token->u.num.val);
20352+
break;
20353+
case TOK_STRING:
20354+
JS_FreeValue(s->ctx, token->u.str.str);
20355+
break;
20356+
case TOK_IDENT:
20357+
JS_FreeAtom(s->ctx, token->u.ident.atom);
20358+
break;
20359+
}
20360+
}
20361+
2034720362
static void free_token(JSParseState *s, JSToken *token)
2034820363
{
2034920364
switch(token->val) {
@@ -21425,14 +21440,30 @@ static int json_parse_string(JSParseState *s, const uint8_t **pp)
2142521440
uint32_t c;
2142621441
StringBuffer b_s, *b = &b_s;
2142721442

21428-
if (string_buffer_init(s->ctx, b, 32))
21443+
if (string_buffer_init(s->ctx, b, 48))
2142921444
goto fail;
2143021445

2143121446
p = *pp;
2143221447
for(;;) {
2143321448
if (p >= s->buf_end) {
2143421449
goto end_of_input;
2143521450
}
21451+
21452+
// Fast path: batch consecutive ASCII characters
21453+
const uint8_t *p_start = p;
21454+
while (p < s->buf_end && *p != '"' && *p != '\\' && *p >= 0x20 && *p < 0x80) {
21455+
p++;
21456+
}
21457+
21458+
// Write batched ASCII in one call
21459+
if (p > p_start) {
21460+
if (string_buffer_write8(b, p_start, p - p_start))
21461+
goto fail;
21462+
}
21463+
21464+
if (p >= s->buf_end)
21465+
goto end_of_input;
21466+
2143621467
c = *p++;
2143721468
if (c == '"')
2143821469
break;
@@ -21578,7 +21609,7 @@ static __exception int json_next_token(JSParseState *s)
2157821609
return -1;
2157921610
}
2158021611

21581-
free_token(s, &s->token);
21612+
json_free_token(s, &s->token);
2158221613

2158321614
p = s->last_ptr = s->buf_ptr;
2158421615
s->last_line_num = s->token.line_num;

0 commit comments

Comments
 (0)