Skip to content

Commit

Permalink
WIP: xkbcomp: allocate AST nodes using bump allocator
Browse files Browse the repository at this point in the history
bench/rulescomp
before:
total heap usage: 10,980,536 allocs, 10,980,536 frees, 490,563,213 bytes allocated
compiled 1000 keymaps in 2.300165s

after:
total heap usage: 4,647,536 allocs, 4,647,536 frees, 538,021,213 bytes allocated
compiled 1000 keymaps in 1.949309s

Signed-off-by: Ran Benita <[email protected]>
  • Loading branch information
bluetech committed Jan 25, 2025
1 parent e928f74 commit e39621b
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 418 deletions.
324 changes: 82 additions & 242 deletions src/xkbcomp/ast-build.c

Large diffs are not rendered by default.

65 changes: 32 additions & 33 deletions src/xkbcomp/ast-build.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,98 +27,97 @@
#ifndef XKBCOMP_AST_BUILD_H
#define XKBCOMP_AST_BUILD_H

#include "bump.h"
#include "ast.h"

ExprDef *
ExprCreateString(xkb_atom_t str);
ExprCreateString(struct bump *bump, xkb_atom_t str);

ExprDef *
ExprCreateInteger(int ival);
ExprCreateInteger(struct bump *bump, int ival);

ExprDef *
ExprCreateFloat(void);
ExprCreateFloat(struct bump *bump);

ExprDef *
ExprCreateBoolean(bool set);
ExprCreateBoolean(struct bump *bump, bool set);

ExprDef *
ExprCreateKeyName(xkb_atom_t key_name);
ExprCreateKeyName(struct bump *bump, xkb_atom_t key_name);

ExprDef *
ExprCreateIdent(xkb_atom_t ident);
ExprCreateIdent(struct bump *bump, xkb_atom_t ident);

ExprDef *
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
ExprCreateUnary(struct bump *bump, enum expr_op_type op, enum expr_value_type type,
ExprDef *child);

ExprDef *
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
ExprCreateBinary(struct bump *bump, enum expr_op_type op, ExprDef *left, ExprDef *right);

ExprDef *
ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field);
ExprCreateFieldRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field);

ExprDef *
ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry);
ExprCreateArrayRef(struct bump *bump, xkb_atom_t element, xkb_atom_t field, ExprDef *entry);

ExprDef *
ExprEmptyList(void);
ExprEmptyList(struct bump *bump);

ExprDef *
ExprCreateAction(xkb_atom_t name, ExprDef *args);
ExprCreateAction(struct bump *bump, xkb_atom_t name, ExprDef *args);

ExprDef *
ExprCreateActionList(ExprDef *actions);
ExprCreateActionList(struct bump *bump, ExprDef *actions);

ExprDef *
ExprCreateKeysymList(xkb_keysym_t sym);
ExprCreateKeysymList(struct bump *bump, xkb_keysym_t sym);

ExprDef *
ExprAppendKeysymList(ExprDef *list, xkb_keysym_t sym);
ExprAppendKeysymList(struct bump *bump, ExprDef *list, xkb_keysym_t sym);

KeycodeDef *
KeycodeCreate(xkb_atom_t name, int64_t value);
KeycodeCreate(struct bump *bump, xkb_atom_t name, int64_t value);

KeyAliasDef *
KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real);
KeyAliasCreate(struct bump *bump, xkb_atom_t alias, xkb_atom_t real);

VModDef *
VModCreate(xkb_atom_t name, ExprDef *value);
VModCreate(struct bump *bump, xkb_atom_t name, ExprDef *value);

VarDef *
VarCreate(ExprDef *name, ExprDef *value);
VarCreate(struct bump *bump, ExprDef *name, ExprDef *value);

VarDef *
BoolVarCreate(xkb_atom_t ident, bool set);
BoolVarCreate(struct bump *bump, xkb_atom_t ident, bool set);

InterpDef *
InterpCreate(xkb_keysym_t sym, ExprDef *match);
InterpCreate(struct bump *bump, xkb_keysym_t sym, ExprDef *match);

KeyTypeDef *
KeyTypeCreate(xkb_atom_t name, VarDef *body);
KeyTypeCreate(struct bump *bump, xkb_atom_t name, VarDef *body);

SymbolsDef *
SymbolsCreate(xkb_atom_t keyName, VarDef *symbols);
SymbolsCreate(struct bump *bump, xkb_atom_t keyName, VarDef *symbols);

GroupCompatDef *
GroupCompatCreate(unsigned group, ExprDef *def);
GroupCompatCreate(struct bump *bump, unsigned group, ExprDef *def);

