From a6c2ed91ca798398dc25eb50dceaf8b18c4105e1 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 14 Nov 2009 23:22:23 +0000 Subject: [PATCH] Optimizations to the main loop inside sqlite3VdbeExec() to help VDBE byte code run a few percent faster. FossilOrigin-Name: d622ac6ac7a297754494d3a33dbaeea02836272e --- manifest | 28 +++++----- manifest.uuid | 2 +- src/global.c | 10 +++- src/sqliteInt.h | 1 + src/vdbe.c | 134 ++++++++++++++++++++++-------------------------- src/vdbe.h | 2 +- src/vdbeInt.h | 1 - src/vdbeaux.c | 13 ++--- 8 files changed, 95 insertions(+), 96 deletions(-) diff --git a/manifest b/manifest index cf35357f94..8823f66e92 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Make\sthe\ssqlite3VdbeExec()\sfunction\sabout\s2%\sfaster\sby\sstoring\sthe\sopcode\narray\sin\sa\slocal\svariable. -D 2009-11-14T18:04:36 +C Optimizations\sto\sthe\smain\sloop\sinside\ssqlite3VdbeExec()\sto\shelp\sVDBE\sbyte\scode\nrun\sa\sfew\spercent\sfaster. +D 2009-11-14T23:22:23 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -121,7 +121,7 @@ F src/expr.c 94f3086a342a1d151fb9d17ef1c33bff4cc768f0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0 F src/func.c bf54e1202cbfb28bf4b1fd9b58899009ae76716f -F src/global.c 271952d199a8cc59d4ce840b3bbbfd2f30c8ba32 +F src/global.c 9481e307caf01c59792f2bc32396061386591124 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 @@ -167,7 +167,7 @@ F src/select.c a727f61f3267bfa20ce1c3e85d38dc2132db1060 F src/shell.c f4948cb6d30665d755a6b5e0ec313d1094aab828 F src/sqlite.h.in 4464e9772122f0447305d425e04d122b6f1bffec F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h ee54fe752ba5672b7ca52bdd0e300c3902103d93 +F src/sqliteInt.h 961a7a3c1428fdc9c18df63ee34c91c7425c47af F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6 F src/status.c e651be6b30d397d86384c6867bc016e4913bcac7 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -210,11 +210,11 @@ F src/update.c 8efeb09822886e33c265dd96d29a3d865ea6dcf2 F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052 F src/util.c ad4f03079ba0fe83590d1cc9197e8e4844e38592 F src/vacuum.c 03309a08d549f9389cc3a3589afd4fadbdaf0679 -F src/vdbe.c 0abb88a10fb243cc753c3ab468d6aab7c3ee5211 -F src/vdbe.h 65cd747e36ad444cb1a17e529030942c45a61fe3 -F src/vdbeInt.h 59c65e7b810836b9e946acee45c7b3c02b967d1b +F src/vdbe.c 0bc1c3aaa0c5c13240c2e39ce3b9ae92586fc30b +F src/vdbe.h 5f35750615163d1064052785b4a9f0eb004a720d +F src/vdbeInt.h d7ea821ac7813c9bea0fe87558c35e07b2c7c44d F src/vdbeapi.c 17680ab7a75ec938c5ba039a6c87489d01faf2cb -F src/vdbeaux.c ee52010d2517eae2ef1c6766a372d79bfaea6e2e +F src/vdbeaux.c 45d1e150d811da2bafe820136b1c21616b2e5fd4 F src/vdbeblob.c 84f924700a7a889152aeebef77ca5f4e3875ffb4 F src/vdbemem.c 1e16e3a16e55f4c3452834f0e041726021aa66e0 F src/vtab.c 456fc226614569f0e46f216e33265bea268bd917 @@ -771,14 +771,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ed820f45cf4354b1e1db64049c47a07221a7ff6d -R 03060ba235b0950aa9146609f8d8a31d +P 8bd3cc82720ac7e8a9d4a03a882b6f8226867b0d +R cb3a1da29955733378e76881557b866a U drh -Z ce5be4ec1d2dd720600d2c9af2d32994 +Z afa90cd668940f60ced698df17c38b7b -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFK/vE5oxKgR168RlERAor4AJ4s/kWdVBsQ2tAlXF4Ix+CSbm+a5wCfWYrX -75gfXpBzWcUcFFhH7YbfTXU= -=IpIH +iD8DBQFK/zu0oxKgR168RlERAk/iAKCEVk6/+bUzTWEw8F/wvHvw0zgqfgCcC5l5 +k8ZGSZvLtvYXVF3tlPQ2ip8= +=cEZ3 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index aba27a3989..1d5ac89ead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8bd3cc82720ac7e8a9d4a03a882b6f8226867b0d \ No newline at end of file +d622ac6ac7a297754494d3a33dbaeea02836272e \ No newline at end of file diff --git a/src/global.c b/src/global.c index 07b133d6fc..3cd6d0b473 100644 --- a/src/global.c +++ b/src/global.c @@ -14,7 +14,6 @@ */ #include "sqliteInt.h" - /* An array to map all upper-case characters into their corresponding ** lower-case character. ** @@ -188,3 +187,12 @@ SQLITE_WSD FuncDefHash sqlite3GlobalFunctions; ** and dileterious behavior. */ int sqlite3PendingByte = 0x40000000; + +#include "opcodes.h" +/* +** Properties of opcodes. The OPFLG_INITIALIZER macro is +** created by mkopcodeh.awk during compilation. Data is obtained +** from the comments following the "case OP_xxxx:" statements in +** the vdbe.c file. +*/ +const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 16c1d6b386..f98baf1aa8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2845,6 +2845,7 @@ char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION +extern const unsigned char sqlite3OpcodeProperty[]; extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char sqlite3CtypeMap[]; extern SQLITE_WSD struct Sqlite3Config sqlite3Config; diff --git a/src/vdbe.c b/src/vdbe.c index f4d66e41ae..99a29c46d0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -170,23 +170,6 @@ void sqlite3VdbeMemStoreType(Mem *pMem){ } } -/* -** Properties of opcodes. The OPFLG_INITIALIZER macro is -** created by mkopcodeh.awk during compilation. Data is obtained -** from the comments following the "case OP_xxxx:" statements in -** this file. -*/ -static const unsigned char opcodeProperty[] = OPFLG_INITIALIZER; - -/* -** Return true if an opcode has any of the OPFLG_xxx properties -** specified by mask. -*/ -int sqlite3VdbeOpcodeHasProperty(int opcode, int mask){ - assert( opcode>0 && opcode<(int)sizeof(opcodeProperty) ); - return (opcodeProperty[opcode]&mask)!=0; -} - /* ** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL ** if we run out of memory. @@ -560,19 +543,21 @@ int sqlite3VdbeExec( int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 encoding = ENC(db); /* The database encoding */ + u8 opProperty; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u8 checkProgress; /* True if progress callbacks are enabled */ + int nProgressOps = 0; /* Opcodes executed since progress callback. */ +#endif + Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ - u8 opProperty; int iCompare = 0; /* Result of last OP_Compare operation */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ -#endif -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif /*** INSERT STACK UNION HERE ***/ @@ -591,6 +576,9 @@ int sqlite3VdbeExec( db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + checkProgress = db->xProgress!=0; +#endif #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); if( p->pc==0 @@ -656,7 +644,7 @@ int sqlite3VdbeExec( ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ - if( db->xProgress ){ + if( checkProgress ){ if( db->nProgressOps==nProgressOps ){ int prc; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; @@ -677,14 +665,15 @@ int sqlite3VdbeExec( ** output which is specified by the P2 parameter. The P2 register ** is initialized to a NULL. */ - opProperty = opcodeProperty[pOp->opcode]; + assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); + opProperty = pOp->opflags; if( opProperty & (OPFLG_OUT2_PRERELEASE | OPFLG_IN1 | OPFLG_IN2 | OPFLG_IN3 | OPFLG_OUT2 | OPFLG_OUT3) ){ if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); - pOut = &p->aMem[pOp->p2]; + pOut = &aMem[pOp->p2]; sqlite3VdbeMemReleaseExternal(pOut); pOut->flags = MEM_Null; pOut->n = 0; @@ -692,19 +681,19 @@ int sqlite3VdbeExec( if( (opProperty & OPFLG_IN1)!=0 ){ assert( pOp->p1>0 ); assert( pOp->p1<=p->nMem ); - pIn1 = &p->aMem[pOp->p1]; + pIn1 = &aMem[pOp->p1]; REGISTER_TRACE(pOp->p1, pIn1); } if( (opProperty & (OPFLG_IN2|OPFLG_OUT2))!=0 ){ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); assert( (opProperty & OPFLG_OUT2)==0 || (opProperty & OPFLG_IN3)==0 ); - pIn2 = pOut = &p->aMem[pOp->p2]; + pIn2 = pOut = &aMem[pOp->p2]; } if( (opProperty & (OPFLG_IN3|OPFLG_OUT3))!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=p->nMem ); - pIn3 = pOut = &p->aMem[pOp->p3]; + pIn3 = pOut = &aMem[pOp->p3]; } #ifdef SQLITE_DEBUG if( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); } @@ -849,6 +838,7 @@ case OP_Halt: { pc = p->aOp[pc].p2-1; } aOp = p->aOp; + aMem = p->aMem; break; } @@ -1004,7 +994,7 @@ case OP_Variable: { if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } - pOut = &p->aMem[p2++]; + pOut = &aMem[p2++]; sqlite3VdbeMemReleaseExternal(pOut); pOut->flags = MEM_Null; sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static); @@ -1032,11 +1022,11 @@ case OP_Move: { assert( n>0 && p1>0 && p2>0 ); assert( p1+n<=p2 || p2+n<=p1 ); - pIn1 = &p->aMem[p1]; - pOut = &p->aMem[p2]; + pIn1 = &aMem[p1]; + pOut = &aMem[p2]; while( n-- ){ - assert( pOut<=&p->aMem[p->nMem] ); - assert( pIn1<=&p->aMem[p->nMem] ); + assert( pOut<=&aMem[p->nMem] ); + assert( pIn1<=&aMem[p->nMem] ); zMalloc = pOut->zMalloc; pOut->zMalloc = 0; sqlite3VdbeMemMove(pOut, pIn1); @@ -1134,7 +1124,7 @@ case OP_ResultRow: { ** and have an assigned type. The results are de-ephemeralized as ** as side effect. */ - pMem = p->pResultSet = &p->aMem[pOp->p1]; + pMem = p->pResultSet = &aMem[pOp->p1]; for(i=0; ip2; i++){ sqlite3VdbeMemNulTerminate(&pMem[i]); sqlite3VdbeMemStoreType(&pMem[i]); @@ -1353,7 +1343,7 @@ case OP_Function: { assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pArg = &p->aMem[pOp->p2]; + pArg = &aMem[pOp->p2]; for(i=0; ip3>0 && pOp->p3<=p->nMem ); - pOut = &p->aMem[pOp->p3]; + pOut = &aMem[pOp->p3]; ctx.s.flags = MEM_Null; ctx.s.db = db; ctx.s.xDel = 0; @@ -1730,7 +1720,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &p->aMem[pOp->p2]; + pOut = &aMem[pOp->p2]; MemSetTypeFlag(pOut, MEM_Null); REGISTER_TRACE(pOp->p2, pOut); }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ @@ -1762,7 +1752,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &p->aMem[pOp->p2]; + pOut = &aMem[pOp->p2]; MemSetTypeFlag(pOut, MEM_Int); pOut->u.i = res; REGISTER_TRACE(pOp->p2, pOut); @@ -1831,12 +1821,12 @@ case OP_Compare: { #endif /* SQLITE_DEBUG */ for(i=0; iaMem[p1+idx]); - REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]); + REGISTER_TRACE(p1+idx, &aMem[p1+idx]); + REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( inField ); pColl = pKeyInfo->aColl[i]; bRev = pKeyInfo->aSortOrder[i]; - iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl); + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); if( iCompare ){ if( bRev ) iCompare = -iCompare; break; @@ -2045,7 +2035,7 @@ case OP_Column: { memset(&sMem, 0, sizeof(sMem)); assert( p1nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pDest = &p->aMem[pOp->p3]; + pDest = &aMem[pOp->p3]; MemSetTypeFlag(pDest, MEM_Null); zRec = 0; @@ -2091,7 +2081,7 @@ case OP_Column: { assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ } }else if( pC->pseudoTableReg>0 ){ - pReg = &p->aMem[pC->pseudoTableReg]; + pReg = &aMem[pC->pseudoTableReg]; assert( pReg->flags & MEM_Blob ); payloadSize = pReg->n; zRec = pReg->z; @@ -2308,7 +2298,7 @@ case OP_Affinity: { Mem *pRec; /* Current register */ zAffinity = pOp->p4.z; - pData0 = &p->aMem[pOp->p1]; + pData0 = &aMem[pOp->p1]; pLast = &pData0[pOp->p2-1]; for(pRec=pData0; pRec<=pLast; pRec++){ ExpandBlob(pRec); @@ -2374,7 +2364,7 @@ case OP_MakeRecord: { nField = pOp->p1; zAffinity = pOp->p4.z; assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 ); - pData0 = &p->aMem[nField]; + pData0 = &aMem[nField]; nField = pOp->p2; pLast = &pData0[nField-1]; file_format = p->minWriteFileFormat; @@ -2418,7 +2408,7 @@ case OP_MakeRecord: { ** sqlite3VdbeMemGrow() could clobber the value before it is used). */ assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); - pOut = &p->aMem[pOp->p3]; + pOut = &aMem[pOp->p3]; if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){ goto no_mem; } @@ -2965,7 +2955,7 @@ case OP_OpenWrite: { if( pOp->p5 ){ assert( p2>0 ); assert( p2<=p->nMem ); - pIn2 = &p->aMem[p2]; + pIn2 = &aMem[p2]; sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; /* The p2 value always comes from a prior OP_CreateTable opcode and @@ -3264,7 +3254,7 @@ case OP_SeekGt: { /* jump, in3 */ assert( oc!=OP_SeekGe || r.flags==0 ); assert( oc!=OP_SeekLt || r.flags==0 ); - r.aMem = &p->aMem[pOp->p3]; + r.aMem = &aMem[pOp->p3]; rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -3448,11 +3438,11 @@ case OP_IsUnique: { /* jump, in3 */ VdbeCursor *pCx; BtCursor *pCrsr; u16 nField; - Mem *aMem; + Mem *aMx; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ - aMem = &p->aMem[pOp->p4.i]; + aMx = &aMem[pOp->p4.i]; /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); @@ -3468,20 +3458,20 @@ case OP_IsUnique: { /* jump, in3 */ /* If any of the values are NULL, take the jump. */ nField = pCx->pKeyInfo->nField; for(ii=0; iip2 - 1; pCrsr = 0; break; } } - assert( (aMem[nField].flags & MEM_Null)==0 ); + assert( (aMx[nField].flags & MEM_Null)==0 ); if( pCrsr!=0 ){ /* Populate the index search key. */ r.pKeyInfo = pCx->pKeyInfo; r.nField = nField + 1; r.flags = UNPACKED_PREFIX_SEARCH; - r.aMem = aMem; + r.aMem = aMx; /* Extract the value of R from register P3. */ sqlite3VdbeMemIntegerify(pIn3); @@ -3657,7 +3647,7 @@ case OP_NewRowid: { /* out2-prerelease */ }else{ /* Assert that P3 is a valid memory cell. */ assert( pOp->p3<=p->nMem ); - pMem = &p->aMem[pOp->p3]; + pMem = &aMem[pOp->p3]; } REGISTER_TRACE(pOp->p3, pMem); @@ -3761,7 +3751,7 @@ case OP_InsertInt: { const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ - pData = &p->aMem[pOp->p2]; + pData = &aMem[pOp->p2]; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -3771,7 +3761,7 @@ case OP_InsertInt: { REGISTER_TRACE(pOp->p2, pData); if( pOp->opcode==OP_Insert ){ - pKey = &p->aMem[pOp->p3]; + pKey = &aMem[pOp->p3]; assert( pKey->flags & MEM_Int ); REGISTER_TRACE(pOp->p3, pKey); iKey = pKey->u.i; @@ -3919,7 +3909,7 @@ case OP_RowData: { u32 n; i64 n64; - pOut = &p->aMem[pOp->p2]; + pOut = &aMem[pOp->p2]; /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -4245,7 +4235,7 @@ case OP_IdxDelete: { r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; r.flags = 0; - r.aMem = &p->aMem[pOp->p2]; + r.aMem = &aMem[pOp->p2]; rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ rc = sqlite3BtreeDelete(pCrsr); @@ -4336,7 +4326,7 @@ case OP_IdxGE: { /* jump */ }else{ r.flags = UNPACKED_IGNORE_ROWID; } - r.aMem = &p->aMem[pOp->p3]; + r.aMem = &aMem[pOp->p3]; rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); if( pOp->opcode==OP_IdxLT ){ res = -res; @@ -4434,7 +4424,7 @@ case OP_Clear: { if( pOp->p3 ){ p->nChange += nChange; if( pOp->p3>0 ){ - p->aMem[pOp->p3].u.i += nChange; + aMem[pOp->p3].u.i += nChange; } } break; @@ -4644,10 +4634,10 @@ case OP_IntegrityCk: { aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pnErr = &p->aMem[pOp->p3]; + pnErr = &aMem[pOp->p3]; assert( (pnErr->flags & MEM_Int)!=0 ); assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); - pIn1 = &p->aMem[pOp->p1]; + pIn1 = &aMem[pOp->p1]; for(j=0; jp4.pProgram; - pRt = &p->aMem[pOp->p3]; + pRt = &aMem[pOp->p3]; assert( pProgram->nOp>0 ); /* If the p5 flag is clear, then recursive invocation of triggers is @@ -4871,10 +4861,10 @@ case OP_Program: { /* jump */ pFrame->nChange = p->nChange; p->nChange = 0; p->pFrame = pFrame; - p->aMem = &VdbeFrameMem(pFrame)[-1]; + p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; p->nMem = pFrame->nChildMem; p->nCursor = (u16)pFrame->nChildCsr; - p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1]; + p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; p->aOp = aOp = pProgram->aOp; p->nOp = pProgram->nOp; pc = -1; @@ -4961,7 +4951,7 @@ case OP_MemMax: { /* in2 */ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); pIn1 = &pFrame->aMem[pOp->p1]; }else{ - pIn1 = &p->aMem[pOp->p1]; + pIn1 = &aMem[pOp->p1]; } sqlite3VdbeMemIntegerify(pIn1); sqlite3VdbeMemIntegerify(pIn2); @@ -5039,7 +5029,7 @@ case OP_AggStep: { n = pOp->p5; assert( n>=0 ); - pRec = &p->aMem[pOp->p2]; + pRec = &aMem[pOp->p2]; apVal = p->apArg; assert( apVal || n==0 ); for(i=0; ip4.pFunc; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - ctx.pMem = pMem = &p->aMem[pOp->p3]; + ctx.pMem = pMem = &aMem[pOp->p3]; pMem->n++; ctx.s.flags = MEM_Null; ctx.s.z = 0; @@ -5087,7 +5077,7 @@ case OP_AggStep: { case OP_AggFinal: { Mem *pMem; assert( pOp->p1>0 && pOp->p1<=p->nMem ); - pMem = &p->aMem[pOp->p1]; + pMem = &aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); if( rc ){ @@ -5312,7 +5302,7 @@ case OP_VFilter: { /* jump */ int i; Mem **apArg; - pQuery = &p->aMem[pOp->p3]; + pQuery = &aMem[pOp->p3]; pArgc = &pQuery[1]; pCur = p->apCsr[pOp->p1]; REGISTER_TRACE(pOp->p3, pQuery); @@ -5373,7 +5363,7 @@ case OP_VColumn: { VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pDest = &p->aMem[pOp->p3]; + pDest = &aMem[pOp->p3]; if( pCur->nullRow ){ sqlite3VdbeMemSetNull(pDest); break; @@ -5480,7 +5470,7 @@ case OP_VRename: { Mem *pName; pVtab = pOp->p4.pVtab->pVtab; - pName = &p->aMem[pOp->p1]; + pName = &aMem[pOp->p1]; assert( pVtab->pModule->xRename ); REGISTER_TRACE(pOp->p1, pName); assert( pName->flags & MEM_Str ); @@ -5534,7 +5524,7 @@ case OP_VUpdate: { assert( pOp->p4type==P4_VTAB ); if( ALWAYS(pModule->xUpdate) ){ apArg = p->apArg; - pX = &p->aMem[pOp->p3]; + pX = &aMem[pOp->p3]; for(i=0; iaOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; + pOp->opflags = sqlite3OpcodeProperty[opcode]; if( opcode==OP_Function || opcode==OP_AggStep ){ if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; -#ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( opcode==OP_VUpdate ){ - if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; -#endif }else if( opcode==OP_Transaction && pOp->p2!=0 ){ p->readOnly = 0; #ifndef SQLITE_OMIT_VIRTUALTABLE + }else if( opcode==OP_VUpdate ){ + if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); @@ -414,7 +415,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ #endif } - if( sqlite3VdbeOpcodeHasProperty(opcode, OPFLG_JUMP) && pOp->p2<0 ){ + if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){ assert( -1-pOp->p2nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; } @@ -476,7 +477,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){ VdbeOp *pOut = &p->aOp[i+addr]; pOut->opcode = pIn->opcode; pOut->p1 = pIn->p1; - if( p2<0 && sqlite3VdbeOpcodeHasProperty(pOut->opcode, OPFLG_JUMP) ){ + if( p2<0 && (sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){ pOut->p2 = addr + ADDR(p2); }else{ pOut->p2 = p2;