use custom location type in the parser

~1% parser speedup from not using TLS indirections, less on system eval.
this could have also gone in flex yyextra data, but that's significantly
slower for some reason (albeit still faster than thread locals).

before:

  Time (mean ± σ):      4.231 s ±  0.004 s    [User: 3.725 s, System: 0.504 s]
  Range (min … max):    4.226 s …  4.240 s    10 runs

after:

  Time (mean ± σ):      4.224 s ±  0.005 s    [User: 3.711 s, System: 0.512 s]
  Range (min … max):    4.218 s …  4.234 s    10 runs
This commit is contained in:
pennae 2023-12-10 13:00:18 +01:00
parent 2e0321912a
commit b78e77b34c
2 changed files with 28 additions and 6 deletions

View file

@ -36,9 +36,6 @@ static inline PosIdx makeCurPos(const YYLTYPE & loc, ParseData * data)
#define CUR_POS makeCurPos(*yylloc, data) #define CUR_POS makeCurPos(*yylloc, data)
// backup to recover from yyless(0)
thread_local YYLTYPE prev_yylloc;
static void initLoc(YYLTYPE * loc) static void initLoc(YYLTYPE * loc)
{ {
loc->first_line = loc->last_line = 1; loc->first_line = loc->last_line = 1;
@ -47,7 +44,7 @@ static void initLoc(YYLTYPE * loc)
static void adjustLoc(YYLTYPE * loc, const char * s, size_t len) static void adjustLoc(YYLTYPE * loc, const char * s, size_t len)
{ {
prev_yylloc = *loc; loc->stash();
loc->first_line = loc->last_line; loc->first_line = loc->last_line;
loc->first_column = loc->last_column; loc->first_column = loc->last_column;
@ -231,7 +228,7 @@ or { return OR_KW; }
{HPATH_START}\$\{ { {HPATH_START}\$\{ {
PUSH_STATE(PATH_START); PUSH_STATE(PATH_START);
yyless(0); yyless(0);
*yylloc = prev_yylloc; yylloc->unstash();
} }
<PATH_START>{PATH_SEG} { <PATH_START>{PATH_SEG} {
@ -287,7 +284,7 @@ or { return OR_KW; }
context (it may be ')', ';', or something of that sort) */ context (it may be ')', ';', or something of that sort) */
POP_STATE(); POP_STATE();
yyless(0); yyless(0);
*yylloc = prev_yylloc; yylloc->unstash();
return PATH_END; return PATH_END;
} }

View file

@ -28,6 +28,31 @@
namespace nix { namespace nix {
#define YYLTYPE ::nix::ParserLocation
struct ParserLocation
{
int first_line, first_column;
int last_line, last_column;
// backup to recover from yyless(0)
int stashed_first_line, stashed_first_column;
int stashed_last_line, stashed_last_column;
void stash() {
stashed_first_line = first_line;
stashed_first_column = first_column;
stashed_last_line = last_line;
stashed_last_column = last_column;
}
void unstash() {
first_line = stashed_first_line;
first_column = stashed_first_column;
last_line = stashed_last_line;
last_column = stashed_last_column;
}
};
struct ParseData struct ParseData
{ {
EvalState & state; EvalState & state;