mem3.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /*
  2. ** 2007 October 14
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** 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. ** This file contains the C functions that implement a memory
  13. ** allocation subsystem for use by SQLite.
  14. **
  15. ** This version of the memory allocation subsystem omits all
  16. ** use of malloc(). All dynamically allocatable memory is
  17. ** contained in a static array, mem.aPool[]. The size of this
  18. ** fixed memory pool is SQLITE_MEMORY_SIZE bytes.
  19. **
  20. ** This version of the memory allocation subsystem is used if
  21. ** and only if SQLITE_MEMORY_SIZE is defined.
  22. **
  23. ** $Id: mem3.c,v 1.7 2007/11/29 18:36:49 drh Exp $
  24. */
  25. /*
  26. ** This version of the memory allocator is used only when
  27. ** SQLITE_MEMORY_SIZE is defined.
  28. */
  29. #if defined(SQLITE_MEMORY_SIZE)
  30. #include "sqliteInt.h"
  31. #ifdef SQLITE_MEMDEBUG
  32. # error cannot define both SQLITE_MEMDEBUG and SQLITE_MEMORY_SIZE
  33. #endif
  34. /*
  35. ** Maximum size (in Mem3Blocks) of a "small" chunk.
  36. */
  37. #define MX_SMALL 10
  38. /*
  39. ** Number of freelist hash slots
  40. */
  41. #define N_HASH 61
  42. /*
  43. ** A memory allocation (also called a "chunk") consists of two or
  44. ** more blocks where each block is 8 bytes. The first 8 bytes are
  45. ** a header that is not returned to the user.
  46. **
  47. ** A chunk is two or more blocks that is either checked out or
  48. ** free. The first block has format u.hdr. u.hdr.size is the
  49. ** size of the allocation in blocks if the allocation is free.
  50. ** If the allocation is checked out, u.hdr.size is the negative
  51. ** of the size. Similarly, u.hdr.prevSize is the size of the
  52. ** immediately previous allocation.
  53. **
  54. ** We often identify a chunk by its index in mem.aPool[]. When
  55. ** this is done, the chunk index refers to the second block of
  56. ** the chunk. In this way, the first chunk has an index of 1.
  57. ** A chunk index of 0 means "no such chunk" and is the equivalent
  58. ** of a NULL pointer.
  59. **
  60. ** The second block of free chunks is of the form u.list. The
  61. ** two fields form a double-linked list of chunks of related sizes.
  62. ** Pointers to the head of the list are stored in mem.aiSmall[]
  63. ** for smaller chunks and mem.aiHash[] for larger chunks.
  64. **
  65. ** The second block of a chunk is user data if the chunk is checked
  66. ** out.
  67. */
  68. typedef struct Mem3Block Mem3Block;
  69. struct Mem3Block {
  70. union {
  71. struct {
  72. int prevSize; /* Size of previous chunk in Mem3Block elements */
  73. int size; /* Size of current chunk in Mem3Block elements */
  74. } hdr;
  75. struct {
  76. int next; /* Index in mem.aPool[] of next free chunk */
  77. int prev; /* Index in mem.aPool[] of previous free chunk */
  78. } list;
  79. } u;
  80. };
  81. /*
  82. ** All of the static variables used by this module are collected
  83. ** into a single structure named "mem". This is to keep the
  84. ** static variables organized and to reduce namespace pollution
  85. ** when this module is combined with other in the amalgamation.
  86. */
  87. static struct {
  88. /*
  89. ** True if we are evaluating an out-of-memory callback.
  90. */
  91. int alarmBusy;
  92. /*
  93. ** Mutex to control access to the memory allocation subsystem.
  94. */
  95. sqlite3_mutex *mutex;
  96. /*
  97. ** The minimum amount of free space that we have seen.
  98. */
  99. int mnMaster;
  100. /*
  101. ** iMaster is the index of the master chunk. Most new allocations
  102. ** occur off of this chunk. szMaster is the size (in Mem3Blocks)
  103. ** of the current master. iMaster is 0 if there is not master chunk.
  104. ** The master chunk is not in either the aiHash[] or aiSmall[].
  105. */
  106. int iMaster;
  107. int szMaster;
  108. /*
  109. ** Array of lists of free blocks according to the block size
  110. ** for smaller chunks, or a hash on the block size for larger
  111. ** chunks.
  112. */
  113. int aiSmall[MX_SMALL-1]; /* For sizes 2 through MX_SMALL, inclusive */
  114. int aiHash[N_HASH]; /* For sizes MX_SMALL+1 and larger */
  115. /*
  116. ** Memory available for allocation
  117. */
  118. Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2];
  119. } mem;
  120. /*
  121. ** Unlink the chunk at mem.aPool[i] from list it is currently
  122. ** on. *pRoot is the list that i is a member of.
  123. */
  124. static void memsys3UnlinkFromList(int i, int *pRoot){
  125. int next = mem.aPool[i].u.list.next;
  126. int prev = mem.aPool[i].u.list.prev;
  127. assert( sqlite3_mutex_held(mem.mutex) );
  128. if( prev==0 ){
  129. *pRoot = next;
  130. }else{
  131. mem.aPool[prev].u.list.next = next;
  132. }
  133. if( next ){
  134. mem.aPool[next].u.list.prev = prev;
  135. }
  136. mem.aPool[i].u.list.next = 0;
  137. mem.aPool[i].u.list.prev = 0;
  138. }
  139. /*
  140. ** Unlink the chunk at index i from
  141. ** whatever list is currently a member of.
  142. */
  143. static void memsys3Unlink(int i){
  144. int size, hash;
  145. assert( sqlite3_mutex_held(mem.mutex) );
  146. size = mem.aPool[i-1].u.hdr.size;
  147. assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
  148. assert( size>=2 );
  149. if( size <= MX_SMALL ){
  150. memsys3UnlinkFromList(i, &mem.aiSmall[size-2]);
  151. }else{
  152. hash = size % N_HASH;
  153. memsys3UnlinkFromList(i, &mem.aiHash[hash]);
  154. }
  155. }
  156. /*
  157. ** Link the chunk at mem.aPool[i] so that is on the list rooted
  158. ** at *pRoot.
  159. */
  160. static void memsys3LinkIntoList(int i, int *pRoot){
  161. assert( sqlite3_mutex_held(mem.mutex) );
  162. mem.aPool[i].u.list.next = *pRoot;
  163. mem.aPool[i].u.list.prev = 0;
  164. if( *pRoot ){
  165. mem.aPool[*pRoot].u.list.prev = i;
  166. }
  167. *pRoot = i;
  168. }
  169. /*
  170. ** Link the chunk at index i into either the appropriate
  171. ** small chunk list, or into the large chunk hash table.
  172. */
  173. static void memsys3Link(int i){
  174. int size, hash;
  175. assert( sqlite3_mutex_held(mem.mutex) );
  176. size = mem.aPool[i-1].u.hdr.size;
  177. assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
  178. assert( size>=2 );
  179. if( size <= MX_SMALL ){
  180. memsys3LinkIntoList(i, &mem.aiSmall[size-2]);
  181. }else{
  182. hash = size % N_HASH;
  183. memsys3LinkIntoList(i, &mem.aiHash[hash]);
  184. }
  185. }
  186. /*
  187. ** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
  188. **
  189. ** Also: Initialize the memory allocation subsystem the first time
  190. ** this routine is called.
  191. */
  192. static void memsys3Enter(void){
  193. if( mem.mutex==0 ){
  194. mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
  195. mem.aPool[0].u.hdr.size = SQLITE_MEMORY_SIZE/8;
  196. mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8;
  197. mem.iMaster = 1;
  198. mem.szMaster = SQLITE_MEMORY_SIZE/8;
  199. mem.mnMaster = mem.szMaster;
  200. }
  201. sqlite3_mutex_enter(mem.mutex);
  202. }
  203. /*
  204. ** Return the amount of memory currently checked out.
  205. */
  206. sqlite3_int64 sqlite3_memory_used(void){
  207. sqlite3_int64 n;
  208. memsys3Enter();
  209. n = SQLITE_MEMORY_SIZE - mem.szMaster*8;
  210. sqlite3_mutex_leave(mem.mutex);
  211. return n;
  212. }
  213. /*
  214. ** Return the maximum amount of memory that has ever been
  215. ** checked out since either the beginning of this process
  216. ** or since the most recent reset.
  217. */
  218. sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
  219. sqlite3_int64 n;
  220. memsys3Enter();
  221. n = SQLITE_MEMORY_SIZE - mem.mnMaster*8;
  222. if( resetFlag ){
  223. mem.mnMaster = mem.szMaster;
  224. }
  225. sqlite3_mutex_leave(mem.mutex);
  226. return n;
  227. }
  228. /*
  229. ** Change the alarm callback.
  230. **
  231. ** This is a no-op for the static memory allocator. The purpose
  232. ** of the memory alarm is to support sqlite3_soft_heap_limit().
  233. ** But with this memory allocator, the soft_heap_limit is really
  234. ** a hard limit that is fixed at SQLITE_MEMORY_SIZE.
  235. */
  236. int sqlite3_memory_alarm(
  237. void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
  238. void *pArg,
  239. sqlite3_int64 iThreshold
  240. ){
  241. return SQLITE_OK;
  242. }
  243. /*
  244. ** Called when we are unable to satisfy an allocation of nBytes.
  245. */
  246. static void memsys3OutOfMemory(int nByte){
  247. if( !mem.alarmBusy ){
  248. mem.alarmBusy = 1;
  249. assert( sqlite3_mutex_held(mem.mutex) );
  250. sqlite3_mutex_leave(mem.mutex);
  251. sqlite3_release_memory(nByte);
  252. sqlite3_mutex_enter(mem.mutex);
  253. mem.alarmBusy = 0;
  254. }
  255. }
  256. /*
  257. ** Return the size of an outstanding allocation, in bytes. The
  258. ** size returned omits the 8-byte header overhead. This only
  259. ** works for chunks that are currently checked out.
  260. */
  261. static int memsys3Size(void *p){
  262. Mem3Block *pBlock = (Mem3Block*)p;
  263. assert( pBlock[-1].u.hdr.size<0 );
  264. return (-1-pBlock[-1].u.hdr.size)*8;
  265. }
  266. /*
  267. ** Chunk i is a free chunk that has been unlinked. Adjust its
  268. ** size parameters for check-out and return a pointer to the
  269. ** user portion of the chunk.
  270. */
  271. static void *memsys3Checkout(int i, int nBlock){
  272. assert( sqlite3_mutex_held(mem.mutex) );
  273. assert( mem.aPool[i-1].u.hdr.size==nBlock );
  274. assert( mem.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
  275. mem.aPool[i-1].u.hdr.size = -nBlock;
  276. mem.aPool[i+nBlock-1].u.hdr.prevSize = -nBlock;
  277. return &mem.aPool[i];
  278. }
  279. /*
  280. ** Carve a piece off of the end of the mem.iMaster free chunk.
  281. ** Return a pointer to the new allocation. Or, if the master chunk
  282. ** is not large enough, return 0.
  283. */
  284. static void *memsys3FromMaster(int nBlock){
  285. assert( sqlite3_mutex_held(mem.mutex) );
  286. assert( mem.szMaster>=nBlock );
  287. if( nBlock>=mem.szMaster-1 ){
  288. /* Use the entire master */
  289. void *p = memsys3Checkout(mem.iMaster, mem.szMaster);
  290. mem.iMaster = 0;
  291. mem.szMaster = 0;
  292. mem.mnMaster = 0;
  293. return p;
  294. }else{
  295. /* Split the master block. Return the tail. */
  296. int newi;
  297. newi = mem.iMaster + mem.szMaster - nBlock;
  298. assert( newi > mem.iMaster+1 );
  299. mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = -nBlock;
  300. mem.aPool[newi-1].u.hdr.size = -nBlock;
  301. mem.szMaster -= nBlock;
  302. mem.aPool[newi-1].u.hdr.prevSize = mem.szMaster;
  303. mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
  304. if( mem.szMaster < mem.mnMaster ){
  305. mem.mnMaster = mem.szMaster;
  306. }
  307. return (void*)&mem.aPool[newi];
  308. }
  309. }
  310. /*
  311. ** *pRoot is the head of a list of free chunks of the same size
  312. ** or same size hash. In other words, *pRoot is an entry in either
  313. ** mem.aiSmall[] or mem.aiHash[].
  314. **
  315. ** This routine examines all entries on the given list and tries
  316. ** to coalesce each entries with adjacent free chunks.
  317. **
  318. ** If it sees a chunk that is larger than mem.iMaster, it replaces
  319. ** the current mem.iMaster with the new larger chunk. In order for
  320. ** this mem.iMaster replacement to work, the master chunk must be
  321. ** linked into the hash tables. That is not the normal state of
  322. ** affairs, of course. The calling routine must link the master
  323. ** chunk before invoking this routine, then must unlink the (possibly
  324. ** changed) master chunk once this routine has finished.
  325. */
  326. static void memsys3Merge(int *pRoot){
  327. int iNext, prev, size, i;
  328. assert( sqlite3_mutex_held(mem.mutex) );
  329. for(i=*pRoot; i>0; i=iNext){
  330. iNext = mem.aPool[i].u.list.next;
  331. size = mem.aPool[i-1].u.hdr.size;
  332. assert( size>0 );
  333. if( mem.aPool[i-1].u.hdr.prevSize>0 ){
  334. memsys3UnlinkFromList(i, pRoot);
  335. prev = i - mem.aPool[i-1].u.hdr.prevSize;
  336. assert( prev>=0 );
  337. if( prev==iNext ){
  338. iNext = mem.aPool[prev].u.list.next;
  339. }
  340. memsys3Unlink(prev);
  341. size = i + size - prev;
  342. mem.aPool[prev-1].u.hdr.size = size;
  343. mem.aPool[prev+size-1].u.hdr.prevSize = size;
  344. memsys3Link(prev);
  345. i = prev;
  346. }
  347. if( size>mem.szMaster ){
  348. mem.iMaster = i;
  349. mem.szMaster = size;
  350. }
  351. }
  352. }
  353. /*
  354. ** Return a block of memory of at least nBytes in size.
  355. ** Return NULL if unable.
  356. */
  357. static void *memsys3Malloc(int nByte){
  358. int i;
  359. int nBlock;
  360. int toFree;
  361. assert( sqlite3_mutex_held(mem.mutex) );
  362. assert( sizeof(Mem3Block)==8 );
  363. if( nByte<=0 ){
  364. nBlock = 2;
  365. }else{
  366. nBlock = (nByte + 15)/8;
  367. }
  368. assert( nBlock >= 2 );
  369. /* STEP 1:
  370. ** Look for an entry of the correct size in either the small
  371. ** chunk table or in the large chunk hash table. This is
  372. ** successful most of the time (about 9 times out of 10).
  373. */
  374. if( nBlock <= MX_SMALL ){
  375. i = mem.aiSmall[nBlock-2];
  376. if( i>0 ){
  377. memsys3UnlinkFromList(i, &mem.aiSmall[nBlock-2]);
  378. return memsys3Checkout(i, nBlock);
  379. }
  380. }else{
  381. int hash = nBlock % N_HASH;
  382. for(i=mem.aiHash[hash]; i>0; i=mem.aPool[i].u.list.next){
  383. if( mem.aPool[i-1].u.hdr.size==nBlock ){
  384. memsys3UnlinkFromList(i, &mem.aiHash[hash]);
  385. return memsys3Checkout(i, nBlock);
  386. }
  387. }
  388. }
  389. /* STEP 2:
  390. ** Try to satisfy the allocation by carving a piece off of the end
  391. ** of the master chunk. This step usually works if step 1 fails.
  392. */
  393. if( mem.szMaster>=nBlock ){
  394. return memsys3FromMaster(nBlock);
  395. }
  396. /* STEP 3:
  397. ** Loop through the entire memory pool. Coalesce adjacent free
  398. ** chunks. Recompute the master chunk as the largest free chunk.
  399. ** Then try again to satisfy the allocation by carving a piece off
  400. ** of the end of the master chunk. This step happens very
  401. ** rarely (we hope!)
  402. */
  403. for(toFree=nBlock*16; toFree<SQLITE_MEMORY_SIZE*2; toFree *= 2){
  404. memsys3OutOfMemory(toFree);
  405. if( mem.iMaster ){
  406. memsys3Link(mem.iMaster);
  407. mem.iMaster = 0;
  408. mem.szMaster = 0;
  409. }
  410. for(i=0; i<N_HASH; i++){
  411. memsys3Merge(&mem.aiHash[i]);
  412. }
  413. for(i=0; i<MX_SMALL-1; i++){
  414. memsys3Merge(&mem.aiSmall[i]);
  415. }
  416. if( mem.szMaster ){
  417. memsys3Unlink(mem.iMaster);
  418. if( mem.szMaster>=nBlock ){
  419. return memsys3FromMaster(nBlock);
  420. }
  421. }
  422. }
  423. /* If none of the above worked, then we fail. */
  424. return 0;
  425. }
  426. /*
  427. ** Free an outstanding memory allocation.
  428. */
  429. void memsys3Free(void *pOld){
  430. Mem3Block *p = (Mem3Block*)pOld;
  431. int i;
  432. int size;
  433. assert( sqlite3_mutex_held(mem.mutex) );
  434. assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] );
  435. i = p - mem.aPool;
  436. size = -mem.aPool[i-1].u.hdr.size;
  437. assert( size>=2 );
  438. assert( mem.aPool[i+size-1].u.hdr.prevSize==-size );
  439. mem.aPool[i-1].u.hdr.size = size;
  440. mem.aPool[i+size-1].u.hdr.prevSize = size;
  441. memsys3Link(i);
  442. /* Try to expand the master using the newly freed chunk */
  443. if( mem.iMaster ){
  444. while( mem.aPool[mem.iMaster-1].u.hdr.prevSize>0 ){
  445. size = mem.aPool[mem.iMaster-1].u.hdr.prevSize;
  446. mem.iMaster -= size;
  447. mem.szMaster += size;
  448. memsys3Unlink(mem.iMaster);
  449. mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
  450. mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
  451. }
  452. while( mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size>0 ){
  453. memsys3Unlink(mem.iMaster+mem.szMaster);
  454. mem.szMaster += mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size;
  455. mem.aPool[mem.iMaster-1].u.hdr.size = mem.szMaster;
  456. mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
  457. }
  458. }
  459. }
  460. /*
  461. ** Allocate nBytes of memory
  462. */
  463. void *sqlite3_malloc(int nBytes){
  464. sqlite3_int64 *p = 0;
  465. if( nBytes>0 ){
  466. memsys3Enter();
  467. p = memsys3Malloc(nBytes);
  468. sqlite3_mutex_leave(mem.mutex);
  469. }
  470. return (void*)p;
  471. }
  472. /*
  473. ** Free memory.
  474. */
  475. void sqlite3_free(void *pPrior){
  476. if( pPrior==0 ){
  477. return;
  478. }
  479. assert( mem.mutex!=0 );
  480. sqlite3_mutex_enter(mem.mutex);
  481. memsys3Free(pPrior);
  482. sqlite3_mutex_leave(mem.mutex);
  483. }
  484. /*
  485. ** Change the size of an existing memory allocation
  486. */
  487. void *sqlite3_realloc(void *pPrior, int nBytes){
  488. int nOld;
  489. void *p;
  490. if( pPrior==0 ){
  491. return sqlite3_malloc(nBytes);
  492. }
  493. if( nBytes<=0 ){
  494. sqlite3_free(pPrior);
  495. return 0;
  496. }
  497. assert( mem.mutex!=0 );
  498. nOld = memsys3Size(pPrior);
  499. if( nBytes<=nOld && nBytes>=nOld-128 ){
  500. return pPrior;
  501. }
  502. sqlite3_mutex_enter(mem.mutex);
  503. p = memsys3Malloc(nBytes);
  504. if( p ){
  505. if( nOld<nBytes ){
  506. memcpy(p, pPrior, nOld);
  507. }else{
  508. memcpy(p, pPrior, nBytes);
  509. }
  510. memsys3Free(pPrior);
  511. }
  512. sqlite3_mutex_leave(mem.mutex);
  513. return p;
  514. }
  515. /*
  516. ** Open the file indicated and write a log of all unfreed memory
  517. ** allocations into that log.
  518. */
  519. void sqlite3_memdebug_dump(const char *zFilename){
  520. #ifdef SQLITE_DEBUG
  521. FILE *out;
  522. int i, j, size;
  523. if( zFilename==0 || zFilename[0]==0 ){
  524. out = stdout;
  525. }else{
  526. out = fopen(zFilename, "w");
  527. if( out==0 ){
  528. fprintf(stderr, "** Unable to output memory debug output log: %s **\n",
  529. zFilename);
  530. return;
  531. }
  532. }
  533. memsys3Enter();
  534. fprintf(out, "CHUNKS:\n");
  535. for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size){
  536. size = mem.aPool[i-1].u.hdr.size;
  537. if( size>=-1 && size<=1 ){
  538. fprintf(out, "%p size error\n", &mem.aPool[i]);
  539. assert( 0 );
  540. break;
  541. }
  542. if( mem.aPool[i+(size<0?-size:size)-1].u.hdr.prevSize!=size ){
  543. fprintf(out, "%p tail size does not match\n", &mem.aPool[i]);
  544. assert( 0 );
  545. break;
  546. }
  547. if( size<0 ){
  548. size = -size;
  549. fprintf(out, "%p %6d bytes checked out\n", &mem.aPool[i], size*8-8);
  550. }else{
  551. fprintf(out, "%p %6d bytes free%s\n", &mem.aPool[i], size*8-8,
  552. i==mem.iMaster ? " **master**" : "");
  553. }
  554. }
  555. for(i=0; i<MX_SMALL-1; i++){
  556. if( mem.aiSmall[i]==0 ) continue;
  557. fprintf(out, "small(%2d):", i);
  558. for(j = mem.aiSmall[i]; j>0; j=mem.aPool[j].u.list.next){
  559. fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8);
  560. }
  561. fprintf(out, "\n");
  562. }
  563. for(i=0; i<N_HASH; i++){
  564. if( mem.aiHash[i]==0 ) continue;
  565. fprintf(out, "hash(%2d):", i);
  566. for(j = mem.aiHash[i]; j>0; j=mem.aPool[j].u.list.next){
  567. fprintf(out, " %p(%d)", &mem.aPool[j], mem.aPool[j-1].u.hdr.size*8-8);
  568. }
  569. fprintf(out, "\n");
  570. }
  571. fprintf(out, "master=%d\n", mem.iMaster);
  572. fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem.szMaster*8);
  573. fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem.mnMaster*8);
  574. sqlite3_mutex_leave(mem.mutex);
  575. if( out==stdout ){
  576. fflush(stdout);
  577. }else{
  578. fclose(out);
  579. }
  580. #endif
  581. }
  582. #endif /* !SQLITE_MEMORY_SIZE */