Skip to content

Commit

Permalink
xkbcomp/scanner: avoid unneeded strdup of IDENT tokens
Browse files Browse the repository at this point in the history
The allocation is immediately discarded, either turned into a keysym or
an atom. So use an sval slice into the input string instead strdup'ing.

memusage ./release/bench-compile-keymap --iter=1000 --layout us,de --variant ,neo

Before:

    Memory usage summary: heap total: 534063576, heap peak: 581022, stack peak: 18848
            total calls   total memory   failed calls
     malloc|   11240525      291897104              0
    realloc|    1447657      192307328              0  (nomove:37629, dec:0, free:0)
     calloc|     430573       49859144              0
       free|   13993903      534063576

After:

    Memory usage summary: heap total: 506839909, heap peak: 581022, stack peak: 18960
            total calls   total memory   failed calls
     malloc|    8016419      264673437              0
    realloc|    1447657      192307328              0  (nomove:37278, dec:0, free:0)
     calloc|     430573       49859144              0
       free|    0769797      506839909

Signed-off-by: Ran Benita <[email protected]>
  • Loading branch information
bluetech committed Feb 3, 2025
1 parent e953159 commit 584b1a1
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 17 deletions.
9 changes: 9 additions & 0 deletions src/scanner-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,21 @@ svaleq(struct sval s1, struct sval s2)
return s1.len == s2.len && memcmp(s1.start, s2.start, s1.len) == 0;
}

static inline bool
isvaleq(struct sval s1, struct sval s2)
{
return s1.len == s2.len && istrncmp(s1.start, s2.start, s1.len) == 0;
}

static inline bool
svaleq_prefix(struct sval s1, struct sval s2)
{
return s1.len <= s2.len && memcmp(s1.start, s2.start, s1.len) == 0;
}

#define SVAL(start, len) (struct sval){(start), len}
#define SVAL_LIT(literal) SVAL(literal, sizeof(literal) - 1)

/* A line:column location in the input string (1-based). */
struct scanner_loc {
size_t line, column;
Expand Down
1 change: 1 addition & 0 deletions src/xkbcomp/parser-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
struct parser_param;
struct scanner;

#include "scanner-utils.h"
#include "parser.h"

int
Expand Down
29 changes: 18 additions & 11 deletions src/xkbcomp/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "xkbcomp/xkbcomp-priv.h"
#include "xkbcomp/ast-build.h"
#include "xkbcomp/parser-priv.h"
#include "scanner-utils.h"
#include "keysym.h"

struct parser_param {
Expand All @@ -59,25 +58,32 @@ _xkbcommon_error(struct parser_param *param, const char *msg)
}

static bool
resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_rtrn)
resolve_keysym(struct parser_param *param, struct sval name, xkb_keysym_t *sym_rtrn)
{
xkb_keysym_t sym;

if (!name || istreq(name, "any") || istreq(name, "nosymbol")) {
if (isvaleq(name, SVAL_LIT("any")) || isvaleq(name, SVAL_LIT("nosymbol"))) {
*sym_rtrn = XKB_KEY_NoSymbol;
return true;
}

if (istreq(name, "none") || istreq(name, "voidsymbol")) {
if (isvaleq(name, SVAL_LIT("none")) || isvaleq(name, SVAL_LIT("voidsymbol"))) {
*sym_rtrn = XKB_KEY_VoidSymbol;
return true;
}

sym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS);
char buf[256];
if (name.len >= sizeof(buf)) {
return false;
}
memcpy(buf, name.start, name.len);
buf[name.len] = '\0';

sym = xkb_keysym_from_name(buf, XKB_KEYSYM_NO_FLAGS);
if (sym != XKB_KEY_NoSymbol) {
*sym_rtrn = sym;
check_deprecated_keysyms(parser_warn, param, param->ctx,
sym, name, name, "%s", "");
sym, buf, buf, "%s", "");
return true;
}

Expand Down Expand Up @@ -168,6 +174,7 @@ resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_r
int64_t num;
enum xkb_file_type file_type;
char *str;
struct sval sval;
xkb_atom_t atom;
enum merge_mode merge;
enum xkb_map_flags mapFlags;
Expand Down Expand Up @@ -195,7 +202,8 @@ resolve_keysym(struct parser_param *param, const char *name, xkb_keysym_t *sym_r
}

%type <num> INTEGER FLOAT
%type <str> IDENT STRING
%type <str> STRING
%type <sval> IDENT
%type <atom> KEYNAME
%type <num> KeyCode Number Integer Float SignedNumber DoodadType
%type <merge> MergeMode OptMergeMode
Expand Down Expand Up @@ -765,12 +773,11 @@ KeySym : IDENT
parser_warn(
param,
XKB_WARNING_UNRECOGNIZED_KEYSYM,
"unrecognized keysym \"%s\"",
$1
"unrecognized keysym \"%.*s\"",
$1.len, $1.start
);
$$ = XKB_KEY_NoSymbol;
}
free($1);
}
/* Handle keysym that is also a keyword */
| SECTION { $$ = XKB_KEY_section; }
Expand Down Expand Up @@ -829,7 +836,7 @@ Integer : INTEGER { $$ = $1; }
KeyCode : INTEGER { $$ = $1; }
;

Ident : IDENT { $$ = xkb_atom_intern(param->ctx, $1, strlen($1)); free($1); }
Ident : IDENT { $$ = xkb_atom_intern(param->ctx, $1.start, $1.len); }
| DEFAULT { $$ = xkb_atom_intern_literal(param->ctx, "default"); }
;

Expand Down
2 changes: 0 additions & 2 deletions src/xkbcomp/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,6 @@ enum rules_mlvo {
_MLVO_NUM_ENTRIES
};

#define SVAL_LIT(literal) { literal, sizeof(literal) - 1 }

static const struct sval rules_mlvo_svals[_MLVO_NUM_ENTRIES] = {
[MLVO_MODEL] = SVAL_LIT("model"),
[MLVO_LAYOUT] = SVAL_LIT("layout"),
Expand Down
5 changes: 1 addition & 4 deletions src/xkbcomp/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include "xkbcomp-priv.h"
#include "parser-priv.h"
#include "scanner-utils.h"

static bool
number(struct scanner *s, int64_t *out, int *out_tok)
Expand Down Expand Up @@ -174,9 +173,7 @@ _xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
tok = keyword_to_token(start, len);
if (tok >= 0) return tok;

yylval->str = strndup(start, len);
if (!yylval->str)
return ERROR_TOK;
yylval->sval = SVAL(start, len);
return IDENT;
}

Expand Down

0 comments on commit 584b1a1

Please sign in to comment.