@samitouri / QOSamiQemu / commits / 55320a2983

json-streamer: do not heap-allocate JSONToken

This is not needed with a push parser. Since it processes tokens immediately, the JSONToken can be created directly on the stack and does not need to copy the lexer's string data. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20260626101727.1727389-6-pbonzini@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Paolo Bonzini committed Jun 26, 2026 at 12:17 UTC 55320a29833f2884d304ee8da8fb372ad86b9a4f
3 files changed +13 -22
qobject/json-parser-int.h
+6 -2
@@ -35,7 +35,12 @@ typedef enum json_token_type {
35 JSON_MAX = JSON_END_OF_INPUT
36 } JSONTokenType;
37
38 -typedef struct JSONToken JSONToken;
38 +typedef struct JSONToken {
39 + JSONTokenType type;
40 + int x;
41 + int y;
42 + char *str;
43 +} JSONToken;
44
45 /* json-lexer.c */
46 void json_lexer_init(JSONLexer *lexer, bool enable_interpolation);
@@ -48,7 +53,6 @@ void json_message_process_token(JSONLexer *lexer, GString *input,
53 JSONTokenType type, int x, int y);
54
55 /* json-parser.c */
51 -JSONToken *json_token(JSONTokenType type, int x, int y, GString *tokstr);
56 void json_parser_init(JSONParserContext *ctxt, va_list *ap);
57 void json_parser_reset(JSONParserContext *ctxt);
58 QObject *json_parser_feed(JSONParserContext *ctxt, const JSONToken *token, Error **errp);
qobject/json-parser.c
-18
@@ -24,13 +24,6 @@
24 #include "qobject/qstring.h"
25 #include "json-parser-int.h"
26
27 -struct JSONToken {
28 - JSONTokenType type;
29 - int x;
30 - int y;
31 - char str[];
32 -};
33 -
27 /*
28 * The JSON parser is a push parser, returning a completed top-level
29 * object, an error, or NULL (if the object is incomplete and no error
@@ -624,17 +617,6 @@ static QObject *parse_token(JSONParserContext *ctxt, const JSONToken *token)
617 return NULL;
618 }
619
627 -JSONToken *json_token(JSONTokenType type, int x, int y, GString *tokstr)
628 -{
629 - JSONToken *token = g_malloc(sizeof(JSONToken) + tokstr->len + 1);
630 -
631 - token->type = type;
632 - memcpy(token->str, tokstr->str, tokstr->len);
633 - token->str[tokstr->len] = 0;
634 - token->x = x;
635 - token->y = y;
636 - return token;
637 -}
620
621 void json_parser_reset(JSONParserContext *ctxt)
622 {
qobject/json-streamer.c
+7 -2
@@ -78,8 +78,13 @@ void json_message_process_token(JSONLexer *lexer, GString *input,
78 } else if (parser->bracket_count + parser->brace_count > MAX_NESTING) {
79 error_setg(&err, "JSON nesting depth limit exceeded");
80 } else {
81 - g_autofree JSONToken *token = json_token(type, x, y, input);
82 - QObject *json = json_parser_feed(&parser->parser, token, &err);
81 + JSONToken token = (JSONToken) {
82 + .type = type,
83 + .x = x,
84 + .y = y,
85 + .str = input->str
86 + };
87 + QObject *json = json_parser_feed(&parser->parser, &token, &err);
88 if (json) {
89 parser->emit(parser->opaque, json, NULL);
90 }