SQLite

Check-in [0a33444105]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further tweaks to malloc paths.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | calloc
Files: files | file ages | folders
SHA1: 0a33444105e29d79475e267021d33c1a006b85a3
User & Date: dan 2012-07-19 20:27:14.139
Context
2012-07-19
20:27
Further tweaks to malloc paths. (Closed-Leaf check-in: 0a33444105 user: dan tags: calloc)
2012-07-18
16:07
Remove another branch from the DbMalloc() paths. (check-in: defd828e90 user: dan tags: calloc)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/malloc.c.
259
260
261
262
263
264
265

266
267
268
269
270
271
272




273

274
275
276

277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294



295
296
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323



324





325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
** 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 
  );




  nFull = sqlite3GlobalConfig.m.xRoundup(n);

  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
  if( mem0.alarmCallback!=0 ){
    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);

    if( nUsed >= mem0.alarmThreshold - nFull ){
      mem0.nearlyFull = 1;
      sqlite3MallocAlarm(nFull);
    }else{
      mem0.nearlyFull = 0;
    }
  }

  p = xAlloc(nFull);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  if( p==0 && mem0.alarmCallback ){
    sqlite3MallocAlarm(nFull);
    p = xAlloc(nFull);
  }
#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 */
  int n                           /* Bytes of space to allocate */
){
  void *p;
  if( n<=0               /* IMP: R-65312-04917 */ 
   || n>=0x7fffff00
  ){
    /* A memory allocation of a number of bytes which is near the maximum
    ** 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;
}


/*
** Allocate memory.  This routine is like sqlite3_malloc() except that it
** assumes the memory subsystem has already been initialized.
*/
void *sqlite3Malloc(int n){
  return memAllocate(sqlite3GlobalConfig.m.xMalloc, n);
}

/*
** Allocate and zero memory.
*/ 
void *sqlite3MallocZero(int n){
  return memAllocate(sqlite3GlobalConfig.m.xCalloc, n);
}

/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/







>
|
<





>
>
>
>
|
>

|

>







>
|







<
|

>
>
>









>













>
|
|
|
|
|
|
|
>
>
>

>
>
>
>
>









|






|







259
260
261
262
263
264
265
266
267

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
** 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 */
){
  void *p;                       /* Pointer to allocated memory */
  int nFull;                     /* Value returned by xRoundup (if required) */


  assert( sqlite3_mutex_held(mem0.mutex) );
  assert( xAlloc==sqlite3GlobalConfig.m.xMalloc 
       || xAlloc==sqlite3GlobalConfig.m.xCalloc 
  );

  /* Note: At one point this function would call xRoundup() and use the
  ** resulting value as the argument to xAlloc(). However, this is not
  ** required. And it is a (small) drag on performance.  */
  /* nFull = sqlite3GlobalConfig.m.xRoundup(n); */

  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
  if( mem0.alarmCallback ){
    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
    nFull = sqlite3GlobalConfig.m.xRoundup(n);
    if( nUsed >= mem0.alarmThreshold - nFull ){
      mem0.nearlyFull = 1;
      sqlite3MallocAlarm(nFull);
    }else{
      mem0.nearlyFull = 0;
    }
  }

  p = xAlloc(n);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  if( p==0 && mem0.alarmCallback ){
    sqlite3MallocAlarm(nFull);
    p = xAlloc(nFull);
  }
#endif
  if( p ){

    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
  }else{
    testcase( sqlite3GlobalConfig.xLog!=0 );
    sqlite3_log(SQLITE_NOMEM, "failed to allocate %d bytes of memory", n);
  }

  return p;
}

/*
** Use allocator function xAlloc to allocate n bytes of memory.
*/
static void *memAllocate(
  sqlite3 *db,
  void *(*xAlloc)(int),           /* Memory allocation function */
  int n                           /* Bytes of space to allocate */
){
  void *p;
  if( n<=0               /* IMP: R-65312-04917 */ 
   || n>=0x7fffff00
  ){
    /* A memory allocation of a number of bytes which is near the maximum
    ** 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);
    }
    if( !p && db ) db->mallocFailed = 1;
  }

  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
  if( db ){
    sqlite3MemdebugSetType(p, MEMTYPE_DB | 
        ((db && db->lookaside.sz) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)
    );
  }
  return p;
}


/*
** Allocate memory.  This routine is like sqlite3_malloc() except that it
** assumes the memory subsystem has already been initialized.
*/
void *sqlite3Malloc(int n){
  return memAllocate(0, sqlite3GlobalConfig.m.xMalloc, n);
}

/*
** Allocate and zero memory.
*/ 
void *sqlite3MallocZero(int n){
  return memAllocate(0, sqlite3GlobalConfig.m.xCalloc, n);
}

/*
** This version of the memory allocation is for use by the application.
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
618
619
620
621
622
623
624

625
626
627
628
629
630
631
      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







>







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
      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;
      }
    }
    sqlite3MemdebugSetType((void *)pBuf, MEMTYPE_DB | MEMTYPE_LOOKASIDE);
    return (void*)pBuf;
  }
  return 0;
}
#else
# define lookasideAlloc(x,y) 0
#endif
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
702
**         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.sz) ? 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.sz) ? 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){







|
<
|
<
<


|
<
<



<
<
|












|
<
|
<
<
|
|
<
<



<
<
|







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
702
703
704
705
706
707
708
**         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 ){

    if( db->mallocFailed ) return 0;


    if( (p = lookasideAlloc(db, n)) ){
      memset(p, 0, n);
      return p;


    }
  }



  return memAllocate(db, sqlite3GlobalConfig.m.xCalloc, n);
}

/*
** 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 ){

    if( db->mallocFailed ) return 0;


    if( (p = lookasideAlloc(db, n)) ){
      return p;


    }
  }



  return memAllocate(db, sqlite3GlobalConfig.m.xMalloc, n);
}

/*
** 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.
97
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
# endif
#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







<
<
<
<
<
<
<
<
<








<

|
<

>


<
|
<
<
<
<

>










<

|
<

>


<
|
<
<
<
<

>







97
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
# endif
#else
# undef SQLITE_MALLOCSIZE
#endif

#endif /* __APPLE__ or not __APPLE__ */










/*
** 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){

#ifdef SQLITE_MALLOCSIZE
  return SQLITE_MALLOC( ROUND8(nByte) );

#else
  i64 *p;
  nByte = ROUND8(nByte);
  p = SQLITE_MALLOC(nByte+8);

  if( p ) *(p++) = (i64)nByte;




  return (void *)p;
#endif
}

/*
** 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){

#ifdef SQLITE_MALLOCSIZE
  return SQLITE_CALLOC( ROUND8(nByte) );

#else
  i64 *p;
  nByte = ROUND8(nByte);
  p = SQLITE_CALLOC(nByte+8);

  if( p ) *(p++) = (i64)nByte;




  return (void *)p;
#endif
}

/*
** Like free() but works for allocations obtained from sqlite3MemMalloc()
** or sqlite3MemRealloc().
**
** For this low-level routine, we already know that pPrior!=0 since
297
298
299
300
301
302
303
304
305
306
307
     sqlite3MemSize,
     sqlite3MemRoundup,
     sqlite3MemInit,
     sqlite3MemShutdown,
     0,
     sqlite3MemCalloc
  };
  sqlite3_config(SQLITE_CONFIG_MALLOC2, &defaultMethods);
}

#endif /* SQLITE_SYSTEM_MALLOC */







|



278
279
280
281
282
283
284
285
286
287
288
     sqlite3MemSize,
     sqlite3MemRoundup,
     sqlite3MemInit,
     sqlite3MemShutdown,
     0,
     sqlite3MemCalloc
  };
  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
}

#endif /* SQLITE_SYSTEM_MALLOC */