/ Check-in [3ca5846d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change the name of the VdbeMemRelease() macro to VdbeMemReleaseExtern() to more accurately reflect what it does. Performance enhancement to the sqlite3VdbeMemRelease() function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3ca5846da7da5e08192a4c96288197be3b7ab6f7
User & Date: drh 2014-08-25 11:20:27
Context
2014-08-25
11:33
Remove the pager_lookup() function since it is redundant with sqlite3PagerLookup(). check-in: 54164ce4 user: drh tags: trunk
11:20
Change the name of the VdbeMemRelease() macro to VdbeMemReleaseExtern() to more accurately reflect what it does. Performance enhancement to the sqlite3VdbeMemRelease() function. check-in: 3ca5846d user: drh tags: trunk
2014-08-24
02:53
The sqlite3VdbeChangeEncoding() routine goes about 3x faster if the sqlite3VdbeMemTranslate() subroutine is not inlined. check-in: 0c7e1b87 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/vdbe.c.

   636    636       */
   637    637       assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
   638    638       if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
   639    639         assert( pOp->p2>0 );
   640    640         assert( pOp->p2<=(p->nMem-p->nCursor) );
   641    641         pOut = &aMem[pOp->p2];
   642    642         memAboutToChange(p, pOut);
   643         -      VdbeMemRelease(pOut);
          643  +      VdbeMemReleaseExtern(pOut);
   644    644         pOut->flags = MEM_Int;
   645    645       }
   646    646   
   647    647       /* Sanity checking on other operands */
   648    648   #ifdef SQLITE_DEBUG
   649    649       if( (pOp->opflags & OPFLG_IN1)!=0 ){
   650    650         assert( pOp->p1>0 );
................................................................................
  1075   1075     u16 nullFlag;
  1076   1076     cnt = pOp->p3-pOp->p2;
  1077   1077     assert( pOp->p3<=(p->nMem-p->nCursor) );
  1078   1078     pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
  1079   1079     while( cnt>0 ){
  1080   1080       pOut++;
  1081   1081       memAboutToChange(p, pOut);
  1082         -    VdbeMemRelease(pOut);
         1082  +    VdbeMemReleaseExtern(pOut);
  1083   1083       pOut->flags = nullFlag;
  1084   1084       cnt--;
  1085   1085     }
  1086   1086     break;
  1087   1087   }
  1088   1088   
  1089   1089   /* Opcode: SoftNull P1 * * * *
................................................................................
  1161   1161     pIn1 = &aMem[p1];
  1162   1162     pOut = &aMem[p2];
  1163   1163     do{
  1164   1164       assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
  1165   1165       assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
  1166   1166       assert( memIsValid(pIn1) );
  1167   1167       memAboutToChange(p, pOut);
  1168         -    VdbeMemRelease(pOut);
         1168  +    VdbeMemReleaseExtern(pOut);
  1169   1169       zMalloc = pOut->zMalloc;
  1170   1170       memcpy(pOut, pIn1, sizeof(Mem));
  1171   1171   #ifdef SQLITE_DEBUG
  1172   1172       if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
  1173   1173         pOut->pScopyFrom += p1 - pOp->p2;
  1174   1174       }
  1175   1175   #endif
................................................................................
  2534   2534     */
  2535   2535     assert( p2<pC->nHdrParsed );
  2536   2536     assert( rc==SQLITE_OK );
  2537   2537     assert( sqlite3VdbeCheckMemInvariants(pDest) );
  2538   2538     if( pC->szRow>=aOffset[p2+1] ){
  2539   2539       /* This is the common case where the desired content fits on the original
  2540   2540       ** page - where the content is not on an overflow page */
  2541         -    VdbeMemRelease(pDest);
         2541  +    VdbeMemReleaseExtern(pDest);
  2542   2542       sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
  2543   2543     }else{
  2544   2544       /* This branch happens only when content is on overflow pages */
  2545   2545       t = aType[p2];
  2546   2546       if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
  2547   2547             && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
  2548   2548        || (len = sqlite3VdbeSerialTypeLen(t))==0

Changes to src/vdbeInt.h.

   426    426   int sqlite3VdbeMemRealify(Mem*);
   427    427   int sqlite3VdbeMemNumerify(Mem*);
   428    428   int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
   429    429   void sqlite3VdbeMemRelease(Mem *p);
   430    430   void sqlite3VdbeMemReleaseExternal(Mem *p);
   431    431   #define VdbeMemDynamic(X)  \
   432    432     (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
   433         -#define VdbeMemRelease(X)  \
          433  +#define VdbeMemReleaseExtern(X)  \
   434    434     if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X);
   435    435   int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
   436    436   const char *sqlite3OpcodeName(int);
   437    437   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   438    438   int sqlite3VdbeCloseStatement(Vdbe *, int);
   439    439   void sqlite3VdbeFrameDelete(VdbeFrame*);
   440    440   int sqlite3VdbeFrameRestore(VdbeFrame *);

Changes to src/vdbemem.c.

   117    117         pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
   118    118         bPreserve = 0;
   119    119       }else{
   120    120         sqlite3DbFree(pMem->db, pMem->zMalloc);
   121    121         pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
   122    122       }
   123    123       if( pMem->zMalloc==0 ){
   124         -      VdbeMemRelease(pMem);
          124  +      VdbeMemReleaseExtern(pMem);
   125    125         pMem->z = 0;
   126    126         pMem->flags = MEM_Null;  
   127    127         return SQLITE_NOMEM;
   128    128       }
   129    129     }
   130    130   
   131    131     if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