ModMapDef *
ModMapCreate(xkb_atom_t modifier, ExprDef *keys);
ModMapCreate(struct bump *bump, xkb_atom_t modifier, ExprDef *keys);

LedMapDef *
LedMapCreate(xkb_atom_t name, VarDef *body);
LedMapCreate(struct bump *bump, xkb_atom_t name, VarDef *body);

LedNameDef *
LedNameCreate(unsigned ndx, ExprDef *name, bool virtual);
LedNameCreate(struct bump *bump, unsigned ndx, ExprDef *name, bool virtual);

IncludeStmt *
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
IncludeCreate(struct bump *bump, struct xkb_context *ctx, char *str,
enum merge_mode merge);

XkbFile *
XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
enum xkb_map_flags flags);

void
FreeStmt(ParseCommon *stmt);
XkbFileCreate(struct bump *bump, enum xkb_file_type type, char *name,
ParseCommon *defs, enum xkb_map_flags flags);

#endif
1 change: 1 addition & 0 deletions src/xkbcomp/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ enum xkb_map_flags {

typedef struct {
ParseCommon common;
struct bump *bump;
enum xkb_file_type file_type;
char *name;
ParseCommon *defs;
Expand Down
12 changes: 5 additions & 7 deletions src/xkbcomp/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
#include "action.h"
#include "vmod.h"
#include "include.h"
#include "util-mem.h"

enum si_field {
SI_FIELD_VIRTUAL_MOD = (1 << 0),
Expand Down Expand Up @@ -399,7 +398,7 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from,
into->mods = from->mods;

if (into->name == NULL) {
into->name = steal(&from->name);
into->name = strdup(from->name);
}

if (darray_empty(into->interps)) {
Expand Down Expand Up @@ -434,7 +433,7 @@ static void
HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge);

static bool
HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include)
HandleIncludeCompatMap(struct bump *bump, CompatInfo *info, IncludeStmt *include)
{
CompatInfo included;

Expand All @@ -445,13 +444,13 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include)

InitCompatInfo(&included, info->ctx, 0 /* unused */,
info->actions, &info->mods);
included.name = steal(&include->stmt);
included.name = strdup(include->stmt);

for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
CompatInfo next_incl;
XkbFile *file;

file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_COMPAT);
file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_COMPAT);
if (!file) {
info->errorCount += 10;
ClearCompatInfo(&included);
Expand All @@ -470,7 +469,6 @@ HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include)
MergeIncludedCompatMaps(&included, &next_incl, stmt->merge);

ClearCompatInfo(&next_incl);
FreeXkbFile(file);
}

MergeIncludedCompatMaps(info, &included, include->merge);
Expand Down Expand Up @@ -774,7 +772,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
switch (stmt->type) {
case STMT_INCLUDE:
ok = HandleIncludeCompatMap(info, (IncludeStmt *) stmt);
ok = HandleIncludeCompatMap(file->bump, info, (IncludeStmt *) stmt);
break;
case STMT_INTERP:
ok = HandleInterpDef(info, (InterpDef *) stmt, merge);
Expand Down
22 changes: 9 additions & 13 deletions src/xkbcomp/include.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@
*
*/
bool
ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
char *nextop_rtrn, char **extra_data)
ParseIncludeMap(struct bump *bump, char **str_inout, char **file_rtrn,
char **map_rtrn, char *nextop_rtrn, char **extra_data)
{
char *tmp, *str, *next;

Expand Down Expand Up @@ -130,7 +130,7 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
tmp = strchr(str, ':');
if (tmp != NULL) {
*tmp++ = '\0';
*extra_data = strdup(tmp);
*extra_data = bump_strdup(bump, tmp);
}
else {
*extra_data = NULL;
Expand All @@ -140,27 +140,24 @@ ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
tmp = strchr(str, '(');
if (tmp == NULL) {
/* No map. */
*file_rtrn = strdup(str);
*file_rtrn = bump_strdup(bump, str);
*map_rtrn = NULL;
}
else if (str[0] == '(') {
/* Map without file - invalid. */
free(*extra_data);
return false;
}
else {
/* Got a map; separate the file and the map for the strdup's. */
*tmp++ = '\0';
*file_rtrn = strdup(str);
*file_rtrn = bump_strdup(bump, str);
str = tmp;
tmp = strchr(str, ')');
if (tmp == NULL || tmp[1] != '\0') {
free(*file_rtrn);
free(*extra_data);
return false;
}
*tmp++ = '\0';
*map_rtrn = strdup(str);
*map_rtrn = bump_strdup(bump, str);
}

/* Set up the next file for the next call, if any. */
Expand Down Expand Up @@ -294,8 +291,8 @@ ExceedsIncludeMaxDepth(struct xkb_context *ctx, unsigned int include_depth)
}

XkbFile *
ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
enum xkb_file_type file_type)
ProcessIncludeFile(struct bump *bump, struct xkb_context *ctx,
IncludeStmt *stmt, enum xkb_file_type file_type)
{
FILE *file;
XkbFile *xkb_file = NULL;
Expand All @@ -306,7 +303,7 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
return NULL;

while (file) {
xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map);
xkb_file = XkbParseFile(bump, ctx, file, stmt->file, stmt->map);
fclose(file);

if (xkb_file) {
Expand All @@ -316,7 +313,6 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
"Include file \"%s\" ignored\n",
xkb_file_type_to_string(file_type),
xkb_file_type_to_string(xkb_file->file_type), stmt->file);
FreeXkbFile(xkb_file);
xkb_file = NULL;
} else {
break;
Expand Down
9 changes: 5 additions & 4 deletions src/xkbcomp/include.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define XKBCOMP_INCLUDE_H

#include "ast.h"
#include "bump.h"

/* Reasonable threshold, with plenty of margin for keymaps in the wild */
#define INCLUDE_MAX_DEPTH 15
Expand All @@ -39,8 +40,8 @@
((ch) == MERGE_OVERRIDE_PREFIX || (ch) == MERGE_AUGMENT_PREFIX)

bool
ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn,
char *nextop_rtrn, char **extra_data);
ParseIncludeMap(struct bump *bump, char **str_inout, char **file_rtrn,
char **map_rtrn, char *nextop_rtrn, char **extra_data);

