2 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3 * Copyright (c) 1991-1996 by Xerox Corporation. All rights reserved.
4 * Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
5 * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved.
7 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
20 signed_word GC_mem_found = 0;
21 /* Number of words of memory reclaimed */
23 static void report_leak(p, sz)
27 if (HDR(p) -> hb_obj_kind == PTRFREE) {
28 GC_err_printf0("Leaked atomic object at ");
30 GC_err_printf0("Leaked composite object at ");
32 if (GC_debugging_started && GC_has_debug_info(p)) {
35 GC_err_printf2("0x%lx (appr. size = %ld)\n",
37 (unsigned long)WORDS_TO_BYTES(sz));
41 # define FOUND_FREE(hblk, word_no) \
43 report_leak((ptr_t)hblk + WORDS_TO_BYTES(word_no), \
44 HDR(hblk) -> hb_sz); \
54 * Test whether a block is completely empty, i.e. contains no marked
55 * objects. This does not require the block to be in physical
59 GC_bool GC_block_empty(hhdr)
62 register word *p = (word *)(&(hhdr -> hb_marks[0]));
63 register word * plim =
64 (word *)(&(hhdr -> hb_marks[MARK_BITS_SZ]));
66 if (*p++) return(FALSE);
71 /* The following functions sometimes return a DONT_KNOW value. */
75 # define GC_block_nearly_full1(hhdr, pat1) DONT_KNOW
76 # define GC_block_nearly_full3(hhdr, pat1, pat2) DONT_KNOW
77 # define GC_block_nearly_full(hhdr) DONT_KNOW
81 * Test whether nearly all of the mark words consist of the same
84 #define FULL_THRESHOLD (MARK_BITS_SZ/16)
86 GC_bool GC_block_nearly_full1(hhdr, pat1)
92 GC_ASSERT((MARK_BITS_SZ & 1) == 0);
93 for (i = 0; i < MARK_BITS_SZ; ++i) {
94 if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
95 if (++misses > FULL_THRESHOLD) return FALSE;
102 * Test whether the same repeating 3 word pattern occurs in nearly
103 * all the mark bit slots.
104 * This is used as a heuristic, so we're a bit sloppy and ignore
105 * the last one or two words.
107 GC_bool GC_block_nearly_full3(hhdr, pat1, pat2, pat3)
109 word pat1, pat2, pat3;
114 if (MARK_BITS_SZ < 4) {
117 for (i = 0; i < MARK_BITS_SZ - 2; i += 3) {
118 if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
119 if (++misses > FULL_THRESHOLD) return FALSE;
121 if ((hhdr -> hb_marks[i+1] | ~pat2) != ONES) {
122 if (++misses > FULL_THRESHOLD) return FALSE;
124 if ((hhdr -> hb_marks[i+2] | ~pat3) != ONES) {
125 if (++misses > FULL_THRESHOLD) return FALSE;
131 /* Check whether a small object block is nearly full by looking at only */
133 /* We manually precomputed the mark bit patterns that need to be */
134 /* checked for, and we give up on the ones that are unlikely to occur, */
135 /* or have period > 3. */
136 /* This would be a lot easier with a mark bit per object instead of per */
137 /* word, but that would rewuire computing object numbers in the mark */
138 /* loop, which would require different data structures ... */
139 GC_bool GC_block_nearly_full(hhdr)
142 int sz = hhdr -> hb_sz;
144 # if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
145 return DONT_KNOW; /* Shouldn't be used in any standard config. */
147 if (0 != HDR_WORDS) return DONT_KNOW;
148 /* Also shouldn't happen */
149 # if CPP_WORDSZ == 32
152 return GC_block_nearly_full1(hhdr, 0xffffffffl);
154 return GC_block_nearly_full1(hhdr, 0x55555555l);
156 return GC_block_nearly_full1(hhdr, 0x11111111l);
158 return GC_block_nearly_full3(hhdr, 0x41041041l,
162 return GC_block_nearly_full1(hhdr, 0x01010101l);
164 return GC_block_nearly_full3(hhdr, 0x01001001l,
168 return GC_block_nearly_full1(hhdr, 0x00010001l);
170 return GC_block_nearly_full1(hhdr, 0x00000001l);
175 # if CPP_WORDSZ == 64
178 return GC_block_nearly_full1(hhdr, 0xffffffffffffffffl);
180 return GC_block_nearly_full1(hhdr, 0x5555555555555555l);
182 return GC_block_nearly_full1(hhdr, 0x1111111111111111l);
184 return GC_block_nearly_full3(hhdr, 0x1041041041041041l,
186 0x0410410410410410l);
188 return GC_block_nearly_full1(hhdr, 0x0101010101010101l);
190 return GC_block_nearly_full3(hhdr, 0x1001001001001001l,
192 0x0010010010010010l);
194 return GC_block_nearly_full1(hhdr, 0x0001000100010001l);
196 return GC_block_nearly_full1(hhdr, 0x0000000100000001l);
202 #endif /* !SMALL_CONFIG */
205 # define INCR_WORDS(sz) n_words_found += (sz)
207 # define INCR_WORDS(sz)
210 * Restore unmarked small objects in h of size sz to the object
211 * free list. Returns the new list.
212 * Clears unmarked objects.
215 ptr_t GC_reclaim_clear(hbp, hhdr, sz, list)
216 register struct hblk *hbp; /* ptr to current heap block */
221 register int word_no;
222 register word *p, *q, *plim;
224 register int n_words_found = 0;
227 p = (word *)(hbp->hb_body);
229 plim = (word *)((((word)hbp) + HBLKSIZE)
230 - WORDS_TO_BYTES(sz));
232 /* go through all words in block */
234 if( mark_bit_from_hdr(hhdr, word_no) ) {
238 /* object is available - put on list */
241 /* Clear object, advance p to next object in the process */
243 p++; /* Skip link field */
244 # if defined(SMALL_CONFIG) && defined(ALIGN_DOUBLE)
245 /* We assert that sz must be even */
260 GC_mem_found += n_words_found;
268 * A special case for 2 word composite objects (e.g. cons cells):
271 ptr_t GC_reclaim_clear2(hbp, hhdr, list)
272 register struct hblk *hbp; /* ptr to current heap block */
276 register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
277 register word *p, *plim;
279 register int n_words_found = 0;
281 register word mark_word;
283 # define DO_OBJ(start_displ) \
284 if (!(mark_word & ((word)1 << start_displ))) { \
285 p[start_displ] = (word)list; \
286 list = (ptr_t)(p+start_displ); \
287 p[start_displ+1] = 0; \
291 p = (word *)(hbp->hb_body);
292 plim = (word *)(((word)hbp) + HBLKSIZE);
294 /* go through all words in block */
296 mark_word = *mark_word_addr++;
297 for (i = 0; i < WORDSZ; i += 8) {
307 GC_mem_found += n_words_found;
314 * Another special case for 4 word composite objects:
317 ptr_t GC_reclaim_clear4(hbp, hhdr, list)
318 register struct hblk *hbp; /* ptr to current heap block */
322 register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
323 register word *p, *plim;
325 register int n_words_found = 0;
327 register word mark_word;
328 # define DO_OBJ(start_displ) \
329 if (!(mark_word & ((word)1 << start_displ))) { \
330 p[start_displ] = (word)list; \
331 list = (ptr_t)(p+start_displ); \
332 p[start_displ+1] = 0; \
333 CLEAR_DOUBLE(p + start_displ + 2); \
337 p = (word *)(hbp->hb_body);
338 plim = (word *)(((word)hbp) + HBLKSIZE);
340 /* go through all words in block */
342 mark_word = *mark_word_addr++;
351 # if CPP_WORDSZ == 64
364 GC_mem_found += n_words_found;
370 #endif /* !SMALL_CONFIG */
372 /* The same thing, but don't clear objects: */
374 ptr_t GC_reclaim_uninit(hbp, hhdr, sz, list)
375 register struct hblk *hbp; /* ptr to current heap block */
380 register int word_no;
381 register word *p, *plim;
383 register int n_words_found = 0;
386 p = (word *)(hbp->hb_body);
388 plim = (word *)((((word)hbp) + HBLKSIZE)
389 - WORDS_TO_BYTES(sz));
391 /* go through all words in block */
393 if( !mark_bit_from_hdr(hhdr, word_no) ) {
395 /* object is available - put on list */
403 GC_mem_found += n_words_found;
408 /* Don't really reclaim objects, just check for unmarked ones: */
410 void GC_reclaim_check(hbp, hhdr, sz)
411 register struct hblk *hbp; /* ptr to current heap block */
415 register int word_no;
416 register word *p, *plim;
418 register int n_words_found = 0;
421 p = (word *)(hbp->hb_body);
423 plim = (word *)((((word)hbp) + HBLKSIZE)
424 - WORDS_TO_BYTES(sz));
426 /* go through all words in block */
428 if( !mark_bit_from_hdr(hhdr, word_no) ) {
429 FOUND_FREE(hbp, word_no);
438 * Another special case for 2 word atomic objects:
441 ptr_t GC_reclaim_uninit2(hbp, hhdr, list)
442 register struct hblk *hbp; /* ptr to current heap block */
446 register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
447 register word *p, *plim;
449 register int n_words_found = 0;
451 register word mark_word;
453 # define DO_OBJ(start_displ) \
454 if (!(mark_word & ((word)1 << start_displ))) { \
455 p[start_displ] = (word)list; \
456 list = (ptr_t)(p+start_displ); \
460 p = (word *)(hbp->hb_body);
461 plim = (word *)(((word)hbp) + HBLKSIZE);
463 /* go through all words in block */
465 mark_word = *mark_word_addr++;
466 for (i = 0; i < WORDSZ; i += 8) {
476 GC_mem_found += n_words_found;
483 * Another special case for 4 word atomic objects:
486 ptr_t GC_reclaim_uninit4(hbp, hhdr, list)
487 register struct hblk *hbp; /* ptr to current heap block */
491 register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
492 register word *p, *plim;
494 register int n_words_found = 0;
496 register word mark_word;
497 # define DO_OBJ(start_displ) \
498 if (!(mark_word & ((word)1 << start_displ))) { \
499 p[start_displ] = (word)list; \
500 list = (ptr_t)(p+start_displ); \
504 p = (word *)(hbp->hb_body);
505 plim = (word *)(((word)hbp) + HBLKSIZE);
507 /* go through all words in block */
509 mark_word = *mark_word_addr++;
518 # if CPP_WORDSZ == 64
531 GC_mem_found += n_words_found;
537 /* Finally the one word case, which never requires any clearing: */
539 ptr_t GC_reclaim1(hbp, hhdr, list)
540 register struct hblk *hbp; /* ptr to current heap block */
544 register word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
545 register word *p, *plim;
547 register int n_words_found = 0;
549 register word mark_word;
551 # define DO_OBJ(start_displ) \
552 if (!(mark_word & ((word)1 << start_displ))) { \
553 p[start_displ] = (word)list; \
554 list = (ptr_t)(p+start_displ); \
558 p = (word *)(hbp->hb_body);
559 plim = (word *)(((word)hbp) + HBLKSIZE);
561 /* go through all words in block */
563 mark_word = *mark_word_addr++;
564 for (i = 0; i < WORDSZ; i += 4) {
574 GC_mem_found += n_words_found;
580 #endif /* !SMALL_CONFIG */
583 * Restore unmarked small objects in the block pointed to by hbp
584 * to the appropriate object free list.
585 * If entirely empty blocks are to be completely deallocated, then
586 * caller should perform that check.
588 void GC_reclaim_small_nonempty_block(hbp, report_if_found)
589 register struct hblk *hbp; /* ptr to current heap block */
590 int report_if_found; /* Abort if a reclaimable object is found */
593 word sz; /* size of objects in current block */
594 struct obj_kind * ok;
601 hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
602 kind = hhdr -> hb_obj_kind;
603 ok = &GC_obj_kinds[kind];
604 flh = &(ok -> ok_freelist[sz]);
606 if (report_if_found) {
607 GC_reclaim_check(hbp, hhdr, sz);
608 } else if (ok -> ok_init) {
610 # ifndef SMALL_CONFIG
612 full = GC_block_nearly_full1(hhdr, 0xffffffffl);
613 if (TRUE == full) goto out;
614 if (FALSE == full) GC_write_hint(hbp);
615 /* In the DONT_KNOW case, we let reclaim fault. */
616 *flh = GC_reclaim1(hbp, hhdr, *flh);
619 full = GC_block_nearly_full1(hhdr, 0x55555555l);
620 if (TRUE == full) goto out;
621 if (FALSE == full) GC_write_hint(hbp);
622 *flh = GC_reclaim_clear2(hbp, hhdr, *flh);
625 full = GC_block_nearly_full1(hhdr, 0x11111111l);
626 if (TRUE == full) goto out;
627 if (FALSE == full) GC_write_hint(hbp);
628 *flh = GC_reclaim_clear4(hbp, hhdr, *flh);
632 full = GC_block_nearly_full(hhdr);
633 if (TRUE == full) goto out;
634 if (FALSE == full) GC_write_hint(hbp);
635 *flh = GC_reclaim_clear(hbp, hhdr, sz, *flh);
640 # ifndef SMALL_CONFIG
642 full = GC_block_nearly_full1(hhdr, 0xffffffffl);
643 if (TRUE == full) goto out;
644 if (FALSE == full) GC_write_hint(hbp);
645 *flh = GC_reclaim1(hbp, hhdr, *flh);
648 full = GC_block_nearly_full1(hhdr, 0x55555555l);
649 if (TRUE == full) goto out;
650 if (FALSE == full) GC_write_hint(hbp);
651 *flh = GC_reclaim_uninit2(hbp, hhdr, *flh);
654 full = GC_block_nearly_full1(hhdr, 0x11111111l);
655 if (TRUE == full) goto out;
656 if (FALSE == full) GC_write_hint(hbp);
657 *flh = GC_reclaim_uninit4(hbp, hhdr, *flh);
661 full = GC_block_nearly_full(hhdr);
662 if (TRUE == full) goto out;
663 if (FALSE == full) GC_write_hint(hbp);
664 *flh = GC_reclaim_uninit(hbp, hhdr, sz, *flh);
669 if (IS_UNCOLLECTABLE(kind)) GC_set_hdr_marks(hhdr);
673 * Restore an unmarked large object or an entirely empty blocks of small objects
674 * to the heap block free list.
675 * Otherwise enqueue the block for later processing
676 * by GC_reclaim_small_nonempty_block.
677 * If report_if_found is TRUE, then process any block immediately, and
678 * simply report free objects; do not actually reclaim them.
680 void GC_reclaim_block(hbp, report_if_found)
681 register struct hblk *hbp; /* ptr to current heap block */
682 word report_if_found; /* Abort if a reclaimable object is found */
685 register word sz; /* size of objects in current block */
686 register struct obj_kind * ok;
691 ok = &GC_obj_kinds[hhdr -> hb_obj_kind];
693 if( sz > MAXOBJSZ ) { /* 1 big object */
694 if( !mark_bit_from_hdr(hhdr, HDR_WORDS) ) {
695 if (report_if_found) {
696 FOUND_FREE(hbp, HDR_WORDS);
705 GC_bool empty = GC_block_empty(hhdr);
706 if (report_if_found) {
707 GC_reclaim_small_nonempty_block(hbp, (int)report_if_found);
710 GC_mem_found += BYTES_TO_WORDS(HBLKSIZE);
714 /* group of smaller objects, enqueue the real work */
715 rlh = &(ok -> ok_reclaim_list[sz]);
716 hhdr -> hb_next = *rlh;
722 #if !defined(NO_DEBUGGING)
723 /* Routines to gather and print heap block info */
724 /* intended for debugging. Otherwise should be called */
726 static size_t number_of_blocks;
727 static size_t total_bytes;
729 /* Number of set bits in a word. Not performance critical. */
730 static int set_bits(n)
734 register int result = 0;
743 /* Return the number of set mark bits in the given header */
744 int GC_n_set_marks(hhdr)
747 register int result = 0;
750 for (i = 0; i < MARK_BITS_SZ; i++) {
751 result += set_bits(hhdr -> hb_marks[i]);
757 void GC_print_block_descr(h, dummy)
761 register hdr * hhdr = HDR(h);
762 register size_t bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
764 GC_printf3("(%lu:%lu,%lu)", (unsigned long)(hhdr -> hb_obj_kind),
765 (unsigned long)bytes,
766 (unsigned long)(GC_n_set_marks(hhdr)));
767 bytes += HDR_BYTES + HBLKSIZE-1;
768 bytes &= ~(HBLKSIZE-1);
769 total_bytes += bytes;
773 void GC_print_block_list()
775 GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n");
776 number_of_blocks = 0;
778 GC_apply_to_all_blocks(GC_print_block_descr, (word)0);
779 GC_printf2("\nblocks = %lu, bytes = %lu\n",
780 (unsigned long)number_of_blocks,
781 (unsigned long)total_bytes);
784 #endif /* NO_DEBUGGING */
787 * Perform GC_reclaim_block on the entire heap, after first clearing
788 * small object free lists (if we are not just looking for leaks).
790 void GC_start_reclaim(report_if_found)
791 int report_if_found; /* Abort if a GC_reclaimable object is found */
795 /* Clear reclaim- and free-lists */
796 for (kind = 0; kind < GC_n_kinds; kind++) {
799 register struct hblk ** rlp;
800 register struct hblk ** rlim;
801 register struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list;
803 if (rlist == 0) continue; /* This kind not used. */
804 if (!report_if_found) {
805 lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]);
806 for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) {
809 } /* otherwise free list objects are marked, */
810 /* and its safe to leave them */
811 rlim = rlist + MAXOBJSZ+1;
812 for( rlp = rlist; rlp < rlim; rlp++ ) {
818 GC_printf0("GC_reclaim: current block sizes:\n");
819 GC_print_block_list();
822 /* Go through all heap blocks (in hblklist) and reclaim unmarked objects */
823 /* or enqueue the block for later processing. */
824 GC_apply_to_all_blocks(GC_reclaim_block, (word)report_if_found);
827 /* This is a very stupid thing to do. We make it possible anyway, */
828 /* so that you can convince yourself that it really is very stupid. */
829 GC_reclaim_all((GC_stop_func)0, FALSE);
835 * Sweep blocks of the indicated object size and kind until either the
836 * appropriate free list is nonempty, or there are no more blocks to
839 void GC_continue_reclaim(sz, kind)
844 register struct hblk * hbp;
845 register struct obj_kind * ok = &(GC_obj_kinds[kind]);
846 struct hblk ** rlh = ok -> ok_reclaim_list;
847 ptr_t *flh = &(ok -> ok_freelist[sz]);
849 if (rlh == 0) return; /* No blocks of this kind. */
851 while ((hbp = *rlh) != 0) {
853 *rlh = hhdr -> hb_next;
854 GC_reclaim_small_nonempty_block(hbp, FALSE);
855 if (*flh != 0) break;
860 * Reclaim all small blocks waiting to be reclaimed.
861 * Abort and return FALSE when/if (*stop_func)() returns TRUE.
862 * If this returns TRUE, then it's safe to restart the world
863 * with incorrectly cleared mark bits.
864 * If ignore_old is TRUE, then reclaim only blocks that have been
865 * recently reclaimed, and discard the rest.
866 * Stop_func may be 0.
868 GC_bool GC_reclaim_all(stop_func, ignore_old)
869 GC_stop_func stop_func;
875 register struct hblk * hbp;
876 register struct obj_kind * ok;
880 CLOCK_TYPE start_time;
881 CLOCK_TYPE done_time;
883 GET_TIME(start_time);
886 for (kind = 0; kind < GC_n_kinds; kind++) {
887 ok = &(GC_obj_kinds[kind]);
888 rlp = ok -> ok_reclaim_list;
889 if (rlp == 0) continue;
890 for (sz = 1; sz <= MAXOBJSZ; sz++) {
892 while ((hbp = *rlh) != 0) {
893 if (stop_func != (GC_stop_func)0 && (*stop_func)()) {
897 *rlh = hhdr -> hb_next;
898 if (!ignore_old || hhdr -> hb_last_reclaimed == GC_gc_no - 1) {
899 /* It's likely we'll need it this time, too */
900 /* It's been touched recently, so this */
901 /* shouldn't trigger paging. */
902 GC_reclaim_small_nonempty_block(hbp, FALSE);
909 GC_printf1("Disposing of reclaim lists took %lu msecs\n",
910 MS_TIME_DIFF(done_time,start_time));