................................................................................
   296    296     return rc;
   297    297   }
   298    298   
   299    299   /*
   300    300   ** If the memory cell contains a string value that must be freed by
   301    301   ** invoking an external callback, free it now. Calling this function
   302    302   ** does not free any Mem.zMalloc buffer.
          303  +**
          304  +** The VdbeMemReleaseExtern() macro invokes this routine if only if there
          305  +** is work for this routine to do.
   303    306   */
   304    307   void sqlite3VdbeMemReleaseExternal(Mem *p){
   305    308     assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
   306    309     if( p->flags&MEM_Agg ){
   307    310       sqlite3VdbeMemFinalize(p, p->u.pDef);
   308    311       assert( (p->flags & MEM_Agg)==0 );
   309    312       sqlite3VdbeMemRelease(p);
................................................................................
   314    317       p->xDel = 0;
   315    318     }else if( p->flags&MEM_RowSet ){
   316    319       sqlite3RowSetClear(p->u.pRowSet);
   317    320     }else if( p->flags&MEM_Frame ){
   318    321       sqlite3VdbeMemSetNull(p);
   319    322     }
   320    323   }
          324  +
          325  +/*
          326  +** Release memory held by the Mem p, both external memory cleared
          327  +** by p->xDel and memory in p->zMalloc.
          328  +**
          329  +** This is a helper routine invoked by sqlite3VdbeMemRelease() in
          330  +** the uncommon case when there really is memory in p that is
          331  +** need of freeing.
          332  +*/
          333  +static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){
          334  +  if( VdbeMemDynamic(p) ){
          335  +    sqlite3VdbeMemReleaseExternal(p);
          336  +  }
          337  +  if( p->zMalloc ){
          338  +    sqlite3DbFree(p->db, p->zMalloc);
          339  +    p->zMalloc = 0;
          340  +  }
          341  +  p->z = 0;
          342  +}
   321    343   
   322    344   /*
   323    345   ** Release any memory held by the Mem. This may leave the Mem in an
   324    346   ** inconsistent state, for example with (Mem.z==0) and
   325    347   ** (Mem.flags==MEM_Str).
   326    348   */
   327    349   void sqlite3VdbeMemRelease(Mem *p){
   328    350     assert( sqlite3VdbeCheckMemInvariants(p) );
   329         -  VdbeMemRelease(p);
   330         -  if( p->zMalloc ){
   331         -    sqlite3DbFree(p->db, p->zMalloc);
   332         -    p->zMalloc = 0;
   333         -  }
          351  +  if( VdbeMemDynamic(p) || p->zMalloc ){
          352  +    vdbeMemRelease(p);
          353  +  }else{
   334    354     p->z = 0;
   335         -  assert( p->xDel==0 );  /* Zeroed by VdbeMemRelease() above */
          355  +  }
          356  +  assert( p->xDel==0 );
   336    357   }
   337    358   
   338    359   /*
   339    360   ** Convert a 64-bit IEEE double into a 64-bit signed integer.
   340    361   ** If the double is out of range of a 64-bit signed integer then
   341    362   ** return the closest available 64-bit signed integer.
   342    363   */
................................................................................
   634    655   ** Make an shallow copy of pFrom into pTo.  Prior contents of
   635    656   ** pTo are freed.  The pFrom->z field is not duplicated.  If
   636    657   ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
   637    658   ** and flags gets srcType (either MEM_Ephem or MEM_Static).
   638    659   */
   639    660   void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
   640    661     assert( (pFrom->flags & MEM_RowSet)==0 );
   641         -  VdbeMemRelease(pTo);
          662  +  VdbeMemReleaseExtern(pTo);
   642    663     memcpy(pTo, pFrom, MEMCELLSIZE);
   643    664     pTo->xDel = 0;
   644    665     if( (pFrom->flags&MEM_Static)==0 ){
   645    666       pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
   646    667       assert( srcType==MEM_Ephem || srcType==MEM_Static );
   647    668       pTo->flags |= srcType;
   648    669     }
................................................................................
   652    673   ** Make a full copy of pFrom into pTo.  Prior contents of pTo are
   653    674   ** freed before the copy is made.
   654    675   */
   655    676   int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   656    677     int rc = SQLITE_OK;
   657    678   
   658    679     assert( (pFrom->flags & MEM_RowSet)==0 );
   659         -  VdbeMemRelease(pTo);
          680  +  VdbeMemReleaseExtern(pTo);
   660    681     memcpy(pTo, pFrom, MEMCELLSIZE);
   661    682     pTo->flags &= ~MEM_Dyn;
   662    683     pTo->xDel = 0;
   663    684   
   664    685     if( pTo->flags&(MEM_Str|MEM_Blob) ){
   665    686       if( 0==(pFrom->flags&MEM_Static) ){
   666    687         pTo->flags |= MEM_Ephem;