From ed71a839fdc5a1fc9ae7bf42fb223db7e0bf8d6d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2014 19:18:10 +0000 Subject: [PATCH] Change the OP_InitCoroutine instruction to jump over the co-routine implementation. FossilOrigin-Name: a522f364a6b8ca6f69c353b30609a2166f6e94cf --- manifest | 23 ++++++++++------------- manifest.uuid | 2 +- src/insert.c | 8 +++----- src/select.c | 19 +++++++------------ src/vdbe.c | 22 +++++++++++++--------- src/vdbeInt.h | 5 +++-- src/where.c | 2 +- 7 files changed, 38 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 87abf54582..cea46f3009 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\srid\sof\sthe\sOP_Undef\sand\sOP_IsUndef\sopcodes\sin\sfavor\sof\shigher-level\nOP_InitCoroutine\sand\sOP_EndCoroutine. -D 2014-02-07T18:27:53.008 +C Change\sthe\sOP_InitCoroutine\sinstruction\sto\sjump\sover\sthe\sco-routine\nimplementation. +D 2014-02-07T19:18:10.928 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 5997c3fbd5957b323f851d84d2ede380519cf2f6 +F src/insert.c b50cb5a51edb0d6e1a99e04b232b8632a54e522a F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -219,7 +219,7 @@ F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 01d0eca0938b588daabb36cd73e395309bdc6097 +F src/select.c 47d93e6f0b58000e2093e7b489bdca778884f82a F src/shell.c 7dedf7367ee49050b0366bf8dbc8ec2bd15b42c7 F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e @@ -280,9 +280,9 @@ F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 10ddcf5fd28ff23655b6e953e345c45b42642472 +F src/vdbe.c e7bb0587ad4866c0db5fe3b83104c4df8f93d19f F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26 -F src/vdbeInt.h bd6d5e70fe7c80f6aa4c56c34589762b9e933929 +F src/vdbeInt.h b5d62957a408c4bea649484008e5f98335b09e97 F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad F src/vdbeaux.c 3fd95b226330e1d50aedb40d750effe726ebb3fb F src/vdbeblob.c 9542e116c1db5ed813977581d506c176e117c0ec @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 07179d15d72c1dfffaf7d175d7e26517de04971e +F src/where.c 8c2aada8b44140382406cf07b84ff2f6127cb39e F src/whereInt.h 921f935af8b684ffb49705610bda7284db1db138 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1152,10 +1152,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6fb7448550f28a3c93053e125faeaf11de1011d0 -R 0b346c83ba3e4f94eace870fa077c226 -T *branch * coroutine-refactor -T *sym-coroutine-refactor * -T -sym-trunk * +P 1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 +R dbad771d6a0c64046f81724e16a6d61c U drh -Z 037b150ffb17771c8c249859dd8749bd +Z bb5cd7d324cd2ad57b192424d498539f diff --git a/manifest.uuid b/manifest.uuid index dfcfb30fb0..9e9204f927 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ec0e9dd4b26d9f597adc8e062317d4866c5a6a6 \ No newline at end of file +a522f364a6b8ca6f69c353b30609a2166f6e94cf \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index c7e60a478e..5dbdf9108a 100644 --- a/src/insert.c +++ b/src/insert.c @@ -389,22 +389,20 @@ void sqlite3AutoincrementEnd(Parse *pParse){ int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){ int regYield; /* Register holding co-routine entry-point */ int addrTop; /* Top of the co-routine */ - int j1; /* Jump instruction */ int rc; /* Result code */ Vdbe *v; /* VDBE under construction */ regYield = ++pParse->nMem; v = sqlite3GetVdbe(pParse); - addrTop = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, addrTop+2); + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield); - j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); rc = sqlite3Select(pParse, pSelect, pDest); assert( pParse->nErr==0 || rc ); if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM; if( rc ) return rc; sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); - sqlite3VdbeJumpHere(v, j1); /* label B: */ + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ return rc; } diff --git a/src/select.c b/src/select.c index c82e3d30c5..c0728f8873 100644 --- a/src/select.c +++ b/src/select.c @@ -2719,27 +2719,24 @@ static int multiSelectOrderBy( sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - /* Jump past the various subroutines and coroutines to the main - ** merge loop - */ - j1 = sqlite3VdbeAddOp0(v, OP_Goto); - - /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ - VdbeNoopComment((v, "coroutine for left SELECT")); - addrSelectA = sqlite3VdbeCurrentAddr(v); + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA); + sqlite3VdbeJumpHere(v, j1); /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ - VdbeNoopComment((v, "coroutine for right SELECT")); - addrSelectB = sqlite3VdbeCurrentAddr(v); + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + VdbeComment((v, "right SELECT")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; @@ -2829,8 +2826,6 @@ static int multiSelectOrderBy( /* This code runs once to initialize everything. */ sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrA, addrSelectA); - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regAddrB, addrSelectB); sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); diff --git a/src/vdbe.c b/src/vdbe.c index dd854d7c18..8067f9a12b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -731,20 +731,24 @@ case OP_Return: { /* in1 */ break; } -/* Opcode: InitCoroutine P1 P2 * * * +/* Opcode: InitCoroutine P1 P2 P3 * * ** -** Identify the co-routine at address P2 using the register P1 -** as its return address. Run this opcode prior to the first -** OP_Yield to invoke the co-routine. +** Set up register P1 so that it will OP_Yield to the co-routine +** located at address P3. +** +** If P2!=0 then the co-routine implementation immediately follows +** this opcode. So jump over the co-routine implementation to +** address P2. */ case OP_InitCoroutine: { /* jump */ - assert( pOp->p1>0 ); - assert( pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); + assert( pOp->p2>=0 && pOp->p2nOp ); + assert( pOp->p3>=0 && pOp->p3nOp ); pOut = &aMem[pOp->p1]; - memAboutToChange(p, pOut); - VdbeMemRelease(pOut); - pOut->u.i = pOp->p2 - 1; + assert( !VdbeMemDynamic(pOut) ); + pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; + if( pOp->p2 ) pc = pOp->p2 - 1; break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4da24b2374..f1d136a8ef 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -425,9 +425,10 @@ int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); +#define VdbeMemDynamic(X) \ + (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) #define VdbeMemRelease(X) \ - if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \ - sqlite3VdbeMemReleaseExternal(X); + if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); diff --git a/src/where.c b/src/where.c index 5ae72e9152..9abe3ad1cb 100644 --- a/src/where.c +++ b/src/where.c @@ -2785,7 +2785,7 @@ static Bitmask codeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->viaCoroutine ){ int regYield = pTabItem->regReturn; - sqlite3VdbeAddOp2(v, OP_InitCoroutine, regYield, pTabItem->addrFillSub); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName)); pLevel->op = OP_Goto; -- 2.39.5