/ Check-in [06e7ff4c]
Login

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

Overview
Comment:A few more optimizations to the VDBE. (CVS 1204)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:06e7ff4cb8c73fd690c6d5b5f530a30d83f4f10c
User & Date: drh 2004-01-31 20:20:30
Context
2004-01-31
20:40
Fix a bug introduced by the previous check-in. (CVS 1205) check-in: 04cf2278 user: drh tags: trunk
20:20
A few more optimizations to the VDBE. (CVS 1204) check-in: 06e7ff4c user: drh tags: trunk
19:22
Rework internal data structures to make the VDBE about 15% smaller. (CVS 1203) check-in: 8273c74b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.253 2004/01/31 19:22:56 drh Exp $
           46  +** $Id: vdbe.c,v 1.254 2004/01/31 20:20:30 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
   142    142   ** has focus.
   143    143   **
   144    144   ** Return 0 on success and 1 if memory is exhausted.
   145    145   */
   146    146   static int AggInsert(Agg *p, char *zKey, int nKey){
   147    147     AggElem *pElem, *pOld;
   148    148     int i;
          149  +  Mem *pMem;
   149    150     pElem = sqliteMalloc( sizeof(AggElem) + nKey +
   150    151                           (p->nMem-1)*sizeof(pElem->aMem[0]) );
   151    152     if( pElem==0 ) return 1;
   152    153     pElem->zKey = (char*)&pElem->aMem[p->nMem];
   153    154     memcpy(pElem->zKey, zKey, nKey);
   154    155     pElem->nKey = nKey;
   155    156     pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
   156    157     if( pOld!=0 ){
   157    158       assert( pOld==pElem );  /* Malloc failed on insert */
   158    159       sqliteFree(pOld);
   159    160       return 0;
   160    161     }
   161         -  for(i=0; i<p->nMem; i++){
   162         -    pElem->aMem[i].flags = MEM_Null;
          162  +  for(i=0, pMem=pElem->aMem; i<p->nMem; i++, pMem++){
          163  +    pMem->flags = MEM_Null;
   163    164     }
   164    165     p->pCurrent = pElem;
   165    166     return 0;
   166    167   }
   167    168   
   168    169   /*
   169    170   ** Get the AggElem currently in focus
................................................................................
   764    765   ** See also the Dup instruction.
   765    766   */
   766    767   case OP_Pull: {
   767    768     Mem *pFrom = &pTos[-pOp->p1];
   768    769     int i;
   769    770     Mem ts;
   770    771   
   771         -  /* Deephemeralize(pFrom); *** not needed */
   772    772     ts = *pFrom;
   773    773     Deephemeralize(pTos);
   774    774     for(i=0; i<pOp->p1; i++, pFrom++){
   775    775       Deephemeralize(&pFrom[1]);
   776    776       *pFrom = pFrom[1];
   777    777       assert( (pFrom->flags & MEM_Ephem)==0 );
   778    778       if( pFrom->flags & MEM_Short ){
   779    779         assert( pFrom->flags & MEM_Str );
   780    780         assert( pFrom->z==pFrom[1].zShort );
   781         -      assert( (pTos->flags & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 );
   782    781         pFrom->z = pFrom->zShort;
   783    782       }
   784    783     }
   785    784     *pTos = ts;
   786         -  /* assert( (pTos->flags & MEM_Ephem)==0 ); *** not needed */
   787    785     if( pTos->flags & MEM_Short ){
   788    786       assert( pTos->flags & MEM_Str );
   789    787       assert( pTos->z==pTos[-pOp->p1].zShort );
   790         -    assert( (pTos->flags & (MEM_Dyn|MEM_Static|MEM_Ephem))==0 );
   791    788       pTos->z = pTos->zShort;
   792    789     }
   793    790     break;
   794    791   }
   795    792   
   796    793   /* Opcode: Push P1 * *
   797    794   **
................................................................................
  4249   4246   **
  4250   4247   ** After the data is stored in the memory location, the
  4251   4248   ** stack is popped once if P2 is 1.  If P2 is zero, then
  4252   4249   ** the original data remains on the stack.
  4253   4250   */
  4254   4251   case OP_MemStore: {
  4255   4252     int i = pOp->p1;
  4256         -  char *zOld;
  4257   4253     Mem *pMem;
  4258         -  int flags;
  4259   4254     assert( pTos>=p->aStack );
  4260   4255     if( i>=p->nMem ){
  4261   4256       int nOld = p->nMem;
  4262   4257       Mem *aMem;
  4263   4258       p->nMem = i + 5;
  4264   4259       aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
  4265   4260       if( aMem==0 ) goto no_mem;
................................................................................
  4272   4267         }
  4273   4268       }
  4274   4269       p->aMem = aMem;
  4275   4270       if( nOld<p->nMem ){
  4276   4271         memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
  4277   4272       }
  4278   4273     }
         4274  +  Deephemeralize(pTos);
  4279   4275     pMem = &p->aMem[i];
  4280         -  flags = pMem->flags;
  4281         -  if( flags & MEM_Dyn ){
  4282         -    zOld = pMem->z;
  4283         -  }else{
  4284         -    zOld = 0;
  4285         -  }
         4276  +  Release(pMem);
  4286   4277     *pMem = *pTos;
  4287         -  flags = pMem->flags;
  4288         -  if( flags & MEM_Dyn ){
         4278  +  if( pMem->flags & MEM_Dyn ){
  4289   4279       if( pOp->p2 ){
  4290   4280         pTos->flags = MEM_Null;
  4291   4281       }else{
  4292         -      /* OR: perhaps just make the stack ephermeral */
  4293   4282         pMem->z = sqliteMallocRaw( pMem->n );
  4294   4283         if( pMem->z==0 ) goto no_mem;
  4295   4284         memcpy(pMem->z, pTos->z, pMem->n);
  4296   4285       }
  4297         -  }else if( flags & MEM_Short ){
         4286  +  }else if( pMem->flags & MEM_Short ){
  4298   4287       pMem->z = pMem->zShort;
  4299   4288     }
  4300         -  if( zOld ) sqliteFree(zOld);
  4301   4289     if( pOp->p2 ){
  4302   4290       Release(pTos);
  4303   4291       pTos--;
  4304   4292     }
  4305   4293     break;
  4306   4294   }
  4307   4295   
................................................................................
  4462   4450   /* Opcode: AggSet * P2 *
  4463   4451   **
  4464   4452   ** Move the top of the stack into the P2-th field of the current
  4465   4453   ** aggregate.  String values are duplicated into new memory.
  4466   4454   */
  4467   4455   case OP_AggSet: {
  4468   4456     AggElem *pFocus = AggInFocus(p->agg);
         4457  +  Mem *pMem;
  4469   4458     int i = pOp->p2;
  4470   4459     assert( pTos>=p->aStack );
  4471   4460     if( pFocus==0 ) goto no_mem;
  4472         -  assert( i>=0 );
  4473         -  assert( i<p->agg.nMem );
  4474         -  if( i<p->agg.nMem ){
  4475         -    Mem *pMem = &pFocus->aMem[i];
  4476         -    char *zOld;
  4477         -    if( pMem->flags & MEM_Dyn ){
  4478         -      zOld = pMem->z;
  4479         -    }else{
  4480         -      zOld = 0;
  4481         -    }
  4482         -    Deephemeralize(pTos);
  4483         -    *pMem = *pTos;
  4484         -    if( pMem->flags & MEM_Dyn ){
  4485         -      pTos->flags = MEM_Null;
  4486         -    }else if( pMem->flags & MEM_Short ){
  4487         -      pMem->z = pMem->zShort;
  4488         -    }
  4489         -    if( zOld ) sqliteFree(zOld);
         4461  +  assert( i>=0 && i<p->agg.nMem );
         4462  +  Deephemeralize(pTos);
         4463  +  pMem = &pFocus->aMem[i];
         4464  +  Release(pMem);
         4465  +  *pMem = *pTos;
         4466  +  if( pMem->flags & MEM_Dyn ){
         4467  +    pTos->flags = MEM_Null;
         4468  +  }else if( pMem->flags & MEM_Short ){
         4469  +    pMem->z = pMem->zShort;
  4490   4470     }
  4491   4471     Release(pTos);
  4492   4472     pTos--;
  4493   4473     break;
  4494   4474   }
  4495   4475   
  4496   4476   /* Opcode: AggGet * P2 *
................................................................................
  4497   4477   **
  4498   4478   ** Push a new entry onto the stack which is a copy of the P2-th field
  4499   4479   ** of the current aggregate.  Strings are not duplicated so
  4500   4480   ** string values will be ephemeral.
  4501   4481   */
  4502   4482   case OP_AggGet: {
  4503   4483     AggElem *pFocus = AggInFocus(p->agg);
         4484  +  Mem *pMem;
  4504   4485     int i = pOp->p2;
  4505   4486     if( pFocus==0 ) goto no_mem;
  4506         -  assert( i>=0 );
         4487  +  assert( i>=0 && i<p->agg.nMem );
  4507   4488     pTos++;
  4508         -  assert( i<p->agg.nMem );
  4509         -  if( i<p->agg.nMem ){
  4510         -    Mem *pMem = &pFocus->aMem[i];
  4511         -    *pTos = *pMem;
  4512         -    pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
  4513         -    pTos->flags |= MEM_Ephem;
  4514         -  }
         4489  +  pMem = &pFocus->aMem[i];
         4490  +  *pTos = *pMem;
         4491  +  pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
         4492  +  pTos->flags |= MEM_Ephem;
  4515   4493     break;
  4516   4494   }
  4517   4495   
  4518   4496   /* Opcode: AggNext * P2 *
  4519   4497   **
  4520   4498   ** Make the next aggregate value the current aggregate.  The prior
  4521   4499   ** aggregate is deleted.  If all aggregate values have been consumed,