Remove the out2-prerelease VDBE opcode property and its associated code,

for a 0.5% performance improvement.

FossilOrigin-Name: e29c7f2c910dac07f0f92dfef5e0e743141954eb
This commit is contained in:
drh 2015-04-13 19:14:06 +00:00
parent 1fe0af200d
commit 27a348c7a0
4 changed files with 79 additions and 63 deletions

View File

@ -1,5 +1,5 @@
C Add\sa\scomment\sto\swal.c\sto\sexplain\swhy\sa\srace\scondition\sis\ssafe.
D 2015-04-13T17:43:43.335
C Remove\sthe\sout2-prerelease\sVDBE\sopcode\sproperty\sand\sits\sassociated\scode,\nfor\sa\s0.5%\sperformance\simprovement.
D 2015-04-13T19:14:06.003
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -154,7 +154,7 @@ F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk ddffac494a82d42772df9fe30d3a78acf4f7cb41
F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea
F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5
F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
F src/vdbe.c c4bd96912f8837777bfe5762d310767ed628b442
F src/vdbe.c 584abb81e4abf9dd51a9a2e71f680289bd0c019b
F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d
F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
@ -1250,7 +1250,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P d06669d968c8f6af8799fbfeabadaab68b9b8db8
R 90c9a3885d268edb8b0fe9dee7687f08
U dan
Z a7fde54970dc241049366741c468ca23
P bc33af866403c23d548dd4705675315810d52d7f
R 6ac0695a2f1b9d518c2805dcc9a01314
U drh
Z 453362d5fdffab6ea02dce6dd25e18dd

View File

@ -1 +1 @@
bc33af866403c23d548dd4705675315810d52d7f
e29c7f2c910dac07f0f92dfef5e0e743141954eb

View File

