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