/* * 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); }
/* The same for size 4 cleared objects. */ STATIC ptr_t GC_build_fl_clear4(struct hblk *h, ptr_t ofl) { word * p = (word *)(h -> hb_body); word * lim = (word *)(h + 1); p[0] = (word)ofl; p[1] = 0; p[2] = 0; p[3] = 0; p += 4; for (; (word)p < (word)lim; p += 4) { PREFETCH_FOR_WRITE((ptr_t)(p+64)); p[0] = (word)(p-4); p[1] = 0; CLEAR_DOUBLE(p+2); }; return((ptr_t)(p-4)); }