Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Reorganize code to remove a few of the branches introduced into the critical sqlite3DbMallocXXX() path by the previous commit. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | calloc |
Files: | files | file ages | folders |
SHA1: |
75c095ee463c0c76e9637edccd33e807 |
User & Date: | dan 2012-07-18 11:28:51.265 |
Context
2012-07-18
| ||
16:07 | Remove another branch from the DbMalloc() paths. (check-in: defd828e90 user: dan tags: calloc) | |
11:28 | Reorganize code to remove a few of the branches introduced into the critical sqlite3DbMallocXXX() path by the previous commit. (check-in: 75c095ee46 user: dan tags: calloc) | |
2012-07-17
| ||
19:32 | Enhance the custom memory allocation interface to allow the user to specify a calloc() function. (check-in: 8752237d12 user: dan tags: calloc) | |
Changes
Changes to src/malloc.c.
︙ | ︙ | |||
255 256 257 258 259 260 261 | mem0.alarmArg = pArg; } /* ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. */ | | | < | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | mem0.alarmArg = pArg; } /* ** Do a memory allocation with statistics and alarms. Assume the ** lock is already held. */ static void *mallocWithAlarm( void *(*xAlloc)(int), /* Memory allocation function */ int n /* Bytes of memory to allocate */ ){ int nFull; void *p; assert( sqlite3_mutex_held(mem0.mutex) ); assert( xAlloc==sqlite3GlobalConfig.m.xMalloc || xAlloc==sqlite3GlobalConfig.m.xCalloc |
︙ | ︙ | |||
290 291 292 293 294 295 296 | } #endif if( p ){ nFull = sqlite3MallocSize(p); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1); } | | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | } #endif if( p ){ nFull = sqlite3MallocSize(p); sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull); sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1); } return p; } /* ** Use allocator function xAlloc to allocate n bytes of memory. */ static void *memAllocate( void *(*xAlloc)(int), /* Memory allocation function */ |
︙ | ︙ | |||
313 314 315 316 317 318 319 | ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving ** 255 bytes of overhead. SQLite itself will never use anything near ** this amount. The only way to reach the limit is with sqlite3_malloc() */ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving ** 255 bytes of overhead. SQLite itself will never use anything near ** this amount. The only way to reach the limit is with sqlite3_malloc() */ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); p = mallocWithAlarm(xAlloc, n); sqlite3_mutex_leave(mem0.mutex); }else{ p = xAlloc(n); } assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */ return p; } |
︙ | ︙ | |||
384 385 386 387 388 389 390 | mem0.nScratchFree--; sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); sqlite3_mutex_leave(mem0.mutex); }else{ if( sqlite3GlobalConfig.bMemstat ){ sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); | | > > | > | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | mem0.nScratchFree--; sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1); sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n); sqlite3_mutex_leave(mem0.mutex); }else{ if( sqlite3GlobalConfig.bMemstat ){ sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, 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); p = sqlite3GlobalConfig.m.xMalloc(n); } sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); } |
︙ | ︙ | |||
593 594 595 596 597 598 599 | #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return sqlite3Realloc(pOld, n); } /* | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < < | < > | | < < < < < < | < | < < < < | < < < < | > | < | < < < < < < < | < < < < < < < < > > > > > > > > > > > > > > > > > > > | | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 | #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return sqlite3Realloc(pOld, n); } /* ** 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. */ #ifndef SQLITE_OMIT_LOOKASIDE 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; db->lookaside.nOut++; db->lookaside.anStat[0]++; if( db->lookaside.nOut>db->lookaside.mxOut ){ db->lookaside.mxOut = db->lookaside.nOut; } } return (void*)pBuf; } } return 0; } #else # define lookasideAlloc(x,y) 0 #endif /* ** 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){ 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){ 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; } /* ** 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){ |
︙ | ︙ |
Changes to src/mem1.c.
︙ | ︙ | |||
98 99 100 101 102 103 104 | #else # undef SQLITE_MALLOCSIZE #endif #endif /* __APPLE__ or not __APPLE__ */ /* | | > > | > > > | > > | > | < > | > > > > > > | > | > > > > > > > > | > | > > | | < < < < < < | < < | < | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | #else # undef SQLITE_MALLOCSIZE #endif #endif /* __APPLE__ or not __APPLE__ */ /* ** 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 *sqlite3MemMalloc(int nByte){ i64 *p; #ifdef SQLITE_MALLOCSIZE p = SQLITE_MALLOC(nByte); if( p==0 ){ #else nByte = ROUND8(nByte); p = SQLITE_MALLOC(nByte+8); if( p ){ *(p++) = (i64)nByte; }else{ #endif logAllocationError(nByte); } return (void *)p; } /* ** 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){ 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; } /* ** Like free() but works for allocations obtained from sqlite3MemMalloc() ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since |
︙ | ︙ |