From: drh Date: Wed, 10 Jul 2013 03:05:14 +0000 (+0000) Subject: Run progress callback checks less frequently in the main VDBE evaluation X-Git-Tag: version-3.8.0~93 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=49afe3aaa067eb050d0e831d351683c8251cba42;p=thirdparty%2Fsqlite.git Run progress callback checks less frequently in the main VDBE evaluation loop. This makes up for the extra CPU cycles used to increment the cycle counter for SQLITE_STMTSTATUS_VM_STEP. FossilOrigin-Name: 3e8b02011db2f393d4850115a471709b0a88594f --- diff --git a/manifest b/manifest index 4f18895950..abe4d511cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\scosts\sin\sthe\sxBestIndex\sfunction\sof\sthe\sspellfix1\svirtual\stable\nto\sforce\sthe\suse\sof\sthe\sMATCH\sterm\sif\sit\sis\savailable. -D 2013-07-09T15:56:44.605 +C Run\sprogress\scallback\schecks\sless\sfrequently\sin\sthe\smain\sVDBE\sevaluation\nloop.\s\sThis\smakes\sup\sfor\sthe\sextra\sCPU\scycles\sused\sto\sincrement\sthe\scycle\ncounter\sfor\sSQLITE_STMTSTATUS_VM_STEP. +D 2013-07-10T03:05:14.910 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,7 +277,7 @@ F src/update.c 8e76c3d03e4b7b21cb250bd2df0c05e12993e577 F src/utf.c 8d819e2e5104a430fc2005f018db14347c95a38f F src/util.c f566b5138099a2df8533b190d0dcc74b7dfbe0c9 F src/vacuum.c d9c5759f4c5a438bb43c2086f72c5d2edabc36c8 -F src/vdbe.c 2e3fc618ff964cd559844fdbf186fdc582b66b1e +F src/vdbe.c b4d29f875ff2c8506783c6831b2d539cdeb39b91 F src/vdbe.h b52887278cb173e66188da84dfab216bea61119d F src/vdbeInt.h aa185c6df4f2b5ec9896cdb5f96789af1ef69f76 F src/vdbeapi.c e3ad4cddb713a387527f982e79d9e001a0dbffa5 @@ -715,7 +715,7 @@ F test/permutations.test 461ef4ea10db02cd421dfe5f988eac3e99b5cd9a F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 +F test/progress.test 552dc1edc37333a8d3098b8c26a2b7f06f5799d7 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 @@ -1101,7 +1101,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 1e39f85077f1f2b96c3a656c5b6334bafb005908 -R 2ea622f28aaf7cdeeb856cb215ef9fb3 +P f003bea9fe1b79e2b4d18fbef86c1d8f0f60e4b6 +R 04afd42ac3962714b1d32f16a2fdd2ad U drh -Z 80087d9cff19d8b6d80e8c14572ef089 +Z 82045c2120955e8475cc20915ea24bea diff --git a/manifest.uuid b/manifest.uuid index 1984d58a78..655deedd5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f003bea9fe1b79e2b4d18fbef86c1d8f0f60e4b6 \ No newline at end of file +3e8b02011db2f393d4850115a471709b0a88594f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f539b400a9..9a56518c57 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -552,12 +552,11 @@ int sqlite3VdbeExec( sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - int checkProgress; /* True if progress callbacks are enabled */ - int nProgressOps = 0; /* Opcodes executed since progress callback. */ -#endif int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + unsigned nProgressOps = 0; /* nVmStep at last progress callback. */ +#endif Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ Mem *pIn2 = 0; /* 2nd input operand */ @@ -586,9 +585,6 @@ int sqlite3VdbeExec( db->busyHandler.nBusy = 0; CHECK_FOR_INTERRUPT; sqlite3VdbeIOTraceSql(p); -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - checkProgress = db->xProgress!=0; -#endif #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){ @@ -636,27 +632,6 @@ int sqlite3VdbeExec( } #endif -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - /* Call the progress callback if it is configured and the required number - ** of VDBE ops have been executed (either since this invocation of - ** sqlite3VdbeExec() or since last time the progress callback was called). - ** If the progress callback returns non-zero, exit the virtual machine with - ** a return code SQLITE_ABORT. - */ - if( checkProgress ){ - if( db->nProgressOps==nProgressOps ){ - int prc; - prc = db->xProgress(db->pProgressArg); - if( prc!=0 ){ - rc = SQLITE_INTERRUPT; - goto vdbe_error_halt; - } - nProgressOps = 0; - } - nProgressOps++; - } -#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 @@ -749,8 +724,38 @@ int sqlite3VdbeExec( ** the program. */ case OP_Goto: { /* jump */ - CHECK_FOR_INTERRUPT; pc = pOp->p2 - 1; + + /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, + ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon + ** completion. Check to see if sqlite3_interrupt() has been called + ** or if the progress callback needs to be invoked. + ** + ** This code uses unstructured "goto" statements and does not look clean. + ** But that is not due to sloppy coding habits. The code is written this + ** way for performance, to avoid having to run the interrupt and progress + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% + ** faster according to "valgrind --tool=cachegrind" */ +check_for_interrupt: + CHECK_FOR_INTERRUPT; +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + /* Call the progress callback if it is configured and the required number + ** of VDBE ops have been executed (either since this invocation of + ** sqlite3VdbeExec() or since last time the progress callback was called). + ** If the progress callback returns non-zero, exit the virtual machine with + ** a return code SQLITE_ABORT. + */ + if( db->xProgress!=0 && (nVmStep - nProgressOps)>=db->nProgressOps ){ + int prc; + prc = db->xProgress(db->pProgressArg); + if( prc!=0 ){ + rc = SQLITE_INTERRUPT; + goto vdbe_error_halt; + } + nProgressOps = nVmStep; + } +#endif + break; } @@ -4502,7 +4507,6 @@ case OP_Next: { /* jump */ VdbeCursor *pC; int res; - CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5<=ArraySize(p->aCounter) ); pC = p->apCsr[pOp->p1]; @@ -4531,7 +4535,7 @@ case OP_Next: { /* jump */ #endif } pC->rowidIsValid = 0; - break; + goto check_for_interrupt; } /* Opcode: IdxInsert P1 P2 P3 * P5 @@ -5057,7 +5061,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 @@ -5069,7 +5073,7 @@ case OP_RowSetRead: { /* jump, in1, out3 */ /* A value was pulled from the index */ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); } - break; + goto check_for_interrupt; } /* Opcode: RowSetTest P1 P2 P3 P4 @@ -5970,7 +5974,7 @@ case OP_VNext: { /* jump */ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; } - break; + goto check_for_interrupt; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/test/progress.test b/test/progress.test index b25a100530..381f4826c8 100644 --- a/test/progress.test +++ b/test/progress.test @@ -166,7 +166,7 @@ do_test progress-1.7 { set ::res [list] db eval {SELECT a, b, c FROM abc} { lappend ::res $a $b $c - db progress 10 "expr 1" + db progress 5 "expr 1" catch {db eval {SELECT a, b, c FROM abc} { }} msg lappend ::res $msg }