Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixes to prior checkins so that they compile and run even if SQLITE_MEMDEBUG is not defined. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | malloc-enhancement |
Files: | files | file ages | folders |
SHA1: |
548bf3f7d7b962d3eb0f5c874ecf40a8 |
User & Date: | drh 2010-07-25 02:39:07.000 |
Original Comment: | Fixes to prior checkins so that they compile and run even if SQLITE_MEMDEBUG is not defined. |
Context
2010-07-25
| ||
02:39 | Fixes to prior checkins so that they compile and run even if SQLITE_MEMDEBUG is not defined. (Closed-Leaf check-in: 548bf3f7d7 user: drh tags: malloc-enhancement) | |
02:12 | Further examples of using automatic deallocation to replace "delete" methods. (check-in: da2f62c502 user: drh tags: malloc-enhancement) | |
Changes
Changes to src/malloc.c.
︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 | ** Macros for querying and setting debugging fields of the EMemHdr object. */ #ifdef SQLITE_MEMDEBUG # define isValidEMem(E) ((E)->iEMemMagic==0xc0a43fad) # define setValidEMem(E) (E)->iEMemMagic = 0xc0a43fad # define clearValidEMem(E) (E)->iEMemMagic = 0x12345678 # define isChildEMem(E) ((E)->isAChild!=0) # define setChildEMem(E) (E)->isAChild = 1 # define clearChildEMem(E) (E)->isAChild = 0 #else | > | | > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | ** Macros for querying and setting debugging fields of the EMemHdr object. */ #ifdef SQLITE_MEMDEBUG # define isValidEMem(E) ((E)->iEMemMagic==0xc0a43fad) # define setValidEMem(E) (E)->iEMemMagic = 0xc0a43fad # define clearValidEMem(E) (E)->iEMemMagic = 0x12345678 # define isChildEMem(E) ((E)->isAChild!=0) # define notChildEMem(E) ((E)->isAChild==0) # define setChildEMem(E) (E)->isAChild = 1 # define clearChildEMem(E) (E)->isAChild = 0 #else # define isValidEMem(E) 1 # define setValidEMem(E) # define clearValidEMem(E) # define isChildEMem(E) 1 # define notChildEMem(E) 1 # define setChildEMem(E) # define clearChildEMem(E) #endif /* ** This routine runs when the memory allocator sees that the ** total memory allocation is about to exceed the soft heap |
︙ | ︙ | |||
446 447 448 449 450 451 452 | } void sqlite3ScratchFree(void *p){ if( p ){ if( sqlite3GlobalConfig.pScratch==0 || p<sqlite3GlobalConfig.pScratch || p>=(void*)mem0.aScratchFree ){ assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); | | | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | } void sqlite3ScratchFree(void *p){ if( p ){ if( sqlite3GlobalConfig.pScratch==0 || p<sqlite3GlobalConfig.pScratch || p>=(void*)mem0.aScratchFree ){ assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); if( sqlite3GlobalConfig.bMemstat ){ int iSize = sqlite3MallocSize(p); sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize); sqlite3GlobalConfig.m.xFree(p); |
︙ | ︙ | |||
502 503 504 505 506 507 508 | ** sqlite3Malloc() or sqlite3_malloc(). ** ** The size returned is the usable size and does not include any ** bookkeeping overhead or sentinals at the end of the allocation. */ int sqlite3MallocSize(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); | | | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | ** sqlite3Malloc() or sqlite3_malloc(). ** ** The size returned is the usable size and does not include any ** bookkeeping overhead or sentinals at the end of the allocation. */ int sqlite3MallocSize(void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(p, MEMTYPE_RECURSIVE) ); return sqlite3GlobalConfig.m.xSize(p); } int sqlite3DbMallocSize(sqlite3 *db, void *pObj){ EMemHdr *p = (EMemHdr*)pObj; assert( db==0 || sqlite3_mutex_held(db->mutex) ); if( p ){ p--; |
︙ | ︙ | |||
527 528 529 530 531 532 533 | } /* ** Free memory previously obtained from sqlite3Malloc(). */ void sqlite3_free(void *p){ if( p==0 ) return; | | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 | } /* ** Free memory previously obtained from sqlite3Malloc(). */ void sqlite3_free(void *p){ if( p==0 ) return; assert( sqlite3MemdebugNoType(p, MEMTYPE_RECURSIVE) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p)); sqlite3GlobalConfig.m.xFree(p); sqlite3_mutex_leave(mem0.mutex); }else{ |
︙ | ︙ | |||
551 552 553 554 555 556 557 | ** allowed to delete a child allocation since that would leave a ** dangling child pointer in the parent. */ void sqlite3DbFree(sqlite3 *db, void *pObj){ EMemHdr *p = (EMemHdr*)pObj; assert( db==0 || sqlite3_mutex_held(db->mutex) ); if( p ) p--; | | | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 | ** allowed to delete a child allocation since that would leave a ** dangling child pointer in the parent. */ void sqlite3DbFree(sqlite3 *db, void *pObj){ EMemHdr *p = (EMemHdr*)pObj; assert( db==0 || sqlite3_mutex_held(db->mutex) ); if( p ) p--; assert( p==0 || notChildEMem(p) ); /* pObj is not child allocation */ while( p ){ EMemHdr *pNext = p->pESibling; assert( isValidEMem(p) ); /* pObj and all siblings are valid */ if( p->pEChild ){ clearChildEMem(p->pEChild); sqlite3DbFree(db, (void*)&p->pEChild[1]); } |
︙ | ︙ | |||
609 610 611 612 613 614 615 | sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= mem0.alarmThreshold ){ sqlite3MallocAlarm(nNew-nOld); } assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ sqlite3MallocAlarm(nBytes); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } if( pNew ){ nNew = sqlite3MallocSize(pNew); |
︙ | ︙ | |||
765 766 767 768 769 770 771 | assert( sqlite3_mutex_held(db->mutex) ); if( db->mallocFailed==0 ){ if( p==0 ){ return sqlite3DbMallocRaw(db, n); } p--; assert( isValidEMem(p) ); /* pOld obtained from extended allocator */ | | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 | assert( sqlite3_mutex_held(db->mutex) ); if( db->mallocFailed==0 ){ if( p==0 ){ return sqlite3DbMallocRaw(db, n); } p--; assert( isValidEMem(p) ); /* pOld obtained from extended allocator */ assert( notChildEMem(p) ); /* pOld must not be a child allocation */ if( isLookaside(db, p) ){ if( n+sizeof(EMemHdr)<=db->lookaside.sz ){ return pOld; } pNew = sqlite3DbMallocRaw(db, n); if( pNew ){ memcpy(pNew-1, p, db->lookaside.sz); |
︙ | ︙ | |||
855 856 857 858 859 860 861 | EMemHdr *pParent = (EMemHdr*)pParentObj; EMemHdr *pChild = (EMemHdr*)pChildObj; if( pParent && pChild ){ pParent--; assert( isValidEMem(pParent) ); /* pParentObj is an extended allocation */ pChild--; assert( isValidEMem(pChild) ); /* pChildObj is an extended allocation */ | | | 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | EMemHdr *pParent = (EMemHdr*)pParentObj; EMemHdr *pChild = (EMemHdr*)pChildObj; if( pParent && pChild ){ pParent--; assert( isValidEMem(pParent) ); /* pParentObj is an extended allocation */ pChild--; assert( isValidEMem(pChild) ); /* pChildObj is an extended allocation */ assert( notChildEMem(pChild) ); /* pChildObj not a child of another obj */ pChild->pESibling = pParent->pEChild; pParent->pEChild = pChild; setChildEMem(pChild); } } /* |
︙ | ︙ |
Changes to src/mem2.c.
︙ | ︙ | |||
404 405 406 407 408 409 410 411 412 413 414 415 416 417 | if( (pHdr->eType&eType)==0 ){ rc = 0; } } return rc; } /* ** Set the number of backtrace levels kept for each allocation. ** A value of zero turns off backtracing. The number is always rounded ** up to a multiple of 2. */ void sqlite3MemdebugBacktrace(int depth){ | > > > > > > > > > > > > > > > > > > > > > | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | if( (pHdr->eType&eType)==0 ){ rc = 0; } } return rc; } /* ** Return TRUE if the mask of type in eType matches no bits of the type of the ** allocation p. Also return true if p==NULL. ** ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** ** assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) ); */ int sqlite3MemdebugNoType(void *p, u8 eType){ int rc = 1; if( p ){ struct MemBlockHdr *pHdr; pHdr = sqlite3MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ if( (pHdr->eType&eType)!=0 ){ rc = 0; } } return rc; } /* ** Set the number of backtrace levels kept for each allocation. ** A value of zero turns off backtracing. The number is always rounded ** up to a multiple of 2. */ void sqlite3MemdebugBacktrace(int depth){ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 | ** sqlite3MemdebugSetType() sets the "type" of an allocation to one of ** the MEMTYPE_* macros defined below. The type must be a bitmask with ** a single bit set. ** ** sqlite3MemdebugHasType() returns true if any of the bits in its second ** argument match the type set by the previous sqlite3MemdebugSetType(). ** sqlite3MemdebugHasType() is intended for use inside assert() statements. ** For example: ** ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); ** ** Perhaps the most important point is the difference between MEMTYPE_HEAP ** and MEMTYPE_DB. If an allocation is MEMTYPE_DB, that means it might have ** been allocated by lookaside, except the allocation was too large or ** lookaside was already full. It is important to verify that allocations ** that might have been satisfied by lookaside are not passed back to ** non-lookaside free() routines. Asserts such as the example above are ** placed on the non-lookaside free() routines to verify this constraint. ** ** All of this is no-op for a production build. It only comes into ** play when the SQLITE_MEMDEBUG compile-time option is used. */ #ifdef SQLITE_MEMDEBUG void sqlite3MemdebugSetType(void*,u8); int sqlite3MemdebugHasType(void*,u8); #else # define sqlite3MemdebugSetType(X,Y) /* no-op */ # define sqlite3MemdebugHasType(X,Y) 1 #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_DB 0x02 /* Associated with a database connection */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ #define MEMTYPE_RECURSIVE 0x10 /* Experimental */ #endif /* _SQLITEINT_H_ */ | > > > > > > | 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 | ** sqlite3MemdebugSetType() sets the "type" of an allocation to one of ** the MEMTYPE_* macros defined below. The type must be a bitmask with ** a single bit set. ** ** sqlite3MemdebugHasType() returns true if any of the bits in its second ** argument match the type set by the previous sqlite3MemdebugSetType(). ** sqlite3MemdebugHasType() is intended for use inside assert() statements. ** ** sqlite3MemdebugNoType() returns true if none of the bits in its second ** argument match the type set by the previous sqlite3MemdebugSetType(). ** ** For example: ** ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); ** ** Perhaps the most important point is the difference between MEMTYPE_HEAP ** and MEMTYPE_DB. If an allocation is MEMTYPE_DB, that means it might have ** been allocated by lookaside, except the allocation was too large or ** lookaside was already full. It is important to verify that allocations ** that might have been satisfied by lookaside are not passed back to ** non-lookaside free() routines. Asserts such as the example above are ** placed on the non-lookaside free() routines to verify this constraint. ** ** All of this is no-op for a production build. It only comes into ** play when the SQLITE_MEMDEBUG compile-time option is used. */ #ifdef SQLITE_MEMDEBUG void sqlite3MemdebugSetType(void*,u8); int sqlite3MemdebugHasType(void*,u8); int sqlite3MemdebugNoType(void*,u8); #else # define sqlite3MemdebugSetType(X,Y) /* no-op */ # define sqlite3MemdebugHasType(X,Y) 1 # define sqlite3MemdebugNoType(X,Y) 1 #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_DB 0x02 /* Associated with a database connection */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ #define MEMTYPE_RECURSIVE 0x10 /* Experimental */ #endif /* _SQLITEINT_H_ */ |