📄 malloc.c
字号:
mem0.aScratchFree[mem0.nScratchFree++] = i; sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); sqlite3_mutex_leave(mem0.mutex); } }}/*** Allocate memory to be used by the page cache. Make use of the** memory buffer provided by SQLITE_CONFIG_PAGECACHE if there is one** and that memory is of the right size and is not completely** consumed. Otherwise, failover to sqlite3Malloc().*/#if 0void *sqlite3PageMalloc(int n){ void *p; assert( n>0 ); assert( (n & (n-1))==0 ); assert( n>=512 && n<=32768 ); if( sqlite3Config.szPage<n ){ goto page_overflow; }else{ sqlite3_mutex_enter(mem0.mutex); if( mem0.nPageFree==0 ){ sqlite3_mutex_leave(mem0.mutex); goto page_overflow; }else{ int i; i = mem0.aPageFree[--mem0.nPageFree]; sqlite3_mutex_leave(mem0.mutex); i *= sqlite3Config.szPage; sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1); p = (void*)&((char*)sqlite3Config.pPage)[i]; } } return p;page_overflow: if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, n); n = mallocWithAlarm(n, &p); if( p ) sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, n); sqlite3_mutex_leave(mem0.mutex); }else{ p = sqlite3Config.m.xMalloc(n); } return p; }void sqlite3PageFree(void *p){ if( p ){ if( sqlite3Config.pPage==0 || p<sqlite3Config.pPage || p>=(void*)mem0.aPageFree ){ /* In this case, the page allocation was obtained from a regular ** call to sqlite3_mem_methods.xMalloc() (a page-cache-memory ** "overflow"). Free the block with sqlite3_mem_methods.xFree(). */ if( sqlite3Config.bMemstat ){ int iSize = sqlite3MallocSize(p); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize); sqlite3Config.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3Config.m.xFree(p); } }else{ /* The page allocation was allocated from the sqlite3Config.pPage ** buffer. In this case all that is add the index of the page in ** the sqlite3Config.pPage array to the set of free indexes stored ** in the mem0.aPageFree[] array. */ int i; i = (u8 *)p - (u8 *)sqlite3Config.pPage; i /= sqlite3Config.szPage; assert( i>=0 && i<sqlite3Config.nPage ); sqlite3_mutex_enter(mem0.mutex); assert( mem0.nPageFree<sqlite3Config.nPage ); mem0.aPageFree[mem0.nPageFree++] = i; sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1); sqlite3_mutex_leave(mem0.mutex);#if !defined(NDEBUG) && 0 /* Assert that a duplicate was not just inserted into aPageFree[]. */ for(i=0; i<mem0.nPageFree-1; i++){ assert( mem0.aPageFree[i]!=mem0.aPageFree[mem0.nPageFree-1] ); }#endif } }}#endif/*** TRUE if p is a lookaside memory allocation from db*/static int isLookaside(sqlite3 *db, void *p){ return db && p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;}/*** Return the size of a memory allocation previously obtained from** sqlite3Malloc() or sqlite3_malloc().*/int sqlite3MallocSize(void *p){ return sqlite3Config.m.xSize(p);}int sqlite3DbMallocSize(sqlite3 *db, void *p){ if( isLookaside(db, p) ){ return db->lookaside.sz; }else{ return sqlite3Config.m.xSize(p); }}/*** Free memory previously obtained from sqlite3Malloc().*/void sqlite3_free(void *p){ if( p==0 ) return; if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); sqlite3Config.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ sqlite3Config.m.xFree(p); }}/*** Free memory that might be associated with a particular database** connection.*/void sqlite3DbFree(sqlite3 *db, void *p){ if( isLookaside(db, p) ){ LookasideSlot *pBuf = (LookasideSlot*)p; pBuf->pNext = db->lookaside.pFree; db->lookaside.pFree = pBuf; db->lookaside.nOut--; }else{ sqlite3_free(p); }}/*** Change the size of an existing memory allocation*/void *sqlite3Realloc(void *pOld, int nBytes){ int nOld, nNew; void *pNew; if( pOld==0 ){ return sqlite3Malloc(nBytes); } if( nBytes<=0 ){ sqlite3_free(pOld); return 0; } nOld = sqlite3MallocSize(pOld); if( sqlite3Config.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); nNew = sqlite3Config.m.xRoundup(nBytes); if( nOld==nNew ){ pNew = pOld; }else{ if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } pNew = sqlite3Config.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nBytes); pNew = sqlite3Config.m.xRealloc(pOld, nNew); } if( pNew ){ nNew = sqlite3MallocSize(pNew); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } } sqlite3_mutex_leave(mem0.mutex); }else{ pNew = sqlite3Config.m.xRealloc(pOld, nBytes); } return pNew;}/*** The public interface to sqlite3Realloc. Make sure that the memory** subsystem is initialized prior to invoking sqliteRealloc.*/void *sqlite3_realloc(void *pOld, int n){#ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0;#endif return sqlite3Realloc(pOld, n);}/*** Allocate and zero memory.*/ void *sqlite3MallocZero(int n){ void *p = sqlite3Malloc(n); if( p ){ memset(p, 0, n); } return p;}/*** Allocate and zero memory. If the allocation fails, make** the mallocFailed flag in the connection pointer.*/void *sqlite3DbMallocZero(sqlite3 *db, int n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ memset(p, 0, n); } return p;}/*** Allocate and zero memory. If the allocation fails, make** the mallocFailed flag in the connection pointer.*/void *sqlite3DbMallocRaw(sqlite3 *db, int n){ void *p; if( db ){ LookasideSlot *pBuf; if( db->mallocFailed ){ return 0; } if( db->lookaside.bEnabled && n<=db->lookaside.sz && (pBuf = db->lookaside.pFree)!=0 ){ db->lookaside.pFree = pBuf->pNext; db->lookaside.nOut++; if( db->lookaside.nOut>db->lookaside.mxOut ){ db->lookaside.mxOut = db->lookaside.nOut; } return (void*)pBuf; } } p = sqlite3Malloc(n); if( !p && db ){ db->mallocFailed = 1; } return p;}/*** Resize the block of memory pointed to by p to n bytes. If the** resize fails, set the mallocFailed flag in the connection object.*/void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ void *pNew = 0; if( db->mallocFailed==0 ){ if( p==0 ){ return sqlite3DbMallocRaw(db, n); } if( isLookaside(db, p) ){ if( n<=db->lookaside.sz ){ return p; } pNew = sqlite3DbMallocRaw(db, n); if( pNew ){ memcpy(pNew, p, db->lookaside.sz); sqlite3DbFree(db, p); } }else{ pNew = sqlite3_realloc(p, n); if( !pNew ){ db->mallocFailed = 1; } } } return pNew;}/*** Attempt to reallocate p. If the reallocation fails, then free p** and set the mallocFailed flag in the database connection.*/void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ void *pNew; pNew = sqlite3DbRealloc(db, p, n); if( !pNew ){ sqlite3DbFree(db, p); } return pNew;}/*** Make a copy of a string in memory obtained from sqliteMalloc(). These ** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This** is because when memory debugging is turned on, these two functions are ** called via macros that record the current file and line number in the** ThreadData structure.*/char *sqlite3DbStrDup(sqlite3 *db, const char *z){ char *zNew; size_t n; if( z==0 ){ return 0; } n = strlen(z)+1; assert( (n&0x7fffffff)==n ); zNew = sqlite3DbMallocRaw(db, (int)n); if( zNew ){ memcpy(zNew, z, n); } return zNew;}char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){ char *zNew; if( z==0 ){ return 0; } assert( (n&0x7fffffff)==n ); zNew = sqlite3DbMallocRaw(db, n+1); if( zNew ){ memcpy(zNew, z, n); zNew[n] = 0; } return zNew;}/*** Create a string from the zFromat argument and the va_list that follows.** Store the string in memory obtained from sqliteMalloc() and make *pz** point to that string.*/void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){ va_list ap; char *z; va_start(ap, zFormat); z = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); sqlite3DbFree(db, *pz); *pz = z;}/*** This function must be called before exiting any API function (i.e. ** returning control to the user) that has called sqlite3_malloc or** sqlite3_realloc.**** The returned value is normally a copy of the second argument to this** function. However, if a malloc() failure has occured since the previous** invocation SQLITE_NOMEM is returned instead. **** If the first argument, db, is not NULL and a malloc() error has occured,** then the connection error-code (the value returned by sqlite3_errcode())** is set to SQLITE_NOMEM.*/int sqlite3ApiExit(sqlite3* db, int rc){ /* If the db handle is not NULL, then we must hold the connection handle ** mutex here. Otherwise the read (and possible write) of db->mallocFailed ** is unsafe, as is the call to sqlite3Error(). */ assert( !db || sqlite3_mutex_held(db->mutex) ); if( db && db->mallocFailed ){ sqlite3Error(db, SQLITE_NOMEM, 0); db->mallocFailed = 0; rc = SQLITE_NOMEM; } return rc & (db ? db->errMask : 0xff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -