]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhancements to the VDBE opcode loop to reduce the number of machine-code
authordrh <drh@noemail.net>
Tue, 17 Nov 2009 23:59:58 +0000 (23:59 +0000)
committerdrh <drh@noemail.net>
Tue, 17 Nov 2009 23:59:58 +0000 (23:59 +0000)
instructions evaluated by about 10%.

FossilOrigin-Name: 9744ffb3f5bc6d8fd59fbb6577a0d549411cd967

manifest
manifest.uuid
src/vdbe.c

index 2767e95ec7d8cb6628fe928ede86fc179ffc995b..a97ab5f5df3a0aa4cd63d0d724e9199946758f00 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Code\sgenerator\stries\sto\savoid\spointless\sOP_IsNull\sand\sOP_Affinity\sopcodes.
-D 2009-11-17T18:31:48
+C Enhancements\sto\sthe\sVDBE\sopcode\sloop\sto\sreduce\sthe\snumber\sof\smachine-code\ninstructions\sevaluated\sby\sabout\s10%.
+D 2009-11-17T23:59:58
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -210,7 +210,7 @@ F src/update.c 8efeb09822886e33c265dd96d29a3d865ea6dcf2
 F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
 F src/util.c ad4f03079ba0fe83590d1cc9197e8e4844e38592
 F src/vacuum.c 03309a08d549f9389cc3a3589afd4fadbdaf0679
-F src/vdbe.c 678dc437014c654707b7980e5a1a76b7dea5fecd
+F src/vdbe.c ed60d48b50b0e21f3ff87936f5c3d5667d4f8b8b
 F src/vdbe.h 5f35750615163d1064052785b4a9f0eb004a720d
 F src/vdbeInt.h d7ea821ac7813c9bea0fe87558c35e07b2c7c44d
 F src/vdbeapi.c 17680ab7a75ec938c5ba039a6c87489d01faf2cb
@@ -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 e4943adb83819dee06e2e9da25ff6d967ca170de
-R 537d50eb63e21c879029e20006a4ef86
+P ebb0c8a3e977dc741704e733b5a5d931d9b27028
+R dad6cdc4c4a1dec37df2a9a1ce7926da
 U drh
-Z 25f5f894370572ec60a402b96fc8f463
+Z 1249a61e88d85d90c0245acb22f5c40f
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFLAuwXoxKgR168RlERAvfhAJ9lIC9tv6mdYLAjmFMbVFDbfsV4pQCdFA1+
-c0IYZzkLkFY6S76oMkFaA2k=
-=BCOF
+iD8DBQFLAzkBoxKgR168RlERApdIAJ4+6zJDY9FY78sInSHpbNE0CiUriQCeMvQr
+4Rd5fpIsbKIZ9/+W9YH/eYE=
+=va/T
 -----END PGP SIGNATURE-----
index 146eb852a075a3699099c255ff09924b3941c25d..ad5fddd94f3d175555fc9931741d97e56f7e9a09 100644 (file)
@@ -1 +1 @@
-ebb0c8a3e977dc741704e733b5a5d931d9b27028
\ No newline at end of file
+9744ffb3f5bc6d8fd59fbb6577a0d549411cd967
\ No newline at end of file
index 4b5c6a1fadad226fb8a318ea273d25954bbcda01..4ea20b752f2e653928d00b89640a0f776d7e1b30 100644 (file)
@@ -543,7 +543,6 @@ 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. */
@@ -660,47 +659,46 @@ int sqlite3VdbeExec(
     }
 #endif
 
-    /* Do common setup processing for any opcode that is marked
-    ** with the "out2-prerelease" tag.  Such opcodes have a single
-    ** output which is specified by the P2 parameter.  The P2 register
-    ** is initialized to a NULL.
+    /* On any opcode with the "out2-prerelase" tag, free any
+    ** external allocations out of mem[p2] and set mem[p2] to be
+    ** an undefined integer.  Opcodes will either fill in the integer
+    ** value or convert mem[p2] to a different type.
     */
     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 = &aMem[pOp->p2];
