blob: 9999295fca8fcd34f716fcd99203ee4ad35d61a4 [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/*
njnc9539842002-10-02 13:26:35 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
sewardjde4a1d02002-03-22 01:27:54 +000010
nethercotebb1c9912004-01-04 16:43:23 +000011 Copyright (C) 2000-2004 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 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
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
32
33#include "vg_include.h"
34
35/* Define to turn on (heavyweight) debugging machinery. */
36/* #define DEBUG_MALLOC */
37
fitzhardinge98abfc72003-12-16 02:05:15 +000038/*------------------------------------------------------------*/
39/*--- Command line options ---*/
40/*------------------------------------------------------------*/
41
42/* Round malloc sizes upwards to integral number of words? default: NO */
43Bool VG_(clo_sloppy_malloc) = False;
44
45/* DEBUG: print malloc details? default: NO */
46Bool VG_(clo_trace_malloc) = False;
47
48/* Minimum alignment in functions that don't specify alignment explicitly.
mueller273d1d72004-03-13 02:49:49 +000049 default: 0, i.e. use default of the machine (== 8) */
fitzhardinge26f33082004-03-13 02:38:33 +000050Int VG_(clo_alignment) = 8;
fitzhardinge98abfc72003-12-16 02:05:15 +000051
52
53Bool VG_(replacement_malloc_process_cmd_line_option)(Char* arg)
54{
jsewardb1a26ae2004-03-14 03:06:37 +000055 if (VG_CLO_STREQN(12, arg, "--alignment=")) {
fitzhardinge98abfc72003-12-16 02:05:15 +000056 VG_(clo_alignment) = (Int)VG_(atoll)(&arg[12]);
57
jsewardb1a26ae2004-03-14 03:06:37 +000058 if (VG_(clo_alignment) < 8
fitzhardinge98abfc72003-12-16 02:05:15 +000059 || VG_(clo_alignment) > 4096
60 || VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */) {
61 VG_(message)(Vg_UserMsg, "");
62 VG_(message)(Vg_UserMsg,
63 "Invalid --alignment= setting. "
jsewardb1a26ae2004-03-14 03:06:37 +000064 "Should be a power of 2, >= 8, <= 4096.");
fitzhardinge98abfc72003-12-16 02:05:15 +000065 VG_(bad_option)("--alignment");
66 }
67 }
68
nethercotef28481f2004-07-10 13:56:19 +000069 else VG_BOOL_CLO("--sloppy-malloc", VG_(clo_sloppy_malloc))
70 else VG_BOOL_CLO("--trace-malloc", VG_(clo_trace_malloc))
fitzhardinge98abfc72003-12-16 02:05:15 +000071 else
72 return False;
73
74 return True;
75}
76
77void VG_(replacement_malloc_print_usage)(void)
78{
79 VG_(printf)(
80" --sloppy-malloc=no|yes round malloc sizes to next word? [no]\n"
mueller273d1d72004-03-13 02:49:49 +000081" --alignment=<number> set minimum alignment of allocations [8]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +000082 );
83}
84
85void VG_(replacement_malloc_print_debug_usage)(void)
86{
87 VG_(printf)(
88" --trace-malloc=no|yes show client malloc details? [no]\n"
89 );
90}
91
sewardjde4a1d02002-03-22 01:27:54 +000092
93/*------------------------------------------------------------*/
94/*--- Structs n stuff ---*/
95/*------------------------------------------------------------*/
96
97#define VG_REDZONE_LO_MASK 0x31415927
98#define VG_REDZONE_HI_MASK 0x14141356
99
100#define VG_N_MALLOC_LISTS 16 /* do not change this */
101
102
103typedef UInt Word;
104typedef Word WordF;
105typedef Word WordL;
106
107
108/* A superblock. */
109typedef
110 struct _Superblock {
111 struct _Superblock* next;
112 /* number of payload words in this superblock. */
113 Int n_payload_words;
114 Word payload_words[0];
115 }
116 Superblock;
117
118
119/* An arena. */
120typedef
121 struct {
122 Char* name;
fitzhardinge98abfc72003-12-16 02:05:15 +0000123 Bool clientmem; /* allocates in the client address space */
124 Int rz_szW; /* Red zone size in words */
125 Bool rz_check; /* Check red-zone on free? */
126 Int min_sblockW; /* Minimum superblock size */
sewardjde4a1d02002-03-22 01:27:54 +0000127 WordF* freelist[VG_N_MALLOC_LISTS];
128 Superblock* sblocks;
129 /* Stats only. */
130 UInt bytes_on_loan;
131 UInt bytes_mmaped;
132 UInt bytes_on_loan_max;
133 }
134 Arena;
135
136
137/* Block layout:
138
139 this block total sizeW (1 word)
140 freelist previous ptr (1 word)
sewardjde4a1d02002-03-22 01:27:54 +0000141 red zone words (depends on .rz_szW field of Arena)
142 (payload words)
143 red zone words (depends on .rz_szW field of Arena)
jsewardb1a26ae2004-03-14 03:06:37 +0000144 freelist next ptr (1 word)
145 this block total sizeW (1 word)
sewardjde4a1d02002-03-22 01:27:54 +0000146
147 Total size in words (bszW) and payload size in words (pszW)
148 are related by
149 bszW == pszW + 4 + 2 * a->rz_szW
150
151 Furthermore, both size fields in the block are negative if it is
152 not in use, and positive if it is in use. A block size of zero
153 is not possible, because a block always has at least four words
154 of overhead.
jsewardb1a26ae2004-03-14 03:06:37 +0000155
156 8-byte payload alignment is ensured by requiring the number
157 of words in the red zones and the number of payload words
158 to both be even (% 2 == 0).
sewardjde4a1d02002-03-22 01:27:54 +0000159*/
160typedef
161 struct {
162 Int bszW_lo;
163 Word* prev;
164 Word* next;
165 Word redzone[0];
166 }
167 BlockHeader;
168
169
170/*------------------------------------------------------------*/
171/*--- Forwardses ... and misc ... ---*/
172/*------------------------------------------------------------*/
173
174static Bool blockSane ( Arena* a, Word* b );
175
176/* Align ptr p upwards to an align-sized boundary. */
177static
178void* align_upwards ( void* p, Int align )
179{
180 Addr a = (Addr)p;
181 if ((a % align) == 0) return (void*)a;
182 return (void*)(a - (a % align) + align);
183}
184
185
186/*------------------------------------------------------------*/
187/*--- Arena management stuff ---*/
188/*------------------------------------------------------------*/
189
nethercotec314eba2004-07-15 12:59:41 +0000190#define CORE_ARENA_MIN_SZW 262144
191
sewardjde4a1d02002-03-22 01:27:54 +0000192/* The arena structures themselves. */
193static Arena vg_arena[VG_N_ARENAS];
194
195/* Functions external to this module identify arenas using ArenaIds,
196 not Arena*s. This fn converts the former to the latter. */
197static Arena* arenaId_to_ArenaP ( ArenaId arena )
198{
199 vg_assert(arena >= 0 && arena < VG_N_ARENAS);
200 return & vg_arena[arena];
201}
202
203
204/* Initialise an arena. */
205static
206void arena_init ( Arena* a, Char* name,
fitzhardinge98abfc72003-12-16 02:05:15 +0000207 Int rz_szW, Bool rz_check, Int min_sblockW, Bool client )
sewardjde4a1d02002-03-22 01:27:54 +0000208{
209 Int i;
jsewardb1a26ae2004-03-14 03:06:37 +0000210 vg_assert(rz_szW >= 0);
211 vg_assert(rz_szW % 2 == 0);
sewardjde4a1d02002-03-22 01:27:54 +0000212 vg_assert((min_sblockW % VKI_WORDS_PER_PAGE) == 0);
213 a->name = name;
fitzhardinge98abfc72003-12-16 02:05:15 +0000214 a->clientmem = client;
sewardjde4a1d02002-03-22 01:27:54 +0000215 a->rz_szW = rz_szW;
216 a->rz_check = rz_check;
217 a->min_sblockW = min_sblockW;
218 for (i = 0; i < VG_N_MALLOC_LISTS; i++) a->freelist[i] = NULL;
219 a->sblocks = NULL;
220 a->bytes_on_loan = 0;
221 a->bytes_mmaped = 0;
222 a->bytes_on_loan_max = 0;
223}
224
225
226/* Print vital stats for an arena. */
227void VG_(show_all_arena_stats) ( void )
228{
229 Int i;
230 for (i = 0; i < VG_N_ARENAS; i++) {
231 VG_(message)(Vg_DebugMsg,
232 "Arena `%s': %7d max useful, %7d mmap'd, %7d current useful",
233 vg_arena[i].name,
234 vg_arena[i].bytes_on_loan_max,
235 vg_arena[i].bytes_mmaped,
236 vg_arena[i].bytes_on_loan
237 );
238 }
239}
240
241
242/* It is important that this library is self-initialising, because it
243 may get called very early on -- as a result of C++ static
244 constructor initialisations -- before Valgrind itself is
njn25e49d8e72002-09-23 09:36:25 +0000245 initialised. Hence VG_(arena_malloc)() and VG_(arena_free)() below always
246 call ensure_mm_init() to ensure things are correctly initialised. */
sewardjde4a1d02002-03-22 01:27:54 +0000247
248static
249void ensure_mm_init ( void )
250{
nethercotec314eba2004-07-15 12:59:41 +0000251 static Int client_rz_szW;
sewardjde4a1d02002-03-22 01:27:54 +0000252 static Bool init_done = False;
jsewardb1a26ae2004-03-14 03:06:37 +0000253
nethercotec314eba2004-07-15 12:59:41 +0000254 if (init_done) {
255 // Make sure the client arena's redzone size never changes. Could
256 // happen if VG_(arena_malloc) was called too early, ie. before the
257 // tool was loaded.
258 vg_assert(client_rz_szW == VG_(vg_malloc_redzone_szB)/4);
259 return;
260 }
sewardjde4a1d02002-03-22 01:27:54 +0000261
nethercotee1efb922004-07-10 16:01:52 +0000262 /* Use checked red zones (of various sizes) for our internal stuff,
sewardjde4a1d02002-03-22 01:27:54 +0000263 and an unchecked zone of arbitrary size for the client. Of
nethercote7cc9c232004-01-21 15:08:04 +0000264 course the client's red zone can be checked by the tool, eg.
njn3e884182003-04-15 13:03:23 +0000265 by using addressibility maps, but not by the mechanism implemented
266 here, which merely checks at the time of freeing that the red
267 zone words are unchanged. */
sewardjde4a1d02002-03-22 01:27:54 +0000268
nethercotec314eba2004-07-15 12:59:41 +0000269 arena_init ( &vg_arena[VG_AR_CORE], "core", 2, True, CORE_ARENA_MIN_SZW, False );
sewardjde4a1d02002-03-22 01:27:54 +0000270
jsewardb1a26ae2004-03-14 03:06:37 +0000271 arena_init ( &vg_arena[VG_AR_TOOL], "tool", 2, True, 262144, False );
sewardjde4a1d02002-03-22 01:27:54 +0000272
jsewardb1a26ae2004-03-14 03:06:37 +0000273 arena_init ( &vg_arena[VG_AR_SYMTAB], "symtab", 2, True, 262144, False );
njn25e49d8e72002-09-23 09:36:25 +0000274
jsewardb1a26ae2004-03-14 03:06:37 +0000275 arena_init ( &vg_arena[VG_AR_JITTER], "JITter", 2, True, 8192, False );
njn25e49d8e72002-09-23 09:36:25 +0000276
njn3e884182003-04-15 13:03:23 +0000277 /* No particular reason for this figure, it's just smallish */
278 sk_assert(VG_(vg_malloc_redzone_szB) < 128);
jsewardb1a26ae2004-03-14 03:06:37 +0000279 sk_assert(VG_(vg_malloc_redzone_szB) >= 0);
280 client_rz_szW = VG_(vg_malloc_redzone_szB)/4;
jsewardb1a26ae2004-03-14 03:06:37 +0000281
njn3e884182003-04-15 13:03:23 +0000282 arena_init ( &vg_arena[VG_AR_CLIENT], "client",
jsewardb1a26ae2004-03-14 03:06:37 +0000283 client_rz_szW, False, 262144, True );
sewardjde4a1d02002-03-22 01:27:54 +0000284
njn3e884182003-04-15 13:03:23 +0000285 arena_init ( &vg_arena[VG_AR_DEMANGLE], "demangle", 4 /*paranoid*/,
fitzhardinge98abfc72003-12-16 02:05:15 +0000286 True, 16384, False );
sewardjde4a1d02002-03-22 01:27:54 +0000287
jsewardb1a26ae2004-03-14 03:06:37 +0000288 arena_init ( &vg_arena[VG_AR_EXECTXT], "exectxt", 2, True, 16384, False );
sewardjde4a1d02002-03-22 01:27:54 +0000289
jsewardb1a26ae2004-03-14 03:06:37 +0000290 arena_init ( &vg_arena[VG_AR_ERRORS], "errors", 2, True, 16384, False );
sewardjde4a1d02002-03-22 01:27:54 +0000291
fitzhardinge98abfc72003-12-16 02:05:15 +0000292 arena_init ( &vg_arena[VG_AR_TRANSIENT], "transien", 2, True, 16384, False );
sewardjde4a1d02002-03-22 01:27:54 +0000293
294 init_done = True;
295# ifdef DEBUG_MALLOC
296 VG_(mallocSanityCheckAll)();
297# endif
298}
299
300
301/*------------------------------------------------------------*/
sewardjecf8e102003-07-12 12:11:39 +0000302/*--- Superblock management stuff ---*/
sewardjde4a1d02002-03-22 01:27:54 +0000303/*------------------------------------------------------------*/
304
nethercotec314eba2004-07-15 12:59:41 +0000305// If not enough memory available, either aborts (for non-client memory)
306// or returns 0 (for client memory).
sewardjde4a1d02002-03-22 01:27:54 +0000307static
308Superblock* newSuperblock ( Arena* a, Int cszW )
309{
nethercotec314eba2004-07-15 12:59:41 +0000310 static Bool called_before = False;
311 static Word bootstrap_superblock[CORE_ARENA_MIN_SZW];
312 Int cszB;
sewardjde4a1d02002-03-22 01:27:54 +0000313 Superblock* sb;
nethercotec314eba2004-07-15 12:59:41 +0000314
sewardjde4a1d02002-03-22 01:27:54 +0000315 cszW += 2; /* Take into account sb->next and sb->n_words fields */
316 if (cszW < a->min_sblockW) cszW = a->min_sblockW;
317 while ((cszW % VKI_WORDS_PER_PAGE) > 0) cszW++;
fitzhardinge98abfc72003-12-16 02:05:15 +0000318
nethercotec314eba2004-07-15 12:59:41 +0000319 cszB = cszW * sizeof(Word);
320
321 if (!called_before) {
322 // First time we're called -- use the special static bootstrap
323 // superblock (see comment at top of main() for details).
324 called_before = True;
325 vg_assert(a == &vg_arena[VG_AR_CORE]);
326 vg_assert(CORE_ARENA_MIN_SZW*sizeof(Word) >= cszB);
327 sb = (Superblock*)bootstrap_superblock;
328
329 } else if (a->clientmem) {
nethercote57e36b32004-07-10 14:56:28 +0000330 // client allocation -- return 0 to client if it fails
jsewardb1a26ae2004-03-14 03:06:37 +0000331 sb = (Superblock *)
nethercotec314eba2004-07-15 12:59:41 +0000332 VG_(client_alloc)(0, cszB,
nethercote57e36b32004-07-10 14:56:28 +0000333 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, 0);
334 if (NULL == sb) {
335 return 0;
336 }
337 } else {
338 // non-client allocation -- abort if it fails
nethercotec314eba2004-07-15 12:59:41 +0000339 sb = VG_(get_memory_from_mmap) ( cszB, "newSuperblock" );
nethercote57e36b32004-07-10 14:56:28 +0000340 }
sewardjde4a1d02002-03-22 01:27:54 +0000341 sb->n_payload_words = cszW - 2;
nethercotec314eba2004-07-15 12:59:41 +0000342 a->bytes_mmaped += cszB;
sewardjde4a1d02002-03-22 01:27:54 +0000343 if (0)
344 VG_(message)(Vg_DebugMsg, "newSuperblock, %d payload words",
345 sb->n_payload_words);
346 return sb;
347}
348
349
350/* Find the superblock containing the given chunk. */
351static
352Superblock* findSb ( Arena* a, UInt* ch )
353{
354 Superblock* sb;
355 for (sb = a->sblocks; sb; sb = sb->next)
356 if (&sb->payload_words[0] <= ch
357 && ch < &sb->payload_words[sb->n_payload_words])
358 return sb;
359 VG_(printf)("findSb: can't find pointer %p in arena `%s'\n",
360 ch, a->name );
njne427a662002-10-02 11:08:25 +0000361 VG_(core_panic)("findSb: vg_free() in wrong arena?");
sewardjde4a1d02002-03-22 01:27:54 +0000362 return NULL; /*NOTREACHED*/
363}
364
365
366/*------------------------------------------------------------*/
367/*--- Low-level functions for working with blocks. ---*/
368/*------------------------------------------------------------*/
369
370/* Add the not-in-use attribute to a bszW. */
371static __inline__
372Int mk_free_bszW ( Int bszW )
373{
374 vg_assert(bszW != 0);
375 return (bszW < 0) ? bszW : -bszW;
376}
377
378/* Add the in-use attribute to a bszW. */
379static __inline__
380Int mk_inuse_bszW ( Int bszW )
381{
382 vg_assert(bszW != 0);
383 return (bszW < 0) ? -bszW : bszW;
384}
385
386/* Remove the in-use/not-in-use attribute from a bszW, leaving just
387 the size. */
388static __inline__
389Int mk_plain_bszW ( Int bszW )
390{
391 vg_assert(bszW != 0);
392 return (bszW < 0) ? -bszW : bszW;
393}
394
395/* Does this bszW have the in-use attribute ? */
396static __inline__
397Bool is_inuse_bszW ( Int bszW )
398{
399 vg_assert(bszW != 0);
400 return (bszW < 0) ? False : True;
401}
402
403
404/* Given the addr of the first word of a block, return the addr of the
405 last word. */
406static __inline__
407WordL* first_to_last ( WordF* fw )
408{
409 return fw + mk_plain_bszW(fw[0]) - 1;
410}
411
412/* Given the addr of the last word of a block, return the addr of the
413 first word. */
414static __inline__
415WordF* last_to_first ( WordL* lw )
416{
417 return lw - mk_plain_bszW(lw[0]) + 1;
418}
419
420
421/* Given the addr of the first word of a block, return the addr of the
422 first word of its payload. */
423static __inline__
424Word* first_to_payload ( Arena* a, WordF* fw )
425{
jsewardb1a26ae2004-03-14 03:06:37 +0000426 return & fw[2 + a->rz_szW];
sewardjde4a1d02002-03-22 01:27:54 +0000427}
428
njn8a6b6c02003-04-22 22:45:55 +0000429/* Given the addr of the first word of the payload of a block,
sewardjde4a1d02002-03-22 01:27:54 +0000430 return the addr of the first word of the block. */
431static __inline__
432Word* payload_to_first ( Arena* a, WordF* payload )
433{
jsewardb1a26ae2004-03-14 03:06:37 +0000434 return & payload[- (2 + a->rz_szW)];
sewardjde4a1d02002-03-22 01:27:54 +0000435}
436
437/* Set and get the lower size field of a block. */
438static __inline__
439void set_bszW_lo ( WordF* fw, Int bszW ) {
440 fw[0] = bszW;
441}
442static __inline__
443Int get_bszW_lo ( WordF* fw )
444{
445 return fw[0];
446}
447
448
449/* Set and get the next and previous link fields of a block. */
450static __inline__
451void set_prev_p ( WordF* fw, Word* prev_p ) {
452 fw[1] = (Word)prev_p;
453}
454static __inline__
jsewardb1a26ae2004-03-14 03:06:37 +0000455void set_next_p ( WordF* fw, Word* next_p ) {
456 WordL* lw = first_to_last(fw);
457 lw[-1] = (Word)next_p;
sewardjde4a1d02002-03-22 01:27:54 +0000458}
459static __inline__
460Word* get_prev_p ( WordF* fw ) {
461 return (Word*)(fw[1]);
462}
463static __inline__
464Word* get_next_p ( WordF* fw ) {
jsewardb1a26ae2004-03-14 03:06:37 +0000465 WordL* lw = first_to_last(fw);
466 return (Word*)(lw[-1]);
sewardjde4a1d02002-03-22 01:27:54 +0000467}
468
469
470/* Set and get the upper size field of a block. */
471static __inline__
472void set_bszW_hi ( WordF* fw, Int bszW ) {
473 WordL* lw = first_to_last(fw);
474 vg_assert(lw == fw + mk_plain_bszW(bszW) - 1);
475 lw[0] = bszW;
476}
477static __inline__
478Int get_bszW_hi ( WordF* fw ) {
479 WordL* lw = first_to_last(fw);
480 return lw[0];
481}
482
483/* Get the upper size field of a block, given a pointer to the last
484 word of it. */
485static __inline__
486Int get_bszW_hi_from_last_word ( WordL* lw ) {
487 WordF* fw = last_to_first(lw);
488 return get_bszW_lo(fw);
489}
490
491
492/* Read and write the lower and upper red-zone words of a block. */
493static __inline__
494void set_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno, Word w )
495{
jsewardb1a26ae2004-03-14 03:06:37 +0000496 fw[2 + rz_wordno] = w;
sewardjde4a1d02002-03-22 01:27:54 +0000497}
498static __inline__
499void set_rz_hi_word ( Arena* a, WordF* fw, Int rz_wordno, Word w )
500{
501 WordL* lw = first_to_last(fw);
jsewardb1a26ae2004-03-14 03:06:37 +0000502 lw[-2-rz_wordno] = w;
sewardjde4a1d02002-03-22 01:27:54 +0000503}
504static __inline__
505Word get_rz_lo_word ( Arena* a, WordF* fw, Int rz_wordno )
506{
jsewardb1a26ae2004-03-14 03:06:37 +0000507 return fw[2 + rz_wordno];
sewardjde4a1d02002-03-22 01:27:54 +0000508}
509static __inline__
510Word get_rz_hi_word ( Arena* a, WordF* fw, Int rz_wordno )
511{
512 WordL* lw = first_to_last(fw);
jsewardb1a26ae2004-03-14 03:06:37 +0000513 return lw[-2-rz_wordno];
sewardjde4a1d02002-03-22 01:27:54 +0000514}
515
516
517/* Return the lower, upper and total overhead in words for a block.
518 These are determined purely by which arena the block lives in. */
519static __inline__
520Int overhead_szW_lo ( Arena* a )
521{
jsewardb1a26ae2004-03-14 03:06:37 +0000522 return 2 + a->rz_szW;
sewardjde4a1d02002-03-22 01:27:54 +0000523}
524static __inline__
525Int overhead_szW_hi ( Arena* a )
526{
jsewardb1a26ae2004-03-14 03:06:37 +0000527 return 2 + a->rz_szW;
sewardjde4a1d02002-03-22 01:27:54 +0000528}
529static __inline__
530Int overhead_szW ( Arena* a )
531{
532 return overhead_szW_lo(a) + overhead_szW_hi(a);
533}
534
535
njn8a6b6c02003-04-22 22:45:55 +0000536/* Convert payload size in words to block size in words, and back. */
sewardjde4a1d02002-03-22 01:27:54 +0000537static __inline__
538Int pszW_to_bszW ( Arena* a, Int pszW )
539{
540 vg_assert(pszW >= 0);
541 return pszW + overhead_szW(a);
542}
543static __inline__
544Int bszW_to_pszW ( Arena* a, Int bszW )
545{
546 Int pszW = bszW - overhead_szW(a);
547 vg_assert(pszW >= 0);
548 return pszW;
549}
550
njn8a6b6c02003-04-22 22:45:55 +0000551Int VG_(arena_payload_szB) ( ArenaId aid, void* ptr )
552{
553 Arena* a = arenaId_to_ArenaP(aid);
554 Word* fw = payload_to_first(a, (WordF*)ptr);
555 Int pszW = bszW_to_pszW(a, get_bszW_lo(fw));
556 return VKI_BYTES_PER_WORD * pszW;
557}
558
559
sewardjde4a1d02002-03-22 01:27:54 +0000560/*------------------------------------------------------------*/
561/*--- Functions for working with freelists. ---*/
562/*------------------------------------------------------------*/
563
564/* Determination of which freelist a block lives on is based on the
565 payload size, not block size, in words. */
566
567/* Convert a payload size in words to a freelist number. */
568
569static
570Int pszW_to_listNo ( Int pszW )
571{
572 vg_assert(pszW >= 0);
573 if (pszW <= 3) return 0;
574 if (pszW <= 4) return 1;
575 if (pszW <= 5) return 2;
576 if (pszW <= 6) return 3;
577 if (pszW <= 7) return 4;
578 if (pszW <= 8) return 5;
579 if (pszW <= 9) return 6;
580 if (pszW <= 10) return 7;
581 if (pszW <= 11) return 8;
582 if (pszW <= 12) return 9;
583 if (pszW <= 16) return 10;
584 if (pszW <= 32) return 11;
585 if (pszW <= 64) return 12;
586 if (pszW <= 128) return 13;
587 if (pszW <= 256) return 14;
588 return 15;
589}
590
591
592/* What are the minimum and maximum payload sizes for a given list? */
593
594static
595Int listNo_to_pszW_min ( Int listNo )
596{
597 Int pszW = 0;
598 vg_assert(listNo >= 0 && listNo <= VG_N_MALLOC_LISTS);
599 while (pszW_to_listNo(pszW) < listNo) pszW++;
600 return pszW;
601}
602
603static
604Int listNo_to_pszW_max ( Int listNo )
605{
606 vg_assert(listNo >= 0 && listNo <= VG_N_MALLOC_LISTS);
607 if (listNo == VG_N_MALLOC_LISTS-1) {
608 return 999999999;
609 } else {
610 return listNo_to_pszW_min(listNo+1) - 1;
611 }
612}
613
614
615/* A nasty hack to try and reduce fragmentation. Try and replace
616 a->freelist[lno] with another block on the same list but with a
617 lower address, with the idea of attempting to recycle the same
618 blocks rather than cruise through the address space. */
619
620static
621void swizzle ( Arena* a, Int lno )
622{
623 UInt* p_best;
624 UInt* pp;
625 UInt* pn;
626 Int i;
627
628 p_best = a->freelist[lno];
629 if (p_best == NULL) return;
630
631 pn = pp = p_best;
632 for (i = 0; i < 20; i++) {
633 pn = get_next_p(pn);
634 pp = get_prev_p(pp);
635 if (pn < p_best) p_best = pn;
636 if (pp < p_best) p_best = pp;
637 }
638 if (p_best < a->freelist[lno]) {
639# ifdef DEBUG_MALLOC
640 VG_(printf)("retreat by %d\n",
641 ((Char*)(a->freelist[lno])) - ((Char*)p_best));
642# endif
643 a->freelist[lno] = p_best;
644 }
645}
646
647
648/*------------------------------------------------------------*/
649/*--- Creating and deleting blocks. ---*/
650/*------------------------------------------------------------*/
651
652/* Mark the words at b .. b+bszW-1 as not in use, and add them to the
653 relevant free list. */
654
655static
656void mkFreeBlock ( Arena* a, Word* b, Int bszW, Int b_lno )
657{
658 Int pszW = bszW_to_pszW(a, bszW);
659 vg_assert(pszW >= 0);
660 vg_assert(b_lno == pszW_to_listNo(pszW));
661 /* Set the size fields and indicate not-in-use. */
662 set_bszW_lo(b, mk_free_bszW(bszW));
663 set_bszW_hi(b, mk_free_bszW(bszW));
664
665 /* Add to the relevant list. */
666 if (a->freelist[b_lno] == NULL) {
667 set_prev_p(b, b);
668 set_next_p(b, b);
669 a->freelist[b_lno] = b;
670 } else {
671 Word* b_prev = get_prev_p(a->freelist[b_lno]);
672 Word* b_next = a->freelist[b_lno];
673 set_next_p(b_prev, b);
674 set_prev_p(b_next, b);
675 set_next_p(b, b_next);
676 set_prev_p(b, b_prev);
677 }
678# ifdef DEBUG_MALLOC
679 (void)blockSane(a,b);
680# endif
681}
682
683
684/* Mark the words at b .. b+bszW-1 as in use, and set up the block
685 appropriately. */
686static
687void mkInuseBlock ( Arena* a, UInt* b, UInt bszW )
688{
689 Int i;
690 set_bszW_lo(b, mk_inuse_bszW(bszW));
691 set_bszW_hi(b, mk_inuse_bszW(bszW));
692 set_prev_p(b, NULL);
693 set_next_p(b, NULL);
694 if (a->rz_check) {
695 for (i = 0; i < a->rz_szW; i++) {
696 set_rz_lo_word(a, b, i, (UInt)b ^ VG_REDZONE_LO_MASK);
697 set_rz_hi_word(a, b, i, (UInt)b ^ VG_REDZONE_HI_MASK);
698 }
699 }
700# ifdef DEBUG_MALLOC
701 (void)blockSane(a,b);
702# endif
703}
704
705
706/* Remove a block from a given list. Does no sanity checking. */
707static
708void unlinkBlock ( Arena* a, UInt* b, Int listno )
709{
710 vg_assert(listno >= 0 && listno < VG_N_MALLOC_LISTS);
711 if (get_prev_p(b) == b) {
712 /* Only one element in the list; treat it specially. */
713 vg_assert(get_next_p(b) == b);
714 a->freelist[listno] = NULL;
715 } else {
716 UInt* b_prev = get_prev_p(b);
717 UInt* b_next = get_next_p(b);
718 a->freelist[listno] = b_prev;
719 set_next_p(b_prev, b_next);
720 set_prev_p(b_next, b_prev);
721 swizzle ( a, listno );
722 }
723 set_prev_p(b, NULL);
724 set_next_p(b, NULL);
725}
726
727
728/* Split an existing free block into two pieces, and put the fragment
729 (the second one along in memory) onto the relevant free list.
730 req_bszW is the required size of the block which isn't the
731 fragment. */
732static
733void splitChunk ( Arena* a, UInt* b, Int b_listno, UInt req_bszW )
734{
sewardj05bcdcb2003-05-18 10:05:38 +0000735 UInt b_bszW;
736 Int frag_bszW;
737 b_bszW = (UInt)mk_plain_bszW(get_bszW_lo(b));
sewardjde4a1d02002-03-22 01:27:54 +0000738 vg_assert(req_bszW < b_bszW);
739 frag_bszW = b_bszW - req_bszW;
740 vg_assert(frag_bszW >= overhead_szW(a));
741 /*
742 printf( "split %d into %d and %d\n",
743 b_bszW,req_bszW,frag_bszW );
744 */
745 vg_assert(bszW_to_pszW(a, frag_bszW) > 0);
746 unlinkBlock(a, b, b_listno);
747 mkInuseBlock(a, b, req_bszW);
748 mkFreeBlock(a, &b[req_bszW], frag_bszW,
749 pszW_to_listNo(bszW_to_pszW(a, frag_bszW)));
750}
751
752
753/*------------------------------------------------------------*/
754/*--- Sanity-check/debugging machinery. ---*/
755/*------------------------------------------------------------*/
756
757/* Do some crude sanity checks on a chunk. */
758static
759Bool blockSane ( Arena* a, Word* b )
760{
761# define BLEAT(str) VG_(printf)("blockSane: fail -- %s\n",str)
762 Int i;
763 if (get_bszW_lo(b) != get_bszW_hi(b))
764 {BLEAT("sizes");return False;}
765 if (a->rz_check && is_inuse_bszW(get_bszW_lo(b))) {
766 for (i = 0; i < a->rz_szW; i++) {
767 if (get_rz_lo_word(a, b, i) != ((Word)b ^ VG_REDZONE_LO_MASK))
768 {BLEAT("redzone-lo");return False;}
769 if (get_rz_hi_word(a, b, i) != ((Word)b ^ VG_REDZONE_HI_MASK))
770 {BLEAT("redzone-hi");return False;}
771 }
772 }
773 return True;
774# undef BLEAT
775}
776
777
778/* Print superblocks (only for debugging). */
779static
780void ppSuperblocks ( Arena* a )
781{
782 Int i, ch_bszW, blockno;
783 UInt* ch;
784 Superblock* sb = a->sblocks;
785 blockno = 1;
786
787 while (sb) {
788 VG_(printf)( "\n" );
789 VG_(printf)( "superblock %d at %p, sb->n_pl_ws = %d, next = %p\n",
790 blockno++, sb, sb->n_payload_words, sb->next );
791 i = 0;
792 while (True) {
793 if (i >= sb->n_payload_words) break;
794 ch = &sb->payload_words[i];
795 ch_bszW = get_bszW_lo(ch);
796 VG_(printf)( " block at %d, bszW %d: ", i, mk_plain_bszW(ch_bszW) );
797 VG_(printf)( "%s, ", is_inuse_bszW(ch_bszW) ? "inuse" : "free" );
798 VG_(printf)( "%s\n", blockSane(a,ch) ? "ok" : "BAD" );
799 i += mk_plain_bszW(ch_bszW);
800 }
801 if (i > sb->n_payload_words)
802 VG_(printf)( " last block overshoots end of SB\n");
803 sb = sb->next;
804 }
805 VG_(printf)( "end of superblocks\n\n" );
806}
807
808
809/* Sanity check both the superblocks and the chains. */
njn25e49d8e72002-09-23 09:36:25 +0000810static void mallocSanityCheckArena ( ArenaId aid )
sewardjde4a1d02002-03-22 01:27:54 +0000811{
812 Int i, superblockctr, b_bszW, b_pszW, blockctr_sb, blockctr_li;
813 Int blockctr_sb_free, listno, list_min_pszW, list_max_pszW;
814 Superblock* sb;
815 Bool thisFree, lastWasFree;
816 Word* b;
817 Word* b_prev;
818 UInt arena_bytes_on_loan;
819 Arena* a;
820
njne427a662002-10-02 11:08:25 +0000821# define BOMB VG_(core_panic)("mallocSanityCheckArena")
sewardjde4a1d02002-03-22 01:27:54 +0000822
823 a = arenaId_to_ArenaP(aid);
824
825 /* First, traverse all the superblocks, inspecting the chunks in
826 each. */
827 superblockctr = blockctr_sb = blockctr_sb_free = 0;
828 arena_bytes_on_loan = 0;
829 sb = a->sblocks;
830 while (sb) {
831 lastWasFree = False;
832 superblockctr++;
833 i = 0;
834 while (True) {
835 if (i >= sb->n_payload_words) break;
836 blockctr_sb++;
837 b = &sb->payload_words[i];
838 b_bszW = get_bszW_lo(b);
839 if (!blockSane(a, b)) {
njn25e49d8e72002-09-23 09:36:25 +0000840 VG_(printf)("mallocSanityCheckArena: sb %p, block %d (bszW %d): "
841 " BAD\n",
sewardjde4a1d02002-03-22 01:27:54 +0000842 sb, i, b_bszW );
843 BOMB;
844 }
845 thisFree = !is_inuse_bszW(b_bszW);
846 if (thisFree && lastWasFree) {
njn25e49d8e72002-09-23 09:36:25 +0000847 VG_(printf)("mallocSanityCheckArena: sb %p, block %d (bszW %d): "
848 "UNMERGED FREES\n",
sewardjde4a1d02002-03-22 01:27:54 +0000849 sb, i, b_bszW );
850 BOMB;
851 }
852 lastWasFree = thisFree;
853 if (thisFree) blockctr_sb_free++;
854 if (!thisFree)
855 arena_bytes_on_loan += sizeof(Word) * bszW_to_pszW(a, b_bszW);
856 i += mk_plain_bszW(b_bszW);
857 }
858 if (i > sb->n_payload_words) {
njn25e49d8e72002-09-23 09:36:25 +0000859 VG_(printf)( "mallocSanityCheckArena: sb %p: last block "
sewardjde4a1d02002-03-22 01:27:54 +0000860 "overshoots end\n", sb);
861 BOMB;
862 }
863 sb = sb->next;
864 }
865
866 if (arena_bytes_on_loan != a->bytes_on_loan) {
867 VG_(printf)(
njn25e49d8e72002-09-23 09:36:25 +0000868 "mallocSanityCheckArena: a->bytes_on_loan %d, "
sewardjde4a1d02002-03-22 01:27:54 +0000869 "arena_bytes_on_loan %d: "
870 "MISMATCH\n", a->bytes_on_loan, arena_bytes_on_loan);
871 ppSuperblocks(a);
872 BOMB;
873 }
874
875 /* Second, traverse each list, checking that the back pointers make
876 sense, counting blocks encountered, and checking that each block
877 is an appropriate size for this list. */
878 blockctr_li = 0;
879 for (listno = 0; listno < VG_N_MALLOC_LISTS; listno++) {
880 list_min_pszW = listNo_to_pszW_min(listno);
881 list_max_pszW = listNo_to_pszW_max(listno);
882 b = a->freelist[listno];
883 if (b == NULL) continue;
884 while (True) {
885 b_prev = b;
886 b = get_next_p(b);
887 if (get_prev_p(b) != b_prev) {
njn25e49d8e72002-09-23 09:36:25 +0000888 VG_(printf)( "mallocSanityCheckArena: list %d at %p: "
sewardjde4a1d02002-03-22 01:27:54 +0000889 "BAD LINKAGE\n",
890 listno, b );
891 BOMB;
892 }
893 b_pszW = bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b)));
894 if (b_pszW < list_min_pszW || b_pszW > list_max_pszW) {
895 VG_(printf)(
njn25e49d8e72002-09-23 09:36:25 +0000896 "mallocSanityCheckArena: list %d at %p: "
sewardjde4a1d02002-03-22 01:27:54 +0000897 "WRONG CHAIN SIZE %d (%d, %d)\n",
898 listno, b, b_pszW, list_min_pszW, list_max_pszW );
899 BOMB;
900 }
901 blockctr_li++;
902 if (b == a->freelist[listno]) break;
903 }
904 }
905
906 if (blockctr_sb_free != blockctr_li) {
907 VG_(printf)(
njn25e49d8e72002-09-23 09:36:25 +0000908 "mallocSanityCheckArena: BLOCK COUNT MISMATCH "
sewardjde4a1d02002-03-22 01:27:54 +0000909 "(via sbs %d, via lists %d)\n",
910 blockctr_sb_free, blockctr_li );
911 ppSuperblocks(a);
912 BOMB;
913 }
914
915 VG_(message)(Vg_DebugMsg,
njn3e884182003-04-15 13:03:23 +0000916 "mSC [%8s]: %2d sbs, %5d tot bs, %4d/%-4d free bs, "
sewardjde4a1d02002-03-22 01:27:54 +0000917 "%2d lists, %7d mmap, %7d loan",
918 a->name,
919 superblockctr,
920 blockctr_sb, blockctr_sb_free, blockctr_li,
921 VG_N_MALLOC_LISTS,
922 a->bytes_mmaped, a->bytes_on_loan);
923# undef BOMB
924}
925
926
927void VG_(mallocSanityCheckAll) ( void )
928{
929 Int i;
930 for (i = 0; i < VG_N_ARENAS; i++)
njn25e49d8e72002-09-23 09:36:25 +0000931 mallocSanityCheckArena ( i );
sewardjde4a1d02002-03-22 01:27:54 +0000932}
933
934
935/* Really, this isn't the right place for this. Nevertheless: find
936 out if an arena is empty -- currently has no bytes on loan. This
937 is useful for checking for memory leaks (of valgrind, not the
938 client.)
939*/
940Bool VG_(is_empty_arena) ( ArenaId aid )
941{
942 Arena* a;
943 Superblock* sb;
944 WordF* b;
945 Int b_bszW;
njn25e49d8e72002-09-23 09:36:25 +0000946
sewardjde4a1d02002-03-22 01:27:54 +0000947 ensure_mm_init();
948 a = arenaId_to_ArenaP(aid);
949 for (sb = a->sblocks; sb != NULL; sb = sb->next) {
950 /* If the superblock is empty, it should contain a single free
951 block, of the right size. */
952 b = &(sb->payload_words[0]);
953 b_bszW = get_bszW_lo(b);
954 if (is_inuse_bszW(b_bszW)) return False;
955 if (mk_plain_bszW(b_bszW) != sb->n_payload_words) return False;
956 /* So this block is not in use and is of the right size. Keep
957 going. */
958 }
959 return True;
960}
961
962
jsewardb1a26ae2004-03-14 03:06:37 +0000963/* Turn a request size in bytes into a payload request size in
964 words. This means 8-aligning the request size.
965*/
966static __inline__
967Int req_pszB_to_req_pszW ( Int req_pszB )
968{
969 return ((req_pszB + 7) / 8) /* # of 64-bit units */
970 * 2; /* # of 32-bit units */
971}
972
973
sewardjde4a1d02002-03-22 01:27:54 +0000974/*------------------------------------------------------------*/
njn25e49d8e72002-09-23 09:36:25 +0000975/*--- Core-visible functions. ---*/
sewardjde4a1d02002-03-22 01:27:54 +0000976/*------------------------------------------------------------*/
977
njn25e49d8e72002-09-23 09:36:25 +0000978void* VG_(arena_malloc) ( ArenaId aid, Int req_pszB )
sewardjde4a1d02002-03-22 01:27:54 +0000979{
980 Int req_pszW, req_bszW, frag_bszW, b_bszW, lno;
981 Superblock* new_sb;
982 Word* b;
983 Arena* a;
jsewardb1a26ae2004-03-14 03:06:37 +0000984 void* v;
sewardjde4a1d02002-03-22 01:27:54 +0000985
986 VGP_PUSHCC(VgpMalloc);
987
988 ensure_mm_init();
989 a = arenaId_to_ArenaP(aid);
990
991 vg_assert(req_pszB >= 0);
992 vg_assert(req_pszB < 0x7FFFFFF0);
993
jsewardb1a26ae2004-03-14 03:06:37 +0000994 req_pszW = req_pszB_to_req_pszW(req_pszB);
sewardjde4a1d02002-03-22 01:27:54 +0000995
996 /* Keep gcc -O happy: */
997 b = NULL;
998
999 /* Start searching at this list. */
1000 lno = pszW_to_listNo(req_pszW);
1001
1002 /* This loop finds a list which has a block big enough, or sets
1003 req_listno to N_LISTS if no such block exists. */
1004 while (True) {
1005 if (lno == VG_N_MALLOC_LISTS) break;
1006 /* If this list is empty, try the next one. */
1007 if (a->freelist[lno] == NULL) {
1008 lno++;
1009 continue;
1010 }
1011 /* Scan a->list[lno] to find a big-enough chunk. */
1012 b = a->freelist[lno];
1013 b_bszW = mk_plain_bszW(get_bszW_lo(b));
1014 while (True) {
1015 if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
1016 b = get_next_p(b);
1017 b_bszW = mk_plain_bszW(get_bszW_lo(b));
1018 if (b == a->freelist[lno]) break;
1019 }
1020 if (bszW_to_pszW(a, b_bszW) >= req_pszW) break;
1021 /* No luck? Try a larger list. */
1022 lno++;
1023 }
1024
1025 /* Either lno < VG_N_MALLOC_LISTS and b points to the selected
1026 block, or lno == VG_N_MALLOC_LISTS, and we have to allocate a
1027 new superblock. */
1028
1029 if (lno == VG_N_MALLOC_LISTS) {
1030 req_bszW = pszW_to_bszW(a, req_pszW);
1031 new_sb = newSuperblock(a, req_bszW);
nethercote57e36b32004-07-10 14:56:28 +00001032 if (NULL == new_sb) {
1033 // Should only fail if for client, otherwise, should have aborted
1034 // already.
1035 vg_assert(VG_AR_CLIENT == aid);
1036 return NULL;
1037 }
sewardjde4a1d02002-03-22 01:27:54 +00001038 new_sb->next = a->sblocks;
1039 a->sblocks = new_sb;
1040 b = &(new_sb->payload_words[0]);
1041 lno = pszW_to_listNo(bszW_to_pszW(a, new_sb->n_payload_words));
1042 mkFreeBlock ( a, b, new_sb->n_payload_words, lno);
1043 }
1044
1045 /* Ok, we can allocate from b, which lives in list req_listno. */
1046 vg_assert(b != NULL);
1047 vg_assert(lno >= 0 && lno < VG_N_MALLOC_LISTS);
1048 vg_assert(a->freelist[lno] != NULL);
1049 b_bszW = mk_plain_bszW(get_bszW_lo(b));
1050 req_bszW = pszW_to_bszW(a, req_pszW);
1051 /* req_bszW is the size of the block we are after. b_bszW is the
1052 size of what we've actually got. */
1053 vg_assert(b_bszW >= req_bszW);
1054
1055 /* Could we split this block and still get a useful fragment?
1056 Where "useful" means that the payload size of the frag is at
1057 least one word. */
1058 frag_bszW = b_bszW - req_bszW;
1059 if (frag_bszW > overhead_szW(a)) {
1060 splitChunk(a, b, lno, req_bszW);
1061 } else {
1062 /* No, mark as in use and use as-is. */
1063 unlinkBlock(a, b, lno);
1064 /*
1065 set_bszW_lo(b, mk_inuse_bszW(b_bszW));
1066 set_bszW_hi(b, mk_inuse_bszW(b_bszW));
1067 */
1068 mkInuseBlock(a, b, b_bszW);
1069 }
1070 vg_assert(req_bszW <= mk_plain_bszW(get_bszW_lo(b)));
1071
1072 a->bytes_on_loan
1073 += sizeof(Word)
1074 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(b)));
1075 if (a->bytes_on_loan > a->bytes_on_loan_max)
1076 a->bytes_on_loan_max = a->bytes_on_loan;
1077
1078# ifdef DEBUG_MALLOC
njn25e49d8e72002-09-23 09:36:25 +00001079 mallocSanityCheckArena(aid);
sewardjde4a1d02002-03-22 01:27:54 +00001080# endif
1081
njn25e49d8e72002-09-23 09:36:25 +00001082 VGP_POPCC(VgpMalloc);
jsewardb1a26ae2004-03-14 03:06:37 +00001083 v = first_to_payload(a, b);
1084 vg_assert( (((UInt)v) & 7) == 0 );
1085 return v;
sewardjde4a1d02002-03-22 01:27:54 +00001086}
1087
1088
njn25e49d8e72002-09-23 09:36:25 +00001089void VG_(arena_free) ( ArenaId aid, void* ptr )
sewardjde4a1d02002-03-22 01:27:54 +00001090{
1091 Superblock* sb;
1092 UInt* sb_payl_firstw;
1093 UInt* sb_payl_lastw;
1094 UInt* other;
1095 UInt* ch;
1096 Int ch_bszW, ch_pszW, other_bszW, ch_listno;
1097 Arena* a;
1098
1099 VGP_PUSHCC(VgpMalloc);
1100
1101 ensure_mm_init();
1102 a = arenaId_to_ArenaP(aid);
1103
njn25e49d8e72002-09-23 09:36:25 +00001104 if (ptr == NULL) {
1105 VGP_POPCC(VgpMalloc);
1106 return;
1107 }
1108
sewardjde4a1d02002-03-22 01:27:54 +00001109 ch = payload_to_first(a, ptr);
1110
1111# ifdef DEBUG_MALLOC
1112 vg_assert(blockSane(a,ch));
1113# endif
1114
1115 a->bytes_on_loan
1116 -= sizeof(Word)
1117 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(ch)));
1118
1119 sb = findSb( a, ch );
1120 sb_payl_firstw = &(sb->payload_words[0]);
1121 sb_payl_lastw = &(sb->payload_words[sb->n_payload_words-1]);
1122
1123 /* Put this chunk back on a list somewhere. */
1124 ch_bszW = get_bszW_lo(ch);
1125 ch_pszW = bszW_to_pszW(a, ch_bszW);
1126 ch_listno = pszW_to_listNo(ch_pszW);
1127 mkFreeBlock( a, ch, ch_bszW, ch_listno );
1128
1129 /* See if this block can be merged with the following one. */
1130 other = ch + ch_bszW;
1131 /* overhead_szW(a) is the smallest possible bszW for this arena.
1132 So the nearest possible end to the block beginning at other is
1133 other+overhead_szW(a)-1. Hence the test below. */
1134 if (other+overhead_szW(a)-1 <= sb_payl_lastw) {
1135 other_bszW = get_bszW_lo(other);
1136 if (!is_inuse_bszW(other_bszW)) {
1137 /* VG_(printf)( "merge-successor\n"); */
1138 other_bszW = mk_plain_bszW(other_bszW);
1139# ifdef DEBUG_MALLOC
1140 vg_assert(blockSane(a, other));
1141# endif
1142 unlinkBlock( a, ch, ch_listno );
1143 unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a,other_bszW)) );
1144 ch_bszW += other_bszW;
1145 ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
1146 mkFreeBlock( a, ch, ch_bszW, ch_listno );
1147 }
1148 }
1149
1150 /* See if this block can be merged with its predecessor. */
1151 if (ch-overhead_szW(a) >= sb_payl_firstw) {
1152 other_bszW = get_bszW_hi_from_last_word( ch-1 );
1153 if (!is_inuse_bszW(other_bszW)) {
1154 /* VG_(printf)( "merge-predecessor\n"); */
1155 other = last_to_first( ch-1 );
1156 other_bszW = mk_plain_bszW(other_bszW);
1157 unlinkBlock( a, ch, ch_listno );
1158 unlinkBlock( a, other, pszW_to_listNo(bszW_to_pszW(a, other_bszW)) );
1159 ch = other;
1160 ch_bszW += other_bszW;
1161 ch_listno = pszW_to_listNo(bszW_to_pszW(a, ch_bszW));
1162 mkFreeBlock( a, ch, ch_bszW, ch_listno );
1163 }
1164 }
1165
1166# ifdef DEBUG_MALLOC
njn25e49d8e72002-09-23 09:36:25 +00001167 mallocSanityCheckArena(aid);
sewardjde4a1d02002-03-22 01:27:54 +00001168# endif
1169
njn25e49d8e72002-09-23 09:36:25 +00001170 VGP_POPCC(VgpMalloc);
sewardjde4a1d02002-03-22 01:27:54 +00001171}
1172
1173
1174/*
1175 The idea for malloc_aligned() is to allocate a big block, base, and
1176 then split it into two parts: frag, which is returned to the the
1177 free pool, and align, which is the bit we're really after. Here's
1178 a picture. L and H denote the block lower and upper overheads, in
1179 words. The details are gruesome. Note it is slightly complicated
1180 because the initial request to generate base may return a bigger
1181 block than we asked for, so it is important to distinguish the base
1182 request size and the base actual size.
1183
1184 frag_b align_b
1185 | |
1186 | frag_p | align_p
1187 | | | |
1188 v v v v
1189
1190 +---+ +---+---+ +---+
1191 | L |----------------| H | L |---------------| H |
1192 +---+ +---+---+ +---+
1193
1194 ^ ^ ^
1195 | | :
1196 | base_p this addr must be aligned
1197 |
1198 base_b
1199
1200 . . . . . . .
1201 <------ frag_bszW -------> . . .
1202 . <------------- base_pszW_act -----------> .
1203 . . . . . . .
1204
1205*/
njn25e49d8e72002-09-23 09:36:25 +00001206void* VG_(arena_malloc_aligned) ( ArenaId aid, Int req_alignB, Int req_pszB )
sewardjde4a1d02002-03-22 01:27:54 +00001207{
1208 Int req_alignW, req_pszW, base_pszW_req, base_pszW_act, frag_bszW;
1209 Word *base_b, *base_p, *align_p;
1210 UInt saved_bytes_on_loan;
1211 Arena* a;
jsewardb1a26ae2004-03-14 03:06:37 +00001212 void* v;
sewardjde4a1d02002-03-22 01:27:54 +00001213
njn25e49d8e72002-09-23 09:36:25 +00001214 VGP_PUSHCC(VgpMalloc);
1215
sewardjde4a1d02002-03-22 01:27:54 +00001216 ensure_mm_init();
1217 a = arenaId_to_ArenaP(aid);
1218
1219 vg_assert(req_pszB >= 0);
1220 vg_assert(req_pszB < 0x7FFFFFF0);
1221
1222 /* Check that the requested alignment seems reasonable; that is, is
sewardjb5045ef2002-06-04 16:48:29 +00001223 a power of 2. */
sewardjde4a1d02002-03-22 01:27:54 +00001224 switch (req_alignB) {
sewardjc76be292002-04-24 20:32:50 +00001225 case 4:
sewardjde4a1d02002-03-22 01:27:54 +00001226 case 8: case 16: case 32: case 64: case 128: case 256:
1227 case 512: case 1024: case 2048: case 4096: case 8192:
1228 case 16384: case 32768: case 65536: case 131072:
sewardjb5045ef2002-06-04 16:48:29 +00001229 case 262144:
sewardjde4a1d02002-03-22 01:27:54 +00001230 case 1048576:
1231 /* can't be bothered to calculate larger ones */
1232 break;
1233 default:
1234 VG_(printf)("vg_malloc_aligned(%p, %d, %d)\nbad alignment request",
njn25e49d8e72002-09-23 09:36:25 +00001235 a, req_alignB, req_pszB );
njne427a662002-10-02 11:08:25 +00001236 VG_(core_panic)("vg_malloc_aligned");
sewardjde4a1d02002-03-22 01:27:54 +00001237 /*NOTREACHED*/
1238 }
1239
1240 /* Required alignment, in words. Since it's constrained to be a
1241 power of 2 >= word size, no need to align the alignment. Still,
1242 we check. */
jsewardb1a26ae2004-03-14 03:06:37 +00001243 if (req_alignB == 4) req_alignB = 8;
sewardjde4a1d02002-03-22 01:27:54 +00001244 req_alignW = req_alignB / VKI_BYTES_PER_WORD;
1245 vg_assert(req_alignB == req_alignW * VKI_BYTES_PER_WORD);
1246
1247 /* Required payload size for the aligned chunk. */
jsewardb1a26ae2004-03-14 03:06:37 +00001248 req_pszW = req_pszB_to_req_pszW(req_pszB);
sewardjde4a1d02002-03-22 01:27:54 +00001249
1250 /* Payload size to request for the big block that we will split
1251 up. */
1252 base_pszW_req = req_pszW + overhead_szW(a) + req_alignW;
1253
1254 /* Payload ptr for the block we are going to split. Note this
1255 changes a->bytes_on_loan; we save and restore it ourselves. */
1256 saved_bytes_on_loan = a->bytes_on_loan;
njn25e49d8e72002-09-23 09:36:25 +00001257 base_p = VG_(arena_malloc) ( aid, base_pszW_req * VKI_BYTES_PER_WORD );
sewardjde4a1d02002-03-22 01:27:54 +00001258 a->bytes_on_loan = saved_bytes_on_loan;
1259
1260 /* Block ptr for the block we are going to split. */
1261 base_b = payload_to_first ( a, base_p );
1262
1263 /* Pointer to the payload of the aligned block we are going to
1264 return. This has to be suitably aligned. */
1265 align_p = align_upwards ( base_b + 2 * overhead_szW_lo(a)
1266 + overhead_szW_hi(a),
1267 req_alignB );
1268
1269 /* The block size of the fragment we will create. This must be big
1270 enough to actually create a fragment. */
1271 frag_bszW = align_p - overhead_szW_lo(a) - base_b;
1272 vg_assert(frag_bszW >= overhead_szW(a));
1273
1274 /* The actual payload size of the block we are going to split. */
1275 base_pszW_act = bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(base_b)));
1276
1277 /* Create the fragment block, and put it back on the relevant free
1278 list. */
1279 mkFreeBlock ( a, base_b, frag_bszW,
1280 pszW_to_listNo(bszW_to_pszW(a, frag_bszW)) );
1281
1282 /* Create the aligned block. */
1283 mkInuseBlock ( a,
1284 align_p - overhead_szW_lo(a),
1285 base_p + base_pszW_act
1286 + overhead_szW_hi(a)
1287 - (align_p - overhead_szW_lo(a)) );
1288
1289 /* Final sanity checks. */
1290 vg_assert(( (UInt)align_p % req_alignB) == 0);
1291
1292 vg_assert(is_inuse_bszW(get_bszW_lo(payload_to_first(a, align_p))));
1293
1294 vg_assert(req_pszW
1295 <=
1296 bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(
1297 payload_to_first(a, align_p))))
1298 );
1299
1300 a->bytes_on_loan
1301 += sizeof(Word)
1302 * bszW_to_pszW(a, mk_plain_bszW(get_bszW_lo(
1303 payload_to_first(a, align_p))));
1304 if (a->bytes_on_loan > a->bytes_on_loan_max)
1305 a->bytes_on_loan_max = a->bytes_on_loan;
1306
1307# ifdef DEBUG_MALLOC
njn25e49d8e72002-09-23 09:36:25 +00001308 mallocSanityCheckArena(aid);
sewardjde4a1d02002-03-22 01:27:54 +00001309# endif
1310
njn25e49d8e72002-09-23 09:36:25 +00001311 VGP_POPCC(VgpMalloc);
1312
jsewardb1a26ae2004-03-14 03:06:37 +00001313 v = (void*)align_p;
1314 vg_assert( (((UInt)v) % req_alignB) == 0 );
1315 return v;
sewardjde4a1d02002-03-22 01:27:54 +00001316}
1317
1318
1319/*------------------------------------------------------------*/
1320/*--- Services layered on top of malloc/free. ---*/
1321/*------------------------------------------------------------*/
1322
njn3e884182003-04-15 13:03:23 +00001323void* VG_(arena_calloc) ( ArenaId aid, Int alignB, Int nmemb, Int nbytes )
sewardjde4a1d02002-03-22 01:27:54 +00001324{
1325 Int i, size;
1326 UChar* p;
njn25e49d8e72002-09-23 09:36:25 +00001327
1328 VGP_PUSHCC(VgpMalloc);
1329
sewardjde4a1d02002-03-22 01:27:54 +00001330 size = nmemb * nbytes;
sewardjd0b9ac32002-05-01 00:10:28 +00001331 vg_assert(size >= 0);
njn3e884182003-04-15 13:03:23 +00001332
jsewardb1a26ae2004-03-14 03:06:37 +00001333 if (alignB == 8)
njn3e884182003-04-15 13:03:23 +00001334 p = VG_(arena_malloc) ( aid, size );
1335 else
1336 p = VG_(arena_malloc_aligned) ( aid, alignB, size );
1337
sewardjde4a1d02002-03-22 01:27:54 +00001338 for (i = 0; i < size; i++) p[i] = 0;
njn25e49d8e72002-09-23 09:36:25 +00001339
1340 VGP_POPCC(VgpMalloc);
1341
sewardjde4a1d02002-03-22 01:27:54 +00001342 return p;
1343}
1344
1345
njn25e49d8e72002-09-23 09:36:25 +00001346void* VG_(arena_realloc) ( ArenaId aid, void* ptr,
jsewardb1a26ae2004-03-14 03:06:37 +00001347 Int req_alignB, Int req_pszB )
sewardjde4a1d02002-03-22 01:27:54 +00001348{
1349 Arena* a;
1350 Int old_bszW, old_pszW, old_pszB, i;
1351 UChar *p_old, *p_new;
1352 UInt* ch;
1353
njn25e49d8e72002-09-23 09:36:25 +00001354 VGP_PUSHCC(VgpMalloc);
1355
sewardjde4a1d02002-03-22 01:27:54 +00001356 ensure_mm_init();
1357 a = arenaId_to_ArenaP(aid);
1358
1359 vg_assert(req_pszB >= 0);
1360 vg_assert(req_pszB < 0x7FFFFFF0);
1361
1362 ch = payload_to_first(a, ptr);
1363 vg_assert(blockSane(a, ch));
1364
1365 old_bszW = get_bszW_lo(ch);
1366 vg_assert(is_inuse_bszW(old_bszW));
1367 old_bszW = mk_plain_bszW(old_bszW);
1368 old_pszW = bszW_to_pszW(a, old_bszW);
1369 old_pszB = old_pszW * VKI_BYTES_PER_WORD;
1370
njn25e49d8e72002-09-23 09:36:25 +00001371 if (req_pszB <= old_pszB) {
1372 VGP_POPCC(VgpMalloc);
1373 return ptr;
1374 }
sewardjde4a1d02002-03-22 01:27:54 +00001375
jsewardb1a26ae2004-03-14 03:06:37 +00001376 if (req_alignB == 8)
njn25e49d8e72002-09-23 09:36:25 +00001377 p_new = VG_(arena_malloc) ( aid, req_pszB );
1378 else
1379 p_new = VG_(arena_malloc_aligned) ( aid, req_alignB, req_pszB );
1380
sewardjde4a1d02002-03-22 01:27:54 +00001381 p_old = (UChar*)ptr;
1382 for (i = 0; i < old_pszB; i++)
1383 p_new[i] = p_old[i];
1384
njn25e49d8e72002-09-23 09:36:25 +00001385 VG_(arena_free)(aid, p_old);
1386
1387 VGP_POPCC(VgpMalloc);
sewardjde4a1d02002-03-22 01:27:54 +00001388 return p_new;
1389}
1390
1391
1392/*------------------------------------------------------------*/
nethercote996901a2004-08-03 13:29:09 +00001393/*--- Tool-visible functions. ---*/
njn25e49d8e72002-09-23 09:36:25 +00001394/*------------------------------------------------------------*/
1395
nethercote7cc9c232004-01-21 15:08:04 +00001396/* All just wrappers to avoid exposing arenas to tools */
njn25e49d8e72002-09-23 09:36:25 +00001397
1398void* VG_(malloc) ( Int nbytes )
1399{
nethercote60f5b822004-01-26 17:24:42 +00001400 return VG_(arena_malloc) ( VG_AR_TOOL, nbytes );
njn25e49d8e72002-09-23 09:36:25 +00001401}
1402
1403void VG_(free) ( void* ptr )
1404{
nethercote60f5b822004-01-26 17:24:42 +00001405 VG_(arena_free) ( VG_AR_TOOL, ptr );
njn25e49d8e72002-09-23 09:36:25 +00001406}
1407
1408void* VG_(calloc) ( Int nmemb, Int nbytes )
1409{
jsewardb1a26ae2004-03-14 03:06:37 +00001410 return VG_(arena_calloc) ( VG_AR_TOOL, /*alignment*/8, nmemb, nbytes );
njn25e49d8e72002-09-23 09:36:25 +00001411}
1412
1413void* VG_(realloc) ( void* ptr, Int size )
1414{
jsewardb1a26ae2004-03-14 03:06:37 +00001415 return VG_(arena_realloc) ( VG_AR_TOOL, ptr, /*alignment*/8, size );
njn25e49d8e72002-09-23 09:36:25 +00001416}
1417
1418void* VG_(malloc_aligned) ( Int req_alignB, Int req_pszB )
1419{
nethercote60f5b822004-01-26 17:24:42 +00001420 return VG_(arena_malloc_aligned) ( VG_AR_TOOL, req_alignB, req_pszB );
njn25e49d8e72002-09-23 09:36:25 +00001421}
1422
1423
njn3e884182003-04-15 13:03:23 +00001424void* VG_(cli_malloc) ( UInt align, Int nbytes )
1425{
jsewardb1a26ae2004-03-14 03:06:37 +00001426 vg_assert(align >= 8);
1427 if (8 == align)
njn3e884182003-04-15 13:03:23 +00001428 return VG_(arena_malloc) ( VG_AR_CLIENT, nbytes );
1429 else
sewardjf1accbc2003-07-12 01:26:52 +00001430 return VG_(arena_malloc_aligned) ( VG_AR_CLIENT, align, nbytes );
njn3e884182003-04-15 13:03:23 +00001431}
1432
1433void VG_(cli_free) ( void* p )
1434{
1435 VG_(arena_free) ( VG_AR_CLIENT, p );
1436}
1437
1438
1439Bool VG_(addr_is_in_block)( Addr a, Addr start, UInt size )
1440{
1441 return (start - VG_(vg_malloc_redzone_szB) <= a
1442 && a < start + size + VG_(vg_malloc_redzone_szB));
1443}
1444
1445
njn25e49d8e72002-09-23 09:36:25 +00001446/*------------------------------------------------------------*/
sewardjde4a1d02002-03-22 01:27:54 +00001447/*--- The original test driver machinery. ---*/
1448/*------------------------------------------------------------*/
1449
1450#if 0
1451
1452#if 1
1453#define N_TEST_TRANSACTIONS 100000000
1454#define N_TEST_ARR 200000
1455#define M_TEST_MALLOC 1000
1456#else
1457#define N_TEST_TRANSACTIONS 500000
1458#define N_TEST_ARR 30000
1459#define M_TEST_MALLOC 500
1460#endif
1461
1462
1463void* test_arr[N_TEST_ARR];
1464
1465int main ( int argc, char** argv )
1466{
1467 Int i, j, k, nbytes, qq;
1468 unsigned char* chp;
njn25e49d8e72002-09-23 09:36:25 +00001469 Arena* a = &arena[VG_AR_CORE];
sewardjde4a1d02002-03-22 01:27:54 +00001470 srandom(1);
1471 for (i = 0; i < N_TEST_ARR; i++)
1472 test_arr[i] = NULL;
1473
1474 for (i = 0; i < N_TEST_TRANSACTIONS; i++) {
1475 if (i % 50000 == 0) mallocSanityCheck(a);
1476 j = random() % N_TEST_ARR;
1477 if (test_arr[j]) {
1478 vg_free(a, test_arr[j]);
1479 test_arr[j] = NULL;
1480 } else {
1481 nbytes = 1 + random() % M_TEST_MALLOC;
1482 qq = random()%64;
1483 if (qq == 32)
1484 nbytes *= 17;
1485 else if (qq == 33)
1486 nbytes = 0;
1487 test_arr[j]
1488 = (i % 17) == 0
1489 ? vg_memalign(a, nbytes, 1<< (3+(random()%10)))
1490 : vg_malloc( a, nbytes );
1491 chp = test_arr[j];
1492 for (k = 0; k < nbytes; k++)
1493 chp[k] = (unsigned char)(k + 99);
1494 }
1495 }
1496
1497
1498 for (i = 0; i < N_TEST_ARR; i++) {
1499 if (test_arr[i]) {
1500 vg_free(a, test_arr[i]);
1501 test_arr[i] = NULL;
1502 }
1503 }
1504 mallocSanityCheck(a);
1505
1506 fprintf(stderr, "ALL DONE\n");
1507
1508 show_arena_stats(a);
1509 fprintf(stderr, "%d max useful, %d bytes mmap'd (%4.1f%%), %d useful\n",
1510 a->bytes_on_loan_max,
1511 a->bytes_mmaped,
1512 100.0 * (double)a->bytes_on_loan_max / (double)a->bytes_mmaped,
1513 a->bytes_on_loan );
1514
1515 return 0;
1516}
1517#endif /* 0 */
1518
1519
1520/*--------------------------------------------------------------------*/
1521/*--- end vg_malloc2.c ---*/
1522/*--------------------------------------------------------------------*/