From f09ac0b336b7fa8b0205fcd8494992264f4283d6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Jan 2018 03:44:06 +0000 Subject: [PATCH] Slightly faster function dispatch in the virtual machine by avoiding unnecessary reinitialization of variables that are already correctly initialized. FossilOrigin-Name: edd4e6876cc08ab907bb21f075380de946562d4c56a04923760848b4b11536ac --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/func.c | 1 + src/vdbe.c | 50 +++++++++++++++++++++++++++++--------------------- src/vdbeInt.h | 3 --- src/vdbeapi.c | 12 ++---------- 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index 6dc303c771..71deaf9781 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sone\sof\sthe\scompiler\swarning\sfixes\sfrom\sthe\sprevious\scheck-in. -D 2018-01-23T00:17:27.230 +C Slightly\sfaster\sfunction\sdispatch\sin\sthe\svirtual\smachine\sby\savoiding\nunnecessary\sreinitialization\sof\svariables\sthat\sare\salready\scorrectly\ninitialized. +D 2018-01-23T03:44:06.287 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2 @@ -442,7 +442,7 @@ F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b F src/expr.c 9e06de431c09f144438aa6895ea4d4290fa3c6875bfcc3ba331012ca78deadf0 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331 -F src/func.c bd528d5ed68ce5cbf78a762e3b735fa75009f7197ff07fab07fd771f35ebaa1b +F src/func.c 24d4746d347442c99153b5f9ac3204f6932d8d591008a94d6967de6b62fc0102 F src/global.c ac3094f1dc59fbeb919aef7cc0cc827a8459d1fb1adb7972ef75bd9e0c10b75b F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -555,10 +555,10 @@ F src/update.c a90a32ffc0100265b0693dbbdbe490756447af181f5ea2c138cce515b08c8795 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c ef4a5f904d942e660abade7fbf3e6bdb402dabe9e7c27f3361ecf40b945538b5 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c ccc1e17a30325068ae4f0292e8601997946886d23acc989c68f2a261a2795c70 +F src/vdbe.c 5aa6fb85281b6af058d2a87b65c1a8a8e0bd2fe554fb3391497ee3702b61e0be F src/vdbe.h 134beb7a12a6213c00eba58febaede33447cc4441bc568a0d9c144b33fc3720a -F src/vdbeInt.h c8cfbbc28e37e67a493c3f892fb0596add56a31a00e7537a06049af9ef2f51b0 -F src/vdbeapi.c 02f773681d06e46454b0606339068d4d4490873dc4a7334bc0c6030552bb2c8c +F src/vdbeInt.h 8d7d07f13cb3c4cbca91e22ba4a1920e542dda7c5d9299920432a0b3d5b009f5 +F src/vdbeapi.c fea41171884a4de119f8b10ab514c788674eeeb7f27218bb6d008e1310bfd07f F src/vdbeaux.c 2756ac68ac259c416554100598fc291870063288cd7e1af22847f57b3e130e56 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 7548dd5af03d24d534a5dbc41e3bbdf1fab83e9c8856a8d2549ed2ccf33d0e80 @@ -1700,7 +1700,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 76a11a80e94d1e9c9645e6e348948f3fd508266d4569c85d80a3879862d0a819 -R 47270bb77ce74e463612a801d427faba -U mistachkin -Z c93f87a6596350b67f49dd4ebf8496b6 +P 012d7d49c571207087bbe24af05d639627b96df526bfcb2098a3e975b74d865d +R 117511e55335ee1f52b85cfdea90c38c +U drh +Z e3904fade688ed958d5e16ed2185daad diff --git a/manifest.uuid b/manifest.uuid index 58bcb92a1a..993b1dc61a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -012d7d49c571207087bbe24af05d639627b96df526bfcb2098a3e975b74d865d \ No newline at end of file +edd4e6876cc08ab907bb21f075380de946562d4c56a04923760848b4b11536ac \ No newline at end of file diff --git a/src/func.c b/src/func.c index 1076b97161..8f409a0ad1 100644 --- a/src/func.c +++ b/src/func.c @@ -35,6 +35,7 @@ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ ** iteration of the aggregate loop. */ static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ + if( context->isError==0 ) context->isError = -1; context->skipFlag = 1; } diff --git a/src/vdbe.c b/src/vdbe.c index d878ca8e31..8d0b35a6f4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6204,12 +6204,17 @@ case OP_AggStep0: { assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); + pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + + (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); if( pCtx==0 ) goto no_mem; pCtx->pMem = 0; + pCtx->pOut = (Mem*)&(pCtx->argv[n]); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; + pCtx->skipFlag = 0; + pCtx->isError = 0; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; @@ -6220,7 +6225,6 @@ case OP_AggStep: { int i; sqlite3_context *pCtx; Mem *pMem; - Mem t; assert( pOp->p4type==P4_FUNCCTX ); pCtx = pOp->p4.pCtx; @@ -6243,26 +6247,28 @@ case OP_AggStep: { #endif pMem->n++; - sqlite3VdbeMemInit(&t, db, MEM_Null); - pCtx->pOut = &t; - pCtx->fErrorOrAux = 0; - pCtx->skipFlag = 0; + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->isError==0 ); + assert( pCtx->skipFlag==0 ); (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ - sqlite3VdbeError(p, "%s", sqlite3_value_text(&t)); + if( pCtx->isError ){ + if( pCtx->isError>0 ){ + sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); rc = pCtx->isError; } - sqlite3VdbeMemRelease(&t); + if( pCtx->skipFlag ){ + assert( pOp[-1].opcode==OP_CollSeq ); + i = pOp[-1].p1; + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); + pCtx->skipFlag = 0; + } + sqlite3VdbeMemRelease(pCtx->pOut); + pCtx->pOut->flags = MEM_Null; + pCtx->isError = 0; if( rc ) goto abort_due_to_error; - }else{ - assert( t.flags==MEM_Null ); - } - if( pCtx->skipFlag ){ - assert( pOp[-1].opcode==OP_CollSeq ); - i = pOp[-1].p1; - if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); } + assert( pCtx->pOut->flags==MEM_Null ); + assert( pCtx->skipFlag==0 ); break; } @@ -6749,7 +6755,7 @@ case OP_VColumn: { } rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); sqlite3VtabImportErrmsg(p, pVtab); - if( sContext.isError ){ + if( sContext.isError>0 ){ rc = sContext.isError; } sqlite3VdbeChangeEncoding(pDest, encoding); @@ -7014,6 +7020,7 @@ case OP_Function0: { pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; + pCtx->isError = 0; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; @@ -7048,16 +7055,17 @@ case OP_Function: { } #endif MemSetTypeFlag(pOut, MEM_Null); - pCtx->fErrorOrAux = 0; + assert( pCtx->isError==0 ); (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */ /* If the function returned an error, throw an exception */ - if( pCtx->fErrorOrAux ){ - if( pCtx->isError ){ + if( pCtx->isError ){ + if( pCtx->isError>0 ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); rc = pCtx->isError; } sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); + pCtx->isError = 0; if( rc ) goto abort_due_to_error; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 976abb3938..1e4f615ba2 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -224,8 +224,6 @@ struct sqlite3_value { ** If the MEM_Null flag is set, then the value is an SQL NULL value. ** For a pointer type created using sqlite3_bind_pointer() or ** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. -** If both MEM_Null and MEM_Zero are set, that means that the value is -** an unchanging column value from VColumn. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main @@ -319,7 +317,6 @@ struct sqlite3_context { int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 skipFlag; /* Skip accumulator loading if true */ - u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ u8 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index bdd6d1cd07..dd4a352003 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -372,14 +372,12 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif @@ -485,8 +483,7 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ return SQLITE_OK; } void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ - pCtx->isError = errCode; - pCtx->fErrorOrAux = 1; + pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif @@ -500,7 +497,6 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; - pCtx->fErrorOrAux = 1; sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } @@ -510,7 +506,6 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; - pCtx->fErrorOrAux = 1; sqlite3OomFault(pCtx->pOut->db); } @@ -917,10 +912,7 @@ void sqlite3_set_auxdata( pAuxData->iAuxArg = iArg; pAuxData->pNextAux = pVdbe->pAuxData; pVdbe->pAuxData = pAuxData; - if( pCtx->fErrorOrAux==0 ){ - pCtx->isError = 0; - pCtx->fErrorOrAux = 1; - } + if( pCtx->isError==0 ) pCtx->isError = -1; }else if( pAuxData->xDeleteAux ){ pAuxData->xDeleteAux(pAuxData->pAux); } -- 2.47.2