AryaWu/sqlite
0
1/*2** 2007 August 143**4** The author disclaims copyright to this source code. In place of5** a legal notice, here is a blessing:6**7** May you do good and not evil.8** May you find forgiveness for yourself and forgive others.9** May you share freely, never taking more than you give.10**11*************************************************************************12**13** This file contains low-level memory allocation drivers for when14** SQLite will use the standard C-library malloc/realloc/free interface15** to obtain the memory it needs.16**17** This file contains implementations of the low-level memory allocation18** routines specified in the sqlite3_mem_methods object. The content of19** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The20** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the21** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The22** default configuration is to use memory allocation routines in this23** file.24**25** C-preprocessor macro summary:26**27** HAVE_MALLOC_USABLE_SIZE The configure script sets this symbol if28** the malloc_usable_size() interface exists29** on the target platform. Or, this symbol30** can be set manually, if desired.31** If an equivalent interface exists by32** a different name, using a separate -D33** option to rename it.34**35** SQLITE_WITHOUT_ZONEMALLOC Some older macs lack support for the zone36** memory allocator. Set this symbol to enable37** building on older macs.38**39** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of40** _msize() on windows systems. This might41** be necessary when compiling for Delphi,42** for example.43*/44#include "sqliteInt.h"45 46/*47** This version of the memory allocator is the default. It is48** used when no other memory allocator is specified using compile-time49** macros.50*/51#ifdef SQLITE_SYSTEM_MALLOC52#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)53 54/*55** Use the zone allocator available on apple products unless the56** SQLITE_WITHOUT_ZONEMALLOC symbol is defined.57*/58#include <sys/sysctl.h>59#include <malloc/malloc.h>60#ifdef SQLITE_MIGHT_BE_SINGLE_CORE61#include <libkern/OSAtomic.h>62#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */63static malloc_zone_t* _sqliteZone_;64#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))65#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));66#define SQLITE_REALLOC(x,y) malloc_zone_realloc(_sqliteZone_, (x), (y))67#define SQLITE_MALLOCSIZE(x) \68 (_sqliteZone_ ? _sqliteZone_->size(_sqliteZone_,x) : malloc_size(x))69 70#else /* if not __APPLE__ */71 72/*73** Use standard C library malloc and free on non-Apple systems. 74** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.75*/76#define SQLITE_MALLOC(x) malloc(x)77#define SQLITE_FREE(x) free(x)78#define SQLITE_REALLOC(x,y) realloc((x),(y))79 80/*81** The malloc.h header file is needed for malloc_usable_size() function82** on some systems (e.g. Linux).83*/84#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE85# define SQLITE_USE_MALLOC_H 186# define SQLITE_USE_MALLOC_USABLE_SIZE 187/*88** The MSVCRT has malloc_usable_size(), but it is called _msize(). The89** use of _msize() is automatic, but can be disabled by compiling with90** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires91** the malloc.h header file.92*/93#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)94# define SQLITE_USE_MALLOC_H95# define SQLITE_USE_MSIZE96#endif97 98/*99** Include the malloc.h header file, if necessary. Also set define macro100** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize()101** for MSVC and malloc_usable_size() for most other systems (e.g. Linux).102** The memory size function can always be overridden manually by defining103** the macro SQLITE_MALLOCSIZE to the desired function name.104*/105#if defined(SQLITE_USE_MALLOC_H)106# include <malloc.h>107# if defined(SQLITE_USE_MALLOC_USABLE_SIZE)108# if !defined(SQLITE_MALLOCSIZE)109# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)110# endif111# elif defined(SQLITE_USE_MSIZE)112# if !defined(SQLITE_MALLOCSIZE)113# define SQLITE_MALLOCSIZE _msize114# endif115# endif116#endif /* defined(SQLITE_USE_MALLOC_H) */117 118#endif /* __APPLE__ or not __APPLE__ */119 120/*121** Like malloc(), but remember the size of the allocation122** so that we can find it later using sqlite3MemSize().123**124** For this low-level routine, we are guaranteed that nByte>0 because125** cases of nByte<=0 will be intercepted and dealt with by higher level126** routines.127*/128static void *sqlite3MemMalloc(int nByte){129#ifdef SQLITE_MALLOCSIZE130 void *p;131 testcase( ROUND8(nByte)==nByte );132 p = SQLITE_MALLOC( nByte );133 if( p==0 ){134 testcase( sqlite3GlobalConfig.xLog!=0 );135 sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);136 }137 return p;138#else139 sqlite3_int64 *p;140 assert( nByte>0 );141 testcase( ROUND8(nByte)!=nByte );142 p = SQLITE_MALLOC( nByte+8 );143 if( p ){144 p[0] = nByte;145 p++;146 }else{147 testcase( sqlite3GlobalConfig.xLog!=0 );148 sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);149 }150 return (void *)p;151#endif152}153 154/*155** Like free() but works for allocations obtained from sqlite3MemMalloc()156** or sqlite3MemRealloc().157**158** For this low-level routine, we already know that pPrior!=0 since159** cases where pPrior==0 will have been intercepted and dealt with160** by higher-level routines.161*/162static void sqlite3MemFree(void *pPrior){163#ifdef SQLITE_MALLOCSIZE164 SQLITE_FREE(pPrior);165#else166 sqlite3_int64 *p = (sqlite3_int64*)pPrior;167 assert( pPrior!=0 );168 p--;169 SQLITE_FREE(p);170#endif171}172 173/*174** Report the allocated size of a prior return from xMalloc()175** or xRealloc().176*/177static int sqlite3MemSize(void *pPrior){178#ifdef SQLITE_MALLOCSIZE179 assert( pPrior!=0 );180 return (int)SQLITE_MALLOCSIZE(pPrior);181#else182 sqlite3_int64 *p;183 assert( pPrior!=0 );184 p = (sqlite3_int64*)pPrior;185 p--;186 return (int)p[0];187#endif188}189 190/*191** Like realloc(). Resize an allocation previously obtained from192** sqlite3MemMalloc().193**194** For this low-level interface, we know that pPrior!=0. Cases where195** pPrior==0 while have been intercepted by higher-level routine and196** redirected to xMalloc. Similarly, we know that nByte>0 because197** cases where nByte<=0 will have been intercepted by higher-level198** routines and redirected to xFree.199*/200static void *sqlite3MemRealloc(void *pPrior, int nByte){201#ifdef SQLITE_MALLOCSIZE202 void *p = SQLITE_REALLOC(pPrior, nByte);203 if( p==0 ){204 testcase( sqlite3GlobalConfig.xLog!=0 );205 sqlite3_log(SQLITE_NOMEM,206 "failed memory resize %u to %u bytes",207 SQLITE_MALLOCSIZE(pPrior), nByte);208 }209 return p;210#else211 sqlite3_int64 *p = (sqlite3_int64*)pPrior;212 assert( pPrior!=0 && nByte>0 );213 assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */214 p--;215 p = SQLITE_REALLOC(p, nByte+8 );216 if( p ){217 p[0] = nByte;218 p++;219 }else{220 testcase( sqlite3GlobalConfig.xLog!=0 );221 sqlite3_log(SQLITE_NOMEM,222 "failed memory resize %u to %u bytes",223 sqlite3MemSize(pPrior), nByte);224 }225 return (void*)p;226#endif227}228 229/*230** Round up a request size to the next valid allocation size.231*/232static int sqlite3MemRoundup(int n){233 return ROUND8(n);234}235 236/*237** Initialize this module.238*/239static int sqlite3MemInit(void *NotUsed){240#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)241 int cpuCount;242 size_t len;243 if( _sqliteZone_ ){244 return SQLITE_OK;245 }246 len = sizeof(cpuCount);247 /* One usually wants to use hw.activecpu for MT decisions, but not here */248 sysctlbyname("hw.ncpu", &cpuCount, &len, NULL, 0);249 if( cpuCount>1 ){250 /* defer MT decisions to system malloc */251 _sqliteZone_ = malloc_default_zone();252 }else{253 /* only 1 core, use our own zone to contention over global locks,254 ** e.g. we have our own dedicated locks */255 _sqliteZone_ = malloc_create_zone(4096, 0);256 malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");257 }258#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */259 UNUSED_PARAMETER(NotUsed);260 return SQLITE_OK;261}262 263/*264** Deinitialize this module.265*/266static void sqlite3MemShutdown(void *NotUsed){267 UNUSED_PARAMETER(NotUsed);268 return;269}270 271/*272** This routine is the only routine in this file with external linkage.273**274** Populate the low-level memory allocation function pointers in275** sqlite3GlobalConfig.m with pointers to the routines in this file.276*/277void sqlite3MemSetDefault(void){278 static const sqlite3_mem_methods defaultMethods = {279 sqlite3MemMalloc,280 sqlite3MemFree,281 sqlite3MemRealloc,282 sqlite3MemSize,283 sqlite3MemRoundup,284 sqlite3MemInit,285 sqlite3MemShutdown,286 0287 };288 sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);289}290 291#endif /* SQLITE_SYSTEM_MALLOC */292 