mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
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:
97
src/vdbe.c
97
src/vdbe.c
@@ -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 ){
|
||||
|
Reference in New Issue
Block a user