-C Enhance\sthe\scustom\smemory\sallocation\sinterface\sto\sallow\sthe\suser\sto\sspecify\sa\scalloc()\sfunction.
-D 2012-07-17T19:32:32.796
+C Reorganize\scode\sto\sremove\sa\sfew\sof\sthe\sbranches\sintroduced\sinto\sthe\scritical\ssqlite3DbMallocXXX()\spath\sby\sthe\sprevious\scommit.
+D 2012-07-18T11:28:51.265
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 8f6d858bf3df9978ba43df19985146a1173025e4
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c 0ce67958cf9cd68330c9c77d78dae275c867418e
-F src/malloc.c e80dccc5d2be2fc0335fb6f430247460e4211388
+F src/malloc.c 1deb02c01b234aae858fc370138af9bf94d99112
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
-F src/mem1.c bc33172c15cbd3d15f0e962311da955c8aba1295
+F src/mem1.c 5ac4fb90adf0aa2beb912abafc67100a6ce126dc
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534
F src/mem5.c c2c63b7067570b00bf33d751c39af24182316f7f
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P e4163596339c2166f9c4356ab824fff8bda8d0b0
-R 884dbf95b40a83feea70896cc9aa3953
-T *branch * calloc
-T *sym-calloc *
-T -sym-trunk *
+P 8752237d123240b330baa461f855dbc01ffcab5b
+R 83cf777410c006c6e09638632424df66
U dan
-Z a86d2e070abe26c339e2a7663eba53d5
+Z 7172e94ea9d607acb82697b15b0d80b0
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
*/
-static int mallocWithAlarm(
+static void *mallocWithAlarm(
void *(*xAlloc)(int), /* Memory allocation function */
- int n, /* Bytes of memory to allocate */
- void **pp /* OUT: Pointer to allocation */
+ int n /* Bytes of memory to allocate */
){
int nFull;
void *p;
sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
}
- *pp = p;
- return nFull;
+
+ return p;
}
/*
p = 0;
}else if( sqlite3GlobalConfig.bMemstat ){
sqlite3_mutex_enter(mem0.mutex);
- mallocWithAlarm(xAlloc, n, &p);
+ p = mallocWithAlarm(xAlloc, n);
sqlite3_mutex_leave(mem0.mutex);
}else{
p = xAlloc(n);
}else{
if( sqlite3GlobalConfig.bMemstat ){
sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
- n = mallocWithAlarm(sqlite3GlobalConfig.m.xMalloc, n, &p);
- if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
+ p = mallocWithAlarm(sqlite3GlobalConfig.m.xMalloc, n);
+ if( p ){
+ n = sqlite3MallocSize(p);
+ sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
+ }
sqlite3_mutex_leave(mem0.mutex);
}else{
sqlite3_mutex_leave(mem0.mutex);
}
/*
-** Allocate and, if bZero is true, zero memory. If the allocation
-** fails, set the mallocFailed flag in the connection pointer.
-**
-** If db!=0 and db->mallocFailed is true (indicating a prior malloc
-** failure on the same database connection) then always return 0.
-** Hence for a particular database connection, once malloc starts
-** failing, it fails consistently until mallocFailed is reset.
-** This is an important assumption. There are many places in the
-** code that do things like this:
-**
-** int *a = (int*)sqlite3DbMallocRaw(db, 100);
-** int *b = (int*)sqlite3DbMallocRaw(db, 200);
-** if( b ) a[10] = 9;
-**
-** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
-** that all prior mallocs (ex: "a") worked too.
+** Attempt to allocate an n byte block from the lookaside buffer of
+** connection db. If successful, return a pointer to the new allocation.
+** Otherwise, return a NULL pointer.
*/
-static void *dbMalloc(sqlite3 *db, int n, int bZero){
- void *p;
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- assert( db==0 || db->pnBytesFreed==0 );
#ifndef SQLITE_OMIT_LOOKASIDE
- if( db ){
- LookasideSlot *pBuf;
- if( db->mallocFailed ){
- return 0;
- }
- if( db->lookaside.bEnabled ){
- if( n>db->lookaside.sz ){
- db->lookaside.anStat[1]++;
- }else if( (pBuf = db->lookaside.pFree)==0 ){
+static void *lookasideAlloc(sqlite3 *db, int n){
+ if( db->lookaside.bEnabled ){
+ if( n>db->lookaside.sz ){
+ db->lookaside.anStat[1]++;
+ }else{
+ LookasideSlot *pBuf;
+ if( (pBuf = db->lookaside.pFree)==0 ){
db->lookaside.anStat[2]++;
}else{
db->lookaside.pFree = pBuf->pNext;
if( db->lookaside.nOut>db->lookaside.mxOut ){
db->lookaside.mxOut = db->lookaside.nOut;
}
- if( bZero ) memset(pBuf, 0, n);
- return (void*)pBuf;
}
+ return (void*)pBuf;
}
}
+ return 0;
+}
#else
- if( db && db->mallocFailed ){
- return 0;
- }
+# define lookasideAlloc(x,y) 0
#endif
- if( bZero ){
- p = sqlite3MallocZero(n);
- }else{
- p = sqlite3Malloc(n);
- }
- if( !p && db ){
- db->mallocFailed = 1;
- }
- sqlite3MemdebugSetType(p, MEMTYPE_DB |
- ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
- return p;
-}
/*
** Allocate and zero memory. If the allocation fails, set the
** mallocFailed flag in the connection pointer.
+**
+** If db!=0 and db->mallocFailed is true (indicating a prior malloc
+** failure on the same database connection) then always return 0.
+** Hence for a particular database connection, once malloc starts
+** failing, it fails consistently until mallocFailed is reset.
+** This is an important assumption. There are many places in the
+** code that do things like this:
+**
+** int *a = (int*)sqlite3DbMallocRaw(db, 100);
+** int *b = (int*)sqlite3DbMallocRaw(db, 200);
+** if( b ) a[10] = 9;
+**
+** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
+** that all prior mallocs (ex: "a") worked too.
*/
void *sqlite3DbMallocZero(sqlite3 *db, int n){
- return dbMalloc(db, n, 1);
+ void *p;
+ if( db==0 ){
+ p = memAllocate(sqlite3GlobalConfig.m.xCalloc, n);
+ }else if( db->mallocFailed ){
+ p = 0;
+ }else{
+ if( (p = lookasideAlloc(db, n)) ){
+ memset(p, 0, n);
+ }else{
+ p = memAllocate(sqlite3GlobalConfig.m.xCalloc, n);
+ if( !p ) db->mallocFailed = 1;
+ }
+ }
+
+ sqlite3MemdebugSetType(p, MEMTYPE_DB |
+ ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+ return p;
}
/*
** Allocate memory. If the allocation fails, make the mallocFailed
** flag in the connection pointer.
+**
+** If db!=0 and db->mallocFailed is true (indicating a prior malloc
+** failure on the same database connection) then always return 0.
+** See also comments above sqlite3DbMallocZero() for details.
*/
void *sqlite3DbMallocRaw(sqlite3 *db, int n){
- return dbMalloc(db, n, 0);
+ void *p;
+ if( db==0 ){
+ p = memAllocate(sqlite3GlobalConfig.m.xMalloc, n);
+ }else if( db->mallocFailed ){
+ p = 0;
+ }else{
+ p = lookasideAlloc(db, n);
+ if( !p ){
+ p = memAllocate(sqlite3GlobalConfig.m.xMalloc, n);
+ if( !p ) db->mallocFailed = 1;
+ }
+ }
+
+ sqlite3MemdebugSetType(p, MEMTYPE_DB |
+ ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+ return p;
}
/*
#endif /* __APPLE__ or not __APPLE__ */
/*
-** Like malloc() (if bZero==0) or calloc() (if bZero!=0), except remember
-** the size of the allocation so that we can find it later using
-** sqlite3MemSize().
+** A memory allocation of nByte bytes has failed. Log an error message
+** using sqlite3_log().
+*/
+static void logAllocationError(int nByte){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
+}
+
+/*
+** Allocate nByte bytes of memory.
**
** For this low-level routine, we are guaranteed that nByte>0 because
** cases of nByte<=0 will be intercepted and dealt with by higher level
** routines.
*/
-static void *memMalloc(int nByte, int bZero){
+static void *sqlite3MemMalloc(int nByte){
+ i64 *p;
#ifdef SQLITE_MALLOCSIZE
- void *p = (bZero ? SQLITE_CALLOC( nByte ) : SQLITE_MALLOC( nByte ));
+ p = SQLITE_MALLOC(nByte);
if( p==0 ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
- }
- return p;
#else
- sqlite3_int64 *p;
- assert( nByte>0 );
nByte = ROUND8(nByte);
- p = (bZero ? SQLITE_CALLOC( nByte+8 ) : SQLITE_MALLOC( nByte+8 ));
+ p = SQLITE_MALLOC(nByte+8);
if( p ){
- p[0] = nByte;
- p++;
+ *(p++) = (i64)nByte;
}else{
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
+#endif
+ logAllocationError(nByte);
}
return (void *)p;
-#endif
}
-static void *sqlite3MemMalloc(int nByte){
- return memMalloc(nByte, 0);
-}
+/*
+** Allocate and zero nByte bytes of memory.
+**
+** For this low-level routine, we are guaranteed that nByte>0 because
+** cases of nByte<=0 will be intercepted and dealt with by higher level
+** routines.
+*/
static void *sqlite3MemCalloc(int nByte){
- return memMalloc(nByte, 1);
+ i64 *p;
+#ifdef SQLITE_MALLOCSIZE
+ p = SQLITE_CALLOC(nByte);
+ if( p==0 ){
+#else
+ nByte = ROUND8(nByte);
+ p = SQLITE_CALLOC(nByte+8);
+ if( p ){
+ *(p++) = (i64)nByte;
+ }else{
+#endif
+ logAllocationError(nByte);
+ }
+ return (void *)p;
}
/*