/ Changes On Branch 2-size-lookaside
Login

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

Changes In Branch 2-size-lookaside Excluding Merge-Ins

This is equivalent to a diff from 907f7965 to 9496b4d3

2019-10-18
22:54
Use an allocation count and freelist instead of a membership bitfield in the mini lookaside allocator (Leaf check-in: 9496b4d3 user: numist tags: 2-size-lookaside)
2019-10-09
18:36
Do not allow users to effectively disable fts5 crisismerge operations by setting the crisismerge threshold to higher than the maximum allowable segment b-trees on a single level. Fix for [d392017c]. (check-in: 86e49720 user: dan tags: trunk)
17:38
Merge recent fixes and enhancements from trunk. (check-in: 553258c2 user: drh tags: 2-size-lookaside)
15:37
An improved fix for the dbsqlfuzz-discovered ALWAYS() failure following OOM in sqlite3ExprCollSeq(). This time with a test case (engineered by Dan). (check-in: 907f7965 user: drh tags: trunk)
15:26
Disallow fts5 page sizes greater than 65536 bytes - as there are 16-bit offsets used in the page header. Fix for [81a7f7b9]. (check-in: 75775c5a user: dan tags: trunk)
15:00
Change sqlite3SelectDup() to always return NULL if an OOM has occurred. (check-in: 01ba4641 user: drh tags: trunk)

Changes to Makefile.in.

   230    230     $(TOP)/src/global.c \
   231    231     $(TOP)/src/hash.c \
   232    232     $(TOP)/src/hash.h \
   233    233     $(TOP)/src/hwtime.h \
   234    234     $(TOP)/src/insert.c \
   235    235     $(TOP)/src/legacy.c \
   236    236     $(TOP)/src/loadext.c \
          237  +  $(TOP)/src/lookaside.c \
          238  +  $(TOP)/src/lookaside.h \
   237    239     $(TOP)/src/main.c \
   238    240     $(TOP)/src/malloc.c \
   239    241     $(TOP)/src/mem0.c \
   240    242     $(TOP)/src/mem1.c \
   241    243     $(TOP)/src/mem2.c \
   242    244     $(TOP)/src/mem3.c \
   243    245     $(TOP)/src/mem5.c \
................................................................................
   521    523   #
   522    524   HDR = \
   523    525      $(TOP)/src/btree.h \
   524    526      $(TOP)/src/btreeInt.h \
   525    527      $(TOP)/src/hash.h \
   526    528      $(TOP)/src/hwtime.h \
   527    529      keywordhash.h \
          530  +   $(TOP)/src/lookaside.h \
   528    531      $(TOP)/src/msvc.h \
   529    532      $(TOP)/src/mutex.h \
   530    533      opcodes.h \
   531    534      $(TOP)/src/os.h \
   532    535      $(TOP)/src/os_common.h \
   533    536      $(TOP)/src/os_setup.h \
   534    537      $(TOP)/src/os_win.h \
................................................................................
   865    868   
   866    869   legacy.lo:	$(TOP)/src/legacy.c $(HDR)
   867    870   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/legacy.c
   868    871   
   869    872   loadext.lo:	$(TOP)/src/loadext.c $(HDR)
   870    873   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/loadext.c
   871    874   
          875  +lookaside.lo:  $(TOP)/src/lookaside.c $(HDR)
          876  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/lookaside.c
          877  +
   872    878   main.lo:	$(TOP)/src/main.c $(HDR)
   873    879   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/main.c
   874    880   
   875    881   malloc.lo:	$(TOP)/src/malloc.c $(HDR)
   876    882   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/malloc.c
   877    883   
   878    884   mem0.lo:	$(TOP)/src/mem0.c $(HDR)

Changes to Makefile.msc.

  1286   1286     $(TOP)\src\fkey.c \
  1287   1287     $(TOP)\src\func.c \
  1288   1288     $(TOP)\src\global.c \
  1289   1289     $(TOP)\src\hash.c \
  1290   1290     $(TOP)\src\insert.c \
  1291   1291     $(TOP)\src\legacy.c \
  1292   1292     $(TOP)\src\loadext.c \
         1293  +  $(TOP)\src\lookaside.c \
  1293   1294     $(TOP)\src\main.c \
  1294   1295     $(TOP)\src\malloc.c \
  1295   1296     $(TOP)\src\mem0.c \
  1296   1297     $(TOP)\src\mem1.c \
  1297   1298     $(TOP)\src\mem2.c \
  1298   1299     $(TOP)\src\mem3.c \
  1299   1300     $(TOP)\src\mem5.c \
................................................................................
  1356   1357   # Core header files, part 1.
  1357   1358   #
  1358   1359   SRC04 = \
  1359   1360     $(TOP)\src\btree.h \
  1360   1361     $(TOP)\src\btreeInt.h \
  1361   1362     $(TOP)\src\hash.h \
  1362   1363     $(TOP)\src\hwtime.h \
         1364  +  $(TOP)\src\lookaside.h \
  1363   1365     $(TOP)\src\msvc.h \
  1364   1366     $(TOP)\src\mutex.h \
  1365   1367     $(TOP)\src\os.h \
  1366   1368     $(TOP)\src\os_common.h \
  1367   1369     $(TOP)\src\os_setup.h \
  1368   1370     $(TOP)\src\os_win.h
  1369   1371   
................................................................................
  1576   1578   # Header files used by all library source files.
  1577   1579   #
  1578   1580   HDR = \
  1579   1581      $(TOP)\src\btree.h \
  1580   1582      $(TOP)\src\btreeInt.h \
  1581   1583      $(TOP)\src\hash.h \
  1582   1584      $(TOP)\src\hwtime.h \
         1585  +   $(TOP)\src\lookaside.h \
  1583   1586      keywordhash.h \
  1584   1587      $(TOP)\src\msvc.h \
  1585   1588      $(TOP)\src\mutex.h \
  1586   1589      opcodes.h \
  1587   1590      $(TOP)\src\os.h \
  1588   1591      $(TOP)\src\os_common.h \
  1589   1592      $(TOP)\src\os_setup.h \
................................................................................
  1957   1960   
  1958   1961   legacy.lo:	$(TOP)\src\legacy.c $(HDR)
  1959   1962   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\legacy.c
  1960   1963   
  1961   1964   loadext.lo:	$(TOP)\src\loadext.c $(HDR)
  1962   1965   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\loadext.c
  1963   1966   
         1967  +lookaside.lo:	$(TOP)\src\lookaside.c $(HDR)
         1968  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\lookaside.c
         1969  +
  1964   1970   main.lo:	$(TOP)\src\main.c $(HDR)
  1965   1971   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\main.c
  1966   1972   
  1967   1973   malloc.lo:	$(TOP)\src\malloc.c $(HDR)
  1968   1974   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\malloc.c
  1969   1975   
  1970   1976   mem0.lo:	$(TOP)\src\mem0.c $(HDR)

Changes to main.mk.

   107    107     $(TOP)/src/global.c \
   108    108     $(TOP)/src/hash.c \
   109    109     $(TOP)/src/hash.h \
   110    110     $(TOP)/src/hwtime.h \
   111    111     $(TOP)/src/insert.c \
   112    112     $(TOP)/src/legacy.c \
   113    113     $(TOP)/src/loadext.c \
          114  +  $(TOP)/src/lookaside.c \
          115  +  $(TOP)/src/lookaside.h \
   114    116     $(TOP)/src/main.c \
   115    117     $(TOP)/src/malloc.c \
   116    118     $(TOP)/src/mem0.c \
   117    119     $(TOP)/src/mem1.c \
   118    120     $(TOP)/src/mem2.c \
   119    121     $(TOP)/src/mem3.c \
   120    122     $(TOP)/src/mem5.c \
