From 7659ce22c50d526fcd4c115b79ac6ff667ee70f0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 27 Jan 2024 02:21:25 +0000 Subject: [PATCH] Optimizations to ParseFinalize() to make up for the extra cleanup associated with the allocated parser stack. This branch now runs faster than trunk and is less than 300 bytes larger. FossilOrigin-Name: f7290db63cc2568090c14dffc4ea4eadfacb5b94b50a1852ef6eefd9e2e32533 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lemon.c | 18 +++++++++++++++++- tool/lempar.c | 21 ++++++++++++++++++++- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d83d65b92d..a87dfc1f4e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\s"parser\sstack\soverflow"\serror\smessage,\ssince\sit\sno\slonger\soccurs.\nReplace\sit\swith\san\sordinary\s"out\sof\smemory". -D 2024-01-27T01:35:07.422 +C Optimizations\sto\sParseFinalize()\sto\smake\sup\sfor\sthe\sextra\scleanup\sassociated\nwith\sthe\sallocated\sparser\sstack.\s\sThis\sbranch\snow\sruns\sfaster\sthan\strunk\nand\sis\sless\sthan\s300\sbytes\slarger. +D 2024-01-27T02:21:25.832 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -2072,8 +2072,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 7e5c3c27062c94a40b73a980b8045a4201cb3335165b72ae476040dc513aa533 -F tool/lempar.c e560057d6e0f578be64894e70e3d86beee6ae26f4aa5a6fb74fdfff8e75ccb35 +F tool/lemon.c db6c77d899f565ab42217d924e5daee5b267724433c7747fb6d3329b3c919fa1 +F tool/lempar.c c85839df516cf3cee74829df59e968646275d327763c64c9e776bac92671f0ac F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 @@ -2161,8 +2161,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e91179fe849760771c3508b1e7d75325183e5c3b029752d0a97dbdbd57188b97 -R a326e9a9ce6869e2191b567c898735a6 +P 33f17ec24880937892d47a5a321c43785ca18e03dde28a9a0d50ae86edb29679 +R 20cc75bdc335ec49c6e2f7e4614d84da U drh -Z 3729898b234031ff25c57e8984e9d7de +Z 297b67eb6c1efaf54d4488f8dcd81ddc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7ea834c5c4..6f41fa279d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33f17ec24880937892d47a5a321c43785ca18e03dde28a9a0d50ae86edb29679 \ No newline at end of file +f7290db63cc2568090c14dffc4ea4eadfacb5b94b50a1852ef6eefd9e2e32533 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index c578b44bab..5b1702f4ee 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4317,7 +4317,7 @@ void ReportTable( struct action *ap; struct rule *rp; struct acttab *pActtab; - int i, j, n, sz; + int i, j, n, sz, mn, mx; int nLookAhead; int szActionType; /* sizeof(YYACTIONTYPE) */ int szCodeType; /* sizeof(YYCODETYPE) */ @@ -4647,6 +4647,22 @@ void ReportTable( fprintf(out,"#define YY_MIN_REDUCE %d\n", lemp->minReduce); lineno++; i = lemp->minReduce + lemp->nrule; fprintf(out,"#define YY_MAX_REDUCE %d\n", i-1); lineno++; + + /* Minimum and maximum token values that have a destructor */ + mn = mx = 0; + for(i=0; insymbol; i++){ + struct symbol *sp = lemp->symbols[i]; + + if( sp && sp->type!=TERMINAL && sp->destructor ){ + if( mn==0 || sp->indexindex; + if( sp->index>mx ) mx = sp->index; + } + } + if( lemp->tokendest ) mn = 0; + if( lemp->vardest ) mx = lemp->nsymbol-1; + fprintf(out,"#define YY_MIN_DSTRCTR %d\n", mn); lineno++; + fprintf(out,"#define YY_MAX_DSTRCTR %d\n", mx); lineno++; + tplt_xfer(lemp->name,in,out,&lineno); /* Now output the action table and its associates: diff --git a/tool/lempar.c b/tool/lempar.c index 1ea66e8402..9be2d409ed 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -83,6 +83,8 @@ ** YY_NO_ACTION The yy_action[] code for no-op ** YY_MIN_REDUCE Minimum value for reduce actions ** YY_MAX_REDUCE Maximum value for reduce actions +** YY_MIN_DSTRCTR Minimum symbol value that has a destructor +** YY_MAX_DSTRCTR Maximum symbol value that has a destructor */ #ifndef INTERFACE # define INTERFACE 1 @@ -438,7 +440,24 @@ static void yy_pop_parser_stack(yyParser *pParser){ */ void ParseFinalize(void *p){ yyParser *pParser = (yyParser*)p; - while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); + + /* In-lined version of calling yy_pop_parser_stack() for each + ** element left in the stack */ + yyStackEntry *yytos = pParser->yytos; + while( yytos>pParser->yystack ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + if( yytos->major>=YY_MIN_DSTRCTR && yytos->major<=YY_MAX_DSTRCTR ){ + yy_destructor(pParser, yytos->major, &yytos->minor); + } + yytos--; + } + #if YYGROWABLESTACK if( pParser->yystack!=pParser->yystk0 ) YYFREE(pParser->yystack); #endif