Upgrade Boehm GC to 7.2alpha4.
[cacao.git] / src / mm / boehm-gc / allchblk.c
1 /*
2  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
4  * Copyright (c) 1998-1999 by Silicon Graphics.  All rights reserved.
5  * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved.
6  *
7  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9  *
10  * Permission is hereby granted to use or copy this program
11  * for any purpose,  provided the above notices are retained on all copies.
12  * Permission to modify the code and to distribute modified code is granted,
13  * provided the above notices are retained, and a notice that the code was
14  * modified is included with the above copyright notice.
15  */
16
17 #include "private/gc_priv.h"
18
19 #include <stdio.h>
20
21 GC_bool GC_use_entire_heap = 0;
22
23 /*
24  * Free heap blocks are kept on one of several free lists,
25  * depending on the size of the block.  Each free list is doubly linked.
26  * Adjacent free blocks are coalesced.
27  */
28
29
30 # define MAX_BLACK_LIST_ALLOC (2*HBLKSIZE)
31                 /* largest block we will allocate starting on a black   */
32                 /* listed block.  Must be >= HBLKSIZE.                  */
33
34
35 # define UNIQUE_THRESHOLD 32
36         /* Sizes up to this many HBLKs each have their own free list    */
37 # define HUGE_THRESHOLD 256
38         /* Sizes of at least this many heap blocks are mapped to a      */
39         /* single free list.                                            */
40 # define FL_COMPRESSION 8
41         /* In between sizes map this many distinct sizes to a single    */
42         /* bin.                                                         */
43
44 # define N_HBLK_FLS (HUGE_THRESHOLD - UNIQUE_THRESHOLD)/FL_COMPRESSION \
45                                  + UNIQUE_THRESHOLD
46
47 STATIC struct hblk * GC_hblkfreelist[N_HBLK_FLS+1] = { 0 };
48                                 /* List of completely empty heap blocks */
49                                 /* Linked through hb_next field of      */
50                                 /* header structure associated with     */
51                                 /* block.                               */
52
53 #ifndef USE_MUNMAP
54
55   STATIC word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
56         /* Number of free bytes on each list.   */
57
58   /* Return the largest n such that                                     */
59   /* Is GC_large_allocd_bytes + the number of free bytes on lists       */
60   /* n .. N_HBLK_FLS > GC_max_large_allocd_bytes.                       */
61   /* If there is no such n, return 0.                                   */
62   GC_INLINE int GC_enough_large_bytes_left(void)
63   {
64     int n;
65     word bytes = GC_large_allocd_bytes;
66
67     GC_ASSERT(GC_max_large_allocd_bytes <= GC_heapsize);
68     for (n = N_HBLK_FLS; n >= 0; --n) {
69         bytes += GC_free_bytes[n];
70         if (bytes >= GC_max_large_allocd_bytes) return n;
71     }
72     return 0;
73   }
74
75 # define INCR_FREE_BYTES(n, b) GC_free_bytes[n] += (b);
76
77 # define FREE_ASSERT(e) GC_ASSERT(e)
78
79 #else /* USE_MUNMAP */
80
81 # define INCR_FREE_BYTES(n, b)
82 # define FREE_ASSERT(e)
83
84 #endif /* USE_MUNMAP */
85
86 /* Map a number of blocks to the appropriate large block free list index. */
87 STATIC int GC_hblk_fl_from_blocks(word blocks_needed)
88 {
89     if (blocks_needed <= UNIQUE_THRESHOLD) return (int)blocks_needed;
90     if (blocks_needed >= HUGE_THRESHOLD) return N_HBLK_FLS;
91     return (int)(blocks_needed - UNIQUE_THRESHOLD)/FL_COMPRESSION
92                                         + UNIQUE_THRESHOLD;
93
94 }
95
96 # define PHDR(hhdr) HDR(hhdr -> hb_prev)
97 # define NHDR(hhdr) HDR(hhdr -> hb_next)
98
99 # ifdef USE_MUNMAP
100 #   define IS_MAPPED(hhdr) (((hhdr) -> hb_flags & WAS_UNMAPPED) == 0)
101 # else  /* !USE_MUNMAP */
102 #   define IS_MAPPED(hhdr) 1
103 # endif /* USE_MUNMAP */
104
105 # if !defined(NO_DEBUGGING)
106 void GC_print_hblkfreelist(void)
107 {
108     struct hblk * h;
109     word total_free = 0;
110     hdr * hhdr;
111     word sz;
112     unsigned i;
113
114     for (i = 0; i <= N_HBLK_FLS; ++i) {
115       h = GC_hblkfreelist[i];
116 #     ifdef USE_MUNMAP
117         if (0 != h) GC_printf("Free list %u:\n", i);
118 #     else
119         if (0 != h) GC_printf("Free list %u (Total size %lu):\n",
120                               i, (unsigned long)GC_free_bytes[i]);
121 #     endif
122       while (h != 0) {
123         hhdr = HDR(h);
124         sz = hhdr -> hb_sz;
125         total_free += sz;
126         GC_printf("\t%p size %lu %s black listed\n", h, (unsigned long)sz,
127                 GC_is_black_listed(h, HBLKSIZE) != 0 ? "start" :
128                 GC_is_black_listed(h, hhdr -> hb_sz) != 0 ? "partially" :
129                                                         "not");
130         h = hhdr -> hb_next;
131       }
132     }
133 #   ifndef USE_MUNMAP
134       if (total_free != GC_large_free_bytes) {
135         GC_printf("GC_large_free_bytes = %lu (INCONSISTENT!!)\n",
136                   (unsigned long) GC_large_free_bytes);
137       }
138 #   endif
139     GC_printf("Total of %lu bytes on free list\n", (unsigned long)total_free);
140 }
141
142 /* Return the free list index on which the block described by the header */
143 /* appears, or -1 if it appears nowhere.                                 */
144 static int free_list_index_of(hdr *wanted)
145 {
146     struct hblk * h;
147     hdr * hhdr;
148     int i;
149
150     for (i = 0; i <= N_HBLK_FLS; ++i) {
151       h = GC_hblkfreelist[i];
152       while (h != 0) {
153         hhdr = HDR(h);
154         if (hhdr == wanted) return i;
155         h = hhdr -> hb_next;
156       }
157     }
158     return -1;
159 }
160
161 void GC_dump_regions(void)
162 {
163     unsigned i;
164     ptr_t start, end;
165     ptr_t p;
166     size_t bytes;
167     hdr *hhdr;
168     for (i = 0; i < GC_n_heap_sects; ++i) {
169         start = GC_heap_sects[i].hs_start;
170         bytes = GC_heap_sects[i].hs_bytes;
171         end = start + bytes;
172         /* Merge in contiguous sections.        */
173           while (i+1 < GC_n_heap_sects && GC_heap_sects[i+1].hs_start == end) {
174             ++i;
175             end = GC_heap_sects[i].hs_start + GC_heap_sects[i].hs_bytes;
176           }
177         GC_printf("***Section from %p to %p\n", start, end);
178         for (p = start; p < end;) {
179             hhdr = HDR(p);
180             if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
181                 GC_printf("\t%p Missing header!!(%p)\n", p, hhdr);
182                 p += HBLKSIZE;
183                 continue;
184             }
185             if (HBLK_IS_FREE(hhdr)) {
186                 int correct_index = GC_hblk_fl_from_blocks(
187                                         divHBLKSZ(hhdr -> hb_sz));
188                 int actual_index;
189
190                 GC_printf("\t%p\tfree block of size 0x%lx bytes%s\n", p,
191                           (unsigned long)(hhdr -> hb_sz),
192                           IS_MAPPED(hhdr) ? "" : " (unmapped)");
193                 actual_index = free_list_index_of(hhdr);
194                 if (-1 == actual_index) {
195                     GC_printf("\t\tBlock not on free list %d!!\n",
196                               correct_index);
197                 } else if (correct_index != actual_index) {
198                     GC_printf("\t\tBlock on list %d, should be on %d!!\n",
199                               actual_index, correct_index);
200                 }
201                 p += hhdr -> hb_sz;
202             } else {
203                 GC_printf("\t%p\tused for blocks of size 0x%lx bytes\n", p,
204                           (unsigned long)(hhdr -> hb_sz));
205                 p += HBLKSIZE * OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz);
206             }
207         }
208     }
209 }
210
211 # endif /* NO_DEBUGGING */
212
213 /* Initialize hdr for a block containing the indicated size and         */
214 /* kind of objects.                                                     */
215 /* Return FALSE on failure.                                             */
216 static GC_bool setup_header(hdr * hhdr, struct hblk *block, size_t byte_sz,
217                             int kind, unsigned flags)
218 {
219     word descr;
220 #   ifndef MARK_BIT_PER_OBJ
221       size_t granules;
222 #   endif
223
224     /* Set size, kind and mark proc fields */
225       hhdr -> hb_sz = byte_sz;
226       hhdr -> hb_obj_kind = (unsigned char)kind;
227       hhdr -> hb_flags = (unsigned char)flags;
228       hhdr -> hb_block = block;
229       descr = GC_obj_kinds[kind].ok_descriptor;
230       if (GC_obj_kinds[kind].ok_relocate_descr) descr += byte_sz;
231       hhdr -> hb_descr = descr;
232
233 #   ifdef MARK_BIT_PER_OBJ
234      /* Set hb_inv_sz as portably as possible.                          */
235      /* We set it to the smallest value such that sz * inv_sz > 2**32    */
236      /* This may be more precision than necessary.                      */
237       if (byte_sz > MAXOBJBYTES) {
238          hhdr -> hb_inv_sz = LARGE_INV_SZ;
239       } else {
240         word inv_sz;
241
242 #       if CPP_WORDSZ == 64
243           inv_sz = ((word)1 << 32)/byte_sz;
244           if (((inv_sz*byte_sz) >> 32) == 0) ++inv_sz;
245 #       else  /* 32 bit words */
246           GC_ASSERT(byte_sz >= 4);
247           inv_sz = ((unsigned)1 << 31)/byte_sz;
248           inv_sz *= 2;
249           while (inv_sz*byte_sz > byte_sz) ++inv_sz;
250 #       endif
251         hhdr -> hb_inv_sz = inv_sz;
252       }
253 #   else /* MARK_BIT_PER_GRANULE */
254       hhdr -> hb_large_block = (unsigned char)(byte_sz > MAXOBJBYTES);
255       granules = BYTES_TO_GRANULES(byte_sz);
256       if (EXPECT(!GC_add_map_entry(granules), FALSE)) {
257         /* Make it look like a valid block. */
258         hhdr -> hb_sz = HBLKSIZE;
259         hhdr -> hb_descr = 0;
260         hhdr -> hb_large_block = TRUE;
261         hhdr -> hb_map = 0;
262         return FALSE;
263       } else {
264         size_t index = (hhdr -> hb_large_block? 0 : granules);
265         hhdr -> hb_map = GC_obj_map[index];
266       }
267 #   endif /* MARK_BIT_PER_GRANULE */
268
269     /* Clear mark bits */
270     GC_clear_hdr_marks(hhdr);
271
272     hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
273     return(TRUE);
274 }
275
276 #define FL_UNKNOWN -1
277 /*
278  * Remove hhdr from the appropriate free list.
279  * We assume it is on the nth free list, or on the size
280  * appropriate free list if n is FL_UNKNOWN.
281  */
282 STATIC void GC_remove_from_fl(hdr *hhdr, int n)
283 {
284     int index;
285
286     GC_ASSERT(((hhdr -> hb_sz) & (HBLKSIZE-1)) == 0);
287 #   ifndef USE_MUNMAP
288       /* We always need index to mainatin free counts.  */
289       if (FL_UNKNOWN == n) {
290           index = GC_hblk_fl_from_blocks(divHBLKSZ(hhdr -> hb_sz));
291       } else {
292           index = n;
293       }
294 #   endif
295     if (hhdr -> hb_prev == 0) {
296 #       ifdef USE_MUNMAP
297           if (FL_UNKNOWN == n) {
298             index = GC_hblk_fl_from_blocks(divHBLKSZ(hhdr -> hb_sz));
299           } else {
300             index = n;
301           }
302 #       endif
303         GC_ASSERT(HDR(GC_hblkfreelist[index]) == hhdr);
304         GC_hblkfreelist[index] = hhdr -> hb_next;
305     } else {
306         hdr *phdr;
307         GET_HDR(hhdr -> hb_prev, phdr);
308         phdr -> hb_next = hhdr -> hb_next;
309     }
310     FREE_ASSERT(GC_free_bytes[index] >= hhdr -> hb_sz);
311     INCR_FREE_BYTES(index, - (signed_word)(hhdr -> hb_sz));
312     if (0 != hhdr -> hb_next) {
313         hdr * nhdr;
314         GC_ASSERT(!IS_FORWARDING_ADDR_OR_NIL(NHDR(hhdr)));
315         GET_HDR(hhdr -> hb_next, nhdr);
316         nhdr -> hb_prev = hhdr -> hb_prev;
317     }
318 }
319
320 /*
321  * Return a pointer to the free block ending just before h, if any.
322  */
323 STATIC struct hblk * GC_free_block_ending_at(struct hblk *h)
324 {
325     struct hblk * p = h - 1;
326     hdr * phdr;
327
328     GET_HDR(p, phdr);
329     while (0 != phdr && IS_FORWARDING_ADDR_OR_NIL(phdr)) {
330         p = FORWARDED_ADDR(p,phdr);
331         phdr = HDR(p);
332     }
333     if (0 != phdr) {
334         if(HBLK_IS_FREE(phdr)) {
335             return p;
336         } else {
337             return 0;
338         }
339     }
340     p = GC_prev_block(h - 1);
341     if (0 != p) {
342       phdr = HDR(p);
343       if (HBLK_IS_FREE(phdr) && (ptr_t)p + phdr -> hb_sz == (ptr_t)h) {
344         return p;
345       }
346     }
347     return 0;
348 }
349
350 /*
351  * Add hhdr to the appropriate free list.
352  * We maintain individual free lists sorted by address.
353  */
354 STATIC void GC_add_to_fl(struct hblk *h, hdr *hhdr)
355 {
356     int index = GC_hblk_fl_from_blocks(divHBLKSZ(hhdr -> hb_sz));
357     struct hblk *second = GC_hblkfreelist[index];
358     hdr * second_hdr;
359 #   if defined(GC_ASSERTIONS) && !defined(USE_MUNMAP)
360       struct hblk *next = (struct hblk *)((word)h + hhdr -> hb_sz);
361       hdr * nexthdr = HDR(next);
362       struct hblk *prev = GC_free_block_ending_at(h);
363       hdr * prevhdr = HDR(prev);
364       GC_ASSERT(nexthdr == 0 || !HBLK_IS_FREE(nexthdr)
365                 || (signed_word)GC_heapsize < 0);
366                 /* In the last case, blocks may be too large to merge. */
367       GC_ASSERT(prev == 0 || !HBLK_IS_FREE(prevhdr)
368                 || (signed_word)GC_heapsize < 0);
369 #   endif
370     GC_ASSERT(((hhdr -> hb_sz) & (HBLKSIZE-1)) == 0);
371     GC_hblkfreelist[index] = h;
372     INCR_FREE_BYTES(index, hhdr -> hb_sz);
373     FREE_ASSERT(GC_free_bytes[index] <= GC_large_free_bytes)
374     hhdr -> hb_next = second;
375     hhdr -> hb_prev = 0;
376     if (0 != second) {
377       GET_HDR(second, second_hdr);
378       second_hdr -> hb_prev = h;
379     }
380     hhdr -> hb_flags |= FREE_BLK;
381 }
382
383 #ifdef USE_MUNMAP
384
385 #   ifndef MUNMAP_THRESHOLD
386 #     define MUNMAP_THRESHOLD 6
387 #   endif
388
389 GC_INNER int GC_unmap_threshold = MUNMAP_THRESHOLD;
390
391 /* Unmap blocks that haven't been recently touched.  This is the only way */
392 /* way blocks are ever unmapped.                                          */
393 GC_INNER void GC_unmap_old(void)
394 {
395     struct hblk * h;
396     hdr * hhdr;
397     int i;
398
399     if (GC_unmap_threshold == 0)
400       return; /* unmapping disabled */
401
402     for (i = 0; i <= N_HBLK_FLS; ++i) {
403       for (h = GC_hblkfreelist[i]; 0 != h; h = hhdr -> hb_next) {
404         hhdr = HDR(h);
405         if (!IS_MAPPED(hhdr)) continue;
406
407         if ((unsigned short)GC_gc_no - hhdr -> hb_last_reclaimed >
408                 (unsigned short)GC_unmap_threshold) {
409           GC_unmap((ptr_t)h, hhdr -> hb_sz);
410           hhdr -> hb_flags |= WAS_UNMAPPED;
411         }
412       }
413     }
414 }
415
416 /* Merge all unmapped blocks that are adjacent to other free            */
417 /* blocks.  This may involve remapping, since all blocks are either     */
418 /* fully mapped or fully unmapped.                                      */
419 GC_INNER void GC_merge_unmapped(void)
420 {
421     struct hblk * h, *next;
422     hdr * hhdr, *nexthdr;
423     word size, nextsize;
424     int i;
425
426     for (i = 0; i <= N_HBLK_FLS; ++i) {
427       h = GC_hblkfreelist[i];
428       while (h != 0) {
429         GET_HDR(h, hhdr);
430         size = hhdr->hb_sz;
431         next = (struct hblk *)((word)h + size);
432         GET_HDR(next, nexthdr);
433         /* Coalesce with successor, if possible */
434           if (0 != nexthdr && HBLK_IS_FREE(nexthdr)
435               && (signed_word) (size + (nextsize = nexthdr->hb_sz)) > 0
436                  /* no pot. overflow */) {
437             /* Note that we usually try to avoid adjacent free blocks   */
438             /* that are either both mapped or both unmapped.  But that  */
439             /* isn't guaranteed to hold since we remap blocks when we   */
440             /* split them, and don't merge at that point.  It may also  */
441             /* not hold if the merged block would be too big.           */
442             if (IS_MAPPED(hhdr) && !IS_MAPPED(nexthdr)) {
443               /* make both consistent, so that we can merge */
444                 if (size > nextsize) {
445                   GC_remap((ptr_t)next, nextsize);
446                 } else {
447                   GC_unmap((ptr_t)h, size);
448                   GC_unmap_gap((ptr_t)h, size, (ptr_t)next, nextsize);
449                   hhdr -> hb_flags |= WAS_UNMAPPED;
450                 }
451             } else if (IS_MAPPED(nexthdr) && !IS_MAPPED(hhdr)) {
452               if (size > nextsize) {
453                 GC_unmap((ptr_t)next, nextsize);
454                 GC_unmap_gap((ptr_t)h, size, (ptr_t)next, nextsize);
455               } else {
456                 GC_remap((ptr_t)h, size);
457                 hhdr -> hb_flags &= ~WAS_UNMAPPED;
458                 hhdr -> hb_last_reclaimed = nexthdr -> hb_last_reclaimed;
459               }
460             } else if (!IS_MAPPED(hhdr) && !IS_MAPPED(nexthdr)) {
461               /* Unmap any gap in the middle */
462                 GC_unmap_gap((ptr_t)h, size, (ptr_t)next, nextsize);
463             }
464             /* If they are both unmapped, we merge, but leave unmapped. */
465             GC_remove_from_fl(hhdr, i);
466             GC_remove_from_fl(nexthdr, FL_UNKNOWN);
467             hhdr -> hb_sz += nexthdr -> hb_sz;
468             GC_remove_header(next);
469             GC_add_to_fl(h, hhdr);
470             /* Start over at beginning of list */
471             h = GC_hblkfreelist[i];
472           } else /* not mergable with successor */ {
473             h = hhdr -> hb_next;
474           }
475       } /* while (h != 0) ... */
476     } /* for ... */
477 }
478
479 #endif /* USE_MUNMAP */
480
481 /*
482  * Return a pointer to a block starting at h of length bytes.
483  * Memory for the block is mapped.
484  * Remove the block from its free list, and return the remainder (if any)
485  * to its appropriate free list.
486  * May fail by returning 0.
487  * The header for the returned block must be set up by the caller.
488  * If the return value is not 0, then hhdr is the header for it.
489  */
490 STATIC struct hblk * GC_get_first_part(struct hblk *h, hdr *hhdr,
491                                        size_t bytes, int index)
492 {
493     word total_size = hhdr -> hb_sz;
494     struct hblk * rest;
495     hdr * rest_hdr;
496
497     GC_ASSERT((total_size & (HBLKSIZE-1)) == 0);
498     GC_remove_from_fl(hhdr, index);
499     if (total_size == bytes) return h;
500     rest = (struct hblk *)((word)h + bytes);
501     rest_hdr = GC_install_header(rest);
502     if (0 == rest_hdr) {
503         /* FIXME: This is likely to be very bad news ... */
504         WARN("Header allocation failed: Dropping block.\n", 0);
505         return(0);
506     }
507     rest_hdr -> hb_sz = total_size - bytes;
508     rest_hdr -> hb_flags = 0;
509 #   ifdef GC_ASSERTIONS
510       /* Mark h not free, to avoid assertion about adjacent free blocks. */
511         hhdr -> hb_flags &= ~FREE_BLK;
512 #   endif
513     GC_add_to_fl(rest, rest_hdr);
514     return h;
515 }
516
517 /*
518  * H is a free block.  N points at an address inside it.
519  * A new header for n has already been set up.  Fix up h's header
520  * to reflect the fact that it is being split, move it to the
521  * appropriate free list.
522  * N replaces h in the original free list.
523  *
524  * Nhdr is not completely filled in, since it is about to allocated.
525  * It may in fact end up on the wrong free list for its size.
526  * That's not a disaster, since n is about to be allocated
527  * by our caller.
528  * (Hence adding it to a free list is silly.  But this path is hopefully
529  * rare enough that it doesn't matter.  The code is cleaner this way.)
530  */
531 STATIC void GC_split_block(struct hblk *h, hdr *hhdr, struct hblk *n,
532                            hdr *nhdr, int index /* Index of free list */)
533 {
534     word total_size = hhdr -> hb_sz;
535     word h_size = (word)n - (word)h;
536     struct hblk *prev = hhdr -> hb_prev;
537     struct hblk *next = hhdr -> hb_next;
538
539     /* Replace h with n on its freelist */
540       nhdr -> hb_prev = prev;
541       nhdr -> hb_next = next;
542       nhdr -> hb_sz = total_size - h_size;
543       nhdr -> hb_flags = 0;
544       if (0 != prev) {
545         HDR(prev) -> hb_next = n;
546       } else {
547         GC_hblkfreelist[index] = n;
548       }
549       if (0 != next) {
550         HDR(next) -> hb_prev = n;
551       }
552       INCR_FREE_BYTES(index, -(signed_word)h_size);
553       FREE_ASSERT(GC_free_bytes[index] > 0);
554 #   ifdef USE_MUNMAP
555       hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
556 #   endif
557     hhdr -> hb_sz = h_size;
558     GC_add_to_fl(h, hhdr);
559     nhdr -> hb_flags |= FREE_BLK;
560 }
561
562 STATIC struct hblk *
563 GC_allochblk_nth(size_t sz/* bytes */, int kind, unsigned flags, int n,
564                  GC_bool may_split);
565
566 /*
567  * Allocate (and return pointer to) a heap block
568  *   for objects of size sz bytes, searching the nth free list.
569  *
570  * NOTE: We set obj_map field in header correctly.
571  *       Caller is responsible for building an object freelist in block.
572  *
573  * The client is responsible for clearing the block, if necessary.
574  */
575 GC_INNER struct hblk *
576 GC_allochblk(size_t sz, int kind, unsigned flags/* IGNORE_OFF_PAGE or 0 */)
577 {
578     word blocks;
579     int start_list;
580     int i;
581     struct hblk *result;
582     int split_limit; /* Highest index of free list whose blocks we      */
583                      /* split.                                          */
584
585     GC_ASSERT((sz & (GRANULE_BYTES - 1)) == 0);
586     blocks = OBJ_SZ_TO_BLOCKS(sz);
587     if ((signed_word)(blocks * HBLKSIZE) < 0) {
588       return 0;
589     }
590     start_list = GC_hblk_fl_from_blocks(blocks);
591     /* Try for an exact match first. */
592     result = GC_allochblk_nth(sz, kind, flags, start_list, FALSE);
593     if (0 != result) return result;
594     if (GC_use_entire_heap || GC_dont_gc
595         || USED_HEAP_SIZE < GC_requested_heapsize
596         || GC_incremental || !GC_should_collect()) {
597         /* Should use more of the heap, even if it requires splitting. */
598         split_limit = N_HBLK_FLS;
599     } else {
600 #     ifdef USE_MUNMAP
601         /* avoid splitting, since that might require remapping */
602         split_limit = 0;
603 #     else
604         if (GC_finalizer_bytes_freed > (GC_heapsize >> 4)) {
605           /* If we are deallocating lots of memory from         */
606           /* finalizers, fail and collect sooner rather         */
607           /* than later.                                        */
608           split_limit = 0;
609         } else {
610           /* If we have enough large blocks left to cover any   */
611           /* previous request for large blocks, we go ahead     */
612           /* and split.  Assuming a steady state, that should   */
613           /* be safe.  It means that we can use the full        */
614           /* heap if we allocate only small objects.            */
615           split_limit = GC_enough_large_bytes_left();
616         }
617 #     endif
618     }
619     if (start_list < UNIQUE_THRESHOLD) {
620       /* No reason to try start_list again, since all blocks are exact  */
621       /* matches.                                                       */
622       ++start_list;
623     }
624     for (i = start_list; i <= split_limit; ++i) {
625         struct hblk * result = GC_allochblk_nth(sz, kind, flags, i, TRUE);
626         if (0 != result) return result;
627     }
628     return 0;
629 }
630
631 STATIC long GC_large_alloc_warn_suppressed = 0;
632                         /* Number of warnings suppressed so far.        */
633
634 /*
635  * The same, but with search restricted to nth free list.
636  * Flags is IGNORE_OFF_PAGE or zero.
637  * Unlike the above, sz is in bytes.
638  * The may_split flag indicates whether it's OK to split larger blocks.
639  */
640 STATIC struct hblk *
641 GC_allochblk_nth(size_t sz, int kind, unsigned flags, int n,
642                  GC_bool may_split)
643 {
644     struct hblk *hbp;
645     hdr * hhdr;         /* Header corr. to hbp */
646                         /* Initialized after loop if hbp !=0    */
647                         /* Gcc uninitialized use warning is bogus.      */
648     struct hblk *thishbp;
649     hdr * thishdr;              /* Header corr. to hbp */
650     signed_word size_needed;    /* number of bytes in requested objects */
651     signed_word size_avail;     /* bytes available in this block        */
652
653     size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz);
654
655     /* search for a big enough block in free list */
656         hbp = GC_hblkfreelist[n];
657         for(; 0 != hbp; hbp = hhdr -> hb_next) {
658             GET_HDR(hbp, hhdr);
659             size_avail = hhdr->hb_sz;
660             if (size_avail < size_needed) continue;
661             if (size_avail != size_needed) {
662               signed_word next_size;
663
664               if (!may_split) continue;
665               /* If the next heap block is obviously better, go on.     */
666               /* This prevents us from disassembling a single large block */
667               /* to get tiny blocks.                                    */
668               thishbp = hhdr -> hb_next;
669               if (thishbp != 0) {
670                 GET_HDR(thishbp, thishdr);
671                 next_size = (signed_word)(thishdr -> hb_sz);
672                 if (next_size < size_avail
673                     && next_size >= size_needed
674                     && !GC_is_black_listed(thishbp, (word)size_needed)) {
675                     continue;
676                 }
677               }
678             }
679             if ( !IS_UNCOLLECTABLE(kind) &&
680                  (kind != PTRFREE || size_needed > MAX_BLACK_LIST_ALLOC)) {
681               struct hblk * lasthbp = hbp;
682               ptr_t search_end = (ptr_t)hbp + size_avail - size_needed;
683               signed_word orig_avail = size_avail;
684               signed_word eff_size_needed = ((flags & IGNORE_OFF_PAGE)?
685                                                 HBLKSIZE
686                                                 : size_needed);
687
688
689               while ((ptr_t)lasthbp <= search_end
690                      && (thishbp = GC_is_black_listed(lasthbp,
691                                                       (word)eff_size_needed))
692                         != 0) {
693                 lasthbp = thishbp;
694               }
695               size_avail -= (ptr_t)lasthbp - (ptr_t)hbp;
696               thishbp = lasthbp;
697               if (size_avail >= size_needed) {
698                 if (thishbp != hbp &&
699                     0 != (thishdr = GC_install_header(thishbp))) {
700                   /* Make sure it's mapped before we mangle it. */
701 #                   ifdef USE_MUNMAP
702                       if (!IS_MAPPED(hhdr)) {
703                         GC_remap((ptr_t)hbp, hhdr -> hb_sz);
704                         hhdr -> hb_flags &= ~WAS_UNMAPPED;
705                       }
706 #                   endif
707                   /* Split the block at thishbp */
708                       GC_split_block(hbp, hhdr, thishbp, thishdr, n);
709                   /* Advance to thishbp */
710                       hbp = thishbp;
711                       hhdr = thishdr;
712                       /* We must now allocate thishbp, since it may     */
713                       /* be on the wrong free list.                     */
714                 }
715               } else if (size_needed > (signed_word)BL_LIMIT
716                          && orig_avail - size_needed
717                             > (signed_word)BL_LIMIT) {
718                 /* Punt, since anything else risks unreasonable heap growth. */
719                 if (++GC_large_alloc_warn_suppressed
720                     >= GC_large_alloc_warn_interval) {
721                   WARN("Repeated allocation of very large block "
722                        "(appr. size %" GC_PRIdPTR "):\n"
723                        "\tMay lead to memory leak and poor performance.\n",
724                        size_needed);
725                   GC_large_alloc_warn_suppressed = 0;
726                 }
727                 size_avail = orig_avail;
728               } else if (size_avail == 0 && size_needed == HBLKSIZE
729                          && IS_MAPPED(hhdr)) {
730                 if (!GC_find_leak) {
731                   static unsigned count = 0;
732
733                   /* The block is completely blacklisted.  We need      */
734                   /* to drop some such blocks, since otherwise we spend */
735                   /* all our time traversing them if pointerfree        */
736                   /* blocks are unpopular.                              */
737                   /* A dropped block will be reconsidered at next GC.   */
738                   if ((++count & 3) == 0) {
739                     /* Allocate and drop the block in small chunks, to  */
740                     /* maximize the chance that we will recover some    */
741                     /* later.                                           */
742                       word total_size = hhdr -> hb_sz;
743                       struct hblk * limit = hbp + divHBLKSZ(total_size);
744                       struct hblk * h;
745                       struct hblk * prev = hhdr -> hb_prev;
746
747                       GC_large_free_bytes -= total_size;
748                       GC_bytes_dropped += total_size;
749                       GC_remove_from_fl(hhdr, n);
750                       for (h = hbp; h < limit; h++) {
751                         if (h == hbp || 0 != (hhdr = GC_install_header(h))) {
752                           (void) setup_header(
753                                   hhdr, h,
754                                   HBLKSIZE,
755                                   PTRFREE, 0); /* Can't fail */
756                           if (GC_debugging_started) {
757                             BZERO(h, HBLKSIZE);
758                           }
759                         }
760                       }
761                     /* Restore hbp to point at free block */
762                       hbp = prev;
763                       if (0 == hbp) {
764                         return GC_allochblk_nth(sz, kind, flags, n, may_split);
765                       }
766                       hhdr = HDR(hbp);
767                   }
768                 }
769               }
770             }
771             if( size_avail >= size_needed ) {
772 #               ifdef USE_MUNMAP
773                   if (!IS_MAPPED(hhdr)) {
774                     GC_remap((ptr_t)hbp, hhdr -> hb_sz);
775                     hhdr -> hb_flags &= ~WAS_UNMAPPED;
776                     /* Note: This may leave adjacent, mapped free blocks. */
777                   }
778 #               endif
779                 /* hbp may be on the wrong freelist; the parameter n    */
780                 /* is important.                                        */
781                 hbp = GC_get_first_part(hbp, hhdr, size_needed, n);
782                 break;
783             }
784         }
785
786     if (0 == hbp) return 0;
787
788     /* Add it to map of valid blocks */
789         if (!GC_install_counts(hbp, (word)size_needed)) return(0);
790         /* This leaks memory under very rare conditions. */
791
792     /* Set up header */
793         if (!setup_header(hhdr, hbp, sz, kind, flags)) {
794             GC_remove_counts(hbp, (word)size_needed);
795             return(0); /* ditto */
796         }
797
798     /* Notify virtual dirty bit implementation that we are about to write.  */
799     /* Ensure that pointerfree objects are not protected if it's avoidable. */
800     /* This also ensures that newly allocated blocks are treated as dirty.  */
801     /* Necessary since we don't protect free blocks.                        */
802         GC_ASSERT((size_needed & (HBLKSIZE-1)) == 0);
803         GC_remove_protection(hbp, divHBLKSZ(size_needed),
804                              (hhdr -> hb_descr == 0) /* pointer-free */);
805
806     /* We just successfully allocated a block.  Restart count of        */
807     /* consecutive failures.                                            */
808     GC_fail_count = 0;
809
810     GC_large_free_bytes -= size_needed;
811
812     GC_ASSERT(IS_MAPPED(hhdr));
813     return( hbp );
814 }
815
816 /*
817  * Free a heap block.
818  *
819  * Coalesce the block with its neighbors if possible.
820  *
821  * All mark words are assumed to be cleared.
822  */
823 GC_INNER void GC_freehblk(struct hblk *hbp)
824 {
825     struct hblk *next, *prev;
826     hdr *hhdr, *prevhdr, *nexthdr;
827     signed_word size;
828
829     GET_HDR(hbp, hhdr);
830     size = hhdr->hb_sz;
831     size = HBLKSIZE * OBJ_SZ_TO_BLOCKS(size);
832     if (size <= 0)
833       ABORT("Deallocating excessively large block.  Too large an allocation?");
834       /* Probably possible if we try to allocate more than half the address */
835       /* space at once.  If we don't catch it here, strange things happen   */
836       /* later.                                                             */
837     GC_remove_counts(hbp, (word)size);
838     hhdr->hb_sz = size;
839 #   ifdef USE_MUNMAP
840       hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
841 #   endif
842
843     /* Check for duplicate deallocation in the easy case */
844       if (HBLK_IS_FREE(hhdr)) {
845         GC_printf("Duplicate large block deallocation of %p\n", hbp);
846         ABORT("Duplicate large block deallocation");
847       }
848
849     GC_ASSERT(IS_MAPPED(hhdr));
850     hhdr -> hb_flags |= FREE_BLK;
851     next = (struct hblk *)((word)hbp + size);
852     GET_HDR(next, nexthdr);
853     prev = GC_free_block_ending_at(hbp);
854     /* Coalesce with successor, if possible */
855       if(0 != nexthdr && HBLK_IS_FREE(nexthdr) && IS_MAPPED(nexthdr)
856          && (signed_word)(hhdr -> hb_sz + nexthdr -> hb_sz) > 0
857          /* no overflow */) {
858         GC_remove_from_fl(nexthdr, FL_UNKNOWN);
859         hhdr -> hb_sz += nexthdr -> hb_sz;
860         GC_remove_header(next);
861       }
862     /* Coalesce with predecessor, if possible. */
863       if (0 != prev) {
864         prevhdr = HDR(prev);
865         if (IS_MAPPED(prevhdr)
866             && (signed_word)(hhdr -> hb_sz + prevhdr -> hb_sz) > 0) {
867           GC_remove_from_fl(prevhdr, FL_UNKNOWN);
868           prevhdr -> hb_sz += hhdr -> hb_sz;
869 #         ifdef USE_MUNMAP
870             prevhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
871 #         endif
872           GC_remove_header(hbp);
873           hbp = prev;
874           hhdr = prevhdr;
875         }
876       }
877     /* FIXME: It is not clear we really always want to do these merges  */
878     /* with USE_MUNMAP, since it updates ages and hence prevents        */
879     /* unmapping.                                                       */
880
881     GC_large_free_bytes += size;
882     GC_add_to_fl(hbp, hhdr);
883 }