blob: 98d62bc912751d9db16fb5ed9bf51bc1f1e0d88f [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- An implementation of malloc/free which doesn't use sbrk. ---*/
4/*--- vg_malloc2.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an x86 protected-mode emulator
9 designed for debugging and profiling binaries on x86-Unixes.
10
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file LICENSE.
30*/
31
32
33#include "vg_include.h"
34
35/* Define to turn on (heavyweight) debugging machinery. */
36/* #define DEBUG_MALLOC */
37
38
39/*------------------------------------------------------------*/
40/*--- Structs n stuff ---*/
41/*------------------------------------------------------------*/
42
43#define VG_REDZONE_LO_MASK 0x31415927
44#define VG_REDZONE_HI_MASK 0x14141356
45
46#define VG_N_MALLOC_LISTS 16 /* do not change this */
47
48
49typedef UInt Word;
50typedef Word WordF;
51typedef Word WordL;
52
53
54/* A superblock. */
55typedef
56 struct _Superblock {
57 struct _Superblock* next;
58 /* number of payload words in this superblock. */
59 Int n_payload_words;
60 Word payload_words[0];
61 }
62 Superblock;
63
64
65/* An arena. */
66typedef
67 struct {
68 Char* name;
69 Int rz_szW; /* Red zone size in words */
70 Bool rz_check; /* Check red-zone on free? */
71 Int min_sblockW; /* Minimum superblock size */
72 WordF* freelist[VG_N_MALLOC_LISTS];
73 Superblock* sblocks;
74 /* Stats only. */
75 UInt bytes_on_loan;
76 UInt bytes_mmaped;
77 UInt bytes_on_loan_max;
78 }
79 Arena;
80
81
82/* Block layout:
83
84 this block total sizeW (1 word)
85 freelist previous ptr (1 word)
86 freelist next ptr (1 word)
87 red zone words (depends on .rz_szW field of Arena)
88 (payload words)
89 red zone words (depends on .rz_szW field of Arena)
90 this block total sizeW (1 word)
91
92 Total size in words (bszW) and payload size in words (pszW)
93 are related by
94 bszW == pszW + 4 + 2 * a->rz_szW
95
96 Furthermore, both size fields in the block are negative if it is
97 not in use, and positive if it is in use. A block size of zero
98 is not possible, because a block always has at least four words
99 of overhead.
100*/
101typedef
102 struct {
103 Int bszW_lo;
104 Word* prev;
105 Word* next;
106 Word redzone[0];
107 }
108 BlockHeader;
109
110
111/*------------------------------------------------------------*/
112/*--- Forwardses ... and misc ... ---*/
113/*------------------------------------------------------------*/
114
115static Bool blockSane ( Arena* a, Word* b );
116
117/* Align ptr p upwards to an align-sized boundary. */
118static
119void* align_upwards ( void* p, Int align )
120{
121 Addr a = (Addr)p;
122 if ((a % align) == 0) return (void*)a;
123 return (void*)(a - (a % align) + align);
124}
125
126
127/*------------------------------------------------------------*/
128/*--- Arena management stuff ---*/
129/*------------------------------------------------------------*/
130
131/* The arena structures themselves. */
132static Arena vg_arena[VG_N_ARENAS];
133
134/* Functions external to this module identify arenas using ArenaIds,
135 not Arena*s. This fn converts the former to the latter. */
136static Arena* arenaId_to_ArenaP ( ArenaId arena )
137{
138 vg_assert(arena >= 0 && arena < VG_N_ARENAS);
139 return & vg_arena[arena];
140}
141
142
143/* Initialise an arena. */
144static
145void arena_init ( Arena* a, Char* name,
146 Int rz_szW, Bool rz_check, Int min_sblockW )
147{
148 Int i;
149 vg_assert((min_sblockW % VKI_WORDS_PER_PAGE) == 0);
150 a->name = name;
151 a->rz_szW = rz_szW;
152 a->rz_check = rz_check;
153 a->min_sblockW = min_sblockW;
154 for (i = 0; i < VG_N_MALLOC_LISTS; i++) a->freelist[i] = NULL;
155 a->sblocks = NULL;
156 a->bytes_on_loan = 0;
157 a->bytes_mmaped = 0;
158 a->bytes_on_loan_max = 0;
159}
160
161
162/* Print vital stats for an arena. */
163void VG_(show_all_arena_stats) ( void )
164{
165 Int i;
166 for (i = 0; i < VG_N_ARENAS; i++) {
167 VG_(message)(Vg_DebugMsg,
168 "Arena `%s': %7d max useful, %7d mmap'd, %7d current useful",
169 vg_arena[i].name,
170 vg_arena[i].bytes_on_loan_max,
171 vg_arena[i].bytes_mmaped,
172 vg_arena[i].bytes_on_loan
173 );
174 }
175}
176
177
178/* It is important that this library is self-initialising, because it
179 may get called very early on -- as a result of C++ static
180 constructor initialisations -- before Valgrind itself is
181 initialised. Hence vg_malloc() and vg_free() below always call
182 ensure_mm_init() to ensure things are correctly initialised. */
183
184static
185void ensure_mm_init ( void )
186{
187 static Bool init_done = False;
188 if (init_done) return;
189
190 /* Use a checked red zone size of 1 word for our internal stuff,
191 and an unchecked zone of arbitrary size for the client. Of
192 course the client's red zone is checked really, but using the
193 addressibility maps, not by the mechanism implemented here,
194 which merely checks at the time of freeing that the red zone
195 words are unchanged. */
196
197 arena_init ( &vg_arena[VG_AR_PRIVATE], "private ",
198 1, True, 262144 );
199
200 arena_init ( &vg_arena[VG_AR_SYMTAB], "symtab ",
201 1, True, 262144 );
202
203 arena_init ( &vg_arena[VG_AR_CLIENT], "client ",
204 VG_AR_CLIENT_REDZONE_SZW, False, 262144 );
205
206 arena_init ( &vg_arena[VG_AR_DEMANGLE], "demangle",
207 4 /*paranoid*/, True, 16384 );
208
209 arena_init ( &vg_arena[VG_AR_EXECTXT], "exectxt ",
210 1, True, 16384 );
211
212 arena_init ( &vg_arena[VG_AR_ERRCTXT], "errctxt ",
213 1, True, 16384 );
214
215 arena_init ( &vg_arena[VG_AR_TRANSIENT], "transien",
216 2, True, 16384 );
217
218 init_done = True;
219# ifdef DEBUG_MALLOC
220 VG_(mallocSanityCheckAll)();
221# endif
222}
223
224
225/*------------------------------------------------------------*/
226/*--- Arena management stuff ---*/
227/*------------------------------------------------------------*/
228
229static
230Superblock* newSuperblock ( Arena* a, Int cszW )
231{
232 Superblock* sb;
233 cszW += 2; /* Take into account sb->next and sb->n_words fields */
234 if (cszW < a->min_sblockW) cszW = a->min_sblockW;
235 while ((cszW % VKI_WORDS_PER_PAGE) > 0) cszW++;
236 sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word) );
237 sb->n_payload_words = cszW - 2;
238 a->bytes_mmaped += cszW * sizeof(Word);
239 if (0)
240 VG_(message)(Vg_DebugMsg, "newSuperblock, %d payload words",
241 sb->n_payload_words);
242 return sb;
243}
244
245
246/* Find the superblock containing the given chunk. */
247static
248Superblock* findSb ( Arena* a, UInt* ch )
249{
250 Superblock* sb;
251 for (sb = a->sblocks; sb; sb = sb->next)
252 if (&sb->payload_words[0] <= ch
253 && ch < &sb->payload_words[sb->n_payload_words])
254 return sb;
255 VG_(printf)("findSb: can't find pointer %p in arena `%s'\n",
256 ch, a->name );
257 VG_(panic)("findSb: vg_free() in wrong arena?");
258 return NULL; /*NOTREACHED*/
259}
260
261
262/*------------------------------------------------------------*/
263/*--- Low-level functions for working with blocks. ---*/
264/*------------------------------------------------------------*/
265
266/* Add the not-in-use attribute to a bszW. */
267static __inline__
268Int mk_free_bszW ( Int bszW )
269{
270 vg_assert(bszW != 0);
271 return (bszW < 0) ? bszW : -bszW;
272}
273
274/* Add the in-use attribute to a bszW. */
275static __inline__
276Int mk_inuse_bszW ( Int bszW )
277{
278 vg_assert(bszW != 0);
279 return (bszW < 0) ? -bszW : bszW;
280}
281
282/* Remove the in-use/not-in-use attribute from a bszW, leaving just
283 the size. */
284static __inline__
285Int mk_plain_bszW ( Int bszW )
286{
287 vg_assert(bszW != 0);
288 return (bszW < 0) ? -bszW : bszW;
289}
290
291/* Does this bszW have the in-use attribute ? */
292static __inline__
293Bool is_inuse_bszW ( Int bszW )
294{
295 vg_assert(bszW != 0);
296 return (bszW < 0) ? False : True;
297}
298
299
300/* Given the addr of the first word of a block, return the addr of the
301 last word. */
302static __inline__
303WordL* first_to_last ( WordF* fw )
304{
305 return fw + mk_plain_bszW(fw[0]) - 1;
306}
307
308/* Given the addr of the last word of a block, return the addr of the
309 first word. */
310static __inline__
311WordF* last_to_first ( WordL* lw )
312{
313 return lw - mk_plain_bszW(lw[0]) + 1;
314}
315
316
317/* Given the addr of the first word of a block, return the addr of the
318 first word of its payload. */
319static __inline__
320Word* first_to_payload ( Arena* a, WordF* fw )
321{
322 return & fw[3 + a->rz_szW];
323}
324
325/* Given the addr of the first word of a the payload of a block,
326 return the addr of the first word of the block. */
327static __inline__
328Word* payload_to_first ( Arena* a, WordF* payload )
329{
330 return & payload[- 3 - a->rz_szW];
331}
332
333/* Set and get the lower size field of a block. */
334static __inline__
335void set_bszW_lo ( WordF* fw, Int bszW ) {
336 fw[0] = bszW;
337}
338static __inline__
339Int get_bszW_lo ( WordF* fw )
340{
341 return fw[0];
342}
343
344
345/* Set and get the next and previous link fields of a block. */
346static __inline__
347void set_prev_p ( WordF* fw, Word* prev_p ) {
348 fw[1] = (Word)prev_p;
349}
350static __inline__
351void set_next_p ( WordF* fw, Word* next_p ) {
352 fw[2] = (Word)next_p;
353}
354static __inline__
355Word* get_prev_p ( WordF* fw ) {
356 return (Word*)(fw[1]);
357}
358static __inline__
359Word* get_next_p ( WordF* fw ) {
360 return (Word*)(fw[2]);
361}
362
363
364/* Set and get the upper size field of a block. */
365static __inline__
366void set_bszW_hi ( WordF* fw, Int bszW ) {
367 WordL* lw = first_to_last(fw);
368 vg_assert(lw == fw + mk_plain_bszW(bszW) - 1);
369 lw[0] = bszW;
370}
371static __inline__
372Int get_bszW_hi ( WordF* fw ) {
373 WordL* lw = first_to_last(fw);
374 return lw[0];
375}
376
377/* Get the upper size field of a block, given a pointer to the last
378 word of it. */
379static __inline__
380Int get_bszW_hi_from_last_word ( WordL* lw ) {
381 WordF* fw = last_to_first(lw);
382 return get_bszW_lo(fw);
383}
384
385
386/* Read and write the lower and upper red-zone words of a block. */
387static __inline__
388void set_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno, Word w )
389{
390 fw[3 + rz_wordno] = w;
391}
392static __inline__
393void set_rz_hi_word ( Arena* a, WordF* fw, Int rz_wordno, Word w )
394{
395 WordL* lw = first_to_last(fw);
396 lw[-1-rz_wordno] = w;
397}
398static __inline__
399Word get_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno )
400{
401 return fw[3 + rz_wordno];
402}
403static __inline__
404Word get_rz_hi_word ( Arena* a, WordF* fw, Int rz_wordno )
405{
406 WordL* lw = first_to_last(fw);
407 return lw[-1-rz_wordno];
408}
409
410
411/* Return the lower, upper and total overhead in words for a block.
412 These are determined purely by which arena the block lives in. */
413static __inline__
414Int overhead_szW_lo ( Arena* a )
415{
416 return 3 + a->rz_szW;
417}
418static __inline__
419Int overhead_szW_hi ( Arena* a )
420{
421 return 1 + a->rz_szW;
422}
423static __inline__
424Int overhead_szW ( Arena* a )
425{
426 return overhead_szW_lo(a) + overhead_szW_hi(a);
427}
428
429
430/* Convert pointer size in words to block size in words, and back. */
431static __inline__
432Int pszW_to_bszW ( Arena* a, Int pszW )
433{
434 vg_assert(pszW >= 0);
435 return pszW + overhead_szW(a);
436}
437static __inline__
438Int bszW_to_pszW ( Arena* a, Int bszW )
439{
440 Int pszW = bszW - overhead_szW(a);
441 vg_assert(pszW >= 0);
442 return pszW;
443}
444
445/*------------------------------------------------------------*/
446/*--- Functions for working with freelists. ---*/
447/*------------------------------------------------------------*/
448
449/* Determination of which freelist a block lives on is based on the
450 payload size, not block size, in words. */
451
452/* Convert a payload size in words to a freelist number. */
453
454static
455Int pszW_to_listNo ( Int pszW )
456{
457 vg_assert(pszW >= 0);
458 if (pszW <= 3) return 0;
459 if (pszW <= 4) return 1;
460 if (pszW <= 5) return 2;
461 if (pszW <= 6) return 3;
462 if (pszW <= 7) return 4;
463 if (pszW <= 8) return 5;
464 if (pszW <= 9) return 6;
465 if (pszW <= 10) return 7;
466 if (pszW <= 11) return 8;
467 if (pszW <= 12) return 9;
468 if (pszW <= 16) return 10;
469 if (pszW <= 32) return 11;
470 if (pszW <= 64) return 12;
471 if (pszW <= 128) return 13;
472 if (pszW <= 256) return 14;
473 return 15;
474}
475
476
477/* What are the minimum and maximum payload sizes for a given list? */
478
479static
480Int listNo_to_pszW_min ( Int listNo )
481{
482 Int pszW = 0;
483 vg_assert(listNo >= 0 && listNo <= VG_N_MALLOC_LISTS);
484 while (pszW_to_listNo(pszW) < listNo) pszW++;
485 return pszW;
486}
487
488static
489Int listNo_to_pszW_max ( Int listNo )
490{
491 vg_assert(listNo >= 0 && listNo <= VG_N_MALLOC_LISTS);
492 if (listNo == VG_N_MALLOC_LISTS-1) {
493 return 999999999;
494 } else {
495 return listNo_to_pszW_min(listNo+1) - 1;
496 }
497}
498
499
500/* A nasty hack to try and reduce fragmentation. Try and replace
501 a->freelist[lno] with another block on the same list but with a
502 lower address, with the idea of attempting to recycle the same
503 blocks rather than cruise through the address space. */
504
505static
506void swizzle ( Arena* a, Int lno )
507{
508 UInt* p_best;
509 UInt* pp;
510 UInt* pn;
511 Int i;
512
513 p_best = a->freelist[lno];
514 if (p_best == NULL) return;
515
516 pn = pp = p_best;
517 for (i = 0; i < 20; i++) {
518 pn = get_next_p(pn);
519 pp = get_prev_p(pp);
520 if (pn < p_best) p_best = pn;
521 if (pp < p_best) p_best = pp;
522 }
523 if (p_best < a->freelist[lno]) {
524# ifdef DEBUG_MALLOC
525 VG_(printf)("retreat by %d\n",
526 ((Char*)(a->freelist[lno])) - ((Char*)p_best));
527# endif
528 a->freelist[lno] = p_best;
529 }
530}
531
532
533/*------------------------------------------------------------*/
534/*--- Creating and deleting blocks. ---*/
535/*------------------------------------------------------------*/
536
537/* Mark the words at b .. b+bszW-1 as not in use, and add them to the
538 relevant free list. */
539
540static
541void mkFreeBlock ( Arena* a, Word* b, Int bszW, Int b_lno )
542{
543 Int pszW = bszW_to_pszW(a, bszW);
544 vg_assert(pszW >= 0);
545 vg_assert(b_lno == pszW_to_listNo(pszW));
546 /* Set the size fields and indicate not-in-use. */
547 set_bszW_lo(b, mk_free_bszW(bszW));
548 set_bszW_hi(b, mk_free_bszW(bszW));
549
550 /* Add to the relevant list. */
551 if (a->freelist[b_lno] == NULL) {
552 set_prev_p(b, b);
553 set_next_p(b, b);
554 a->freelist[b_lno] = b;
555 } else {
556 Word* b_prev = get_prev_p(a->freelist[b_lno]);
557 Word* b_next = a->freelist[b_lno];
558 set_next_p(b_prev, b);
559 set_prev_p(b_next, b);
560 set_next_p(b, b_next);
561 set_prev_p(b, b_prev);
562 }
563# ifdef DEBUG_MALLOC
564 (void)blockSane(a,b);
565# endif
566}
567
568
569/* Mark the words at b .. b+bszW-1 as in use, and set up the block
570 appropriately. */
571static
572void mkInuseBlock ( Arena* a, UInt* b, UInt bszW )
573{
574 Int i;
575 set_bszW_lo(b, mk_inuse_bszW(bszW));
576 set_bszW_hi(b, mk_inuse_bszW(bszW));
577 set_prev_p(b, NULL);
578 set_next_p(b, NULL);
579 if (a->rz_check) {
580 for (i = 0; i < a->rz_szW; i++) {
581 set_rz_lo_word(a, b, i, (UInt)b ^ VG_REDZONE_LO_MASK);
582 set_rz_hi_word(a, b, i, (UInt)b ^ VG_REDZONE_HI_MASK);
583 }
584 }
585# ifdef DEBUG_MALLOC
586 (void)blockSane(a,b);
587# endif
588}
589
590
591/* Remove a block from a given list. Does no sanity checking. */
592static
593void unlinkBlock ( Arena* a, UInt* b, Int listno )
594{
595 vg_assert(listno >= 0 && listno < VG_N_MALLOC_LISTS);
596 if (get_prev_p(b) == b) {
597 /* Only one element in the list; treat it specially. */
598 vg_assert(get_next_p(b) == b);
599 a->freelist[listno] = NULL;
600 } else {
601 UInt* b_prev = get_prev_p(b);
602 UInt* b_next = get_next_p(b);
603 a->freelist[listno] = b_prev;
604 set_next_p(b_prev, b_next);
605 set_prev_p(b_next, b_prev);
606 swizzle ( a, listno );
607 }
608 set_prev_p(b, NULL);
609 set_next_p(b, NULL);
610}
611
612
613/* Split an existing free block into two pieces, and put the fragment
614 (the second one along in memory) onto the relevant free list.
615 req_bszW is the required size of the block which isn't the
616 fragment. */
617static
618void splitChunk ( Arena* a, UInt* b, Int b_listno, UInt req_bszW )
619{
620 Int b_bszW, frag_bszW;
621 b_bszW = mk_plain_bszW(get_bszW_lo(b));
622 vg_assert(req_bszW < b_bszW);
623 frag_bszW = b_bszW - req_bszW;
624 vg_assert(frag_bszW >= overhead_szW(a));
625 /*
626 printf( "split %d into %d and %d\n",
627 b_bszW,req_bszW,frag_bszW );
628 */
629 vg_assert(bszW_to_pszW(a, frag_bszW) > 0);
630 unlinkBlock(a, b, b_listno);
631 mkInuseBlock(a, b, req_bszW);
632 mkFreeBlock(a, &b[req_bszW], frag_bszW,
633 pszW_to_listNo(bszW_to_pszW(a, frag_bszW)));
634}
635
636
637/*------------------------------------------------------------*/
638/*--- Sanity-check/debugging machinery. ---*/
639/*------------------------------------------------------------*/
640
641/* Do some crude sanity checks on a chunk. */
642static
643Bool blockSane ( Arena* a, Word* b )
644{
645# define BLEAT(str) VG_(printf)("blockSane: fail -- %s\n",str)
646 Int i;
647 if (get_bszW_lo(b) != get_bszW_hi(b))
648 {BLEAT("sizes");return False;}
649 if (a->rz_check && is_inuse_bszW(get_bszW_lo(b))) {
650 for (i = 0; i < a->rz_szW; i++) {
651 if (get_rz_lo_word(a, b, i) != ((Word)b ^ VG_REDZONE_LO_MASK))
652 {BLEAT("redzone-lo");return False;}
653 if (get_rz_hi_word(a, b, i) != ((Word)b ^ VG_REDZONE_HI_MASK))
654 {BLEAT("redzone-hi");return False;}
655 }
656 }
657 return True;
658# undef BLEAT
659}
660
661
662/* Print superblocks (only for debugging). */
663static
664void ppSuperblocks ( Arena* a )
665{
666 Int i, ch_bszW, blockno;
667 UInt* ch;
668 Superblock* sb = a->sblocks;
669 blockno = 1;
670
671 while (sb) {
672 VG_(printf)( "\n" );
673 VG_(printf)( "superblock %d at %p, sb->n_pl_ws = %d, next = %p\n",
674 blockno++, sb, sb->n_payload_words, sb->next );
675 i = 0;
676 while (True) {
677 if (i >= sb->n_payload_words) break;
678 ch = &sb->payload_words[i];
679 ch_bszW = get_bszW_lo(ch);
680 VG_(printf)( " block at %d, bszW %d: ", i, mk_plain_bszW(ch_bszW) );
681 VG_(printf)( "%s, ", is_inuse_bszW(ch_bszW) ? "inuse" : "free" );
682 VG_(printf)( "%s\n", blockSane(a,ch) ? "ok" : "BAD" );
683 i += mk_plain_bszW(ch_bszW);
684 }
685 if (i > sb->n_payload_words)
686 VG_(printf)( " last block overshoots end of SB\n");
687 sb = sb->next;
688 }
689 VG_(printf)( "end of superblocks\n\n" );
690}
691
692
693/* Sanity check both the superblocks and the chains. */
694void VG_(mallocSanityCheckArena) ( ArenaId aid )
695{
696 Int i, superblockctr, b_bszW, b_pszW, blockctr_sb, blockctr_li;
697 Int blockctr_sb_free, listno, list_min_pszW, list_max_pszW;
698 Superblock* sb;
699 Bool thisFree, lastWasFree;
700 Word* b;
701 Word* b_prev;
702 UInt arena_bytes_on_loan;
703 Arena* a;
704
705# define BOMB VG_(panic)("vg_mallocSanityCheckArena")
706
707 a = arenaId_to_ArenaP(aid);
708
709 /* First, traverse all the superblocks, inspecting the chunks in
710 each. */
711 superblockctr = blockctr_sb = blockctr_sb_free = 0;
712 arena_bytes_on_loan = 0;
713 sb = a->sblocks;
714 while (sb) {
715 lastWasFree = False;
716 superblockctr++;
717 i = 0;
718 while (True) {
719 if (i >= sb->n_payload_words) break;
720 blockctr_sb++;
721 b = &sb->payload_words[i];
722 b_bszW = get_bszW_lo(b);
723 if (!blockSane(a, b)) {
724 VG_(printf)( "mallocSanityCheck: sb %p, block %d (bszW %d): "
725 "BAD\n",
726 sb, i, b_bszW );
727 BOMB;
728 }
729 thisFree = !is_inuse_bszW(b_bszW);
730 if (thisFree && lastWasFree) {
731 VG_(printf)( "mallocSanityCheck: sb %p, block %d (bszW %d): "
732 "UNMERGED FREES\n",
733 sb, i, b_bszW );
734 BOMB;
735 }
736 lastWasFree = thisFree;
737 if (thisFree) blockctr_sb_free++;
738 if (!thisFree)
739 arena_bytes_on_loan += sizeof(Word) * bszW_to_pszW(a, b_bszW);
740 i += mk_plain_bszW(b_bszW);
741 }
742 if (i > sb->n_payload_words) {
743 VG_(printf)( "mallocSanityCheck: sb %p: last block "
744 "overshoots end\n", sb);
745 BOMB;
746 }
747 sb = sb->next;
748 }
749
750 if (arena_bytes_on_loan != a->bytes_on_loan) {
751 VG_(printf)(
752 "mallocSanityCheck: a->bytes_on_loan %d, "
753 "arena_bytes_on_loan %d: "
754 "MISMATCH\n", a->bytes_on_loan, arena_bytes_on_loan);
755 ppSuperblocks(a);
756 BOMB;
757 }
758
759 /* Second, traverse each list, checking that the back pointers make
760 sense, counting blocks encountered, and checking that each block
761 is an appropriate size for this list. */
762 blockctr_li = 0;
763 for (listno = 0; listno < VG_N_MALLOC_LISTS; listno++) {
764 list_min_pszW = listNo_to_pszW_min(listno);
765 list_max_pszW = listNo_to_pszW_max(listno);
766 b = a->freelist[listno];
767 if (b == NULL) continue;
768 while (True) {
769 b_prev = b;
770 b = get_next_p(b);
771 if (get_prev_p(b) != b_prev) {
772 VG_(printf)( "mallocSanityCheck: list %d at %p: "
773 "BAD LINKAGE\n",
774 listno, b );
775 BOMB;
776 }
777 b_pszW = bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b)));
778 if (b_pszW < list_min_pszW || b_pszW > list_max_pszW) {
779 VG_(printf)(
780 "mallocSanityCheck: list %d at %p: "
781 "WRONG CHAIN SIZE %d (%d, %d)\n",
782 listno, b, b_pszW, list_min_pszW, list_max_pszW );
783 BOMB;
784 }
785 blockctr_li++;
786 if (b == a->freelist[listno]) break;
787 }
788 }
789
790 if (blockctr_sb_free != blockctr_li) {
791 VG_(printf)(
792 "mallocSanityCheck: BLOCK COUNT MISMATCH "
793 "(via sbs %d, via lists %d)\n",
794 blockctr_sb_free, blockctr_li );
795 ppSuperblocks(a);
796 BOMB;
797 }
798
799 VG_(message)(Vg_DebugMsg,
800 "mSC [%s]: %2d sbs, %5d tot bs, %4d/%-4d free bs, "
801 "%2d lists, %7d mmap, %7d loan",
802 a->name,
803 superblockctr,
804 blockctr_sb, blockctr_sb_free, blockctr_li,
805 VG_N_MALLOC_LISTS,
806 a->bytes_mmaped, a->bytes_on_loan);
807# undef BOMB
808}
809
810
811void VG_(mallocSanityCheckAll) ( void )
812{
813 Int i;
814 for (i = 0; i < VG_N_ARENAS; i++)
815 VG_(mallocSanityCheckArena) ( i );
816}
817
818
819/* Really, this isn't the right place for this. Nevertheless: find
820 out if an arena is empty -- currently has no bytes on loan. This
821 is useful for checking for memory leaks (of valgrind, not the
822 client.)
823*/
824Bool VG_(is_empty_arena) ( ArenaId aid )
825{
826 Arena* a;
827 Superblock* sb;
828 WordF* b;
829 Int b_bszW;
830 ensure_mm_init();
831 a = arenaId_to_ArenaP(aid);
832 for (sb = a->sblocks; sb != NULL; sb = sb->next) {
833 /* If the superblock is empty, it should contain a single free
834 block, of the right size. */
835 b = &(sb->payload_words[0]);
836 b_bszW = get_bszW_lo(b);
837 if (is_inuse_bszW(b_bszW)) return False;
838 if (mk_plain_bszW(b_bszW) != sb->n_payload_words) return False;
839 /* So this block is not in use and is of the right size. Keep
840 going. */
841 }
842 return True;
843}
844
845
846/*------------------------------------------------------------*/
847/*--- Externally-visible functions. ---*/
848/*------------------------------------------------------------*/
849
850void* VG_(malloc) ( ArenaId aid, Int req_pszB )
851{
852 Int req_pszW, req_bszW, frag_bszW, b_bszW, lno;
853 Superblock* new_sb;
854 Word* b;
855 Arena* a;
856
857 VGP_PUSHCC(VgpMalloc);
858
859 ensure_mm_init();
860 a = arenaId_to_ArenaP(aid);
861
862 vg_assert(req_pszB >= 0);
863 vg_assert(req_pszB < 0x7FFFFFF0);
864
865 req_pszW = (req_pszB + VKI_BYTES_PER_WORD - 1) / VKI_BYTES_PER_WORD;
866
867 /* Keep gcc -O happy: */
868 b = NULL;
869
870 /* Start searching at this list. */
871 lno = pszW_to_listNo(req_pszW);
872
873 /* This loop finds a list which has a block big enough, or sets
874 req_listno to N_LISTS if no such block exists. */
875 while (True) {
876 if (lno == VG_N_MALLOC_LISTS) break;
877 /* If this list is empty, try the next one. */
878 if (a->freelist[lno] == NULL) {
879 lno++;
880 continue;
881 }
882 /* Scan a->list[lno] to find a big-enough chunk. */
883 b = a->freelist[lno];
884 b_bszW = mk_plain_bszW(get_bszW_lo(b));
885 while (True) {
886 if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
887 b = get_next_p(b);
888 b_bszW = mk_plain_bszW(get_bszW_lo(b));
889 if (b == a->freelist[lno]) break;
890 }
891 if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
892 /* No luck? Try a larger list. */
893 lno++;
894 }
895
896 /* Either lno < VG_N_MALLOC_LISTS and b points to the selected
897 block, or lno == VG_N_MALLOC_LISTS, and we have to allocate a
898 new superblock. */
899
900 if (lno == VG_N_MALLOC_LISTS) {
901 req_bszW = pszW_to_bszW(a, req_pszW);
902 new_sb = newSuperblock(a, req_bszW);
903 vg_assert(new_sb != NULL);
904 new_sb->next = a->sblocks;
905 a->sblocks = new_sb;
906 b = &(new_sb->payload_words[0]);
907 lno = pszW_to_listNo(bszW_to_pszW(a, new_sb->n_payload_words));
908 mkFreeBlock ( a, b, new_sb->n_payload_words, lno);
909 }
910
911 /* Ok, we can allocate from b, which lives in list req_listno. */
912 vg_assert(b != NULL);
913 vg_assert(lno >= 0 && lno < VG_N_MALLOC_LISTS);
914 vg_assert(a->freelist[lno] != NULL);
915 b_bszW = mk_plain_bszW(get_bszW_lo(b));
916 req_bszW = pszW_to_bszW(a, req_pszW);
917 /* req_bszW is the size of the block we are after. b_bszW is the
918 size of what we've actually got. */
919 vg_assert(b_bszW >= req_bszW);
920
921 /* Could we split this block and still get a useful fragment?
922 Where "useful" means that the payload size of the frag is at
923 least one word. */
924 frag_bszW = b_bszW - req_bszW;
925 if (frag_bszW > overhead_szW(a)) {
926 splitChunk(a, b, lno, req_bszW);
927 } else {
928 /* No, mark as in use and use as-is. */
929 unlinkBlock(a, b, lno);
930 /*
931 set_bszW_lo(b, mk_inuse_bszW(b_bszW));
932 set_bszW_hi(b, mk_inuse_bszW(b_bszW));
933 */
934 mkInuseBlock(a, b, b_bszW);
935 }
936 vg_assert(req_bszW <= mk_plain_bszW(get_bszW_lo(b)));
937
938 a->bytes_on_loan
939 += sizeof(Word)
940 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b)));
941 if (a->bytes_on_loan > a->bytes_on_loan_max)
942 a->bytes_on_loan_max = a->bytes_on_loan;
943
944# ifdef DEBUG_MALLOC
945 VG_(mallocSanityCheckArena)(aid);
946# endif
947
948 VGP_POPCC;
949 return first_to_payload(a, b);
950}
951
952
953void VG_(free) ( ArenaId aid, void* ptr )
954{
955 Superblock* sb;
956 UInt* sb_payl_firstw;
957 UInt* sb_payl_lastw;
958 UInt* other;
959 UInt* ch;
960 Int ch_bszW, ch_pszW, other_bszW, ch_listno;
961 Arena* a;
962
963 VGP_PUSHCC(VgpMalloc);
964
965 ensure_mm_init();
966 a = arenaId_to_ArenaP(aid);
967
968 if (ptr == NULL) return;
969
970 ch = payload_to_first(a, ptr);
971
972# ifdef DEBUG_MALLOC
973 vg_assert(blockSane(a,ch));
974# endif
975
976 a->bytes_on_loan
977 -= sizeof(Word)
978 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(ch)));
979
980 sb = findSb( a, ch );
981 sb_payl_firstw = &(sb->payload_words[0]);
982 sb_payl_lastw = &(sb->payload_words[sb->n_payload_words-1]);
983
984 /* Put this chunk back on a list somewhere. */
985 ch_bszW = get_bszW_lo(ch);
986 ch_pszW = bszW_to_pszW(a, ch_bszW);
987 ch_listno = pszW_to_listNo(ch_pszW);
988 mkFreeBlock( a, ch, ch_bszW, ch_listno );
989
990 /* See if this block can be merged with the following one. */
991 other = ch + ch_bszW;
992 /* overhead_szW(a) is the smallest possible bszW for this arena.
993 So the nearest possible end to the block beginning at other is
994 other+overhead_szW(a)-1. Hence the test below. */
995 if (other+overhead_szW(a)-1 <= sb_payl_lastw) {
996 other_bszW = get_bszW_lo(other);
997 if (!is_inuse_bszW(other_bszW)) {
998 /* VG_(printf)( "merge-successor\n"); */
999 other_bszW = mk_plain_bszW(other_bszW);
1000# ifdef DEBUG_MALLOC
1001 vg_assert(blockSane(a, other));
1002# endif
1003 unlinkBlock( a, ch, ch_listno );
1004 unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a,other_bszW)) );
1005 ch_bszW += other_bszW;
1006 ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
1007 mkFreeBlock( a, ch, ch_bszW, ch_listno );
1008 }
1009 }
1010
1011 /* See if this block can be merged with its predecessor. */
1012 if (ch-overhead_szW(a) >= sb_payl_firstw) {
1013 other_bszW = get_bszW_hi_from_last_word( ch-1 );
1014 if (!is_inuse_bszW(other_bszW)) {
1015 /* VG_(printf)( "merge-predecessor\n"); */
1016 other = last_to_first( ch-1 );
1017 other_bszW = mk_plain_bszW(other_bszW);
1018 unlinkBlock( a, ch, ch_listno );
1019 unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a, other_bszW)) );
1020 ch = other;
1021 ch_bszW += other_bszW;
1022 ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
1023 mkFreeBlock( a, ch, ch_bszW, ch_listno );
1024 }
1025 }
1026
1027# ifdef DEBUG_MALLOC
1028 VG_(mallocSanityCheckArena)(aid);
1029# endif
1030
1031 VGP_POPCC;
1032}
1033
1034
1035/*
1036 The idea for malloc_aligned() is to allocate a big block, base, and
1037 then split it into two parts: frag, which is returned to the the
1038 free pool, and align, which is the bit we're really after. Here's
1039 a picture. L and H denote the block lower and upper overheads, in
1040 words. The details are gruesome. Note it is slightly complicated
1041 because the initial request to generate base may return a bigger
1042 block than we asked for, so it is important to distinguish the base
1043 request size and the base actual size.
1044
1045 frag_b align_b
1046 | |
1047 | frag_p | align_p
1048 | | | |
1049 v v v v
1050
1051 +---+ +---+---+ +---+
1052 | L |----------------| H | L |---------------| H |
1053 +---+ +---+---+ +---+
1054
1055 ^ ^ ^
1056 | | :
1057 | base_p this addr must be aligned
1058 |
1059 base_b
1060
1061 . . . . . . .
1062 <------ frag_bszW -------> . . .
1063 . <------------- base_pszW_act -----------> .
1064 . . . . . . .
1065
1066*/
1067void* VG_(malloc_aligned) ( ArenaId aid, Int req_alignB, Int req_pszB )
1068{
1069 Int req_alignW, req_pszW, base_pszW_req, base_pszW_act, frag_bszW;
1070 Word *base_b, *base_p, *align_p;
1071 UInt saved_bytes_on_loan;
1072 Arena* a;
1073
1074 ensure_mm_init();
1075 a = arenaId_to_ArenaP(aid);
1076
1077 vg_assert(req_pszB >= 0);
1078 vg_assert(req_pszB < 0x7FFFFFF0);
1079
1080 /* Check that the requested alignment seems reasonable; that is, is
1081 a power of 2. There must be a better way to do this. What is
1082 it? */
1083 switch (req_alignB) {
sewardjc76be292002-04-24 20:32:50 +00001084 case 4:
sewardjde4a1d02002-03-22 01:27:54 +00001085 case 8: case 16: case 32: case 64: case 128: case 256:
1086 case 512: case 1024: case 2048: case 4096: case 8192:
1087 case 16384: case 32768: case 65536: case 131072:
1088 case 1048576:
1089 /* can't be bothered to calculate larger ones */
1090 break;
1091 default:
1092 VG_(printf)("vg_malloc_aligned(%p, %d, %d)\nbad alignment request",
1093 a, req_pszB, req_alignB );
1094 VG_(panic)("vg_malloc_aligned");
1095 /*NOTREACHED*/
1096 }
1097
1098 /* Required alignment, in words. Since it's constrained to be a
1099 power of 2 >= word size, no need to align the alignment. Still,
1100 we check. */
1101 req_alignW = req_alignB / VKI_BYTES_PER_WORD;
1102 vg_assert(req_alignB == req_alignW * VKI_BYTES_PER_WORD);
1103
1104 /* Required payload size for the aligned chunk. */
1105 req_pszW = (req_pszB + VKI_BYTES_PER_WORD - 1) / VKI_BYTES_PER_WORD;
1106
1107 /* Payload size to request for the big block that we will split
1108 up. */
1109 base_pszW_req = req_pszW + overhead_szW(a) + req_alignW;
1110
1111 /* Payload ptr for the block we are going to split. Note this
1112 changes a->bytes_on_loan; we save and restore it ourselves. */
1113 saved_bytes_on_loan = a->bytes_on_loan;
1114 base_p = VG_(malloc) ( aid, base_pszW_req * VKI_BYTES_PER_WORD );
1115 a->bytes_on_loan = saved_bytes_on_loan;
1116
1117 /* Block ptr for the block we are going to split. */
1118 base_b = payload_to_first ( a, base_p );
1119
1120 /* Pointer to the payload of the aligned block we are going to
1121 return. This has to be suitably aligned. */
1122 align_p = align_upwards ( base_b + 2 * overhead_szW_lo(a)
1123 + overhead_szW_hi(a),
1124 req_alignB );
1125
1126 /* The block size of the fragment we will create. This must be big
1127 enough to actually create a fragment. */
1128 frag_bszW = align_p - overhead_szW_lo(a) - base_b;
1129 vg_assert(frag_bszW >= overhead_szW(a));
1130
1131 /* The actual payload size of the block we are going to split. */
1132 base_pszW_act = bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(base_b)));
1133
1134 /* Create the fragment block, and put it back on the relevant free
1135 list. */
1136 mkFreeBlock ( a, base_b, frag_bszW,
1137 pszW_to_listNo(bszW_to_pszW(a, frag_bszW)) );
1138
1139 /* Create the aligned block. */
1140 mkInuseBlock ( a,
1141 align_p - overhead_szW_lo(a),
1142 base_p + base_pszW_act
1143 + overhead_szW_hi(a)
1144 - (align_p - overhead_szW_lo(a)) );
1145
1146 /* Final sanity checks. */
1147 vg_assert(( (UInt)align_p % req_alignB) == 0);
1148
1149 vg_assert(is_inuse_bszW(get_bszW_lo(payload_to_first(a, align_p))));
1150
1151 vg_assert(req_pszW
1152 <=
1153 bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(
1154 payload_to_first(a, align_p))))
1155 );
1156
1157 a->bytes_on_loan
1158 += sizeof(Word)
1159 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(
1160 payload_to_first(a, align_p))));
1161 if (a->bytes_on_loan > a->bytes_on_loan_max)
1162 a->bytes_on_loan_max = a->bytes_on_loan;
1163
1164# ifdef DEBUG_MALLOC
1165 VG_(mallocSanityCheckArena)(aid);
1166# endif
1167
1168 return align_p;
1169}
1170
1171
1172/*------------------------------------------------------------*/
1173/*--- Services layered on top of malloc/free. ---*/
1174/*------------------------------------------------------------*/
1175
1176void* VG_(calloc) ( ArenaId aid, Int nmemb, Int nbytes )
1177{
1178 Int i, size;
1179 UChar* p;
1180 size = nmemb * nbytes;
sewardjd0b9ac32002-05-01 00:10:28 +00001181 vg_assert(size >= 0);
sewardjde4a1d02002-03-22 01:27:54 +00001182 p = VG_(malloc) ( aid, size );
1183 for (i = 0; i < size; i++) p[i] = 0;
1184 return p;
1185}
1186
1187
1188void* VG_(realloc) ( ArenaId aid, void* ptr, Int req_pszB )
1189{
1190 Arena* a;
1191 Int old_bszW, old_pszW, old_pszB, i;
1192 UChar *p_old, *p_new;
1193 UInt* ch;
1194
1195 ensure_mm_init();
1196 a = arenaId_to_ArenaP(aid);
1197
1198 vg_assert(req_pszB >= 0);
1199 vg_assert(req_pszB < 0x7FFFFFF0);
1200
1201 ch = payload_to_first(a, ptr);
1202 vg_assert(blockSane(a, ch));
1203
1204 old_bszW = get_bszW_lo(ch);
1205 vg_assert(is_inuse_bszW(old_bszW));
1206 old_bszW = mk_plain_bszW(old_bszW);
1207 old_pszW = bszW_to_pszW(a, old_bszW);
1208 old_pszB = old_pszW * VKI_BYTES_PER_WORD;
1209
1210 if (req_pszB <= old_pszB) return ptr;
1211
1212 p_new = VG_(malloc) ( aid, req_pszB );
1213 p_old = (UChar*)ptr;
1214 for (i = 0; i < old_pszB; i++)
1215 p_new[i] = p_old[i];
1216
1217 VG_(free)(aid, p_old);
1218 return p_new;
1219}
1220
1221
1222/*------------------------------------------------------------*/
1223/*--- The original test driver machinery. ---*/
1224/*------------------------------------------------------------*/
1225
1226#if 0
1227
1228#if 1
1229#define N_TEST_TRANSACTIONS 100000000
1230#define N_TEST_ARR 200000
1231#define M_TEST_MALLOC 1000
1232#else
1233#define N_TEST_TRANSACTIONS 500000
1234#define N_TEST_ARR 30000
1235#define M_TEST_MALLOC 500
1236#endif
1237
1238
1239void* test_arr[N_TEST_ARR];
1240
1241int main ( int argc, char** argv )
1242{
1243 Int i, j, k, nbytes, qq;
1244 unsigned char* chp;
1245 Arena* a = &arena[VG_AR_PRIVATE];
1246 srandom(1);
1247 for (i = 0; i < N_TEST_ARR; i++)
1248 test_arr[i] = NULL;
1249
1250 for (i = 0; i < N_TEST_TRANSACTIONS; i++) {
1251 if (i % 50000 == 0) mallocSanityCheck(a);
1252 j = random() % N_TEST_ARR;
1253 if (test_arr[j]) {
1254 vg_free(a, test_arr[j]);
1255 test_arr[j] = NULL;
1256 } else {
1257 nbytes = 1 + random() % M_TEST_MALLOC;
1258 qq = random()%64;
1259 if (qq == 32)
1260 nbytes *= 17;
1261 else if (qq == 33)
1262 nbytes = 0;
1263 test_arr[j]
1264 = (i % 17) == 0
1265 ? vg_memalign(a, nbytes, 1<< (3+(random()%10)))
1266 : vg_malloc( a, nbytes );
1267 chp = test_arr[j];
1268 for (k = 0; k < nbytes; k++)
1269 chp[k] = (unsigned char)(k + 99);
1270 }
1271 }
1272
1273
1274 for (i = 0; i < N_TEST_ARR; i++) {
1275 if (test_arr[i]) {
1276 vg_free(a, test_arr[i]);
1277 test_arr[i] = NULL;
1278 }
1279 }
1280 mallocSanityCheck(a);
1281
1282 fprintf(stderr, "ALL DONE\n");
1283
1284 show_arena_stats(a);
1285 fprintf(stderr, "%d max useful, %d bytes mmap'd (%4.1f%%), %d useful\n",
1286 a->bytes_on_loan_max,
1287 a->bytes_mmaped,
1288 100.0 * (double)a->bytes_on_loan_max / (double)a->bytes_mmaped,
1289 a->bytes_on_loan );
1290
1291 return 0;
1292}
1293#endif /* 0 */
1294
1295
1296/*--------------------------------------------------------------------*/
1297/*--- end vg_malloc2.c ---*/
1298/*--------------------------------------------------------------------*/