]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improved interface to the Mem object handling. Small size reduction and
authordrh <drh@noemail.net>
Wed, 17 Sep 2014 14:52:46 +0000 (14:52 +0000)
committerdrh <drh@noemail.net>
Wed, 17 Sep 2014 14:52:46 +0000 (14:52 +0000)
performance increase.

FossilOrigin-Name: 4e437844322cc20eef92928b53fa6b37eded586e

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
src/vdbemem.c

index 0c489655898f77e134028ebd485beaab134f80f4..56db1ec7500657109195dfe87e39df508dd1e430 100644 (file)
--- 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
index 1ed225fb043515d61b71cf74b1d93f0cf50e7d52..52a893ba8370e1d16c407dc34b8de56c10c69a0c 100644 (file)
@@ -1 +1 @@
-2598aedc5dd2bac67e2e518a31f2803e469c2ba6
\ No newline at end of file
+4e437844322cc20eef92928b53fa6b37eded586e
\ No newline at end of file
index 4bdfbfbdeb4e91376f634137e69163b7859b1ef5..edccc1c6014ffa3d9a1bc2f9c67b10600c683764 100644 (file)
@@ -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( p2<pC->nHdrParsed );
   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 */
index 14ae09130c463ff8f667baa0ce7f0e8058d6b6ef..556dfa16c7982648ea1ba391d1e708e2109991fb 100644 (file)
@@ -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);
index 14d6b8412ee7ef1fae3bf59be6d2158a22eeaf5d..dbfabebbf051de2e6e3565dd33fe5aa8e0e695bf 100644 (file)
@@ -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);
index 27a2301a9de3b7ee966c1bcdf2554de73523a42b..e1b4e4949f1ae0a56953b37b8e7666f31ea3f6fa 100644 (file)
@@ -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){}
     }