/ Check-in [1e21bbe8]
Login

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

Overview
Comment:Avoid unnecessary zeroing of fields in the Vdbe object when it is allocated.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1e21bbe836539e64d24857f4faa3d12cd607dc7e
User & Date: drh 2016-10-01 00:37:50
Context
2016-10-01
11:39
Avoid accessing Vdbe.pc if it is uninitialized. Check Vdbe.magic first. check-in: 6ac6e446 user: drh tags: trunk
00:37
Avoid unnecessary zeroing of fields in the Vdbe object when it is allocated. check-in: 1e21bbe8 user: drh tags: trunk
2016-09-30
22:24
Avoid initializing the column-cache section of the Parse object, since entries in the cache will be initialized as they are used, and avoiding the initial memset() saves many CPU cycles. check-in: 63cf7eaf user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbeInt.h.

   336    336   ** state of the virtual machine.
   337    337   **
   338    338   ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
   339    339   ** is really a pointer to an instance of this structure.
   340    340   */
   341    341   struct Vdbe {
   342    342     sqlite3 *db;            /* The database connection that owns this statement */
          343  +  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
          344  +  Parse *pParse;          /* Parsing context used to create this Vdbe */
          345  +  ynVar nVar;             /* Number of entries in aVar[] */
          346  +  ynVar nzVar;            /* Number of entries in azVar[] */
          347  +  u32 magic;              /* Magic number for sanity checking */
          348  +  int nMem;               /* Number of memory locations currently allocated */
          349  +  int nCursor;            /* Number of slots in apCsr[] */
          350  +  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
          351  +  int pc;                 /* The program counter */
          352  +  int rc;                 /* Value to return */
          353  +  int nChange;            /* Number of db changes made since last reset */
          354  +  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
          355  +  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
          356  +  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
          357  +  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
          358  +  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
          359  +
          360  +  /* When allocating a new Vdbe object, all of the fields below should be
          361  +  ** initialized to zero or NULL */
          362  +
   343    363     Op *aOp;                /* Space to hold the virtual machine's program */
   344    364     Mem *aMem;              /* The memory locations */
   345    365     Mem **apArg;            /* Arguments to currently executing user function */
   346    366     Mem *aColName;          /* Column names to return */
   347    367     Mem *pResultSet;        /* Pointer to an array of results */
   348         -  Parse *pParse;          /* Parsing context used to create this Vdbe */
   349         -  int nMem;               /* Number of memory locations currently allocated */
   350         -  int nOp;                /* Number of instructions in the program */
   351         -  int nCursor;            /* Number of slots in apCsr[] */
   352         -  u32 magic;              /* Magic number for sanity checking */
   353    368     char *zErrMsg;          /* Error message written here */
   354         -  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
   355    369     VdbeCursor **apCsr;     /* One element of this array for each open cursor */
   356    370     Mem *aVar;              /* Values for the OP_Variable opcode. */
   357    371     char **azVar;           /* Name of variables */
   358         -  ynVar nVar;             /* Number of entries in aVar[] */
   359         -  ynVar nzVar;            /* Number of entries in azVar[] */
   360         -  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
   361         -  int pc;                 /* The program counter */
   362         -  int rc;                 /* Value to return */
          372  +#ifndef SQLITE_OMIT_TRACE
          373  +  i64 startTime;          /* Time when query started - used for profiling */
          374  +#endif
          375  +  int nOp;                /* Number of instructions in the program */
   363    376   #ifdef SQLITE_DEBUG
   364    377     int rcApp;              /* errcode set by sqlite3_result_error_code() */
   365    378   #endif
   366    379     u16 nResColumn;         /* Number of columns in one row of the result set */
   367    380     u8 errorAction;         /* Recovery action to do in case of an error */
          381  +  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   368    382     bft expired:1;          /* True if the VM needs to be recompiled */
   369    383     bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
   370         -  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   371    384     bft explain:2;          /* True if EXPLAIN present on SQL command */
   372    385     bft changeCntOn:1;      /* True to update the change-counter */
   373    386     bft runOnlyOnce:1;      /* Automatically expire on reset */
   374    387     bft usesStmtJournal:1;  /* True if uses a statement journal */
   375    388     bft readOnly:1;         /* True for statements that do not write */
   376    389     bft bIsReader:1;        /* True for statements that read */
   377    390     bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
   378         -  int nChange;            /* Number of db changes made since last reset */
   379    391     yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
   380    392     yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
   381         -  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
   382    393     u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
   383         -#ifndef SQLITE_OMIT_TRACE
   384         -  i64 startTime;          /* Time when query started - used for profiling */
   385         -#endif
   386         -  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
   387         -  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   388         -  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   389         -  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
   390    394     char *zSql;             /* Text of the SQL statement that generated this */
   391    395     void *pFree;            /* Free this when deleting the vdbe */
   392    396     VdbeFrame *pFrame;      /* Parent frame */
   393    397     VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   394    398     int nFrame;             /* Number of frames in pFrame list */
   395    399     u32 expmask;            /* Binding to these vars invalidates VM */
   396    400     SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
................................................................................
   401    405     ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
   402    406   #endif
   403    407   };
   404    408   
   405    409   /*
   406    410   ** The following are allowed values for Vdbe.magic
   407    411   */
   408         -#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
   409         -#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
   410         -#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
   411         -#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
          412  +#define VDBE_MAGIC_INIT     0x16bceaa5    /* Building a VDBE program */
          413  +#define VDBE_MAGIC_RUN      0x2df20da3    /* VDBE is ready to execute */
          414  +#define VDBE_MAGIC_HALT     0x319c2973    /* VDBE has completed execution */
          415  +#define VDBE_MAGIC_RESET    0x48fa9f76    /* Reset and ready to run again */
          416  +#define VDBE_MAGIC_DEAD     0x5606c3c8    /* The VDBE has been deallocated */
   412    417   
   413    418   /*
   414    419   ** Structure used to store the context required by the 
   415    420   ** sqlite3_preupdate_*() API functions.
   416    421   */
   417    422   struct PreUpdate {
   418    423     Vdbe *v;

Changes to src/vdbeaux.c.

    17     17   
    18     18   /*
    19     19   ** Create a new virtual database engine.
    20     20   */
    21     21   Vdbe *sqlite3VdbeCreate(Parse *pParse){
    22     22     sqlite3 *db = pParse->db;
    23     23     Vdbe *p;
    24         -  p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
           24  +  p = sqlite3DbMallocRaw(db, sizeof(Vdbe) );
    25     25     if( p==0 ) return 0;
           26  +  memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
    26     27     p->db = db;
    27     28     if( db->pVdbe ){
    28     29       db->pVdbe->pPrev = p;
    29     30     }
    30     31     p->pNext = db->pVdbe;
    31     32     p->pPrev = 0;
    32     33     db->pVdbe = p;
................................................................................
  1822   1823   ** running it.
  1823   1824   */
  1824   1825   void sqlite3VdbeRewind(Vdbe *p){
  1825   1826   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  1826   1827     int i;
  1827   1828   #endif
  1828   1829     assert( p!=0 );
  1829         -  assert( p->magic==VDBE_MAGIC_INIT );
         1830  +  assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
  1830   1831   
  1831   1832     /* There should be at least one opcode.
  1832   1833     */
  1833   1834     assert( p->nOp>0 );
  1834   1835   
  1835   1836     /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
  1836   1837     p->magic = VDBE_MAGIC_RUN;
................................................................................
  1949   1950     }while( !db->mallocFailed );
  1950   1951   
  1951   1952     p->nzVar = pParse->nzVar;
  1952   1953     p->azVar = pParse->azVar;
  1953   1954     pParse->nzVar =  0;
  1954   1955     pParse->azVar = 0;
  1955   1956     p->explain = pParse->explain;
  1956         -  if( db->mallocFailed==0 ){
         1957  +  if( db->mallocFailed ){
         1958  +    p->nVar = 0;
         1959  +    p->nCursor = 0;
         1960  +    p->nMem = 0;
         1961  +  }else{
  1957   1962       p->nCursor = nCursor;
  1958   1963       p->nVar = (ynVar)nVar;
  1959   1964       initMemArray(p->aVar, nVar, db, MEM_Null);
  1960   1965       p->nMem = nMem;
  1961   1966       initMemArray(p->aMem, nMem, db, MEM_Undefined);
  1962   1967       memset(p->apArg, 0, nArg*sizeof(Mem*));
  1963   1968       memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
................................................................................
  2876   2881           sqlite3VdbePrintOp(out, i, &p->aOp[i]);
  2877   2882         }
  2878   2883         fclose(out);
  2879   2884       }
  2880   2885     }
  2881   2886   #endif
  2882   2887     p->iCurrentTime = 0;
  2883         -  p->magic = VDBE_MAGIC_INIT;
         2888  +  p->magic = VDBE_MAGIC_RESET;
  2884   2889     return p->rc & db->errMask;
  2885   2890   }
  2886   2891    
  2887   2892   /*
  2888   2893   ** Clean up and delete a VDBE after execution.  Return an integer which is
  2889   2894   ** the result code.  Write any error message text into *pzErrMsg.
  2890   2895   */
................................................................................
  2947   2952     releaseMemArray(p->aVar, p->nVar);
  2948   2953     releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  2949   2954     for(pSub=p->pProgram; pSub; pSub=pNext){
  2950   2955       pNext = pSub->pNext;
  2951   2956       vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
  2952   2957       sqlite3DbFree(db, pSub);
  2953   2958     }
  2954         -  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
         2959  +  if( p->magic!=VDBE_MAGIC_INIT ){
         2960  +    for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
         2961  +  }
  2955   2962     sqlite3DbFree(db, p->azVar);
  2956   2963     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2957   2964     sqlite3DbFree(db, p->aColName);
  2958   2965     sqlite3DbFree(db, p->zSql);
  2959   2966     sqlite3DbFree(db, p->pFree);
  2960   2967   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  2961   2968     for(i=0; i<p->nScan; i++){