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