-        sqlite3VdbeMemReleaseExternal(pOut);
-        pOut->flags = MEM_Null;
-        pOut->n = 0;
-      }else{
-        if( (opProperty & OPFLG_IN1)!=0 ){
-          assert( pOp->p1>0 );
-          assert( pOp->p1<=p->nMem );
-          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 = &aMem[pOp->p2];
-        }
-        if( (opProperty & (OPFLG_IN3|OPFLG_OUT3))!=0 ){
-          assert( pOp->p3>0 );
-          assert( pOp->p3<=p->nMem );
-          pIn3 = pOut = &aMem[pOp->p3];
-        }
+    if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
+      assert( pOp->p2>0 );
+      assert( pOp->p2<=p->nMem );
+      pOut = &aMem[pOp->p2];
+      sqlite3VdbeMemReleaseExternal(pOut);
+      pOut->flags = MEM_Int;
+    }
+
+    /* Sanity checking on other operands */
 #ifdef SQLITE_DEBUG
-        if( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); }
-        if( opProperty & OPFLG_IN3 ){ REGISTER_TRACE(pOp->p3, pIn3); }
-#endif
-      }
+    if( (pOp->opflags & OPFLG_IN1)!=0 ){
+      assert( pOp->p1>0 );
+      assert( pOp->p1<=p->nMem );
+      REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
+    }
+    if( (pOp->opflags & OPFLG_IN2)!=0 ){
+      assert( pOp->p2>0 );
+      assert( pOp->p2<=p->nMem );
+      REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
     }
