diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 16 | ||||
-rw-r--r-- | src/btree.c | 97 | ||||
-rw-r--r-- | src/btreeInt.h | 5 | ||||
-rw-r--r-- | src/build.c | 4 | ||||
-rw-r--r-- | src/date.c | 4 | ||||
-rw-r--r-- | src/func.c | 4 | ||||
-rw-r--r-- | src/hash.c | 6 | ||||
-rw-r--r-- | src/legacy.c | 4 | ||||
-rw-r--r-- | src/malloc.c | 60 | ||||
-rw-r--r-- | src/mem1.c | 4 | ||||
-rw-r--r-- | src/mem2.c | 4 | ||||
-rw-r--r-- | src/mutex.c | 4 | ||||
-rw-r--r-- | src/mutex.h | 4 | ||||
-rw-r--r-- | src/os.c | 6 | ||||
-rw-r--r-- | src/pager.c | 18 | ||||
-rw-r--r-- | src/prepare.c | 4 | ||||
-rw-r--r-- | src/printf.c | 8 | ||||
-rw-r--r-- | src/sqlite.h.in | 12 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/tokenize.c | 4 | ||||
-rw-r--r-- | src/vdbe.c | 6 | ||||
-rw-r--r-- | src/vdbeaux.c | 4 | ||||
-rw-r--r-- | src/vdbefifo.c | 4 | ||||
-rw-r--r-- | src/where.c | 4 |
24 files changed, 178 insertions, 112 deletions
diff --git a/src/attach.c b/src/attach.c index c0f177328..3964f379e 100644 --- a/src/attach.c +++ b/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.75 2008/04/17 17:02:01 drh Exp $ +** $Id: attach.c,v 1.76 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" @@ -112,18 +112,12 @@ static void attachFunc( ** hash tables. */ if( db->aDb==db->aDbStatic ){ - aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } + aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); + if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ - aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ){ - db->mallocFailed = 1; - return; - } + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + if( aNew==0 ) return; } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; diff --git a/src/btree.c b/src/btree.c index 9d7c2266b..1140e7756 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.463 2008/06/11 18:27:55 danielk1977 Exp $ +** $Id: btree.c,v 1.464 2008/06/15 02:51:47 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -300,7 +300,7 @@ static int saveCursorPosition(BtCursor *pCur){ ** data. */ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ - void *pKey = sqlite3_malloc(pCur->nKey); + void *pKey = sqlite3Malloc(pCur->nKey); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); if( rc==SQLITE_OK ){ @@ -1190,7 +1190,7 @@ int sqlite3BtreeOpen( ){ if( sqlite3SharedCacheEnabled ){ int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = (char *)sqlite3_malloc(nFullPathname); + char *zFullPathname = sqlite3Malloc(nFullPathname); sqlite3_mutex *mutexShared; p->sharable = 1; if( db ){ @@ -1267,9 +1267,6 @@ int sqlite3BtreeOpen( || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ pBt->pageSize = 0; sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - pBt->maxEmbedFrac = 64; /* 25% */ - pBt->minEmbedFrac = 32; /* 12.5% */ - pBt->minLeafFrac = 32; /* 12.5% */ #ifndef SQLITE_OMIT_AUTOVACUUM /* If the magic name ":memory:" will create an in-memory database, then ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if @@ -1285,9 +1282,6 @@ int sqlite3BtreeOpen( nReserve = 0; }else{ nReserve = zDbHeader[20]; - pBt->maxEmbedFrac = zDbHeader[21]; - pBt->minEmbedFrac = zDbHeader[22]; - pBt->minLeafFrac = zDbHeader[23]; pBt->pageSizeFixed = 1; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); @@ -1677,6 +1671,15 @@ static int lockBtree(BtShared *pBt){ if( page1[19]>1 ){ goto page1_init_failed; } + + /* The maximum embedded fraction must be exactly 25%. And the minimum + ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data. + ** The original design allowed these amounts to vary, but as of + ** version 3.6.0, we require them to be fixed. + */ + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } pageSize = get2byte(&page1[16]); if( ((pageSize-1)&pageSize)!=0 || pageSize<512 || (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE) @@ -1705,9 +1708,6 @@ static int lockBtree(BtShared *pBt){ } pBt->pageSize = pageSize; pBt->usableSize = usableSize; - pBt->maxEmbedFrac = page1[21]; - pBt->minEmbedFrac = page1[22]; - pBt->minLeafFrac = page1[23]; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); @@ -1727,10 +1727,10 @@ static int lockBtree(BtShared *pBt){ ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow ** page pointer. */ - pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23; - pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23; + pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23; + pBt->minLocal = (pBt->usableSize-12)*32/255 - 23; pBt->maxLeaf = pBt->usableSize - 35; - pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23; + pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23; if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){ goto page1_init_failed; } @@ -1823,9 +1823,9 @@ static int newDatabase(BtShared *pBt){ data[18] = 1; data[19] = 1; data[20] = pBt->pageSize - pBt->usableSize; - data[21] = pBt->maxEmbedFrac; - data[22] = pBt->minEmbedFrac; - data[23] = pBt->minLeafFrac; + data[21] = 64; + data[22] = 32; + data[23] = 32; memset(&data[24], 0, 100-24); zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); pBt->pageSizeFixed = 1; @@ -3719,14 +3719,14 @@ int sqlite3BtreeMoveto( if( available>=nCellKey ){ c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); }else{ - pCellKey = sqlite3_malloc( nCellKey ); + pCellKey = sqlite3TempMalloc( nCellKey ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey); - sqlite3_free(pCellKey); + sqlite3TempFree(pCellKey); if( rc ) goto moveto_finish; } } @@ -4858,7 +4858,8 @@ static int balance_nonroot(MemPage *pPage){ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int subtotal; /* Subtotal of bytes in cells on one page */ - int iSpace = 0; /* First unused byte of aSpace[] */ + int iSpace1 = 0; /* First unused byte of aSpace1[] */ + int iSpace2 = 0; /* First unused byte of aSpace2[] */ MemPage *apOld[NB]; /* pPage and up to two siblings */ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ @@ -4869,8 +4870,9 @@ static int balance_nonroot(MemPage *pPage){ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell = 0; /* All cells begin balanced */ u16 *szCell; /* Local size of all cells in apCell[] */ - u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ - u8 *aSpace; /* Space to hold copies of dividers cells */ + u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ + u8 *aSpace1; /* Space for copies of dividers cells before balance */ + u8 *aSpace2 = 0; /* Space for overflow dividers cells after balance */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 *aFrom = 0; #endif @@ -4988,11 +4990,11 @@ static int balance_nonroot(MemPage *pPage){ /* ** Allocate space for memory structures */ - apCell = sqlite3_malloc( + apCell = sqlite3TempMalloc( nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(u16) /* szCell */ + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ - + pBt->pageSize*5 /* aSpace */ + + pBt->pageSize /* aSpace1 */ + (ISAUTOVACUUM ? nMaxCells : 0) /* aFrom */ ); if( apCell==0 ){ @@ -5006,13 +5008,18 @@ static int balance_nonroot(MemPage *pPage){ aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ } - aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; - assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ + aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; + assert( ((aSpace1 - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */ #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - aFrom = &aSpace[5*pBt->pageSize]; + aFrom = &aSpace1[pBt->pageSize]; } #endif + aSpace2 = sqlite3Malloc(pBt->pageSize); + if( aSpace2==0 ){ + rc = SQLITE_NOMEM; + goto balance_cleanup; + } /* ** Make copies of the content of pPage and its siblings into aOld[]. @@ -5030,12 +5037,12 @@ static int balance_nonroot(MemPage *pPage){ /* ** Load pointers to all cells on sibling pages and the divider cells ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained form aSpace[] and remove the the divider Cells + ** into space obtained form aSpace1[] and remove the the divider Cells ** from pParent. ** ** If the siblings are on leaf pages, then the child pointers of the ** divider cells are stripped from the cells before they are copied - ** into aSpace[]. In this way, all cells in apCell[] are without + ** into aSpace1[]. In this way, all cells in apCell[] are without ** child pointers. If siblings are not leaves, then all cell in ** apCell[] include child pointers. Either way, all cells in apCell[] ** are alike. @@ -5080,9 +5087,10 @@ static int balance_nonroot(MemPage *pPage){ u8 *pTemp; assert( nCell<nMaxCells ); szCell[nCell] = sz; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + pTemp = &aSpace1[iSpace1]; + iSpace1 += sz; + assert( sz<=pBt->pageSize/4 ); + assert( iSpace1<=pBt->pageSize ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -5303,9 +5311,9 @@ static int balance_nonroot(MemPage *pPage){ assert( j<nMaxCells ); pCell = apCell[j]; sz = szCell[j] + leafCorrection; + pTemp = &aSpace2[iSpace2]; if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); - pTemp = 0; }else if( leafData ){ /* If the tree is a leaf-data tree, and the siblings are leaves, ** then there is no divider cell in apCell[]. Instead, the divider @@ -5315,16 +5323,11 @@ static int balance_nonroot(MemPage *pPage){ CellInfo info; j--; sqlite3BtreeParseCellPtr(pNew, apCell[j], &info); - pCell = &aSpace[iSpace]; + pCell = pTemp; fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz); - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); pTemp = 0; }else{ pCell -= 4; - pTemp = &aSpace[iSpace]; - iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 ** bytes, then it may actually be smaller than this @@ -5341,6 +5344,9 @@ static int balance_nonroot(MemPage *pPage){ sz = cellSizePtr(pParent, pCell); } } + iSpace2 += sz; + assert( sz<=pBt->pageSize/4 ); + assert( iSpace2<=pBt->pageSize ); rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); if( rc!=SQLITE_OK ) goto balance_cleanup; put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); @@ -5391,13 +5397,16 @@ static int balance_nonroot(MemPage *pPage){ ** But the parent page will always be initialized. */ assert( pParent->isInit ); + sqlite3TempFree(apCell); + apCell = 0; rc = balance(pParent, 0); /* ** Cleanup before returning. */ balance_cleanup: - sqlite3_free(apCell); + sqlite3_free(aSpace2); + sqlite3TempFree(apCell); for(i=0; i<nOld; i++){ releasePage(apOld[i]); } @@ -5429,7 +5438,7 @@ static int balance_shallower(MemPage *pPage){ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); - apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); + apCell = sqlite3Malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) ); if( apCell==0 ) return SQLITE_NOMEM; szCell = (u16*)&apCell[mxCellPerPage]; if( pPage->leaf ){ @@ -5673,7 +5682,7 @@ static int checkReadLocks( */ static void allocateTempSpace(BtShared *pBt){ if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3_malloc(MX_CELL_SIZE(pBt)); + pBt->pTmpSpace = sqlite3Malloc(MX_CELL_SIZE(pBt)); } } @@ -6729,7 +6738,7 @@ char *sqlite3BtreeIntegrityCheck( sqlite3BtreeLeave(p); return 0; } - sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); + sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ unlockBtreeIfUnused(pBt); *pnErr = 1; diff --git a/src/btreeInt.h b/src/btreeInt.h index a60e1cbe8..f5783fa24 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.21 2008/04/24 19:15:10 shane Exp $ +** $Id: btreeInt.h,v 1.22 2008/06/15 02:51:47 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -371,9 +371,6 @@ struct BtShared { MemPage *pPage1; /* First page of the database */ u8 inStmt; /* True if we are in a statement subtransaction */ u8 readOnly; /* True if the underlying file is readonly */ - u8 maxEmbedFrac; /* Maximum payload as % of total page size */ - u8 minEmbedFrac; /* Minimum payload as % of total page size */ - u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 pageSizeFixed; /* True if the page size can no longer be changed */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ diff --git a/src/build.c b/src/build.c index c1b5a4530..09a82cbaf 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.484 2008/05/01 17:16:53 drh Exp $ +** $Id: build.c,v 1.485 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1367,7 +1367,7 @@ static char *createTableStmt(sqlite3 *db, Table *p, int isTemp){ zEnd = "\n)"; } n += 35 + 6*p->nCol; - zStmt = sqlite3_malloc( n ); + zStmt = sqlite3Malloc( n ); if( zStmt==0 ){ db->mallocFailed = 1; return 0; diff --git a/src/date.c b/src/date.c index f258d5cfd..c698eb92e 100644 --- a/src/date.c +++ b/src/date.c @@ -16,7 +16,7 @@ ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.83 2008/06/12 16:35:38 drh Exp $ +** $Id: date.c,v 1.84 2008/06/15 02:51:47 drh Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -888,7 +888,7 @@ static void strftimeFunc( sqlite3_result_error_toobig(context); return; }else{ - z = sqlite3_malloc( n ); + z = sqlite3Malloc( n ); if( z==0 ){ sqlite3_result_error_nomem(context); return; diff --git a/src/func.c b/src/func.c index 10c3baa31..bb2ba4900 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.192 2008/04/27 18:40:12 drh Exp $ +** $Id: func.c,v 1.193 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -249,7 +249,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){ sqlite3_result_error_toobig(context); z = 0; }else{ - z = sqlite3_malloc(nByte); + z = sqlite3Malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } diff --git a/src/hash.c b/src/hash.c index b8d0af629..12f5593c9 100644 --- a/src/hash.c +++ b/src/hash.c @@ -12,7 +12,7 @@ ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: hash.c,v 1.28 2008/05/13 13:27:34 drh Exp $ +** $Id: hash.c,v 1.29 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" #include <assert.h> @@ -387,10 +387,10 @@ void *sqlite3HashInsert(Hash *pH, const void *pKey, int nKey, void *data){ } } if( data==0 ) return 0; - new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) ); + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); if( new_elem==0 ) return data; if( pH->copyKey && pKey!=0 ){ - new_elem->pKey = sqlite3_malloc( nKey ); + new_elem->pKey = sqlite3Malloc( nKey ); if( new_elem->pKey==0 ){ sqlite3_free(new_elem); return data; diff --git a/src/legacy.c b/src/legacy.c index 130ba0174..6d84d7039 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: legacy.c,v 1.26 2008/05/20 15:44:31 drh Exp $ +** $Id: legacy.c,v 1.27 2008/06/15 02:51:47 drh Exp $ */ #include "sqliteInt.h" @@ -133,7 +133,7 @@ exec_out: rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){ int nErrMsg = 1 + strlen(sqlite3_errmsg(db)); - *pzErrMsg = sqlite3_malloc(nErrMsg); + *pzErrMsg = sqlite3Malloc(nErrMsg); if( *pzErrMsg ){ memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); } diff --git a/src/malloc.c b/src/malloc.c index 5916ec251..3c567c9c0 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -12,7 +12,7 @@ ** ** Memory allocation functions used throughout sqlite. ** -** $Id: malloc.c,v 1.16 2008/06/14 16:56:22 drh Exp $ +** $Id: malloc.c,v 1.17 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> @@ -90,7 +90,8 @@ static struct { */ sqlite3_int64 nowUsed; /* Main memory currently in use */ sqlite3_int64 mxUsed; /* Highwater mark for nowUsed */ - int mxReq; /* maximum request size for main or page-cache mem */ + int mxReq; /* Max request size for ordinary mallocs */ + int mxTempReq; /* Max request size for xTemp mallocs */ } mem0; /* @@ -227,6 +228,55 @@ void *sqlite3_malloc(int n){ } /* +** Each thread may only have a single outstanding allocation from +** xTempMalloc(). We verify this constraint in the single-threaded +** case by setting tempAllocOut to 1 when an allocation +** is outstanding clearing it when the allocation is freed. +*/ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) +static int tempAllocOut = 0; +#endif + + +/* +** Allocate memory that is to be used and released right away. +** This routine is similar to alloca() in that it is not intended +** for situations where the memory might be held long-term. This +** routine is intended to get memory to old large transient data +** structures that would not normally fit on the stack of an +** embedded processor. +*/ +void *sqlite3TempMalloc(int n){ + void *p; + assert( n>0 ); + if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){ + return 0; + } +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==0 ); + tempAllocOut = 1; +#endif + if( sqlite3Config.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + if( n>mem0.mxTempReq ) mem0.mxTempReq = n; + p = sqlite3Config.m.xTempMalloc(n); + sqlite3_mutex_leave(mem0.mutex); + }else{ + p = sqlite3Config.m.xTempMalloc(n); + } + return p; +} +void sqlite3TempFree(void *p){ + if( p ){ +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) + assert( tempAllocOut==1 ); + tempAllocOut = 0; +#endif + sqlite3Config.m.xTempFree(p); + } +} + +/* ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ @@ -386,14 +436,14 @@ char *sqlite3StrDup(const char *z){ int n; if( z==0 ) return 0; n = strlen(z)+1; - zNew = sqlite3_malloc(n); + zNew = sqlite3Malloc(n); if( zNew ) memcpy(zNew, z, n); return zNew; } char *sqlite3StrNDup(const char *z, int n){ char *zNew; if( z==0 ) return 0; - zNew = sqlite3_malloc(n+1); + zNew = sqlite3Malloc(n+1); if( zNew ){ memcpy(zNew, z, n); zNew[n] = 0; @@ -437,7 +487,7 @@ void sqlite3SetString(char **pz, ...){ } va_end(ap); sqlite3_free(*pz); - *pz = zResult = sqlite3_malloc(nByte); + *pz = zResult = sqlite3Malloc(nByte); if( zResult==0 ){ return; } diff --git a/src/mem1.c b/src/mem1.c index e7491f8ab..120fc040c 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -17,7 +17,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem1.c,v 1.19 2008/06/14 16:56:22 drh Exp $ +** $Id: mem1.c,v 1.20 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -130,6 +130,8 @@ void sqlite3MemSetDefault(void){ sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, + sqlite3MemMalloc, + sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 diff --git a/src/mem2.c b/src/mem2.c index 3206b25a5..ffc31987c 100644 --- a/src/mem2.c +++ b/src/mem2.c @@ -19,7 +19,7 @@ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: mem2.c,v 1.28 2008/06/14 16:56:22 drh Exp $ +** $Id: mem2.c,v 1.29 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -312,6 +312,8 @@ void sqlite3MemSetDefault(void){ sqlite3MemRealloc, sqlite3MemSize, sqlite3MemRoundup, + sqlite3MemMalloc, + sqlite3MemFree, sqlite3MemInit, sqlite3MemShutdown, 0 diff --git a/src/mutex.c b/src/mutex.c index 82812bc75..23c0422f6 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -19,7 +19,7 @@ ** implementation is suitable for testing. ** debugging purposes ** -** $Id: mutex.c,v 1.19 2008/06/14 16:56:23 drh Exp $ +** $Id: mutex.c,v 1.20 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -55,7 +55,7 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){ switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { - pNew = sqlite3_malloc(sizeof(*pNew)); + pNew = sqlite3Malloc(sizeof(*pNew)); if( pNew ){ pNew->id = id; pNew->cnt = 0; diff --git a/src/mutex.h b/src/mutex.h index f85739d2c..91922862a 100644 --- a/src/mutex.h +++ b/src/mutex.h @@ -19,7 +19,7 @@ ** Source files should #include the sqliteInt.h file and let that file ** include this one indirectly. ** -** $Id: mutex.h,v 1.3 2008/06/13 18:24:27 drh Exp $ +** $Id: mutex.h,v 1.4 2008/06/15 02:51:48 drh Exp $ */ @@ -77,7 +77,7 @@ #define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) 1 #define sqlite3_mutex_notheld(X) 1 -#define sqlite3_mutex_init() +#define sqlite3_mutex_init() SQLITE_OK #define sqlite3_mutex_end() #endif @@ -13,7 +13,7 @@ ** This file contains OS interface code that is common to all ** architectures. ** -** $Id: os.c,v 1.112 2008/06/13 18:24:27 drh Exp $ +** $Id: os.c,v 1.113 2008/06/15 02:51:48 drh Exp $ */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" @@ -38,7 +38,7 @@ */ #if defined(SQLITE_TEST) && (OS_WIN==0) #define DO_OS_MALLOC_TEST if (1) { \ - void *pTstAlloc = sqlite3_malloc(10); \ + void *pTstAlloc = sqlite3Malloc(10); \ if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ sqlite3_free(pTstAlloc); \ } @@ -168,7 +168,7 @@ int sqlite3OsOpenMalloc( ){ int rc = SQLITE_NOMEM; sqlite3_file *pFile; - pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile); + pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); if( pFile ){ rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ diff --git a/src/pager.c b/src/pager.c index 06fce97b2..5dab5a41d 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.456 2008/06/07 08:58:22 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.457 2008/06/15 02:51:48 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1650,7 +1650,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Open the master journal file exclusively in case some other process ** is running this routine also. Not that it makes too much difference. */ - pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2); + pMaster = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile * 2); pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM; @@ -1672,7 +1672,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Load the entire master journal file into space obtained from ** sqlite3_malloc() and pointed to by zMasterJournal. */ - zMasterJournal = (char *)sqlite3_malloc(nMasterJournal + nMasterPtr); + zMasterJournal = (char *)sqlite3Malloc(nMasterJournal + nMasterPtr); if( !zMasterJournal ){ rc = SQLITE_NOMEM; goto delmaster_out; @@ -2193,7 +2193,7 @@ int sqlite3PagerOpen( */ if( zFilename && zFilename[0] ){ nPathname = pVfs->mxPathname+1; - zPathname = sqlite3_malloc(nPathname*2); + zPathname = sqlite3Malloc(nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM; } @@ -2421,7 +2421,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ if( pageSize && pageSize!=pPager->pageSize && !pPager->memDb && pPager->nRef==0 ){ - char *pNew = (char *)sqlite3_malloc(pageSize); + char *pNew = (char *)sqlite3Malloc(pageSize); if( !pNew ){ rc = SQLITE_NOMEM; }else{ @@ -3647,9 +3647,9 @@ static int pagerAllocatePage(Pager *pPager, PgHdr **ppPg){ pagerLeave(pPager); nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra + MEMDB*sizeof(PgHistory); - pPg = sqlite3_malloc( nByteHdr ); + pPg = sqlite3Malloc( nByteHdr ); if( pPg ){ - pData = sqlite3_malloc( pPager->pageSize ); + pData = sqlite3Malloc( pPager->pageSize ); if( pData==0 ){ sqlite3_free(pPg); pPg = 0; @@ -4223,7 +4223,7 @@ static int pager_write(PgHdr *pPg){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); assert( pHist->pOrig==0 ); - pHist->pOrig = sqlite3_malloc( pPager->pageSize ); + pHist->pOrig = sqlite3Malloc( pPager->pageSize ); if( !pHist->pOrig ){ return SQLITE_NOMEM; } @@ -4293,7 +4293,7 @@ static int pager_write(PgHdr *pPg){ if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( pHist->pStmt==0 ); - pHist->pStmt = sqlite3_malloc( pPager->pageSize ); + pHist->pStmt = sqlite3Malloc( pPager->pageSize ); if( pHist->pStmt ){ memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); } diff --git a/src/prepare.c b/src/prepare.c index 5fa16f2d3..676f4370e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.86 2008/05/23 14:49:49 drh Exp $ +** $Id: prepare.c,v 1.87 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -448,7 +448,7 @@ static int schemaIsValid(sqlite3 *db){ int cookie; int allOk = 1; - curTemp = (BtCursor *)sqlite3_malloc(sqlite3BtreeCursorSize()); + curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize()); if( curTemp ){ assert( sqlite3_mutex_held(db->mutex) ); for(iDb=0; allOk && iDb<db->nDb; iDb++){ diff --git a/src/printf.c b/src/printf.c index 333765a53..d0b219a41 100644 --- a/src/printf.c +++ b/src/printf.c @@ -5,7 +5,7 @@ ** an historical reference. Most of the "enhancements" have been backed ** out so that the functionality is now the same as standard printf(). ** -** $Id: printf.c,v 1.85 2008/05/16 04:51:55 danielk1977 Exp $ +** $Id: printf.c,v 1.86 2008/06/15 02:51:48 drh Exp $ ** ************************************************************************** ** @@ -650,7 +650,7 @@ static void vxprintf( needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ - bufpt = zExtra = sqlite3_malloc( n ); + bufpt = zExtra = sqlite3Malloc( n ); if( bufpt==0 ) return; }else{ bufpt = buf; @@ -752,7 +752,7 @@ void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){ }else{ p->nAlloc = szNew; } - zNew = sqlite3_malloc( p->nAlloc ); + zNew = sqlite3Malloc( p->nAlloc ); if( zNew ){ memcpy(zNew, p->zText, p->nChar); sqlite3StrAccumReset(p); @@ -777,7 +777,7 @@ char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ p->zText[p->nChar] = 0; if( p->useMalloc && p->zText==p->zBase ){ - p->zText = sqlite3_malloc( p->nChar+1 ); + p->zText = sqlite3Malloc( p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); }else{ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ea46093ee..ca26f2c71 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.327 2008/06/14 16:56:23 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.328 2008/06/15 02:51:48 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -977,6 +977,14 @@ int sqlite3_config(int, ...); ** allocators round up memory allocations at least to the next multiple ** of 8. Some round up to a larger multiple or to a power of 2. ** +** The xTempMalloc and xTempFree methods are used to allocate a large +** chunk of temporary-use memory whose lifetime is a single procedure +** call. These routines may be the same as xMalloc and xFree, if desired, +** though some specialized applications may benefit from using a different +** allocation algorithm in this case. +** SQLite will never request more than one outstanding memory allocation +** per thread using xTempMalloc. +** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by @@ -991,6 +999,8 @@ struct sqlite3_mem_methods { void *(*xRealloc)(void*,int); /* Resize an allocation */ int (*xSize)(void*); /* Return the size of an allocation */ int (*xRoundup)(int); /* Round up request size to allocation size */ + void *(*xTempMalloc)(int); /* Allocate temporary space */ + void (*xTempFree)(void*); /* Free space from xTempMalloc */ int (*xInit)(void*); /* Initialize the memory allocator */ void (*xShutdown)(void*); /* Deinitialize the memory allocator */ void *pAppData; /* Argument to xInit() and xShutdown() */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6b9eda6c8..cccc29e77 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.709 2008/06/14 16:56:23 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.710 2008/06/15 02:51:48 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1791,6 +1791,8 @@ void *sqlite3Realloc(void*, int); void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); void *sqlite3DbRealloc(sqlite3 *, void *, int); int sqlite3MallocSize(void *); +void *sqlite3TempMalloc(int); +void sqlite3TempFree(void*); void sqlite3MemSetDefault(void); int sqlite3IsNaN(double); diff --git a/src/tokenize.c b/src/tokenize.c index 9af0e95ee..4b545a324 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.143 2008/06/02 13:00:33 danielk1977 Exp $ +** $Id: tokenize.c,v 1.144 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -393,7 +393,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ pParse->rc = SQLITE_OK; pParse->zTail = pParse->zSql = zSql; i = 0; - pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3_malloc); + pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; diff --git a/src/vdbe.c b/src/vdbe.c index 0b2a7e3ab..354edf938 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.748 2008/06/07 08:58:22 danielk1977 Exp $ +** $Id: vdbe.c,v 1.749 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -3380,7 +3380,7 @@ case OP_Insert: { pData->zMalloc = 0; } }else{ - pC->pData = sqlite3_malloc( pC->nData+2 ); + pC->pData = sqlite3Malloc( pC->nData+2 ); if( !pC->pData ) goto no_mem; memcpy(pC->pData, pData->z, pC->nData); pC->pData[pC->nData] = 0; @@ -4140,7 +4140,7 @@ case OP_IntegrityCk: { nRoot = pOp->p2; assert( nRoot>0 ); - aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) ); + aRoot = sqlite3Malloc( sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); pnErr = &p->aMem[pOp->p3]; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8818378f6..cb670edf5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.386 2008/06/06 15:04:37 drh Exp $ +** $Id: vdbeaux.c,v 1.387 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -547,7 +547,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ nField = ((KeyInfo*)zP4)->nField; nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField; - pKeyInfo = sqlite3_malloc( nByte ); + pKeyInfo = sqlite3Malloc( nByte ); pOp->p4.pKeyInfo = pKeyInfo; if( pKeyInfo ){ memcpy(pKeyInfo, zP4, nByte); diff --git a/src/vdbefifo.c b/src/vdbefifo.c index 8bf465f6c..956321c05 100644 --- a/src/vdbefifo.c +++ b/src/vdbefifo.c @@ -12,7 +12,7 @@ ** This file implements a FIFO queue of rowids used for processing ** UPDATE and DELETE statements. ** -** $Id: vdbefifo.c,v 1.6 2008/05/16 04:51:55 danielk1977 Exp $ +** $Id: vdbefifo.c,v 1.7 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -38,7 +38,7 @@ static FifoPage *allocateFifoPage(int nEntry){ if( nEntry>FIFOSIZE_MAX ){ nEntry = FIFOSIZE_MAX; } - pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); + pPage = sqlite3Malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) ); if( pPage ){ pPage->nSlot = nEntry; pPage->iWrite = 0; diff --git a/src/where.c b/src/where.c index 011357281..3a14bf321 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.308 2008/06/12 00:07:29 drh Exp $ +** $Id: where.c,v 1.309 2008/06/15 02:51:48 drh Exp $ */ #include "sqliteInt.h" @@ -228,7 +228,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, int flags){ int idx; if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; - pWC->a = sqlite3_malloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); + pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ pWC->pParse->db->mallocFailed = 1; if( flags & TERM_DYNAMIC ){ |