From: drh Date: Wed, 17 Sep 2014 14:52:46 +0000 (+0000) Subject: Improved interface to the Mem object handling. Small size reduction and X-Git-Tag: version-3.8.7~107^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0725cabe3a807b1fe8065ef3689dcfb8b4242265;p=thirdparty%2Fsqlite.git Improved interface to the Mem object handling. Small size reduction and performance increase. FossilOrigin-Name: 4e437844322cc20eef92928b53fa6b37eded586e --- diff --git a/manifest b/manifest index 0c48965589..56db1ec750 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Continuing\scleanup\sof\smemory\sregister\smemory\sallocation\shandling. -D 2014-09-16T21:54:11.409 +C Improved\sinterface\sto\sthe\sMem\sobject\shandling.\s\sSmall\ssize\sreduction\sand\nperformance\sincrease. +D 2014-09-17T14:52:46.727 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,13 +288,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 6a45baf86fcc6c294d57e0aef8c9f2c54f07ff18 +F src/vdbe.c d39487782c0c6a2448bd1b351eba6a2dce101343 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 -F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 +F src/vdbeInt.h 9d398055c873980b61ce0f7bf82140a8e4e2ccbc +F src/vdbeapi.c c6e63f913bcb12977731a8b12e7e5c5762981527 F src/vdbeaux.c 211ad29d51e01c44a0db1ab69b74c11c8de1cccf F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 9615c9aba37ec42bd6ea705d3d72379c77720b00 +F src/vdbemem.c cf552a404f0e73a48bd266699aa27f0df26b096b F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 78fb8838d80b229418c347c63579989432e1af7d -R 386107f24552e12c4df7dfd8a184a53a +P 2598aedc5dd2bac67e2e518a31f2803e469c2ba6 +R f63e98cc1bcae44946c79c20cdee7610 U drh -Z 90927a6d3c50834bddf5d6b0b977d8d6 +Z 1559702e8c6b5218f324b4f43d7dc2c7 diff --git a/manifest.uuid b/manifest.uuid index 1ed225fb04..52a893ba83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2598aedc5dd2bac67e2e518a31f2803e469c2ba6 \ No newline at end of file +4e437844322cc20eef92928b53fa6b37eded586e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4bdfbfbdeb..edccc1c601 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -640,7 +640,7 @@ int sqlite3VdbeExec( assert( pOp->p2<=(p->nMem-p->nCursor) ); pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); - VdbeMemReleaseExtern(pOut); + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); pOut->flags = MEM_Int; } @@ -1079,7 +1079,7 @@ case OP_Null: { /* out2-prerelease */ while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); - VdbeMemReleaseExtern(pOut); + sqlite3VdbeMemSetNull(pOut); pOut->flags = nullFlag; cnt--; } @@ -2107,10 +2107,10 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ case OP_Not: { /* same as TK_NOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - if( pIn1->flags & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - }else{ - sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1)); + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = !sqlite3VdbeIntValue(pIn1); } break; } @@ -2125,10 +2125,10 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - if( pIn1->flags & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - }else{ - sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); } break; } @@ -2437,7 +2437,7 @@ case OP_Column: { assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); - VdbeMemReleaseExtern(pDest); + if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 14ae09130c..556dfa16c7 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -429,11 +429,8 @@ int sqlite3VdbeMemNumerify(Mem*); void sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); -void sqlite3VdbeMemReleaseExternal(Mem *p); #define VdbeMemDynamic(X) \ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) -#define VdbeMemReleaseExtern(X) \ - if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 14d6b8412e..dbfabebbf0 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -662,8 +662,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ Mem *pMem = p->pMem; assert( (pMem->flags & MEM_Agg)==0 ); if( nByte<=0 ){ - sqlite3VdbeMemReleaseExternal(pMem); - pMem->flags = MEM_Null; + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; }else{ sqlite3VdbeMemGrow(pMem, nByte, 0); diff --git a/src/vdbemem.c b/src/vdbemem.c index 27a2301a9d..e1b4e4949f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -48,7 +48,6 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 ); } - return 1; } #endif @@ -121,9 +120,8 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ - VdbeMemReleaseExtern(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; - pMem->flags = MEM_Null; return SQLITE_NOMEM; } } @@ -311,23 +309,22 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ /* ** If the memory cell contains a value that must be freed by -** invoking an external callback, then free it now. -** -** This routine does NOT do any of the following: -** (1) Set the Mem.flags field to a rational value. -** (2) Free memory held by Mem.zMalloc -** The caller is expected to take care of setting Mem.flags appropriately. +** invoking the external callback in Mem.xDel, then this routine +** will free that value. It also sets Mem.flags to MEM_Null. ** -** The VdbeMemReleaseExtern() macro invokes this routine if only if there -** is work for this routine to do. +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the +** entry point for releasing Mem resources. */ -void sqlite3VdbeMemReleaseExternal(Mem *p){ +static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + assert( VdbeMemDynamic(p) ); if( p->flags&MEM_Agg ){ sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); - sqlite3VdbeMemRelease(p); - }else if( p->flags&MEM_Dyn ){ + testcase( p->flags & MEM_Dyn ); + } + if( p->flags&MEM_Dyn ){ assert( (p->flags&MEM_RowSet)==0 ); assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); p->xDel((void *)p->z); @@ -347,12 +344,12 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ ** by p->xDel and memory in p->zMalloc. ** ** This is a helper routine invoked by sqlite3VdbeMemRelease() in -** the uncommon case when there really is memory in p that needs -** to be freeing. +** the unusual case where there really is memory in p that needs +** to be freed. */ -static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ +static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ if( VdbeMemDynamic(p) ){ - sqlite3VdbeMemReleaseExternal(p); + vdbeMemClearExternAndSetNull(p); } if( p->zMalloc ){ sqlite3DbFree(p->db, p->zMalloc); @@ -362,18 +359,19 @@ static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ } /* -** Release any memory held by the Mem. This may leave the Mem.flags in an -** inconsistent state, for example with (Mem.z==0) and (Mem.flags==MEM_Str). +** Release any memory resources held by the Mem. Both the memory that is +** free by Mem.xDel and the Mem.zMalloc allocation are freed. +** +** Use this routine prior to clean up prior to abandoning a Mem, or to +** reset a Mem back to its minimum memory utilization. ** -** This routine releases both the Mem.xDel space and the Mem.zMalloc space. -** Use sqlite3VdbeMemReleaseExternal() to release just the Mem.xDel space. +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space +** prior to inserting new content into the Mem. */ void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); if( VdbeMemDynamic(p) || p->zMalloc ){ - vdbeMemRelease(p); - }else{ - p->z = 0; + vdbeMemClear(p); } assert( p->xDel==0 ); } @@ -590,10 +588,19 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ /* ** Delete any previous value and set the value stored in *pMem to NULL. +** +** This routine calls the Mem.xDel destructor to dispose of values that +** require the destructor. But it preserves the Mem.zMalloc memory allocation. +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this +** routine to invoke the destructor and deallocates Mem.zMalloc. +** +** Use this routine to reset the Mem prior to insert a new value. +** +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. */ void sqlite3VdbeMemSetNull(Mem *pMem){ if( VdbeMemDynamic(pMem) ){ - sqlite3VdbeMemReleaseExternal(pMem); + vdbeMemClearExternAndSetNull(pMem); }else{ pMem->flags = MEM_Null; } @@ -613,14 +620,7 @@ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ if( n<0 ) n = 0; pMem->u.nZero = n; pMem->enc = SQLITE_UTF8; - -#ifdef SQLITE_OMIT_INCRBLOB - sqlite3VdbeMemGrow(pMem, n, 0); - if( pMem->z ){ - pMem->n = n; - memset(pMem->z, 0, n); - } -#endif + pMem->z = 0; } /* @@ -629,7 +629,7 @@ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ ** a 64-bit integer. */ static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ - sqlite3VdbeMemReleaseExternal(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->u.i = val; pMem->flags = MEM_Int; } @@ -653,10 +653,8 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ ** manifest type REAL. */ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ - if( sqlite3IsNaN(val) ){ - sqlite3VdbeMemSetNull(pMem); - }else{ - sqlite3VdbeMemRelease(pMem); + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ pMem->r = val; pMem->flags = MEM_Real; } @@ -736,7 +734,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); assert( pTo->db==pFrom->db ); - VdbeMemReleaseExtern(pTo); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); assert( pTo->xDel==0 ); if( (pFrom->flags&MEM_Static)==0 ){ @@ -755,7 +753,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ assert( pTo->db==pFrom->db ); assert( (pFrom->flags & MEM_RowSet)==0 ); - VdbeMemReleaseExtern(pTo); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; assert( pTo->xDel==0 ); @@ -832,7 +830,8 @@ int sqlite3VdbeMemSetStr( if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ - for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){} + nByte = sqlite3Strlen30(z); + if( nByte>iLimit ) nByte = iLimit+1; }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} }