-C Simplify\sthe\spcache\sby\snot\skeeping\scontinuous\strack\sof\spage\s1\sbut\sinstead\njust\sloading\spage\s1\son\sthe\srare\soccasions\swhen\sit\sis\sactually\sneeded.
-D 2015-06-26T02:41:31.913
+C Cache\sthe\smost\srecently\ssqlite3_context\sused\sby\sOP_Function\sand\sreuse\sit\son\nsubsequent\scalls,\sif\sappropriate.\sThis\sgives\sa\snoticable\sperformance\sboost.
+D 2015-06-26T13:31:02.230
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c a6431c92803b975b7322724a7b433e538d243539
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
-F src/vdbe.c 3af2d06e2b36012631dc3331957df52febdf8678
+F src/vdbe.c 592957316d7bced599384e7897f6ee7728af5a61
F src/vdbe.h 90048aea1910f9df93e6044592bd4a466dc9c5e7
F src/vdbeInt.h 20295e482121d13437f69985f77db211cdc8bac1
F src/vdbeapi.c 6a0d7757987018ff6b1b81bc5293219cd26bb299
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 8d79f3a1443391bee204bb8c49240f44477168db
-R c56e8779f6e8f4f9de88fc3a0bf56b01
+P 015302f15e46a087ec92f3644c6741600dbf4306
+R 7832174f14c22d1eacdad67bafdfeaa7
+T *branch * function-ctx-cache
+T *sym-function-ctx-cache *
+T -sym-trunk *
U drh
-Z 87d94359f0bb80945f07f56dd11de5b2
+Z e48fb4a345ac7f54e42bdc087583de4b
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
#endif
+ Op *pCtxOp = 0; /* Opcode for which ctx is initialized */
+ sqlite3_context ctx; /* Function call context */
+
/*** INSERT STACK UNION HERE ***/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
aOp = p->aOp;
aMem = p->aMem;
pOp = &aOp[pcx];
+ pCtxOp = 0;
break;
}
p->rc = pOp->p1;
case OP_Function: {
int i;
Mem *pArg;
- sqlite3_context ctx;
sqlite3_value **apVal;
int n;
n = pOp->p5;
- apVal = p->apArg;
- assert( apVal || n==0 );
- assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- ctx.pOut = &aMem[pOp->p3];
- memAboutToChange(p, ctx.pOut);
-
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
- pArg = &aMem[pOp->p2];
- for(i=0; i<n; i++, pArg++){
- assert( memIsValid(pArg) );
- apVal[i] = pArg;
- Deephemeralize(pArg);
- REGISTER_TRACE(pOp->p2+i, pArg);
+ if( pOp!=pCtxOp ){
+ apVal = p->apArg;
+ assert( apVal || n==0 );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ ctx.pOut = &aMem[pOp->p3];
+
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+ pArg = &aMem[pOp->p2];
+ for(i=0; i<n; i++, pArg++){
+ apVal[i] = pArg;
+ }
+ assert( pOp->p4type==P4_FUNCDEF );
+ ctx.pFunc = pOp->p4.pFunc;
+ ctx.iOp = (int)(pOp - aOp);
+ ctx.pVdbe = p;
+ pCtxOp = pOp;
}
-
- assert( pOp->p4type==P4_FUNCDEF );
- ctx.pFunc = pOp->p4.pFunc;
- ctx.iOp = (int)(pOp - aOp);
- ctx.pVdbe = p;
+#ifdef SQLITE_DEBUG
+ for(i=0; i<n; i++){
+ assert( memIsValid(p->apArg[i]) );
+ REGISTER_TRACE(pOp->p2+i, p->apArg[i]);
+ }
+#endif
+ memAboutToChange(p, ctx.pOut);
MemSetTypeFlag(ctx.pOut, MEM_Null);
ctx.fErrorOrAux = 0;
db->lastRowid = lastRowid;
- (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+ (*ctx.pFunc->xFunc)(&ctx, n, p->apArg); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
/* If the function returned an error, throw an exception */
p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
p->aOp = aOp = pProgram->aOp;
+ pCtxOp = 0;
p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
p->nOnceFlag = pProgram->nOnce;
Mem *pMem;
Mem *pRec;
Mem t;
- sqlite3_context ctx;
+ sqlite3_context actx;
sqlite3_value **apVal;
n = pOp->p5;
assert( n>=0 );
pRec = &aMem[pOp->p2];
+ pCtxOp = 0;
apVal = p->apArg;
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
apVal[i] = pRec;
memAboutToChange(p, pRec);
}
- ctx.pFunc = pOp->p4.pFunc;
+ actx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- ctx.pMem = pMem = &aMem[pOp->p3];
+ actx.pMem = pMem = &aMem[pOp->p3];
pMem->n++;
sqlite3VdbeMemInit(&t, db, MEM_Null);
- ctx.pOut = &t;
- ctx.isError = 0;
- ctx.pVdbe = p;
- ctx.iOp = (int)(pOp - aOp);
- ctx.skipFlag = 0;
- (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
- if( ctx.isError ){
+ actx.pOut = &t;
+ actx.isError = 0;
+ actx.pVdbe = p;
+ actx.iOp = (int)(pOp - aOp);
+ actx.skipFlag = 0;
+ (actx.pFunc->xStep)(&actx, n, apVal); /* IMP: R-24505-23230 */
+ if( actx.isError ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
- rc = ctx.isError;
+ rc = actx.isError;
}
- if( ctx.skipFlag ){
+ if( actx.skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
i = pOp[-1].p1;
if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
+ pCtxOp = 0;
rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
if( ALWAYS(pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
apArg = p->apArg;
+ pCtxOp = 0;
pX = &aMem[pOp->p3];
for(i=0; i<nArg; i++){
assert( memIsValid(pX) );