................................................................................
   439    441   #
   440    442   HDR = \
   441    443      $(TOP)/src/btree.h \
   442    444      $(TOP)/src/btreeInt.h \
   443    445      $(TOP)/src/hash.h \
   444    446      $(TOP)/src/hwtime.h \
   445    447      keywordhash.h \
          448  +   $(TOP)/src/lookaside.h \
   446    449      $(TOP)/src/msvc.h \
   447    450      $(TOP)/src/mutex.h \
   448    451      opcodes.h \
   449    452      $(TOP)/src/os.h \
   450    453      $(TOP)/src/os_common.h \
   451    454      $(TOP)/src/os_setup.h \
   452    455      $(TOP)/src/os_win.h \

Changes to src/analyze.c.

   137    137   ** of a blob encoding of the complete index key as is found in
   138    138   ** sqlite_stat4.sample.  The nEq, nLt, and nDLt entries of sqlite_stat3
   139    139   ** all contain just a single integer which is the same as the first
   140    140   ** integer in the equivalent columns in sqlite_stat4.
   141    141   */
   142    142   #ifndef SQLITE_OMIT_ANALYZE
   143    143   #include "sqliteInt.h"
          144  +#include "lookaside.h"
   144    145   
   145    146   #if defined(SQLITE_ENABLE_STAT4)
   146    147   # define IsStat4     1
   147    148   #else
   148    149   # define IsStat4     0
   149    150   # undef SQLITE_STAT4_SAMPLES
   150    151   # define SQLITE_STAT4_SAMPLES 1
................................................................................
  1658   1659   ){
  1659   1660     int rc;                       /* Result codes from subroutines */
  1660   1661     sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
  1661   1662     char *zSql;                   /* Text of the SQL statement */
  1662   1663     Index *pPrevIdx = 0;          /* Previous index in the loop */
  1663   1664     IndexSample *pSample;         /* A slot in pIdx->aSample[] */
  1664   1665   
  1665         -  assert( db->lookaside.bDisable );
         1666  +  assert( sqlite3LookasideDisabled(&db->lookaside) );
  1666   1667     zSql = sqlite3MPrintf(db, zSql1, zDb);
  1667   1668     if( !zSql ){
  1668   1669       return SQLITE_NOMEM_BKPT;
  1669   1670     }
  1670   1671     rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
  1671   1672     sqlite3DbFree(db, zSql);
  1672   1673     if( rc ) return rc;
................................................................................
  1769   1770   /*
  1770   1771   ** Load content from the sqlite_stat4 table into 
  1771   1772   ** the Index.aSample[] arrays of all indices.
  1772   1773   */
  1773   1774   static int loadStat4(sqlite3 *db, const char *zDb){
  1774   1775     int rc = SQLITE_OK;             /* Result codes from subroutines */
  1775   1776   
  1776         -  assert( db->lookaside.bDisable );
         1777  +  assert( sqlite3LookasideDisabled(&db->lookaside) );
  1777   1778     if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
  1778   1779       rc = loadStatTbl(db,
  1779   1780         "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
  1780   1781         "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
  1781   1782         zDb
  1782   1783       );
  1783   1784     }
................................................................................
  1850   1851       Index *pIdx = sqliteHashData(i);
  1851   1852       if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
  1852   1853     }
  1853   1854   
  1854   1855     /* Load the statistics from the sqlite_stat4 table. */
  1855   1856   #ifdef SQLITE_ENABLE_STAT4
  1856   1857     if( rc==SQLITE_OK ){
  1857         -    DisableLookaside;
         1858  +    sqlite3LookasideDisable(&db->lookaside);
  1858   1859       rc = loadStat4(db, sInfo.zDatabase);
  1859         -    EnableLookaside;
         1860  +    sqlite3LookasideEnable(&db->lookaside);
  1860   1861     }
  1861   1862     for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
  1862   1863       Index *pIdx = sqliteHashData(i);
  1863   1864       sqlite3_free(pIdx->aiRowEst);
  1864   1865       pIdx->aiRowEst = 0;
  1865   1866     }
  1866   1867   #endif

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   */
    25     25   #include "sqliteInt.h"
           26  +#include "lookaside.h"
    26     27   
    27     28   #ifndef SQLITE_OMIT_SHARED_CACHE
    28     29   /*
    29     30   ** The TableLock structure is only used by the sqlite3TableLock() and
    30     31   ** codeTableLocks() functions.
    31     32   */
    32     33   struct TableLock {
................................................................................
   622    623     ** lookaside, this number should not change. 
   623    624     **
   624    625     ** If malloc has already failed, it may be that it failed while allocating
   625    626     ** a Table object that was going to be marked ephemeral. So do not check
   626    627     ** that no lookaside memory is used in this case either. */
   627    628     int nLookaside = 0;
   628    629     if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){
   629         -    nLookaside = sqlite3LookasideUsed(db, 0);
          630  +    nLookaside = sqlite3LookasideUsed(&db->lookaside, 0);
   630    631     }
   631    632   #endif
   632    633   
   633    634     /* Delete all indices associated with this table. */
   634    635     for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
   635    636       pNext = pIndex->pNext;
   636    637       assert( pIndex->pSchema==pTable->pSchema
................................................................................
   658    659     sqlite3ExprListDelete(db, pTable->pCheck);
   659    660   #ifndef SQLITE_OMIT_VIRTUALTABLE
   660    661     sqlite3VtabClear(db, pTable);
   661    662   #endif
   662    663     sqlite3DbFree(db, pTable);
   663    664   
   664    665     /* Verify that no lookaside memory was used by schema tables */
   665         -  assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
          666  +  assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(&db->lookaside,0) );
   666    667   }
   667    668   void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
   668    669     /* Do not delete the table until the reference count reaches zero. */
   669    670     if( !pTable ) return;
   670    671     if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
   671    672     deleteTable(db, pTable);
   672    673   }

