From: drh Date: Fri, 6 Jun 2008 15:04:36 +0000 (+0000) Subject: Remove the subroutine return stack from the VDBE. Return addresses X-Git-Tag: version-3.6.10~986 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2eb95377ef7498a5ed48525ab1d75e68ae78aefa;p=thirdparty%2Fsqlite.git Remove the subroutine return stack from the VDBE. Return addresses for subroutines are now stored in registers. (CVS 5191) FossilOrigin-Name: ef1956eebcaf5aca51af8c3b406b1fd4b1f391a7 --- diff --git a/manifest b/manifest index c777018773..aee2fce092 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sxGetTempname()\smethod\sfrom\sthe\svfs\sstructure.\sTemp\sfiles\sare\snow\sopened\sby\spassing\sa\sNULL\spointer\sas\sthe\sfilename\sto\sxOpen().\s(CVS\s5190) -D 2008-06-06T11:11:26 +C Remove\sthe\ssubroutine\sreturn\sstack\sfrom\sthe\sVDBE.\s\sReturn\saddresses\nfor\ssubroutines\sare\snow\sstored\sin\sregisters.\s(CVS\s5191) +D 2008-06-06T15:04:37 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in ce92ea8dc7adfb743757794f51c10d1b0d9c55e4 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -110,7 +110,7 @@ F src/func.c 77a910a1ca7613d291fd0b5cba3be14c02f0dce0 F src/hash.c fd8cb06fb54c2fe7d48c9195792059a2e5be8b70 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 F src/hwtime.h 10fae2093aefa2b00be13bcac40c06e90924bc83 -F src/insert.c e3277f313352ac27282b5be39972fda4f315d0c6 +F src/insert.c c2ead6c36566de8e3f130e7ab1431723a269d5d7 F src/journal.c cffd2cd214e58c0e99c3ff632b3bee6c7cbb260e F src/legacy.c 8f5a2b25d9673b4004287cf2bf51dbf7d0738406 F src/loadext.c eac6c61810a3b531808774bec7f3d238cfe261f3 @@ -140,11 +140,11 @@ F src/pragma.c 70e7c865dce85fdf9df81848af2169009a56ed08 F src/prepare.c cbc9301aba1d0fc3d05fae576f2eb667c189cb36 F src/printf.c f2d4f6c5b0ec24b643e85fe60258adad8b1f6acc F src/random.c 2b2db2de4ab491f5a14d3480466f8f4b5a5db74a -F src/select.c da43ce3080112aa77863e9c570c1df19a892acb8 +F src/select.c 669687459e7d0193c89de06c5dbed55b4a41191c F src/shell.c a12ea645271b7876c8f080146f48e20b00d367ec F src/sqlite.h.in d60f963be07b6961037b1962a09bf172eb9d570f F src/sqlite3ext.h faacd0e6a81aabee0861c6d7883c9172e74ef5b3 -F src/sqliteInt.h debc576f4476cde358f3c7d8214b0c2f47b24555 +F src/sqliteInt.h 1593404d8aee13687ca7b5d552cb153de7441bef F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8 F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822 F src/tclsqlite.c c57e740e30bd6dda678796eed62c7f0e64689834 @@ -179,11 +179,11 @@ F src/update.c 2d7143b9014e955509cc4f323f9a9584fb898f34 F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b F src/util.c 43277088f8fea4109a640aa46731b8752c3fb4a7 F src/vacuum.c a5c289e561ed72283e97d2485491986bc7d684eb -F src/vdbe.c 04fec4d3c89c409f52c885f5904a884a74f31666 +F src/vdbe.c a113a62ae6779830dcc6b2caec9b89d894db4f71 F src/vdbe.h 1e3722d471739c2b213c6283b60373290e52f7ea -F src/vdbeInt.h ede1a31cfa74d4718f41da491bd1d2b3abc137fc +F src/vdbeInt.h de321b2c02593e1420106634ed1f5a7d77ad35a7 F src/vdbeapi.c 22b01ed175e4d4c613ee82cabc7a44a275641206 -F src/vdbeaux.c 433be5e2fff724d3a0e086d15d5597a8ef85bb29 +F src/vdbeaux.c 08ec9a7d9dd47df2faa31d1bdf9595d88789f141 F src/vdbeblob.c 554736781ee273a8089c776e96bdb53e66f57ce6 F src/vdbefifo.c 1644a41c6366ff25a920df4ca675f12d3f559687 F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911 @@ -591,7 +591,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c c65494ca99d1e09c246dfe37a7ca7a354af9990f -P 16d4c53a8e4d3cfc1abac3b8bb44d8bfd9471e32 -R dc477a96e7521594f69924f7a3878189 -U danielk1977 -Z 6a0735c3e200d6d56eadd6bfef72f1ef +P 5173b3e816c7eb711cd21a9068bbafb9ebb7cff1 +R 45b622f4f2c3d79a7a9794b6b11a4883 +U drh +Z 45ba29cafdd2a7e7669def4206bfdcea diff --git a/manifest.uuid b/manifest.uuid index cc8700c747..b44c03a3c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5173b3e816c7eb711cd21a9068bbafb9ebb7cff1 \ No newline at end of file +ef1956eebcaf5aca51af8c3b406b1fd4b1f391a7 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index e7b9a6945d..42ce65f854 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.239 2008/05/29 03:20:59 drh Exp $ +** $Id: insert.c,v 1.240 2008/06/06 15:04:37 drh Exp $ */ #include "sqliteInt.h" @@ -366,6 +366,7 @@ void sqlite3Insert( int iSelectLoop = 0; /* Address of code that implements the SELECT */ int iCleanup = 0; /* Address of the cleanup code */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */ + SelectDest dest; /* Destination for SELECT on rhs of INSERT */ int newIdx = -1; /* Cursor for the NEW pseudo-table */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ @@ -484,13 +485,13 @@ void sqlite3Insert( if( pSelect ){ /* Data is coming from a SELECT. Generate code to implement that SELECT */ - SelectDest dest; int rc, iInitCode; iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); sqlite3SelectDestInit(&dest, SRT_Subroutine, iInsertBlock); + dest.regReturn = ++pParse->nMem; /* Resolve the expressions in the SELECT statement and execute it. */ rc = sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0); @@ -529,7 +530,7 @@ void sqlite3Insert( sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regRowid); - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + sqlite3VdbeAddOp1(v, OP_Return, dest.regReturn); sqlite3ReleaseTempReg(pParse, regRec); sqlite3ReleaseTempReg(pParse, regRowid); @@ -898,17 +899,17 @@ void sqlite3Insert( if( useTempTable ){ sqlite3VdbeAddOp2(v, OP_Next, srcTab, iCont); sqlite3VdbeResolveLabel(v, iBreak); - sqlite3VdbeAddOp2(v, OP_Close, srcTab, 0); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); }else if( pSelect ){ - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + sqlite3VdbeAddOp1(v, OP_Return, dest.regReturn); sqlite3VdbeResolveLabel(v, iCleanup); } if( !IsVirtual(pTab) && !isView ){ /* Close all tables opened */ - sqlite3VdbeAddOp2(v, OP_Close, baseCur, 0); + sqlite3VdbeAddOp1(v, OP_Close, baseCur); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqlite3VdbeAddOp2(v, OP_Close, idx+baseCur, 0); + sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur); } } diff --git a/src/select.c b/src/select.c index b8eb6f92db..70f37dc290 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.429 2008/05/01 17:03:49 drh Exp $ +** $Id: select.c,v 1.430 2008/06/06 15:04:37 drh Exp $ */ #include "sqliteInt.h" @@ -39,6 +39,7 @@ static void clearSelect(Select *p){ void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ pDest->eDest = eDest; pDest->iParm = iParm; + pDest->regReturn = 0; pDest->affinity = 0; pDest->iMem = 0; pDest->nMem = 0; @@ -711,7 +712,7 @@ static void selectInnerLoop( pushOntoSorter(pParse, pOrderBy, p, r1); sqlite3ReleaseTempReg(pParse, r1); }else if( eDest==SRT_Subroutine ){ - sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); + sqlite3VdbeAddOp2(v, OP_Gosub, pDest->regReturn, iParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); @@ -858,7 +859,7 @@ static void generateSortTail( sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); }else{ - sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); + sqlite3VdbeAddOp2(v, OP_Gosub, pDest->regReturn, iParm); } break; } @@ -3291,6 +3292,7 @@ int sqlite3Select( /* The following variables hold addresses or labels for parts of the ** virtual machine program we are putting together */ int addrOutputRow; /* Start of subroutine that outputs a result row */ + int regOutputRow; /* Return address register for outputrow subroutine */ int addrSetAbort; /* Set the abort flag and return */ int addrInitializeLoop; /* Start of code that initializes the input loop */ int addrTopOfLoop; /* Top of the input loop */ @@ -3299,6 +3301,7 @@ int sqlite3Select( int addrEnd; /* End of all processing */ int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ + int regReset; /* Return address register for reset subroutine */ addrEnd = sqlite3VdbeMakeLabel(v); @@ -3371,11 +3374,12 @@ int sqlite3Select( addrSetAbort = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); VdbeComment((v, "set abort flag")); - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + regOutputRow = ++pParse->nMem; + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); addrOutputRow = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeComment((v, "Groupby result generator entry point")); - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, &sAggInfo); if( pHaving ){ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); @@ -3383,14 +3387,15 @@ int sqlite3Select( selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy, distinct, pDest, addrOutputRow+1, addrSetAbort, aff); - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); VdbeComment((v, "end groupby result generator")); /* Generate a subroutine that will reset the group-by accumulator */ addrReset = sqlite3VdbeCurrentAddr(v); + regReset = ++pParse->nMem; resetAccumulator(pParse, &sAggInfo); - sqlite3VdbeAddOp2(v, OP_Return, 0, 0); + sqlite3VdbeAddOp1(v, OP_Return, regReset); /* Begin a loop that will extract all source rows in GROUP BY order. ** This might involve two separate loops with an OP_Sort in between, or @@ -3398,7 +3403,7 @@ int sqlite3Select( ** in the right order to begin with. */ sqlite3VdbeResolveLabel(v, addrInitializeLoop); - sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0); if( pWInfo==0 ) goto select_end; if( pGroupBy==0 ){ @@ -3493,11 +3498,11 @@ int sqlite3Select( for(j=0; jnExpr; j++){ sqlite3ExprCodeMove(pParse, iBMem+j, iAMem+j); } - sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeComment((v, "check abort flag")); - sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of @@ -3519,7 +3524,7 @@ int sqlite3Select( /* Output the final row of result */ - sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output final row")); } /* endif pGroupBy */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9981ef071c..0a3c2a3fe2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.706 2008/06/05 16:47:39 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.707 2008/06/06 15:04:37 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1449,6 +1449,7 @@ struct SelectDest { u8 eDest; /* How to dispose of the results */ u8 affinity; /* Affinity used when eDest==SRT_Set */ int iParm; /* A parameter used by the eDest disposal method */ + int regReturn; /* Return address register for SRT_Subroutine */ int iMem; /* Base register where results are written */ int nMem; /* Number of registers allocated */ }; diff --git a/src/vdbe.c b/src/vdbe.c index 1c2ee18ce0..62a68b5683 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.746 2008/06/05 11:39:11 danielk1977 Exp $ +** $Id: vdbe.c,v 1.747 2008/06/06 15:04:37 drh Exp $ */ #include "sqliteInt.h" #include @@ -749,33 +749,30 @@ case OP_Goto: { /* jump */ break; } -/* Opcode: Gosub * P2 * * * +/* Opcode: Gosub P1 P2 * * * ** -** Push the current address plus 1 onto the return address stack +** Write the current address onto register P1 ** and then jump to address P2. -** -** The return address stack is of limited depth. If too many -** OP_Gosub operations occur without intervening OP_Returns, then -** the return address stack will fill up and processing will abort -** with a fatal error. */ case OP_Gosub: { /* jump */ - assert( p->returnDepthreturnStack)/sizeof(p->returnStack[0]) ); - p->returnStack[p->returnDepth++] = pc+1; + assert( pOp->p1>0 ); + assert( pOp->p1<=p->nMem ); + pIn1 = &p->aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Dyn)==0 ); + pIn1->flags = MEM_Int; + pIn1->u.i = pc; + REGISTER_TRACE(pOp->p1, pIn1); pc = pOp->p2 - 1; break; } -/* Opcode: Return * * * * * +/* Opcode: Return P1 * * * * ** -** Jump immediately to the next instruction after the last unreturned -** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then -** processing aborts with a fatal error. +** Jump to the next instruction after the address in register P1. */ -case OP_Return: { - assert( p->returnDepth>0 ); - p->returnDepth--; - pc = p->returnStack[p->returnDepth] - 1; +case OP_Return: { /* in1 */ + assert( pIn1->flags & MEM_Int ); + pc = pIn1->u.i; break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 384f023994..ea8fafb623 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -15,7 +15,7 @@ ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** -** $Id: vdbeInt.h,v 1.146 2008/05/16 04:51:55 danielk1977 Exp $ +** $Id: vdbeInt.h,v 1.147 2008/06/06 15:04:37 drh Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ @@ -311,8 +311,6 @@ struct Vdbe { unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */ int errorAction; /* Recovery action to do in case of an error */ int inTempTrans; /* True if temp database is transactioned */ - int returnStack[25]; /* Return address stack for OP_Gosub & OP_Return */ - int returnDepth; /* Next unused element in returnStack[] */ int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ char *zErrMsg; /* Error message written here */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5398ec1800..8818378f66 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.385 2008/06/06 11:11:27 danielk1977 Exp $ +** $Id: vdbeaux.c,v 1.386 2008/06/06 15:04:37 drh Exp $ */ #include "sqliteInt.h" #include @@ -1043,7 +1043,6 @@ void sqlite3VdbeMakeReady( p->pc = -1; p->rc = SQLITE_OK; p->uniqueCnt = 0; - p->returnDepth = 0; p->errorAction = OE_Abort; p->explain |= isExplain; p->magic = VDBE_MAGIC_RUN;