+    if( (pOp->opflags & OPFLG_IN3)!=0 ){
+      assert( pOp->p3>0 );
+      assert( pOp->p3<=p->nMem );
+      REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
+    }
+    if( (pOp->opflags & OPFLG_OUT2)!=0 ){
+      assert( pOp->p2>0 );
+      assert( pOp->p2<=p->nMem );
+    }
+    if( (pOp->opflags & OPFLG_OUT3)!=0 ){
+      assert( pOp->p3>0 );
+      assert( pOp->p3<=p->nMem );
+    }
+#endif
   
     switch( pOp->opcode ){
 
@@ -758,6 +756,7 @@ case OP_Goto: {             /* jump */
 ** and then jump to address P2.
 */
 case OP_Gosub: {            /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   assert( (pIn1->flags & MEM_Dyn)==0 );
   pIn1->flags = MEM_Int;
   pIn1->u.i = pc;
@@ -771,6 +770,7 @@ case OP_Gosub: {            /* jump, in1 */
 ** Jump to the next instruction after the address in register P1.
 */
 case OP_Return: {           /* in1 */
+  pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags & MEM_Int );
   pc = (int)pIn1->u.i;
   break;
@@ -782,6 +782,7 @@ case OP_Return: {           /* in1 */
 */
 case OP_Yield: {            /* in1 */
   int pcDest;
+  pIn1 = &aMem[pOp->p1];
   assert( (pIn1->flags & MEM_Dyn)==0 );
   pIn1->flags = MEM_Int;
   pcDest = (int)pIn1->u.i;
@@ -798,6 +799,7 @@ case OP_Yield: {            /* in1 */
 ** value in register P3 is not NULL, then this routine is a no-op.
 */
 case OP_HaltIfNull: {      /* in3 */
+  pIn3 = &aMem[pOp->p3];
   if( (pIn3->flags & MEM_Null)==0 ) break;
   /* Fall through into OP_Halt */
 }
@@ -865,7 +867,6 @@ case OP_Halt: {
 ** The 32-bit integer value P1 is written into register P2.
 */
 case OP_Integer: {         /* out2-prerelease */
-  pOut->flags = MEM_Int;
   pOut->u.i = pOp->p1;
   break;
 }
@@ -877,7 +878,6 @@ case OP_Integer: {         /* out2-prerelease */
 */
 case OP_Int64: {           /* out2-prerelease */
   assert( pOp->p4.pI64!=0 );
-  pOut->flags = MEM_Int;
   pOut->u.i = *pOp->p4.pI64;
   break;
 }
@@ -947,6 +947,7 @@ case OP_String: {          /* out2-prerelease */
 ** Write a NULL into register P2.
 */
 case OP_Null: {           /* out2-prerelease */
+  pOut->flags = MEM_Null;
   break;
 }
 
@@ -1046,6 +1047,8 @@ case OP_Move: {
 ** is made of any string or blob constant.  See also OP_SCopy.
 */
 case OP_Copy: {             /* in1, out2 */
+  pIn1 = &aMem[pOp->p1];
+  pOut = &aMem[pOp->p2];
   assert( pOut!=pIn1 );
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
   Deephemeralize(pOut);
@@ -1066,6 +1069,8 @@ case OP_Copy: {             /* in1, out2 */
 ** copy.
 */
 case OP_SCopy: {            /* in1, out2 */
+  pIn1 = &aMem[pOp->p1];
+  pOut = &aMem[pOp->p2];
   assert( pOut!=pIn1 );
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
   REGISTER_TRACE(pOp->p2, pOut);
@@ -1154,6 +1159,9 @@ case OP_ResultRow: {
 case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
   i64 nByte;
 
+  pIn1 = &aMem[pOp->p1];
+  pIn2 = &aMem[pOp->p2];
+  pOut = &aMem[pOp->p3];
   assert( pIn1!=pOut );
   if( (pIn1->flags | pIn2->flags) & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
@@ -1227,8 +1235,11 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
   double rA;      /* Real value of left operand */
   double rB;      /* Real value of right operand */
 
+  pIn1 = &aMem[pOp->p1];
   applyNumericAffinity(pIn1);
+  pIn2 = &aMem[pOp->p2];
   applyNumericAffinity(pIn2);
+  pOut = &aMem[pOp->p3];
   flags = pIn1->flags | pIn2->flags;
   if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
   if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
@@ -1459,6 +1470,9 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
   i64 a;
   i64 b;
 
+  pIn1 = &aMem[pOp->p1];
+  pIn2 = &aMem[pOp->p2];
+  pOut = &aMem[pOp->p3];
   if( (pIn1->flags | pIn2->flags) & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
     break;
@@ -1485,6 +1499,7 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
 ** To force any register to be an integer, just add 0.
 */
 case OP_AddImm: {            /* in1 */
+  pIn1 = &aMem[pOp->p1];
   sqlite3VdbeMemIntegerify(pIn1);
   pIn1->u.i += pOp->p2;
   break;
@@ -1498,6 +1513,7 @@ case OP_AddImm: {            /* in1 */
 ** raise an SQLITE_MISMATCH exception.
 */
 case OP_MustBeInt: {            /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
   if( (pIn1->flags & MEM_Int)==0 ){
     if( pOp->p2==0 ){
@@ -1522,6 +1538,7 @@ case OP_MustBeInt: {            /* jump, in1 */
 ** to have only a real value.
 */
 case OP_RealAffinity: {                  /* in1 */
+  pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Int ){
     sqlite3VdbeMemRealify(pIn1);
   }
@@ -1539,6 +1556,7 @@ case OP_RealAffinity: {                  /* in1 */
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
 case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ) break;
   assert( MEM_Str==(MEM_Blob>>3) );
   pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
@@ -1560,6 +1578,7 @@ case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
 case OP_ToBlob: {                  /* same as TK_TO_BLOB, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ) break;
   if( (pIn1->flags & MEM_Blob)==0 ){
     applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
@@ -1583,6 +1602,7 @@ case OP_ToBlob: {                  /* same as TK_TO_BLOB, in1 */
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
 case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){
     sqlite3VdbeMemNumerify(pIn1);
   }
@@ -1600,6 +1620,7 @@ case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, in1 */
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
 case OP_ToInt: {                  /* same as TK_TO_INT, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_Null)==0 ){
     sqlite3VdbeMemIntegerify(pIn1);
   }
@@ -1617,6 +1638,7 @@ case OP_ToInt: {                  /* same as TK_TO_INT, in1 */
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
 case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_Null)==0 ){
     sqlite3VdbeMemRealify(pIn1);
   }
@@ -1705,6 +1727,8 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
   int res;            /* Result of the comparison of pIn1 against pIn3 */
   char affinity;      /* Affinity to use for comparison */
 
+  pIn1 = &aMem[pOp->p1];
+  pIn3 = &aMem[pOp->p3];
   if( (pIn1->flags | pIn3->flags)&MEM_Null ){
     /* One or both operands are NULL */
     if( pOp->p5 & SQLITE_NULLEQ ){
@@ -1876,11 +1900,13 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
   int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
   int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
 
+  pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ){
     v1 = 2;
   }else{
     v1 = sqlite3VdbeIntValue(pIn1)!=0;
   }
+  pIn2 = &aMem[pOp->p2];
   if( pIn2->flags & MEM_Null ){
     v2 = 2;
   }else{
@@ -1893,6 +1919,7 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
     static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
     v1 = or_logic[v1*3+v2];
   }
+  pOut = &aMem[pOp->p3];
   if( v1==2 ){
     MemSetTypeFlag(pOut, MEM_Null);
   }else{
@@ -1909,6 +1936,8 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
 ** NULL, then a NULL is stored in P2.
 */
 case OP_Not: {                /* same as TK_NOT, in1, out2 */
+  pIn1 = &aMem[pOp->p1];
+  pOut = &aMem[pOp->p2];
   if( pIn1->flags & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
   }else{
@@ -1924,6 +1953,8 @@ case OP_Not: {                /* same as TK_NOT, in1, out2 */
 ** a NULL then store a NULL in P2.
 */
 case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
+  pIn1 = &aMem[pOp->p1];
+  pOut = &aMem[pOp->p2];
   if( pIn1->flags & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
   }else{
@@ -1947,6 +1978,7 @@ case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
 case OP_If:                 /* jump, in1 */
 case OP_IfNot: {            /* jump, in1 */
   int c;
+  pIn1 = &aMem[pOp->p1];
   if( pIn1->flags & MEM_Null ){
     c = pOp->p3;
   }else{
@@ -1968,6 +2000,7 @@ case OP_IfNot: {            /* jump, in1 */
 ** Jump to P2 if the value in register P1 is NULL.
 */
 case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_Null)!=0 ){
     pc = pOp->p2 - 1;
   }
@@ -1979,6 +2012,7 @@ case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */
 ** Jump to P2 if the value in register P1 is not NULL.  
 */
 case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_Null)==0 ){
     pc = pOp->p2 - 1;
   }
@@ -2456,7 +2490,6 @@ case OP_Count: {         /* out2-prerelease */
   }else{
     nEntry = 0;
   }
-  pOut->flags = MEM_Int;
   pOut->u.i = nEntry;
   break;
 }
@@ -2777,7 +2810,6 @@ case OP_ReadCookie: {               /* out2-prerelease */
 
   sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
   pOut->u.i = iMeta;
-  MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
 
@@ -2798,6 +2830,7 @@ case OP_SetCookie: {       /* in3 */
   assert( (p->btreeMask & (1<<pOp->p1))!=0 );
   pDb = &db->aDb[pOp->p1];
   assert( pDb->pBt!=0 );
+  pIn3 = &aMem[pOp->p3];
   sqlite3VdbeMemIntegerify(pIn3);
   /* See note about index shifting on OP_ReadCookie */
   rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
@@ -3182,6 +3215,7 @@ case OP_SeekGt: {       /* jump, in3 */
       /* The input value in P3 might be of any type: integer, real, string,
       ** blob, or NULL.  But it needs to be an integer before we can do
       ** the seek, so covert it. */
+      pIn3 = &aMem[pOp->p3];
       applyNumericAffinity(pIn3);
       iKey = sqlite3VdbeIntValue(pIn3);
       pC->rowidIsValid = 0;
@@ -3321,6 +3355,7 @@ case OP_Seek: {    /* in2 */
   if( ALWAYS(pC->pCursor!=0) ){
     assert( pC->isTable );
     pC->nullRow = 0;
+    pIn2 = &aMem[pOp->p2];
     pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
     pC->rowidIsValid = 0;
     pC->deferredMoveto = 1;
@@ -3371,6 +3406,7 @@ case OP_Found: {        /* jump, in3 */
   assert( pOp->p4type==P4_INT32 );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
+  pIn3 = &aMem[pOp->p3];
   if( ALWAYS(pC->pCursor!=0) ){
 
     assert( pC->isTable==0 );
@@ -3444,6 +3480,7 @@ case OP_IsUnique: {        /* jump, in3 */
   UnpackedRecord r;                  /* B-Tree index search key */
   i64 R;                             /* Rowid stored in register P3 */
 
+  pIn3 = &aMem[pOp->p3];
   aMx = &aMem[pOp->p4.i];
   /* Assert that the values of parameters P1 and P4 are in range. */
   assert( pOp->p4type==P4_INT32 );
@@ -3512,6 +3549,7 @@ case OP_NotExists: {        /* jump, in3 */
   int res;
   u64 iKey;
 
+  pIn3 = &aMem[pOp->p3];
   assert( pIn3->flags & MEM_Int );
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
@@ -3555,7 +3593,6 @@ case OP_Sequence: {           /* out2-prerelease */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( p->apCsr[pOp->p1]!=0 );
   pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
-  MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
 
@@ -3692,7 +3729,6 @@ case OP_NewRowid: {           /* out2-prerelease */
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
   }
-  MemSetTypeFlag(pOut, MEM_Int);
   pOut->u.i = v;
   break;
 }
@@ -3984,7 +4020,7 @@ case OP_Rowid: {                 /* out2-prerelease */
   assert( pC!=0 );
   assert( pC->pseudoTableReg==0 );
   if( pC->nullRow ){
-    /* Do nothing so that reg[P2] remains NULL */
+    pOut->flags = MEM_Null;
     break;
   }else if( pC->deferredMoveto ){
     v = pC->movetoTarget;
@@ -4012,7 +4048,6 @@ case OP_Rowid: {                 /* out2-prerelease */
     }
   }
   pOut->u.i = v;
-  MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
 
@@ -4197,6 +4232,7 @@ case OP_IdxInsert: {        /* in2 */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
+  pIn2 = &aMem[pOp->p2];
   assert( pIn2->flags & MEM_Blob );
   pCrsr = pC->pCursor;
   if( ALWAYS(pCrsr!=0) ){
@@ -4265,6 +4301,7 @@ case OP_IdxRowid: {              /* out2-prerelease */
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   pCrsr = pC->pCursor;
+  pOut->flags = MEM_Null;
   if( ALWAYS(pCrsr!=0) ){
     rc = sqlite3VdbeCursorMoveto(pC);
     if( NEVER(rc) ) goto abort_due_to_error;
@@ -4275,8 +4312,8 @@ case OP_IdxRowid: {              /* out2-prerelease */
       if( rc!=SQLITE_OK ){
         goto abort_due_to_error;
       }
-      MemSetTypeFlag(pOut, MEM_Int);
       pOut->u.i = rowid;
+      pOut->flags = MEM_Int;
     }
   }
   break;
@@ -4378,6 +4415,7 @@ case OP_Destroy: {     /* out2-prerelease */
 #else
   iCnt = db->activeVdbeCnt;
 #endif
+  pOut->flags = MEM_Null;
   if( iCnt>1 ){
     rc = SQLITE_LOCKED;
     p->errorAction = OE_Abort;
@@ -4386,7 +4424,7 @@ case OP_Destroy: {     /* out2-prerelease */
     assert( iCnt==1 );
     assert( (p->btreeMask & (1<<iDb))!=0 );
     rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
-    MemSetTypeFlag(pOut, MEM_Int);
+    pOut->flags = MEM_Int;
     pOut->u.i = iMoved;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( rc==SQLITE_OK && iMoved!=0 ){
@@ -4473,7 +4511,6 @@ case OP_CreateTable: {          /* out2-prerelease */
   }
   rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
   pOut->u.i = pgno;
-  MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
 
@@ -4672,6 +4709,8 @@ case OP_IntegrityCk: {
 ** An assertion fails if P2 is not an integer.
 */
 case OP_RowSetAdd: {       /* in1, in2 */
+  pIn1 = &aMem[pOp->p1];
+  pIn2 = &aMem[pOp->p2];
   assert( (pIn2->flags & MEM_Int)!=0 );
   if( (pIn1->flags & MEM_RowSet)==0 ){
     sqlite3VdbeMemSetRowSet(pIn1);
@@ -4690,6 +4729,7 @@ case OP_RowSetAdd: {       /* in1, in2 */
 case OP_RowSetRead: {       /* jump, in1, out3 */
   i64 val;
   CHECK_FOR_INTERRUPT;
+  pIn1 = &aMem[pOp->p1];
   if( (pIn1->flags & MEM_RowSet)==0 
    || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
   ){
@@ -4698,7 +4738,7 @@ case OP_RowSetRead: {       /* jump, in1, out3 */
     pc = pOp->p2 - 1;
   }else{
     /* A value was pulled from the index */
-    sqlite3VdbeMemSetInt64(pOut, val);
+    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
   }
   break;
 }
@@ -4730,6 +4770,8 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */
   int iSet;
   int exists;
 
+  pIn1 = &aMem[pOp->p1];
+  pIn3 = &aMem[pOp->p3];
   iSet = pOp->p4.i;
   assert( pIn3->flags&MEM_Int );
 
@@ -4956,6 +4998,7 @@ case OP_MemMax: {        /* in2 */
     pIn1 = &aMem[pOp->p1];
   }
   sqlite3VdbeMemIntegerify(pIn1);
+  pIn2 = &aMem[pOp->p2];
   sqlite3VdbeMemIntegerify(pIn2);
   if( pIn1->u.i<pIn2->u.i){
     pIn1->u.i = pIn2->u.i;
@@ -4972,6 +5015,7 @@ case OP_MemMax: {        /* in2 */
 ** not contain an integer.  An assertion fault will result if you try.
 */
 case OP_IfPos: {        /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags&MEM_Int );
   if( pIn1->u.i>0 ){
      pc = pOp->p2 - 1;
@@ -4987,6 +5031,7 @@ case OP_IfPos: {        /* jump, in1 */
 ** not contain an integer.  An assertion fault will result if you try.
 */
 case OP_IfNeg: {        /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags&MEM_Int );
   if( pIn1->u.i<0 ){
      pc = pOp->p2 - 1;
@@ -5003,6 +5048,7 @@ case OP_IfNeg: {        /* jump, in1 */
 ** not contain an integer.  An assertion fault will result if you try.
 */
 case OP_IfZero: {        /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags&MEM_Int );
   pIn1->u.i += pOp->p3;
   if( pIn1->u.i==0 ){
@@ -5565,7 +5611,6 @@ case OP_Pagecount: {            /* out2-prerelease */
   ** page count has already been successfully read and cached.  So the
   ** sqlite3PagerPagecount() call above cannot fail. */
   if( ALWAYS(rc==SQLITE_OK) ){
-    pOut->flags = MEM_Int;
     pOut->u.i = nPage;
   }
   break;
@@ -5643,11 +5688,11 @@ default: {          /* This is really OP_Noop and OP_Explain */
 #ifdef SQLITE_DEBUG
     if( p->trace ){
       if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
-      if( opProperty & OPFLG_OUT2_PRERELEASE ){
-        registerTrace(p->trace, pOp->p2, pOut);
+      if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
+        registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
       }
-      if( opProperty & OPFLG_OUT3 ){
-        registerTrace(p->trace, pOp->p3, pOut);
+      if( pOp->opflags & OPFLG_OUT3 ){
+        registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
       }
     }
 #endif  /* SQLITE_DEBUG */