/ Check-in [63cf7eaf]
Login

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

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 63cf7eafae5c3c1379edf416c5157010c7c120b5
User & Date: drh 2016-09-30 22:24:29
Context
2016-10-01
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
21:20
Fix an always-true conditional left over from the previous commit. check-in: ab12fce3 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

   247    247   ** care if you decide to try to use this routine for some other purposes.
   248    248   */
   249    249   void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   250    250     va_list ap;
   251    251     char *zSql;
   252    252     char *zErrMsg = 0;
   253    253     sqlite3 *db = pParse->db;
   254         -# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
   255         -  char saveBuf[SAVE_SZ];
          254  +  char saveBuf[PARSE_TAIL_SZ];
   256    255   
   257    256     if( pParse->nErr ) return;
   258    257     assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
   259    258     va_start(ap, zFormat);
   260    259     zSql = sqlite3VMPrintf(db, zFormat, ap);
   261    260     va_end(ap);
   262    261     if( zSql==0 ){
   263    262       return;   /* A malloc must have failed */
   264    263     }
   265    264     pParse->nested++;
   266         -  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
   267         -  memset(&pParse->nVar, 0, SAVE_SZ);
          265  +  memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
          266  +  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
   268    267     sqlite3RunParser(pParse, zSql, &zErrMsg);
   269    268     sqlite3DbFree(db, zErrMsg);
   270    269     sqlite3DbFree(db, zSql);
   271         -  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
          270  +  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
   272    271     pParse->nested--;
   273    272   }
   274    273   
   275    274   #if SQLITE_USER_AUTHENTICATION
   276    275   /*
   277    276   ** Return TRUE if zTable is the name of the system table that stores the
   278    277   ** list of users and their access credentials.

Changes to src/prepare.c.

   520    520   ){
   521    521     Parse *pParse;            /* Parsing context */
   522    522     char *zErrMsg = 0;        /* Error message */
   523    523     int rc = SQLITE_OK;       /* Result code */
   524    524     int i;                    /* Loop counter */
   525    525   
   526    526     /* Allocate the parsing context */
   527         -  pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
          527  +  pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
   528    528     if( pParse==0 ){
   529    529       rc = SQLITE_NOMEM_BKPT;
   530    530       goto end_prepare;
   531    531     }
          532  +  memset(pParse, 0, PARSE_HDR_SZ);
          533  +  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
   532    534     pParse->pReprepare = pReprepare;
   533    535     assert( ppStmt && *ppStmt==0 );
   534    536     /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
   535    537     assert( sqlite3_mutex_held(db->mutex) );
   536    538   
   537    539     /* Check to verify that it is possible to get a read lock on all
   538    540     ** database schemas.  The inability to get a read lock indicates that

Changes to src/sqliteInt.h.

  2900   2900     int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  2901   2901     int ckBase;          /* Base register of data during check constraints */
  2902   2902     int iSelfTab;        /* Table of an index whose exprs are being coded */
  2903   2903     int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  2904   2904     int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  2905   2905     int nLabel;          /* Number of labels used */
  2906   2906     int *aLabel;         /* Space to hold the labels */
  2907         -  struct yColCache {
  2908         -    int iTable;           /* Table cursor number */
  2909         -    i16 iColumn;          /* Table column number */
  2910         -    u8 tempReg;           /* iReg is a temp register that needs to be freed */
  2911         -    int iLevel;           /* Nesting level */
  2912         -    int iReg;             /* Reg with value of this column. 0 means none. */
  2913         -    int lru;              /* Least recently used entry has the smallest value */
  2914         -  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
  2915   2907     ExprList *pConstExpr;/* Constant expressions */
  2916   2908     Token constraintName;/* Name of the constraint currently being parsed */
  2917   2909     yDbMask writeMask;   /* Start a write transaction on these databases */
  2918   2910     yDbMask cookieMask;  /* Bitmask of schema verified databases */
  2919   2911     int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  2920   2912     int regRoot;         /* Register holding root page number for new objects */
  2921   2913     int nMaxArg;         /* Max args passed to user function by sub-program */
................................................................................
  2936   2928     u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  2937   2929     u32 oldmask;         /* Mask of old.* columns referenced */
  2938   2930     u32 newmask;         /* Mask of new.* columns referenced */
  2939   2931     u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  2940   2932     u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
  2941   2933     u8 disableTriggers;  /* True to disable triggers */
  2942   2934   
         2935  +  /* The column cache comes at the end of the recursive section
         2936  +  ** When initializing a new Parse object, the header above, and
         2937  +  ** the non-recursive part that follows the column cache both need
         2938  +  ** to be zeroed.  But the column cache itself does not need zeroing
         2939  +  */
         2940  +  struct yColCache {
         2941  +    int iTable;           /* Table cursor number */
         2942  +    i16 iColumn;          /* Table column number */
         2943  +    u8 tempReg;           /* iReg is a temp register that needs to be freed */
         2944  +    int iLevel;           /* Nesting level */
         2945  +    int iReg;             /* Reg with value of this column. 0 means none. */
         2946  +    int lru;              /* Least recently used entry has the smallest value */
         2947  +  } aColCache[SQLITE_N_COLCACHE];  /* One for each column cache entry */
         2948  +
  2943   2949     /************************************************************************
  2944   2950     ** Above is constant between recursions.  Below is reset before and after
  2945   2951     ** each recursion.  The boundary between these two regions is determined
  2946   2952     ** using offsetof(Parse,nVar) so the nVar field must be the first field
  2947   2953     ** in the recursive region.
  2948   2954     ************************************************************************/
  2949   2955   
................................................................................
  2974   2980   #endif
  2975   2981     Table *pZombieTab;        /* List of Table objects to delete after code gen */
  2976   2982     TriggerPrg *pTriggerPrg;  /* Linked list of coded triggers */
  2977   2983     With *pWith;              /* Current WITH clause, or NULL */
  2978   2984     With *pWithToFree;        /* Free this WITH object at the end of the parse */
  2979   2985   };
  2980   2986   
         2987  +/*
         2988  +** Sizes and pointers of various parts of the Parse object.
         2989  +*/
         2990  +#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
         2991  +#define PARSE_RECURSE_SZ offsetof(Parse,nVar)  /* Recursive part */
         2992  +#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
         2993  +#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ)  /* Pointer to tail */
         2994  +
  2981   2995   /*
  2982   2996   ** Return true if currently inside an sqlite3_declare_vtab() call.
  2983   2997   */
  2984   2998   #ifdef SQLITE_OMIT_VIRTUALTABLE
  2985   2999     #define IN_DECLARE_VTAB 0
  2986   3000   #else
  2987   3001     #define IN_DECLARE_VTAB (pParse->declareVtab)