Changes to src/fkey.c.

     8      8   **    May you share freely, never taking more than you give.
     9      9   **
    10     10   *************************************************************************
    11     11   ** This file contains code used by the compiler to add foreign key
    12     12   ** support to compiled SQL statements.
    13     13   */
    14     14   #include "sqliteInt.h"
           15  +#include "lookaside.h"
    15     16   
    16     17   #ifndef SQLITE_OMIT_FOREIGN_KEY
    17     18   #ifndef SQLITE_OMIT_TRIGGER
    18     19   
    19     20   /*
    20     21   ** Deferred and Immediate FKs
    21     22   ** --------------------------
................................................................................
  1295   1296             pWhere,
  1296   1297             0, 0, 0, 0, 0
  1297   1298         );
  1298   1299         pWhere = 0;
  1299   1300       }
  1300   1301   
  1301   1302       /* Disable lookaside memory allocation */
  1302         -    DisableLookaside;
         1303  +    sqlite3LookasideDisable(&db->lookaside);
  1303   1304   
  1304   1305       pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
  1305   1306           sizeof(Trigger) +         /* struct Trigger */
  1306   1307           sizeof(TriggerStep) +     /* Single step in trigger program */
  1307   1308           nFrom + 1                 /* Space for pStep->zTarget */
  1308   1309       );
  1309   1310       if( pTrigger ){
................................................................................
  1317   1318         if( pWhen ){
  1318   1319           pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
  1319   1320           pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
  1320   1321         }
  1321   1322       }
  1322   1323   
  1323   1324       /* Re-enable the lookaside buffer, if it was disabled earlier. */
  1324         -    EnableLookaside;
         1325  +    sqlite3LookasideEnable(&db->lookaside);
  1325   1326   
  1326   1327       sqlite3ExprDelete(db, pWhere);
  1327   1328       sqlite3ExprDelete(db, pWhen);
  1328   1329       sqlite3ExprListDelete(db, pList);
  1329   1330       sqlite3SelectDelete(db, pSelect);
  1330   1331       if( db->mallocFailed==1 ){
  1331   1332         fkTriggerDelete(db, pTrigger);

Added src/lookaside.c.

            1  +/*
            2  +** 2019-10-02
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** Lookaside memory allocation functions used throughout sqlite.
           14  +*/
           15  +
           16  +#include "sqliteInt.h"
           17  +#include "lookaside.h"
           18  +
           19  +/*
           20  +** Return the number of LookasideSlot elements on the linked list
           21  +*/
           22  +static u32 countLookasideSlots(LookasideSlot *p){
           23  +  u32 cnt = 0;
           24  +  while( p ){
           25  +    p = p->pNext;
           26  +    cnt++;
           27  +  }
           28  +  return cnt;
           29  +}
           30  +
           31  +/*
           32  +** Count the number of slots of lookaside memory that are outstanding
           33  +*/
           34  +int sqlite3LookasideUsed(Lookaside *pLookaside, int *pHighwater){
           35  +  u32 nInit = countLookasideSlots(pLookaside->pInit);
           36  +  u32 nFree = countLookasideSlots(pLookaside->pFree);
           37  +  if( pHighwater ) *pHighwater = pLookaside->nSlot - nInit;
           38  +  return pLookaside->nSlot - (nInit+nFree);
           39  +}
           40  +
           41  +void sqlite3LookasideResetUsed(Lookaside *pLookaside){
           42  +  LookasideSlot *p = pLookaside->pFree;
           43  +  if( p ){
           44  +    while( p->pNext ) p = p->pNext;
           45  +    p->pNext = pLookaside->pInit;
           46  +    pLookaside->pInit = pLookaside->pFree;
           47  +    pLookaside->pFree = 0;
           48  +  }
           49  +}
           50  +
           51  +#ifndef SQLITE_OMIT_LOOKASIDE
           52  +
           53  +static void *lookasideSlotAlloc(Lookaside *pLookaside){
           54  +  LookasideSlot *pBuf;
           55  +  if( (pBuf = pLookaside->pFree)!=0 ){
           56  +    pLookaside->pFree = pBuf->pNext;
           57  +    pLookaside->anStat[0]++;
           58  +    return (void*)pBuf;
           59  +  }else if( (pBuf = pLookaside->pInit)!=0 ){
           60  +    pLookaside->pInit = pBuf->pNext;
           61  +    pLookaside->anStat[0]++;
           62  +    return (void*)pBuf;
           63  +  }else{
           64  +    pLookaside->anStat[2]++;
           65  +    return 0;
           66  +  }
           67  +}
           68  +
           69  +static void lookasideSlotFree(Lookaside *pLookaside, void *p){
           70  +  LookasideSlot *pBuf = (LookasideSlot*)p;
           71  +# ifdef SQLITE_DEBUG
           72  +  /* Scribble over the content in the buffer being freed */
           73  +  memset(p, 0xaa, pLookaside->szTrue);
           74  +# endif
           75  +  pBuf->pNext = pLookaside->pFree;
           76  +  pLookaside->pFree = pBuf;
           77  +}
           78  +
           79  +# ifndef SQLITE_OMIT_MINI_LOOKASIDE
           80  +#  ifndef SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE
           81  +#   define SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE 128
           82  +#  endif
           83  +
           84  +static void *miniLookasideAlloc(Lookaside *pLookaside){
           85  +  LookasideSlot *pMiniSlot;
           86  +  LookasideSlot *pSlot;
           87  +  int iMiniSlot;
           88  +  
           89  +  if( !pLookaside->pMini ){
           90  +    pSlot = lookasideSlotAlloc(pLookaside);
           91  +    if( !pSlot ){
           92  +      return 0;
           93  +    }
           94  +    bzero(pSlot, sizeof(LookasideSlot));
           95  +    pLookaside->pMini = pSlot;
           96  +  }else{
           97  +    pSlot = pLookaside->pMini;
           98  +    assert( pSlot->nAlloc );
           99  +  }
          100  +  
          101  +  assert( pSlot->nAlloc < pLookaside->nMini );
          102  +
          103  +  if( (pMiniSlot = pSlot->pFree) ){
          104  +    pSlot->pFree = pMiniSlot->pNext;
          105  +  }else{
          106  +    iMiniSlot = pSlot->nAlloc;
          107  +    assert(iMiniSlot < pLookaside->nMini);
          108  +    pMiniSlot = (LookasideSlot *)((char *)pSlot + sizeof(LookasideSlot) + (pLookaside->szMini * iMiniSlot));
          109  +  }
          110  +
          111  +  /* Remove slot from pMini if it is full of sub-allocations */
          112  +  if( ++(pSlot->nAlloc) == pLookaside->nMini ){
          113  +    /* Slot is full, dequeue from list */
          114  +    if( pSlot->pNext ){
          115  +      assert( pSlot->pNext->pPrev == pSlot );
          116  +      pSlot->pNext->pPrev = pSlot->pPrev;
          117  +    }
          118  +    if( pSlot->pPrev ){
          119  +      assert( pSlot->pPrev->pNext == pSlot );
          120  +      pSlot->pPrev->pNext = pSlot->pNext;
          121  +    }else{
          122  +      assert( pLookaside->pMini == pSlot );
          123  +      pLookaside->pMini = pSlot->pNext;
          124  +    }
          125  +    pSlot->pNext = pSlot->pPrev = 0;
          126  +  }
          127  +  return pMiniSlot;
          128  +}
          129  +
          130  +static void miniLookasideFree(Lookaside *pLookaside, void *p){
          131  +  int iSlotNum = ((u8*)p - (u8*)pLookaside->pStart) / pLookaside->szTrue;
          132  +  LookasideSlot *pSlot = (LookasideSlot *)(iSlotNum * pLookaside->szTrue + (u8*)pLookaside->pStart);
          133  +  LookasideSlot *pMiniSlot = (LookasideSlot *)p;
          134  +  
          135  +  assert( pSlot->nAlloc );
          136  +  assert( pSlot->nAlloc <= pLookaside->nMini );
          137  +  assert( iMiniSlot<pLookaside->nMini );
          138  +  
          139  +  /* Return slot to pMini list if it was full */
          140  +  if( pSlot->nAlloc==pLookaside->nMini ){
          141  +    assert( pSlot->pNext == pSlot->pPrev && pSlot->pPrev == 0 );
          142  +    if( pLookaside->pMini ){
          143  +      assert( !pLookaside->pMini->pPrev );
          144  +      pSlot->pNext = pLookaside->pMini;
          145  +      pSlot->pNext->pPrev = pSlot;
          146  +    }
          147  +    pLookaside->pMini = pSlot;
          148  +  }
          149  +  
          150  +
          151  +#ifdef SQLITE_DEBUG
          152  +  memset(p, 0xaa, pLookaside->szMini);
          153  +#endif
          154  +  pSlot->nAlloc--;
          155  +  pMiniSlot->pNext = pSlot->pFree;
          156  +  pSlot->pFree = pMiniSlot;
          157  +
          158  +  /* Return slot to the lookaside pool if it is empty */
          159  +  if( pSlot->nAlloc == 0 ){
          160  +    if( pSlot->pNext ){
          161  +      assert( pSlot->pNext->pPrev == pSlot );
          162  +      pSlot->pNext->pPrev = pSlot->pPrev;
          163  +    }
          164  +    if( pSlot->pPrev ){
          165  +      assert( pSlot->pPrev->pNext == pSlot );
          166  +      pSlot->pPrev->pNext = pSlot->pNext;
          167  +    }else{
          168  +      assert( pLookaside->pMini==pSlot );
          169  +      pLookaside->pMini = pSlot->pNext;
          170  +    }
          171  +    lookasideSlotFree(pLookaside, pSlot);
          172  +  }
          173  +}
          174  +
          175  +# else
          176  +#  define miniLookasideAlloc(A) lookasideSlotAlloc(A)
          177  +#  define miniLookasideFree(A, B) lookasideSlotFree(A, B)
          178  +# endif /* !SQLITE_OMIT_MINI_LOOKASIDE */
          179  +
          180  +int sqlite3LookasideOpen(void *pBuf, int sz, int cnt, Lookaside *pLookaside){
          181  +  void *pStart;
          182  +
          183  +  if( sqlite3LookasideUsed(pLookaside,0)>0 ){
          184  +    return SQLITE_BUSY;
          185  +  }
          186  +  /* Free any existing lookaside buffer for this handle before
          187  +  ** allocating a new one so we don't have to have space for
          188  +  ** both at the same time.
          189  +  */
          190  +  if( pLookaside->bMalloced ){
          191  +    sqlite3_free(pLookaside->pStart);
          192  +  }
          193  +  /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
          194  +  ** than sizeof(LookasideSlot) to be useful.
          195  +  */
          196  +  sz = ROUNDDOWN8(sz);  /* IMP: R-33038-09382 */
          197  +  if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
          198  +  if( cnt<0 ) cnt = 0;
          199  +  if( sz==0 || cnt==0 ){
          200  +    sz = 0;
          201  +    pStart = 0;
          202  +  }else if( pBuf==0 ){
          203  +    sqlite3BeginBenignMalloc();
          204  +    pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt );  /* IMP: R-61949-35727 */
          205  +    sqlite3EndBenignMalloc();
          206  +    if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
          207  +  }else{
          208  +    pStart = pBuf;
          209  +  }
          210  +  pLookaside->pStart = pStart;
          211  +  pLookaside->pInit = 0;
          212  +  pLookaside->pFree = 0;
          213  +  pLookaside->sz = (u16)sz;
          214  +  pLookaside->szTrue = (u16)sz;
          215  +#ifndef SQLITE_OMIT_MINILOOKASIDE
          216  +  pLookaside->pMini = 0;
          217  +  pLookaside->nMini = (sz - sizeof(LookasideSlot)) / SQLITE_MINI_LOOKASIDE_MIN_SLOT_SIZE;
          218  +  if( pLookaside->nMini ){
          219  +    pLookaside->szMini = ((sz - sizeof(LookasideSlot)) / pLookaside->nMini) & ~(sizeof(void *) - 1);
          220  +  }else{
          221  +    pLookaside->szMini = 0;
          222  +  }
          223  +#endif /* SQLITE_OMIT_MINILOOKASIDE */
          224  +  if( pStart ){
          225  +    int i;
          226  +    LookasideSlot *p;
          227  +    assert( sz > (int)sizeof(LookasideSlot*) );
          228  +    pLookaside->nSlot = cnt;
          229  +    p = (LookasideSlot*)pStart;
          230  +    for(i=cnt-1; i>=0; i--){
          231  +      p->pNext = pLookaside->pInit;
          232  +      pLookaside->pInit = p;
          233  +      p = (LookasideSlot*)&((u8*)p)[sz];
          234  +    }
          235  +    pLookaside->pEnd = p;
          236  +    pLookaside->bDisable = 0;
          237  +    pLookaside->bMalloced = pBuf==0 ?1:0;
          238  +  }else{
          239  +    pLookaside->pStart = 0;
          240  +    pLookaside->pEnd = 0;
          241  +    pLookaside->bDisable = 1;
          242  +    pLookaside->bMalloced = 0;
          243  +    pLookaside->nSlot = 0;
          244  +  }
          245  +  return SQLITE_OK;
          246  +}
          247  +
          248  +void sqlite3LookasideClose(Lookaside *pLookaside){
          249  +  assert( sqlite3LookasideUsed(pLookaside,0)==0 );
          250  +  if( pLookaside->bMalloced ){
          251  +    sqlite3_free(pLookaside->pStart);
          252  +  }
          253  +}
          254  +
          255  +int sqlite3IsLookaside(Lookaside *pLookaside, void *p){
          256  +  return SQLITE_WITHIN(p, pLookaside->pStart, pLookaside->pEnd);
          257  +}
          258  +
          259  +/*
          260  +** Returns a pointer to a region at least n bytes in size, or NULL if the
          261  +** lookaside allocator has exhausted its available memory.
          262  +*/
          263  +void *sqlite3LookasideAlloc(Lookaside *pLookaside, u64 n){
          264  +  if( n>pLookaside->sz ){
          265  +    if( !pLookaside->bDisable ){
          266  +      pLookaside->anStat[1]++;
          267  +    }
          268  +    return 0;
          269  +  }
          270  +  if( n<=pLookaside->szMini && pLookaside->nMini > 1 ){
          271  +    return miniLookasideAlloc(pLookaside);
          272  +  }
          273  +  return lookasideSlotAlloc(pLookaside);
          274  +}
          275  +
          276  +/*
          277  +** Free memory previously obtained from sqlite3LookasideAlloc().
          278  +*/
          279  +void sqlite3LookasideFree(Lookaside *pLookaside, void *p){
          280  +  assert( sqlite3IsLookaside(pLookaside, p) );
          281  +  if( ((u8*)p - (u8*)pLookaside->pStart) % pLookaside->szTrue == 0 ){
          282  +    lookasideSlotFree(pLookaside, p);
          283  +  }else{
          284  +    miniLookasideFree(pLookaside, p);
          285  +  }
          286  +}
          287  +
          288  +/*
          289  +** Return the size of a memory allocation previously obtained from
          290  +** sqlite3LookasideAlloc().
          291  +*/
          292  +int sqlite3LookasideSize(Lookaside *pLookaside, void *p){
          293  +  assert(sqlite3IsLookaside(pLookaside, p));
          294  +
          295  +# ifndef SQLITE_OMIT_MINI_LOOKASIDE
          296  +  if( ((u8*)p - (u8*)pLookaside->pStart) % pLookaside->szTrue != 0 ){
          297  +    return pLookaside->szMini;
          298  +  }else
          299  +#endif /* SQLITE_OMIT_MINI_LOOKASIDE */
          300  +  {
          301  +    return pLookaside->szTrue;
          302  +  }
          303  +}
          304  +
          305  +#endif /* !SQLITE_OMIT_LOOKASIDE */

