From b6991796b4b6f1a9c591349dd6d6ac4438f1db79 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Dec 2018 20:14:03 +0000 Subject: [PATCH 1/2] Move the nOpAlloc field from Parse into Vdbe to avoid an extra pointer deference on the fast path in sqlite3VdbeAddOp3(). FossilOrigin-Name: 8f10efc29dea7b816b1ba401726c268950d6671d890f686911269082a241d8d9 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqliteInt.h | 1 - src/vdbeInt.h | 3 ++- src/vdbeaux.c | 22 +++++++++++----------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 4cb8b187db..558a9b524d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\swith\sloading\sthe\sstructure\srecord\sfrom\sa\scorrupt\sfts5\ndatabase. -D 2018-12-28T18:09:45.448 +C Move\sthe\snOpAlloc\sfield\sfrom\sParse\sinto\sVdbe\sto\savoid\san\sextra\spointer\ndeference\son\sthe\sfast\spath\sin\ssqlite3VdbeAddOp3(). +D 2018-12-28T20:14:03.641 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in d8b254f8bb81bab43c340d70d17dc3babab40fcc8a348c8255881f780a45fee6 @@ -515,7 +515,7 @@ F src/shell.c.in 207da30342db0b6fac8b2487abd60b059a5ea80cc9494bd1db76a1dd4aae7cc F src/sqlite.h.in b54cd42d2f3b739a00de540cafe2dcd0de3b8e1748a2db33a68def487e9e602f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h 031e09cf6ea600e23fb4ce6e0a81f3f0e256b990dc6a71d21324d9ab8533b6cd +F src/sqliteInt.h 00590d0d0b1befd7bd19969f8a3c73b2378c4880634c6e5a0b01891e29cff2f9 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -583,9 +583,9 @@ F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 3ffe64ecfc94b7528c5d7bdb1c3a19d72fec63f2aa846e3b90f8de5dbbddf5aa F src/vdbe.c 8869a60f4b910c0f6d4ae0f0e23b7a835cae7ed67aa0ce2053d1bbe3e9facc53 F src/vdbe.h 8990d668a89890a33326b0a29b992c4014b72f3b6cdcd9ee0e190593c247f9b0 -F src/vdbeInt.h 73f5051923f3f29779bfc374c0c68e23b8e5e3792def2e33e51b427edb890abd +F src/vdbeInt.h 24975074bd9e3b375afefc79ac01f63edc8e823938b410398b4139ce73ceaed6 F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4 -F src/vdbeaux.c 0d7b40bc340e831efa8629e8af4bccfe2bdf694aebbb0e4fc6eb554c6f557d26 +F src/vdbeaux.c 742fb6de47b5db220371552f01685c0133ce3218fff5c84ca0cf0118a1329d08 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f @@ -1795,7 +1795,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 0140f6dbfbea93eadcd7f727d84064a0c0d1f0806dbe3e5ef1017da603157e3b -R d88edad902dccade29aed9ac22766474 -U dan -Z df5da4eeddcf8426b83484754213b103 +P c4d44542d259bbec11aea60ae94fcb4acd53e97e125723cae078cf0f8873f8ef +R 1ab45fb4eb1f997b9040d140828d5b55 +U drh +Z b6640113f9663b2a5c9ad0fe2d11cd40 diff --git a/manifest.uuid b/manifest.uuid index 4f6beb5f52..8683f6fba5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4d44542d259bbec11aea60ae94fcb4acd53e97e125723cae078cf0f8873f8ef \ No newline at end of file +8f10efc29dea7b816b1ba401726c268950d6671d890f686911269082a241d8d9 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2af59ecf85..93befd451f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3065,7 +3065,6 @@ struct Parse { int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ - int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 70543526c1..1dc7f66134 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -390,6 +390,8 @@ struct Vdbe { ** initialized to zero or NULL */ Op *aOp; /* Space to hold the virtual machine's program */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Slots allocated for aOp[] */ Mem *aMem; /* The memory locations */ Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ @@ -401,7 +403,6 @@ struct Vdbe { #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif - int nOp; /* Number of instructions in the program */ #ifdef SQLITE_DEBUG int rcApp; /* errcode set by sqlite3_result_error_code() */ u32 nWrite; /* Number of write operations that have occurred */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dd78c3d31a..ada89ce900 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -36,7 +36,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ pParse->pVdbe = p; assert( pParse->aLabel==0 ); assert( pParse->nLabel==0 ); - assert( pParse->nOpAlloc==0 ); + assert( p->nOpAlloc==0 ); assert( pParse->szOpAlloc==0 ); sqlite3VdbeAddOp2(p, OP_Init, 0, 1); return p; @@ -139,7 +139,7 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ ** to 1024/sizeof(Op). ** ** If an out-of-memory error occurs while resizing the array, return -** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain ** unchanged (this is so that any opcodes already allocated can be ** correctly deallocated along with the rest of the Vdbe). */ @@ -155,9 +155,9 @@ static int growOpArray(Vdbe *v, int nOp){ ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current ** size of the op array or add 1KB of space, whichever is smaller. */ #ifdef SQLITE_TEST_REALLOC_STRESS - int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp); + int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp); #else - int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); + int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op))); UNUSED_PARAMETER(nOp); #endif @@ -168,11 +168,11 @@ static int growOpArray(Vdbe *v, int nOp){ } assert( nOp<=(1024/sizeof(Op)) ); - assert( nNew>=(p->nOpAlloc+nOp) ); + assert( nNew>=(v->nOpAlloc+nOp) ); pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); - p->nOpAlloc = p->szOpAlloc/sizeof(Op); + v->nOpAlloc = p->szOpAlloc/sizeof(Op); v->aOp = pNew; } return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); @@ -206,9 +206,9 @@ static void test_addop_breakpoint(void){ ** operand. */ static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ - assert( p->pParse->nOpAlloc<=p->nOp ); + assert( p->nOpAlloc<=p->nOp ); if( growOpArray(p, 1) ) return 1; - assert( p->pParse->nOpAlloc>p->nOp ); + assert( p->nOpAlloc>p->nOp ); return sqlite3VdbeAddOp3(p, op, p1, p2, p3); } int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ @@ -218,7 +218,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); - if( p->pParse->nOpAlloc<=i ){ + if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } p->nOp++; @@ -793,7 +793,7 @@ int sqlite3VdbeCurrentAddr(Vdbe *p){ */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ - assert( p->nOp + N <= p->pParse->nOpAlloc ); + assert( p->nOp + N <= p->nOpAlloc ); } #endif @@ -865,7 +865,7 @@ VdbeOp *sqlite3VdbeAddOpList( VdbeOp *pOut, *pFirst; assert( nOp>0 ); assert( p->magic==VDBE_MAGIC_INIT ); - if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ + if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } pFirst = pOut = &p->aOp[p->nOp]; From 81f9159b5ec0e19d9aafee9c03a13bc4e7735cd8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Dec 2018 20:48:07 +0000 Subject: [PATCH 2/2] Faster allocation of new sqlite3_stmt objects. FossilOrigin-Name: 891f1f72187f0f9ec0d24fda98cc08be3ae3c3ff8b27c4e409ee7135c3106398 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeInt.h | 8 ++++---- src/vdbeaux.c | 26 +++++++++++++++++--------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 558a9b524d..3590353ddb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\snOpAlloc\sfield\sfrom\sParse\sinto\sVdbe\sto\savoid\san\sextra\spointer\ndeference\son\sthe\sfast\spath\sin\ssqlite3VdbeAddOp3(). -D 2018-12-28T20:14:03.641 +C Faster\sallocation\sof\snew\ssqlite3_stmt\sobjects. +D 2018-12-28T20:48:07.501 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in d8b254f8bb81bab43c340d70d17dc3babab40fcc8a348c8255881f780a45fee6 @@ -583,9 +583,9 @@ F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157 F src/vacuum.c 3ffe64ecfc94b7528c5d7bdb1c3a19d72fec63f2aa846e3b90f8de5dbbddf5aa F src/vdbe.c 8869a60f4b910c0f6d4ae0f0e23b7a835cae7ed67aa0ce2053d1bbe3e9facc53 F src/vdbe.h 8990d668a89890a33326b0a29b992c4014b72f3b6cdcd9ee0e190593c247f9b0 -F src/vdbeInt.h 24975074bd9e3b375afefc79ac01f63edc8e823938b410398b4139ce73ceaed6 +F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4 -F src/vdbeaux.c 742fb6de47b5db220371552f01685c0133ce3218fff5c84ca0cf0118a1329d08 +F src/vdbeaux.c c5d6c0afa98dbc42eac7f74da9f126fe33ec38fa13fec0790b268547f3d96ff2 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f @@ -1795,7 +1795,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 c4d44542d259bbec11aea60ae94fcb4acd53e97e125723cae078cf0f8873f8ef -R 1ab45fb4eb1f997b9040d140828d5b55 +P 8f10efc29dea7b816b1ba401726c268950d6671d890f686911269082a241d8d9 +R 7062d8a270754e07b86fa92b28527403 U drh -Z b6640113f9663b2a5c9ad0fe2d11cd40 +Z 74c93f83e36562633bb10d90f0e5b0ee diff --git a/manifest.uuid b/manifest.uuid index 8683f6fba5..528beb0961 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f10efc29dea7b816b1ba401726c268950d6671d890f686911269082a241d8d9 \ No newline at end of file +891f1f72187f0f9ec0d24fda98cc08be3ae3c3ff8b27c4e409ee7135c3106398 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1dc7f66134..acc7f5a6a0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -385,6 +385,10 @@ struct Vdbe { i64 nFkConstraint; /* Number of imm. FK constraints this VM */ i64 nStmtDefCons; /* Number of def. constraints when stmt started */ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ + Mem *aMem; /* The memory locations */ + Mem **apArg; /* Arguments to currently executing user function */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + Mem *aVar; /* Values for the OP_Variable opcode. */ /* When allocating a new Vdbe object, all of the fields below should be ** initialized to zero or NULL */ @@ -392,13 +396,9 @@ struct Vdbe { Op *aOp; /* Space to hold the virtual machine's program */ int nOp; /* Number of instructions in the program */ int nOpAlloc; /* Slots allocated for aOp[] */ - Mem *aMem; /* The memory locations */ - Mem **apArg; /* Arguments to currently executing user function */ Mem *aColName; /* Column names to return */ Mem *pResultSet; /* Pointer to an array of results */ char *zErrMsg; /* Error message written here */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - Mem *aVar; /* Values for the OP_Variable opcode. */ VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ada89ce900..bd1d180584 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2187,19 +2187,27 @@ void sqlite3VdbeMakeReady( ** the leftover memory at the end of the opcode array. This can significantly ** reduce the amount of memory held by a prepared statement. */ - do { - x.nNeeded = 0; - p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); - p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); - p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); - p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); + x.nNeeded = 0; + p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); + p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); #endif - if( x.nNeeded==0 ) break; + if( x.nNeeded ){ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; - }while( !db->mallocFailed ); + if( !db->mallocFailed ){ + p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); +#endif + } + } p->pVList = pParse->pVList; pParse->pVList = 0;