/* The same thing, but don't clear objects: */ STATIC ptr_t GC_reclaim_uninit(struct hblk *hbp, hdr *hhdr, size_t sz, ptr_t list, signed_word *count) { word bit_no = 0; word *p, *plim; signed_word n_bytes_found = 0; GC_ASSERT(sz == hhdr -> hb_sz); p = (word *)(hbp->hb_body); plim = (word *)((ptr_t)hbp + HBLKSIZE - sz); /* go through all words in block */ while (p <= plim) { if( !mark_bit_from_hdr(hhdr, bit_no) ) { n_bytes_found += sz; /* object is available - put on list */ obj_link(p) = list; list = ((ptr_t)p); } p = (word *)((ptr_t)p + sz); bit_no += MARK_BIT_OFFSET(sz); } *count += n_bytes_found; return(list); }
/*ARGSUSED*/ void GC_check_heap_block(struct hblk *hbp, word dummy) { struct hblkhdr * hhdr = HDR(hbp); size_t sz = hhdr -> hb_sz; size_t bit_no; char *p, *plim; p = hbp->hb_body; bit_no = 0; if (sz > MAXOBJBYTES) { plim = p; } else { plim = hbp->hb_body + HBLKSIZE - sz; } /* go through all words in block */ while( p <= plim ) { if( mark_bit_from_hdr(hhdr, bit_no) && GC_HAS_DEBUG_INFO((ptr_t)p)) { ptr_t clobbered = GC_check_annotated_obj((oh *)p); if (clobbered != 0) GC_add_smashed(clobbered); } bit_no += MARK_BIT_OFFSET(sz); p += sz; } }
/* Remains externally visible as used by GNU GCJ currently. */ int GC_n_set_marks(hdr *hhdr) { int result = 0; int i; size_t sz = hhdr -> hb_sz; int offset = (int)MARK_BIT_OFFSET(sz); int limit = (int)FINAL_MARK_BIT(sz); for (i = 0; i < limit; i += offset) { result += hhdr -> hb_marks[i]; } GC_ASSERT(hhdr -> hb_marks[limit]); return(result); }
/* Don't really reclaim objects, just check for unmarked ones: */ STATIC void GC_reclaim_check(struct hblk *hbp, hdr *hhdr, word sz) { word bit_no; ptr_t p, plim; GC_ASSERT(sz == hhdr -> hb_sz); /* go through all words in block */ p = hbp->hb_body; plim = p + HBLKSIZE - sz; for (bit_no = 0; p <= plim; p += sz, bit_no += MARK_BIT_OFFSET(sz)) { if (!mark_bit_from_hdr(hhdr, bit_no)) { GC_add_leaked(p); } } }
/* * Restore unmarked small objects in h of size sz to the object * free list. Returns the new list. * Clears unmarked objects. Sz is in bytes. */ STATIC ptr_t GC_reclaim_clear(struct hblk *hbp, hdr *hhdr, size_t sz, ptr_t list, signed_word *count) { word bit_no = 0; word *p, *q, *plim; signed_word n_bytes_found = 0; GC_ASSERT(hhdr == GC_find_header((ptr_t)hbp)); GC_ASSERT(sz == hhdr -> hb_sz); GC_ASSERT((sz & (BYTES_PER_WORD-1)) == 0); p = (word *)(hbp->hb_body); plim = (word *)(hbp->hb_body + HBLKSIZE - sz); /* go through all words in block */ while (p <= plim) { if( mark_bit_from_hdr(hhdr, bit_no) ) { p = (word *)((ptr_t)p + sz); } else { n_bytes_found += sz; /* object is available - put on list */ obj_link(p) = list; list = ((ptr_t)p); /* Clear object, advance p to next object in the process */ q = (word *)((ptr_t)p + sz); # ifdef USE_MARK_BYTES GC_ASSERT(!(sz & 1) && !((word)p & (2 * sizeof(word) - 1))); p[1] = 0; p += 2; while (p < q) { CLEAR_DOUBLE(p); p += 2; } # else p++; /* Skip link field */ while (p < q) { *p++ = 0; } # endif } bit_no += MARK_BIT_OFFSET(sz); } *count += n_bytes_found; return(list); }
/* Avoid GC_apply_to_each_object for performance reasons. */ STATIC void GC_check_heap_block(struct hblk *hbp, word dummy GC_ATTR_UNUSED) { struct hblkhdr * hhdr = HDR(hbp); word sz = hhdr -> hb_sz; word bit_no; char *p, *plim; p = hbp->hb_body; if (sz > MAXOBJBYTES) { plim = p; } else { plim = hbp->hb_body + HBLKSIZE - sz; } /* go through all words in block */ for (bit_no = 0; (word)p <= (word)plim; bit_no += MARK_BIT_OFFSET(sz), p += sz) { if (mark_bit_from_hdr(hhdr, bit_no) && GC_HAS_DEBUG_INFO((ptr_t)p)) { ptr_t clobbered = GC_check_annotated_obj((oh *)p); if (clobbered != 0) GC_add_smashed(clobbered); } } }