Added src/lookaside.h.

            1  +/*
            2  +** 2019-10-02
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +** Header file for the lookaside allocator
           13  +**
           14  +** This header defines the interface to the lookaside allocator.
           15  +** The lookaside allocator implements a two-size memory allocator using a
           16  +** buffer provided at initialization-time to exploit the fact that 75% of
           17  +** SQLite's allocations are <=128B.
           18  +*/
           19  +#ifndef SQLITE_LOOKASIDE_H
           20  +#define SQLITE_LOOKASIDE_H
           21  +
           22  +/*
           23  +** Count the number of slots of lookaside memory that are outstanding
           24  +*/
           25  +int sqlite3LookasideUsed(Lookaside *pLookaside, int *pHighwater);
           26  +
           27  +void sqlite3LookasideResetUsed(Lookaside *pLookaside);
           28  +
           29  +#define sqlite3LookasideDisable(pLookaside) do{(pLookaside)->bDisable++;\
           30  +  (pLookaside)->sz=0;}while(0)
           31  +#define sqlite3LookasideEnable(pLookaside) do{(pLookaside)->bDisable--;\
           32  +  (pLookaside)->sz=(pLookaside)->bDisable?0:(pLookaside)->szTrue;} while(0)
           33  +#define sqlite3LookasideEnableCnt(pLookaside, CNT) do{(pLookaside)->bDisable -= (CNT);\
           34  +  (pLookaside)->sz=(pLookaside)->bDisable?0:(pLookaside)->szTrue;} while(0)
           35  +#define sqlite3LookasideDisabled(pLookaside) ((pLookaside)->bDisable)
           36  +
           37  +# ifndef SQLITE_OMIT_LOOKASIDE
           38  +
           39  +/*
           40  +** Set up a lookaside allocator.
           41  +** Returns SQLITE_OK on success.
           42  +** If lookaside is already active, return SQLITE_BUSY.
           43  +**
           44  +** If pStart is NULL the space for the lookaside memory is obtained from
           45  +** sqlite3_malloc(). If pStart is not NULL then it is sz*cnt bytes of memory
           46  +** to use for the lookaside memory.
           47  +*/
           48  +int sqlite3LookasideOpen(
           49  +  void *pBuf,           /* NULL or sz*cnt bytes of memory */
           50  +  int sz,               /* Number of bytes in each lookaside slot */
           51  +  int cnt,              /* Number of slots */
           52  +  Lookaside *pLookaside /* Preallocated space for the Lookaside */
           53  +);
           54  +
           55  +/* Reset and close the lookaside object */
           56  +void sqlite3LookasideClose(Lookaside *pLookaside);
           57  +
           58  +/*
           59  +** Returns TRUE if p is a lookaside memory allocation from db
           60  +*/
           61  +int sqlite3IsLookaside(Lookaside *pLookaside, void *p);
           62  +
           63  +/*
           64  +** Returns a pointer to a region at least n bytes in size, or NULL if the
           65  +** lookaside allocator has exhausted its available memory.
           66  +*/
           67  +void *sqlite3LookasideAlloc(Lookaside *pLookaside, u64 n);
           68  +
           69  +/*
           70  +** Free memory previously obtained from sqlite3LookasideAlloc().
           71  +*/
           72  +void sqlite3LookasideFree(Lookaside *pLookaside, void *p);
           73  +
           74  +/*
           75  +** Return the size of a memory allocation previously obtained from
           76  +** sqlite3LookasideAlloc().
           77  +*/
           78  +int sqlite3LookasideSize(Lookaside *pLookaside, void *p);
           79  +
           80  +# else
           81  +#  define sqlite3LookasideOpen(A, B, C, D) SQLITE_OK
           82  +#  define sqlite3LookasideClose(A)
           83  +#  define sqlite3IsLookaside(A, B) 0
           84  +#  define sqlite3LookasideAlloc(A, B) 0
           85  +#  define sqlite3LookasideFree(A, B) assert(0);
           86  +#  define sqlite3LookasideSize(A, B) -1
           87  +# endif
           88  +
           89  +#endif /* SQLITE_LOOKASIDE_H */