@ -72,7 +72,6 @@
sub("\r","",name)
op[name] = -1 # op[x] holds the numeric value for OP symbol x
jump[name] = 0
out2_prerelease[name] = 0
in1[name] = 0
in2[name] = 0
in3[name] = 0
@ -92,8 +91,6 @@
sub(",","",x)
if(x=="jump"){
jump[name] = 1
}else if(x=="out2-prerelease"){
out2_prerelease[name] = 1
}else if(x=="in1"){
in1[name] = 1
}else if(x=="in2"){
@ -194,13 +191,12 @@ END {
name = def[i]
a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
if( jump[name] ) a0 = 1;
if( out2_prerelease[name] ) a1 = 2;
if( in1[name] ) a2 = 4;
if( in2[name] ) a3 = 8;
if( in3[name] ) a4 = 16;
if( out2[name] ) a5 = 32;
if( out3[name] ) a6 = 64;
bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
if( in1[name] ) a2 = 2;
if( in2[name] ) a3 = 4;
if( in3[name] ) a4 = 8;
if( out2[name] ) a5 = 16;
if( out3[name] ) a6 = 32;
bv[i] = a0+a1+a2+a3+a4+a5+a6;
}
print "\n"
print "/* Properties such as \"out2\" or \"jump\" that are specified in"
@ -208,12 +204,11 @@ END {
print "** are encoded into bitvectors as follows:"
print "*/"
print "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */"
print "#define OPFLG_OUT2_PRERELEASE 0x0002 /* out2-prerelease: */"
print "#define OPFLG_IN1 0x0004 /* in1: P1 is an input */"
print "#define OPFLG_IN2 0x0008 /* in2: P2 is an input */"
print "#define OPFLG_IN3 0x0010 /* in3: P3 is an input */"
print "#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */"
print "#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */"
print "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */"
print "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */"
print "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */"
print "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */"
print "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */"
print "#define OPFLG_INITIALIZER {\\"
for(i=0; i<=max; i++){
if( i%8==0 ) printf("/* %3d */",i)

View File

@ -514,6 +514,21 @@ static int checkSavepointCount(sqlite3 *db){
}
#endif
/*
** Return the register of pOp->p2 after first preparing it to be
** overwritten with an integer value.
*/
static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
Mem *pOut;
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &p->aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
pOut->flags = MEM_Int;
return pOut;
}
/*
** Execute as much of a VDBE program as we can.
@ -633,23 +648,9 @@ int sqlite3VdbeExec(
}
#endif
/* On any opcode with the "out2-prerelease" 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] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
pOut->flags = MEM_Int;
}
/* Sanity checking on other operands */
#ifdef SQLITE_DEBUG
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
@ -705,7 +706,7 @@ int sqlite3VdbeExec(
**
** Other keywords in the comment that follows each case are used to
** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
** Keywords include: in1, in2, in3, out2_prerelease, out2, out3. See
** Keywords include: in1, in2, in3, out2, out3. See
** the mkopcodeh.awk script for additional information.
**
** Documentation about VDBE opcodes is generated by scanning this file
@ -979,7 +980,8 @@ case OP_Halt: {
**
** The 32-bit integer value P1 is written into register P2.
*/
case OP_Integer: { /* out2-prerelease */
case OP_Integer: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = pOp->p1;
break;
}
@ -990,7 +992,8 @@ case OP_Integer: { /* out2-prerelease */
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
*/
case OP_Int64: { /* out2-prerelease */
case OP_Int64: { /* out2 */
pOut = out2Prerelease(p, pOp);
assert( pOp->p4.pI64!=0 );
pOut->u.i = *pOp->p4.pI64;
break;
@ -1003,7 +1006,8 @@ case OP_Int64: { /* out2-prerelease */
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
*/
case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
case OP_Real: { /* same as TK_FLOAT, out2 */
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Real;
assert( !sqlite3IsNaN(*pOp->p4.pReal) );
pOut->u.r = *pOp->p4.pReal;
@ -1019,8 +1023,9 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
** this transformation, the length of string P4 is computed and stored
** as the P1 parameter.
*/
case OP_String8: { /* same as TK_STRING, out2-prerelease */
case OP_String8: { /* same as TK_STRING, out2 */
assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOp->opcode = OP_String;
pOp->p1 = sqlite3Strlen30(pOp->p4.z);
@ -1057,8 +1062,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
** the same sequence of bytes, it is merely interpreted as a BLOB instead
** of a string, as if it had been CAST.
*/
case OP_String: { /* out2-prerelease */
case OP_String: { /* out2 */
assert( pOp->p4.z!=0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
pOut->z = pOp->p4.z;
pOut->n = pOp->p1;
@ -1086,9 +1092,10 @@ case OP_String: { /* out2-prerelease */
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
case OP_Null: { /* out2 */
int cnt;
u16 nullFlag;
pOut = out2Prerelease(p, pOp);
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
@ -1123,8 +1130,9 @@ case OP_SoftNull: {
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
*/
case OP_Blob: { /* out2-prerelease */
case OP_Blob: { /* out2 */
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
@ -1139,7 +1147,7 @@ case OP_Blob: { /* out2-prerelease */
** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2-prerelease */
case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
@ -1148,6 +1156,7 @@ case OP_Variable: { /* out2-prerelease */
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
pOut = out2Prerelease(p, pOp);
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
@ -2721,7 +2730,7 @@ case OP_MakeRecord: {
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
@ -2729,6 +2738,7 @@ case OP_Count: { /* out2-prerelease */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
}
@ -3117,7 +3127,7 @@ case OP_Transaction: {
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: { /* out2-prerelease */
case OP_ReadCookie: { /* out2 */
int iMeta;
int iDb;
int iCookie;
@ -3131,6 +3141,7 @@ case OP_ReadCookie: { /* out2-prerelease */
assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut = out2Prerelease(p, pOp);
pOut->u.i = iMeta;
break;
}
@ -3951,9 +3962,10 @@ case OP_NotExists: { /* jump, in3 */
** The sequence number on the cursor is incremented after this
** instruction.
*/
case OP_Sequence: { /* out2-prerelease */
case OP_Sequence: { /* out2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( p->apCsr[pOp->p1]!=0 );
pOut = out2Prerelease(p, pOp);
pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
break;
}
@ -3974,7 +3986,7 @@ case OP_Sequence: { /* out2-prerelease */
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: { /* out2-prerelease */
case OP_NewRowid: { /* out2 */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
@ -3984,6 +3996,7 @@ case OP_NewRowid: { /* out2-prerelease */
v = 0;
res = 0;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@ -4428,12 +4441,13 @@ case OP_RowData: {
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
case OP_Rowid: { /* out2-prerelease */
case OP_Rowid: { /* out2 */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@ -4808,11 +4822,12 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
case OP_IdxRowid: { /* out2 */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
pOut = out2Prerelease(p, pOp);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
@ -4951,11 +4966,12 @@ case OP_IdxGE: { /* jump */
**
** See also: Clear
*/
case OP_Destroy: { /* out2-prerelease */
case OP_Destroy: { /* out2 */
int iMoved;
int iDb;
assert( p->readOnly==0 );
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Null;
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
@ -5064,12 +5080,13 @@ case OP_ResetSorter: {
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex: /* out2-prerelease */
case OP_CreateTable: { /* out2-prerelease */
case OP_CreateIndex: /* out2 */
case OP_CreateTable: { /* out2 */
int pgno;
int flags;
Db *pDb;
pOut = out2Prerelease(p, pOp);
pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
@ -5505,9 +5522,10 @@ case OP_Program: { /* jump */
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
case OP_Param: { /* out2-prerelease */
case OP_Param: { /* out2 */
VdbeFrame *pFrame;
Mem *pIn;
pOut = out2Prerelease(p, pOp);
pFrame = p->pFrame;
pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
@ -5814,7 +5832,7 @@ case OP_Checkpoint: {
**
** Write a string containing the final journal-mode to register P2.
*/
case OP_JournalMode: { /* out2-prerelease */
case OP_JournalMode: { /* out2 */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
@ -5823,6 +5841,7 @@ case OP_JournalMode: { /* out2-prerelease */
const char *zFilename; /* Name of database file for pPager */
#endif
pOut = out2Prerelease(p, pOp);
eNew = pOp->p3;
assert( eNew==PAGER_JOURNALMODE_DELETE
|| eNew==PAGER_JOURNALMODE_TRUNCATE
@ -6378,7 +6397,8 @@ case OP_VUpdate: {
**
** Write the current number of pages in database P1 to memory cell P2.
*/
case OP_Pagecount: { /* out2-prerelease */
case OP_Pagecount: { /* out2 */
pOut = out2Prerelease(p, pOp);
pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
break;
}
@ -6394,10 +6414,11 @@ case OP_Pagecount: { /* out2-prerelease */
**
** Store the maximum page count after the change in register P2.
*/
case OP_MaxPgcnt: { /* out2-prerelease */
case OP_MaxPgcnt: { /* out2 */
unsigned int newMax;
Btree *pBt;
pOut = out2Prerelease(p, pOp);
pBt = db->aDb[pOp->p1].pBt;
newMax = 0;
if( pOp->p3 ){
@ -6503,7 +6524,7 @@ default: { /* This is really OP_Noop and OP_Explain */
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
if( rc!=0 ) printf("rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
if( pOp->opflags & (OPFLG_OUT2) ){
registerTrace(pOp->p2, &aMem[pOp->p2]);
}
if( pOp->opflags & OPFLG_OUT3 ){