FILE *
FindFileInXkbPath(struct xkb_context *ctx, const char *name,
Expand All @@ -51,7 +52,7 @@ bool
ExceedsIncludeMaxDepth(struct xkb_context *ctx, unsigned int include_depth);

XkbFile *
ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
enum xkb_file_type file_type);
ProcessIncludeFile(struct bump *bump, struct xkb_context *ctx,
IncludeStmt *stmt, enum xkb_file_type file_type);

#endif
12 changes: 5 additions & 7 deletions src/xkbcomp/keycodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "text.h"
#include "expr.h"
#include "include.h"
#include "util-mem.h"

typedef struct {
enum merge_mode merge;
Expand Down Expand Up @@ -267,7 +266,7 @@ MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from,
}

if (into->name == NULL) {
into->name = steal(&from->name);
into->name = strdup(from->name);
}

/* Merge key names. */
Expand Down Expand Up @@ -336,7 +335,7 @@ static void
HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge);

static bool
HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include)
HandleIncludeKeycodes(struct bump *bump, KeyNamesInfo *info, IncludeStmt *include)
{
KeyNamesInfo included;

Expand All @@ -346,13 +345,13 @@ HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include)
}

InitKeyNamesInfo(&included, info->ctx, 0 /* unused */);
included.name = steal(&include->stmt);
included.name = strdup(include->stmt);

for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) {
KeyNamesInfo next_incl;
XkbFile *file;

file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_KEYCODES);
file = ProcessIncludeFile(bump, info->ctx, stmt, FILE_TYPE_KEYCODES);
if (!file) {
info->errorCount += 10;
ClearKeyNamesInfo(&included);
Expand All @@ -366,7 +365,6 @@ HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include)
MergeIncludedKeycodes(&included, &next_incl, stmt->merge);

ClearKeyNamesInfo(&next_incl);
FreeXkbFile(file);
}

MergeIncludedKeycodes(info, &included, include->merge);
Expand Down Expand Up @@ -503,7 +501,7 @@ HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge)
for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) {
switch (stmt->type) {
case STMT_INCLUDE:
ok = HandleIncludeKeycodes(info, (IncludeStmt *) stmt);
ok = HandleIncludeKeycodes(file->bump, info, (IncludeStmt *) stmt);
break;
case STMT_KEYCODE:
ok = HandleKeycodeDef(info, (KeycodeDef *) stmt, merge);
Expand Down
2 changes: 1 addition & 1 deletion src/xkbcomp/parser-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ int
_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner);

XkbFile *
parse(struct xkb_context *ctx, struct scanner *scanner, const char *map);
parse(struct bump *bump, struct xkb_context *ctx, struct scanner *scanner, const char *map);

int
keyword_to_token(const char *string, size_t len);
Expand Down
Loading

0 comments on commit e39621b

Please sign in to comment.