/* * Is the block starting at h of size len bytes black listed? If so, * return the address of the next plausible r such that (r, len) might not * be black listed. (R may not actually be in the heap. We guarantee only * that every smaller value of r after h is also black listed.) * If (h,len) is not black listed, return 0. * Knows about the structure of the black list hash tables. */ struct hblk * GC_is_black_listed(struct hblk *h, word len) { word index = PHT_HASH((word)h); word i; word nblocks; if (!GC_all_interior_pointers && (get_pht_entry_from_index(GC_old_normal_bl, index) || get_pht_entry_from_index(GC_incomplete_normal_bl, index))) { return (h+1); } nblocks = divHBLKSZ(len); for (i = 0;;) { if (GC_old_stack_bl[divWORDSZ(index)] == 0 && GC_incomplete_stack_bl[divWORDSZ(index)] == 0) { /* An easy case */ i += WORDSZ - modWORDSZ(index); } else { if (get_pht_entry_from_index(GC_old_stack_bl, index) || get_pht_entry_from_index(GC_incomplete_stack_bl, index)) { return(h+i+1); } i++; } if (i >= nblocks) break; index = PHT_HASH((word)(h+i)); } return(0); }
/* Caller does not hold allocation lock. */ STATIC signed_word GC_add_ext_descriptor(const word * bm, word nbits) { size_t nwords = divWORDSZ(nbits + WORDSZ-1); signed_word result; size_t i; word last_part; size_t extra_bits; DCL_LOCK_STATE; LOCK(); while (GC_avail_descr + nwords >= GC_ed_size) { ext_descr * newExtD; size_t new_size; word ed_size = GC_ed_size; if (ed_size == 0) { GC_ASSERT((word)(&GC_ext_descriptors) % sizeof(word) == 0); GC_push_typed_structures = GC_push_typed_structures_proc; UNLOCK(); new_size = ED_INITIAL_SIZE; } else { UNLOCK(); new_size = 2 * ed_size; if (new_size > MAX_ENV) return(-1); } newExtD = (ext_descr *)GC_malloc_atomic(new_size * sizeof(ext_descr)); if (NULL == newExtD) return -1; LOCK(); if (ed_size == GC_ed_size) { if (GC_avail_descr != 0) { BCOPY(GC_ext_descriptors, newExtD, GC_avail_descr * sizeof(ext_descr)); } GC_ed_size = new_size; GC_ext_descriptors = newExtD; } /* else another thread already resized it in the meantime */ } result = GC_avail_descr; for (i = 0; i < nwords-1; i++) { GC_ext_descriptors[result + i].ed_bitmap = bm[i]; GC_ext_descriptors[result + i].ed_continued = TRUE; } last_part = bm[i]; /* Clear irrelevant bits. */ extra_bits = nwords * WORDSZ - nbits; last_part <<= extra_bits; last_part >>= extra_bits; GC_ext_descriptors[result + i].ed_bitmap = last_part; GC_ext_descriptors[result + i].ed_continued = FALSE; GC_avail_descr += nwords; UNLOCK(); return(result); }
int GC_n_set_marks(hdr *hhdr) { int result = 0; int i; int n_mark_words; # ifdef MARK_BIT_PER_OBJ int n_objs = (int)HBLK_OBJS(hhdr -> hb_sz); if (0 == n_objs) n_objs = 1; n_mark_words = divWORDSZ(n_objs + WORDSZ - 1); # else /* MARK_BIT_PER_GRANULE */ n_mark_words = MARK_BITS_SZ; # endif for (i = 0; i < n_mark_words - 1; i++) { result += set_bits(hhdr -> hb_marks[i]); } # ifdef MARK_BIT_PER_OBJ result += set_bits((hhdr -> hb_marks[n_mark_words - 1]) << (n_mark_words * WORDSZ - n_objs)); # else result += set_bits(hhdr -> hb_marks[n_mark_words - 1]); # endif return result ? (result - 1) : 0; //discount for the last bit if any set }