Changes to src/main.c.

    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   */
    17     17   #include "sqliteInt.h"
           18  +#include "lookaside.h"
    18     19   
    19     20   #ifdef SQLITE_ENABLE_FTS3
    20     21   # include "fts3.h"
    21     22   #endif
    22     23   #ifdef SQLITE_ENABLE_RTREE
    23     24   # include "rtree.h"
    24     25   #endif
................................................................................
   665    666         break;
   666    667       }
   667    668     }
   668    669     va_end(ap);
   669    670     return rc;
   670    671   }
   671    672   
   672         -/*
   673         -** Set up the lookaside buffers for a database connection.
   674         -** Return SQLITE_OK on success.  
   675         -** If lookaside is already active, return SQLITE_BUSY.
   676         -**
   677         -** The sz parameter is the number of bytes in each lookaside slot.
   678         -** The cnt parameter is the number of slots.  If pStart is NULL the
   679         -** space for the lookaside memory is obtained from sqlite3_malloc().
   680         -** If pStart is not NULL then it is sz*cnt bytes of memory to use for
   681         -** the lookaside memory.
   682         -*/
   683         -static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
   684         -#ifndef SQLITE_OMIT_LOOKASIDE
   685         -  void *pStart;
   686         -  
   687         -  if( sqlite3LookasideUsed(db,0)>0 ){
   688         -    return SQLITE_BUSY;
   689         -  }
   690         -  /* Free any existing lookaside buffer for this handle before
   691         -  ** allocating a new one so we don't have to have space for 
   692         -  ** both at the same time.
   693         -  */
   694         -  if( db->lookaside.bMalloced ){
   695         -    sqlite3_free(db->lookaside.pStart);
   696         -  }
   697         -  /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
   698         -  ** than a pointer to be useful.
   699         -  */
   700         -  sz = ROUNDDOWN8(sz);  /* IMP: R-33038-09382 */
   701         -  if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
   702         -  if( cnt<0 ) cnt = 0;
   703         -  if( sz==0 || cnt==0 ){
   704         -    sz = 0;
   705         -    pStart = 0;
   706         -  }else if( pBuf==0 ){
   707         -    sqlite3BeginBenignMalloc();
   708         -    pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt );  /* IMP: R-61949-35727 */
   709         -    sqlite3EndBenignMalloc();
   710         -    if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
   711         -  }else{
   712         -    pStart = pBuf;
   713         -  }
   714         -  db->lookaside.pStart = pStart;
   715         -  db->lookaside.pInit = 0;
   716         -  db->lookaside.pFree = 0;
   717         -  db->lookaside.sz = (u16)sz;
   718         -  db->lookaside.szTrue = (u16)sz;
   719         -  if( pStart ){
   720         -    int i;
   721         -    LookasideSlot *p;
   722         -    assert( sz > (int)sizeof(LookasideSlot*) );
   723         -    db->lookaside.nSlot = cnt;
   724         -    p = (LookasideSlot*)pStart;
   725         -    for(i=cnt-1; i>=0; i--){
   726         -      p->pNext = db->lookaside.pInit;
   727         -      db->lookaside.pInit = p;
   728         -      p = (LookasideSlot*)&((u8*)p)[sz];
   729         -    }
   730         -    db->lookaside.pEnd = p;
   731         -    db->lookaside.bDisable = 0;
   732         -    db->lookaside.bMalloced = pBuf==0 ?1:0;
   733         -  }else{
   734         -    db->lookaside.pStart = db;
   735         -    db->lookaside.pEnd = db;
   736         -    db->lookaside.bDisable = 1;
   737         -    db->lookaside.sz = 0;
   738         -    db->lookaside.bMalloced = 0;
   739         -    db->lookaside.nSlot = 0;
   740         -  }
   741         -#endif /* SQLITE_OMIT_LOOKASIDE */
   742         -  return SQLITE_OK;
   743         -}
   744         -
   745    673   /*
   746    674   ** Return the mutex associated with a database connection.
   747    675   */
   748    676   sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
   749    677   #ifdef SQLITE_ENABLE_API_ARMOR
   750    678     if( !sqlite3SafetyCheckOk(db) ){
   751    679       (void)SQLITE_MISUSE_BKPT;
................................................................................
   824    752         rc = SQLITE_OK;
   825    753         break;
   826    754       }
   827    755       case SQLITE_DBCONFIG_LOOKASIDE: {
   828    756         void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
   829    757         int sz = va_arg(ap, int);       /* IMP: R-47871-25994 */
   830    758         int cnt = va_arg(ap, int);      /* IMP: R-04460-53386 */
   831         -      rc = setupLookaside(db, pBuf, sz, cnt);
          759  +      rc = sqlite3LookasideOpen(pBuf, sz, cnt, &db->lookaside);
   832    760         break;
   833    761       }
   834    762       default: {
   835    763         static const struct {
   836    764           int op;      /* The opcode */
   837    765           u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
   838    766         } aFlagOp[] = {
................................................................................
  1260   1188     ** the same sqliteMalloc() as the one that allocates the database 
  1261   1189     ** structure?
  1262   1190     */
  1263   1191     sqlite3DbFree(db, db->aDb[1].pSchema);
  1264   1192     sqlite3_mutex_leave(db->mutex);
  1265   1193     db->magic = SQLITE_MAGIC_CLOSED;
  1266   1194     sqlite3_mutex_free(db->mutex);
  1267         -  assert( sqlite3LookasideUsed(db,0)==0 );
  1268         -  if( db->lookaside.bMalloced ){
  1269         -    sqlite3_free(db->lookaside.pStart);
  1270         -  }
         1195  +  sqlite3LookasideClose(&db->lookaside);
  1271   1196     sqlite3_free(db);
  1272   1197   }
  1273   1198   
  1274   1199   /*
  1275   1200   ** Rollback all database files.  If tripCode is not SQLITE_OK, then
  1276   1201   ** any write cursors are invalidated ("tripped" - as in "tripping a circuit
  1277   1202   ** breaker") and made to return tripCode if there are any further
................................................................................
  3061   2986       }
  3062   2987     }
  3063   2988     sqlite3_mutex_enter(db->mutex);
  3064   2989     db->errMask = 0xff;
  3065   2990     db->nDb = 2;
  3066   2991     db->magic = SQLITE_MAGIC_BUSY;
  3067   2992     db->aDb = db->aDbStatic;
  3068         -  db->lookaside.bDisable = 1;
  3069         -  db->lookaside.sz = 0;
         2993  +  sqlite3LookasideDisable(&db->lookaside);
  3070   2994   
  3071   2995     assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  3072   2996     memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  3073   2997     db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
  3074   2998     db->autoCommit = 1;
  3075   2999     db->nextAutovac = -1;
  3076   3000     db->szMmap = sqlite3GlobalConfig.szMmap;
................................................................................
  3319   3243     sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt),
  3320   3244                             SQLITE_DEFAULT_LOCKING_MODE);
  3321   3245   #endif
  3322   3246   
  3323   3247     if( rc ) sqlite3Error(db, rc);
  3324   3248   
  3325   3249     /* Enable the lookaside-malloc subsystem */
  3326         -  setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
  3327         -                        sqlite3GlobalConfig.nLookaside);
         3250  +  sqlite3LookasideOpen(0, sqlite3GlobalConfig.szLookaside,
         3251  +                        sqlite3GlobalConfig.nLookaside, &db->lookaside);
  3328   3252   
  3329   3253     sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);
  3330   3254   
  3331   3255   opendb_out:
  3332   3256     if( db ){
  3333   3257       assert( db->mutex!=0 || isThreadsafe==0
  3334   3258              || sqlite3GlobalConfig.bFullMutex==0 );

Changes to src/malloc.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** Memory allocation functions used throughout sqlite.
    14     14   */
    15     15   #include "sqliteInt.h"
           16  +#include "lookaside.h"
    16     17   #include <stdarg.h>
    17     18   
    18     19   /*
    19     20   ** Attempt to release up to n bytes of non-essential memory currently
    20     21   ** held by SQLite. An example of non-essential memory is memory used to
    21     22   ** cache database pages that are not currently in use.
    22     23   */
................................................................................
   260    261   void *sqlite3_malloc64(sqlite3_uint64 n){
   261    262   #ifndef SQLITE_OMIT_AUTOINIT
   262    263     if( sqlite3_initialize() ) return 0;
   263    264   #endif
   264    265     return sqlite3Malloc(n);
   265    266   }
   266    267   
   267         -/*
   268         -** TRUE if p is a lookaside memory allocation from db
   269         -*/
   270         -#ifndef SQLITE_OMIT_LOOKASIDE
   271         -static int isLookaside(sqlite3 *db, void *p){
   272         -  return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
   273         -}
   274         -#else
   275         -#define isLookaside(A,B) 0
   276         -#endif
   277         -
   278    268   /*
   279    269   ** Return the size of a memory allocation previously obtained from
   280    270   ** sqlite3Malloc() or sqlite3_malloc().
   281    271   */
   282    272   int sqlite3MallocSize(void *p){
   283    273     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   284    274     return sqlite3GlobalConfig.m.xSize(p);
   285    275   }
   286    276   int sqlite3DbMallocSize(sqlite3 *db, void *p){
   287    277     assert( p!=0 );
   288         -  if( db==0 || !isLookaside(db,p) ){
          278  +  if( db==0 || !sqlite3IsLookaside(&db->lookaside,p) ){
   289    279   #ifdef SQLITE_DEBUG
   290    280       if( db==0 ){
   291    281         assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
   292    282         assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   293    283       }else{
   294    284         assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   295    285         assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   296    286       }
   297    287   #endif
   298    288       return sqlite3GlobalConfig.m.xSize(p);
   299    289     }else{
   300    290       assert( sqlite3_mutex_held(db->mutex) );
   301         -    return db->lookaside.szTrue;
          291  +    return sqlite3LookasideSize(&db->lookaside, p);
   302    292     }
   303    293   }
   304    294   sqlite3_uint64 sqlite3_msize(void *p){
   305    295     assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
   306    296     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
   307    297     return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
   308    298   }
................................................................................
   342    332     assert( db==0 || sqlite3_mutex_held(db->mutex) );
   343    333     assert( p!=0 );
   344    334     if( db ){
   345    335       if( db->pnBytesFreed ){
   346    336         measureAllocationSize(db, p);
   347    337         return;
   348    338       }
   349         -    if( isLookaside(db, p) ){
   350         -      LookasideSlot *pBuf = (LookasideSlot*)p;
   351         -#ifdef SQLITE_DEBUG
   352         -      /* Trash all content in the buffer being freed */
   353         -      memset(p, 0xaa, db->lookaside.szTrue);
   354         -#endif
   355         -      pBuf->pNext = db->lookaside.pFree;
   356         -      db->lookaside.pFree = pBuf;
          339  +    if( sqlite3IsLookaside(&db->lookaside, p) ){
          340  +      sqlite3LookasideFree(&db->lookaside, p);
   357    341         return;
   358    342       }
   359    343     }
   360    344     assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   361    345     assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   362    346     assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
   363    347     sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
................................................................................
   464    448   
   465    449   /* Finish the work of sqlite3DbMallocRawNN for the unusual and
   466    450   ** slower case when the allocation cannot be fulfilled using lookaside.
   467    451   */
   468    452   static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){
   469    453     void *p;
   470    454     assert( db!=0 );
          455  +  if( db->mallocFailed ){ return 0; }
   471    456     p = sqlite3Malloc(n);
   472    457     if( !p ) sqlite3OomFault(db);
   473    458     sqlite3MemdebugSetType(p, 
   474         -         (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
          459  +    sqlite3LookasideDisabled(&db->lookaside) ? MEMTYPE_HEAP : MEMTYPE_LOOKASIDE);
   475    460     return p;
   476    461   }
   477    462   
   478    463   /*
   479    464   ** Allocate memory, either lookaside (if possible) or heap.  
   480    465   ** If the allocation fails, set the mallocFailed flag in
   481    466   ** the connection pointer.
................................................................................
   501    486     void *p;
   502    487     if( db ) return sqlite3DbMallocRawNN(db, n);
   503    488     p = sqlite3Malloc(n);
   504    489     sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   505    490     return p;
   506    491   }
   507    492   void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
   508         -#ifndef SQLITE_OMIT_LOOKASIDE
   509         -  LookasideSlot *pBuf;
   510    493     assert( db!=0 );
   511    494     assert( sqlite3_mutex_held(db->mutex) );
   512    495     assert( db->pnBytesFreed==0 );
   513         -  if( n>db->lookaside.sz ){
   514         -    if( db->lookaside.bDisable ){
   515         -      return db->mallocFailed ? 0 : dbMallocRawFinish(db, n);
   516         -    }
   517         -    db->lookaside.anStat[1]++;
   518         -  }else if( (pBuf = db->lookaside.pFree)!=0 ){
   519         -    db->lookaside.pFree = pBuf->pNext;
   520         -    db->lookaside.anStat[0]++;
   521         -    return (void*)pBuf;
   522         -  }else if( (pBuf = db->lookaside.pInit)!=0 ){
   523         -    db->lookaside.pInit = pBuf->pNext;
   524         -    db->lookaside.anStat[0]++;
   525         -    return (void*)pBuf;
   526         -  }else{
   527         -    db->lookaside.anStat[2]++;
   528         -  }
          496  +#ifndef SQLITE_OMIT_LOOKASIDE
          497  +  return sqlite3LookasideAlloc(&db->lookaside, n) ?: dbMallocRawFinish(db, n);
   529    498   #else
   530    499     assert( db!=0 );
   531    500     assert( sqlite3_mutex_held(db->mutex) );
   532    501     assert( db->pnBytesFreed==0 );
   533    502     if( db->mallocFailed ){
   534    503       return 0;
   535    504     }
   536         -#endif
   537    505     return dbMallocRawFinish(db, n);
          506  +#endif
   538    507   }
   539    508   
   540    509   /* Forward declaration */
   541    510   static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n);
   542    511   
   543    512   /*
   544    513   ** Resize the block of memory pointed to by p to n bytes. If the
   545    514   ** resize fails, set the mallocFailed flag in the connection object.
   546    515   */
   547    516   void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
   548    517     assert( db!=0 );
   549    518     if( p==0 ) return sqlite3DbMallocRawNN(db, n);
   550    519     assert( sqlite3_mutex_held(db->mutex) );
   551         -  if( isLookaside(db,p) && n<=db->lookaside.szTrue ) return p;
          520  +  if( sqlite3IsLookaside(&db->lookaside,p) && n<=sqlite3LookasideSize(&db->lookaside, p) ) return p;
   552    521     return dbReallocFinish(db, p, n);
   553    522   }
   554    523   static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
   555    524     void *pNew = 0;
   556    525     assert( db!=0 );
   557    526     assert( p!=0 );
   558    527     if( db->mallocFailed==0 ){
   559         -    if( isLookaside(db, p) ){
          528  +    if( sqlite3IsLookaside(&db->lookaside,p) ){
   560    529         pNew = sqlite3DbMallocRawNN(db, n);
   561    530         if( pNew ){
   562         -        memcpy(pNew, p, db->lookaside.szTrue);
          531  +        memcpy(pNew, p, sqlite3LookasideSize(&db->lookaside, p));
   563    532           sqlite3DbFree(db, p);
   564    533         }
   565    534       }else{
   566    535         assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   567    536         assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   568    537         sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   569    538         pNew = sqlite3_realloc64(p, n);
   570    539         if( !pNew ){
   571    540           sqlite3OomFault(db);
   572    541         }
   573         -      sqlite3MemdebugSetType(pNew,
   574         -            (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
          542  +      sqlite3MemdebugSetType(p,
          543  +        sqlite3LookasideDisabled(&db->lookaside) ? MEMTYPE_HEAP : MEMTYPE_LOOKASIDE);
   575    544       }
   576    545     }
   577    546     return pNew;
   578    547   }
   579    548   
   580    549   /*
   581    550   ** Attempt to reallocate p.  If the reallocation fails, then free p
................................................................................
   644    613   void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
   645    614     sqlite3DbFree(db, *pz);
   646    615     *pz = sqlite3DbStrDup(db, zNew);
   647    616   }
   648    617   
   649    618   /*
   650    619   ** Call this routine to record the fact that an OOM (out-of-memory) error
   651         -** has happened.  This routine will set db->mallocFailed, and also
   652         -** temporarily disable the lookaside memory allocator and interrupt
          620  +** has happened.  This routine will set db->mallocFailed and interrupt
   653    621   ** any running VDBEs.
   654    622   */
   655    623   void sqlite3OomFault(sqlite3 *db){
   656    624     if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
   657    625       db->mallocFailed = 1;
   658    626       if( db->nVdbeExec>0 ){
   659    627         db->u1.isInterrupted = 1;
   660    628       }
   661         -    DisableLookaside;
          629  +    sqlite3LookasideDisable(&db->lookaside);;
   662    630       if( db->pParse ){
   663    631         db->pParse->rc = SQLITE_NOMEM_BKPT;
   664    632       }
   665    633     }
   666    634   }
   667    635   
   668    636   /*
................................................................................
   672    640   ** The memory allocator is not restarted if there are running
   673    641   ** VDBEs.
   674    642   */
   675    643   void sqlite3OomClear(sqlite3 *db){
   676    644     if( db->mallocFailed && db->nVdbeExec==0 ){
   677    645       db->mallocFailed = 0;
   678    646       db->u1.isInterrupted = 0;
   679         -    assert( db->lookaside.bDisable>0 );
          647  +    assert( sqlite3LookasideDisabled(&db->lookaside) );
   680    648       EnableLookaside;
   681    649     }
   682    650   }
   683    651   
   684    652   /*
   685    653   ** Take actions at the end of an API call to indicate an OOM error
   686    654   */

Changes to src/parse.y.

    47     47   %name sqlite3Parser
    48     48   
    49     49   // The following text is included near the beginning of the C source
    50     50   // code file that implements the parser.
    51     51   //
    52     52   %include {
    53     53   #include "sqliteInt.h"
           54  +#include "lookaside.h"
    54     55   
    55     56   /*
    56     57   ** Disable all error recovery processing in the parser push-down
    57     58   ** automaton.
    58     59   */
    59     60   #define YYNOERRORRECOVERY 1
    60     61   
................................................................................
   104    105   /*
   105    106   ** Disable lookaside memory allocation for objects that might be
   106    107   ** shared across database connections.
   107    108   */
   108    109   static void disableLookaside(Parse *pParse){
   109    110     sqlite3 *db = pParse->db;
   110    111     pParse->disableLookaside++;
   111         -  DisableLookaside;
          112  +  sqlite3LookasideDisable(&db->lookaside);
   112    113   }
   113    114   
   114    115   } // end %include
   115    116   
   116    117   // Input is a single SQL command
   117    118   input ::= cmdlist.
   118    119   cmdlist ::= cmdlist ecmd.

Changes to src/prepare.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   */
    16     16   #include "sqliteInt.h"
           17  +#include "lookaside.h"
    17     18   
    18     19   /*
    19     20   ** Fill the InitData structure with an error message that indicates
    20     21   ** that the database is corrupt.
    21     22   */
    22     23   static void corruptSchema(
    23     24     InitData *pData,     /* Initialization context */
................................................................................
   534    535   ** Free all memory allocations in the pParse object
   535    536   */
   536    537   void sqlite3ParserReset(Parse *pParse){
   537    538     sqlite3 *db = pParse->db;
   538    539     sqlite3DbFree(db, pParse->aLabel);
   539    540     sqlite3ExprListDelete(db, pParse->pConstExpr);
   540    541     if( db ){
   541         -    assert( db->lookaside.bDisable >= pParse->disableLookaside );
   542         -    db->lookaside.bDisable -= pParse->disableLookaside;
   543         -    db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue;
          542  +    assert( sqlite3LookasideDisabled(&db->lookaside) >= pParse->disableLookaside );
          543  +    sqlite3LookasideEnableCnt(&db->lookaside, pParse->disableLookaside);
   544    544     }
   545    545     pParse->disableLookaside = 0;
   546    546   }
   547    547   
   548    548   /*
   549    549   ** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
   550    550   */
................................................................................
   570    570     assert( sqlite3_mutex_held(db->mutex) );
   571    571   
   572    572     /* For a long-term use prepared statement avoid the use of
   573    573     ** lookaside memory.
   574    574     */
   575    575     if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
   576    576       sParse.disableLookaside++;
   577         -    DisableLookaside;
          577  +    sqlite3LookasideDisable(&db->lookaside);
   578    578     }
   579    579     sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
   580    580   
   581    581     /* Check to verify that it is possible to get a read lock on all
   582    582     ** database schemas.  The inability to get a read lock indicates that
   583    583     ** some other database connection is holding a write-lock, which in
   584    584     ** turn means that the other connection has made uncommitted changes

Changes to src/select.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** to handle SELECT statements in SQLite.
    14     14   */
    15     15   #include "sqliteInt.h"
           16  +#include "lookaside.h"
    16     17   
    17     18   /*
    18     19   ** Trace output macros
    19     20   */
    20     21   #if SELECTTRACE_ENABLED
    21     22   /***/ int sqlite3SelectTrace = 0;
    22     23   # define SELECTTRACE(K,P,S,X)  \

Changes to src/sqliteInt.h.

  1285   1285     u8 bMalloced;           /* True if pStart obtained from sqlite3_malloc() */
  1286   1286     u32 nSlot;              /* Number of lookaside slots allocated */
  1287   1287     u32 anStat[3];          /* 0: hits.  1: size misses.  2: full misses */
  1288   1288     LookasideSlot *pInit;   /* List of buffers not previously used */
  1289   1289     LookasideSlot *pFree;   /* List of available buffers */
  1290   1290     void *pStart;           /* First byte of available memory space */
  1291   1291     void *pEnd;             /* First byte past end of available space */
         1292  +#ifndef SQLITE_OMIT_MINILOOKASIDE
         1293  +  LookasideSlot *pMini;   /* List of buffers used by mini allocator */
         1294  +  u16 szMini;             /* Size of each mini-allocator buffer in bytes */
         1295  +  u16 nMini;              /* Number of mini-allocator buffers per slot */
         1296  +#endif /* SQLITE_OMIT_MINILOOKASIDE */
  1292   1297   };
  1293   1298   struct LookasideSlot {
  1294         -  LookasideSlot *pNext;    /* Next buffer in the list of free buffers */
         1299  +  LookasideSlot *pNext;    /* Next buffer in the list of buffers */
         1300  +#ifndef SQLITE_OMIT_MINILOOKASIDE
         1301  +  /* The members below are only valid for slots inside the mini-allocator */
         1302  +  LookasideSlot *pPrev;    /* Previous partially-used buffer in the list */
         1303  +  u16 nAlloc;              /* Number of sub-allocations ever returned from this slot */
         1304  +  LookasideSlot *pFree;    /* List of freed sub-allocations */
         1305  +#endif /* SQLITE_OMIT_MINILOOKASIDE */
  1295   1306   };
  1296   1307   
  1297   1308   #define DisableLookaside  db->lookaside.bDisable++;db->lookaside.sz=0
  1298   1309   #define EnableLookaside   db->lookaside.bDisable--;\
  1299   1310      db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue
  1300   1311   
  1301   1312   /*
................................................................................
  3821   3832   # define sqlite3MemoryBarrier()
  3822   3833   #endif
  3823   3834   
  3824   3835   sqlite3_int64 sqlite3StatusValue(int);
  3825   3836   void sqlite3StatusUp(int, int);
  3826   3837   void sqlite3StatusDown(int, int);
  3827   3838   void sqlite3StatusHighwater(int, int);
  3828         -int sqlite3LookasideUsed(sqlite3*,int*);
  3829   3839   
  3830   3840   /* Access to mutexes used by sqlite3_status() */
  3831   3841   sqlite3_mutex *sqlite3Pcache1Mutex(void);
  3832   3842   sqlite3_mutex *sqlite3MallocMutex(void);
  3833   3843   
  3834   3844   #if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
  3835   3845   void sqlite3MutexWarnOnContention(sqlite3_mutex*);

Changes to src/status.c.

    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This module implements the sqlite3_status() interface and related
    14     14   ** functionality.
    15     15   */
    16     16   #include "sqliteInt.h"
           17  +#include "lookaside.h"
    17     18   #include "vdbeInt.h"
    18     19   
    19     20   /*
    20     21   ** Variables in which to record status information.
    21     22   */
    22     23   #if SQLITE_PTRSIZE>4
    23     24   typedef sqlite3_int64 sqlite3StatValueType;
................................................................................
   166    167     if( rc==0 ){
   167    168       *pCurrent = (int)iCur;
   168    169       *pHighwater = (int)iHwtr;
   169    170     }
   170    171     return rc;
   171    172   }
   172    173   
   173         -/*
   174         -** Return the number of LookasideSlot elements on the linked list
   175         -*/
   176         -static u32 countLookasideSlots(LookasideSlot *p){
   177         -  u32 cnt = 0;
   178         -  while( p ){
   179         -    p = p->pNext;
   180         -    cnt++;
   181         -  }
   182         -  return cnt;
   183         -}
   184         -
   185         -/*
   186         -** Count the number of slots of lookaside memory that are outstanding
   187         -*/
   188         -int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
   189         -  u32 nInit = countLookasideSlots(db->lookaside.pInit);
   190         -  u32 nFree = countLookasideSlots(db->lookaside.pFree);
   191         -  if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
   192         -  return db->lookaside.nSlot - (nInit+nFree);
   193         -}
   194         -
   195    174   /*
   196    175   ** Query status information for a single database connection
   197    176   */
   198    177   int sqlite3_db_status(
   199    178     sqlite3 *db,          /* The database connection whose status is desired */
   200    179     int op,               /* Status verb */
   201    180     int *pCurrent,        /* Write current value here */
................................................................................
   207    186     if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
   208    187       return SQLITE_MISUSE_BKPT;
   209    188     }
   210    189   #endif
   211    190     sqlite3_mutex_enter(db->mutex);
   212    191     switch( op ){
   213    192       case SQLITE_DBSTATUS_LOOKASIDE_USED: {
   214         -      *pCurrent = sqlite3LookasideUsed(db, pHighwater);
          193  +      *pCurrent = sqlite3LookasideUsed(&db->lookaside, pHighwater);
   215    194         if( resetFlag ){
   216         -        LookasideSlot *p = db->lookaside.pFree;
   217         -        if( p ){
   218         -          while( p->pNext ) p = p->pNext;
   219         -          p->pNext = db->lookaside.pInit;
   220         -          db->lookaside.pInit = db->lookaside.pFree;
   221         -          db->lookaside.pFree = 0;
   222         -        }
          195  +        sqlite3LookasideResetUsed(&db->lookaside);
   223    196         }
   224    197         break;
   225    198       }
   226    199   
   227    200       case SQLITE_DBSTATUS_LOOKASIDE_HIT:
   228    201       case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
   229    202       case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {

Changes to tool/mksqlite3c-noext.tcl.

    94     94   #
    95     95   foreach hdr {
    96     96      btree.h
    97     97      btreeInt.h
    98     98      hash.h
    99     99      hwtime.h
   100    100      keywordhash.h
          101  +   lookaside.h
   101    102      msvc.h
   102    103      mutex.h
   103    104      opcodes.h
   104    105      os_common.h
   105    106      os_setup.h
   106    107      os_win.h
   107    108      os.h
................................................................................
   279    280      global.c
   280    281      ctime.c
   281    282      status.c
   282    283      date.c
   283    284      os.c
   284    285   
   285    286      fault.c
          287  +   lookaside.c
   286    288      mem0.c
   287    289      mem1.c
   288    290      mem2.c
   289    291      mem3.c
   290    292      mem5.c
   291    293      mutex.c
   292    294      mutex_noop.c

Changes to tool/mksqlite3c.tcl.

    99     99      fts3Int.h
   100    100      fts3_hash.h
   101    101      fts3_tokenizer.h
   102    102      geopoly.c
   103    103      hash.h
   104    104      hwtime.h
   105    105      keywordhash.h
          106  +   lookaside.h
   106    107      msvc.h
   107    108      mutex.h
   108    109      opcodes.h
   109    110      os_common.h
   110    111      os_setup.h
   111    112      os_win.h
   112    113      os.h
................................................................................
   296    297   
   297    298      global.c
   298    299      status.c
   299    300      date.c
   300    301      os.c
   301    302   
   302    303      fault.c
          304  +   lookaside.c
   303    305      mem0.c
   304    306      mem1.c
   305    307      mem2.c
   306    308      mem3.c
   307    309      mem5.c
   308    310      mutex.c
   309    311      mutex_noop.c

Changes to tool/mksqlite3internalh.tcl.

    54     54   #
    55     55   foreach hdr {
    56     56      btree.h
    57     57      btreeInt.h
    58     58      hash.h
    59     59      hwtime.h
    60     60      keywordhash.h
           61  +   lookaside.h
    61     62      msvc.h
    62     63      opcodes.h
    63     64      os_common.h
    64     65      os_setup.h
    65     66      os_win.h
    66     67      os.h
    67     68      pager.h