int kind, unsigned flags)
{
word descr;
-# ifndef MARK_BIT_PER_OBJ
+# ifdef MARK_BIT_PER_GRANULE
size_t granules;
-# endif
+ if (byte_sz > MAXOBJBYTES)
+ flags |= LARGE_BLOCK;
+# endif
# ifdef ENABLE_DISCLAIM
if (GC_obj_kinds[kind].ok_disclaim_proc)
flags |= HAS_DISCLAIM;
hhdr -> hb_inv_sz = inv_sz;
}
# else /* MARK_BIT_PER_GRANULE */
- hhdr -> hb_large_block = (unsigned char)(byte_sz > MAXOBJBYTES);
granules = BYTES_TO_GRANULES(byte_sz);
if (EXPECT(!GC_add_map_entry(granules), FALSE)) {
/* Make it look like a valid block. */
hhdr -> hb_sz = HBLKSIZE;
hhdr -> hb_descr = 0;
- hhdr -> hb_large_block = TRUE;
+ hhdr -> hb_flags |= LARGE_BLOCK;
hhdr -> hb_map = 0;
return FALSE;
- } else {
- size_t index = (hhdr -> hb_large_block? 0 : granules);
- hhdr -> hb_map = GC_obj_map[index];
}
+ hhdr -> hb_map = GC_obj_map[(hhdr -> hb_flags & LARGE_BLOCK) != 0 ?
+ 0 : granules];
# endif /* MARK_BIT_PER_GRANULE */
/* Clear mark bits */
ptr_t base = current; \
/* The following always fails for large block references. */ \
if (EXPECT((gran_offset | byte_offset) != 0, FALSE)) { \
- if (hhdr -> hb_large_block) { \
+ if ((hhdr -> hb_flags & LARGE_BLOCK) != 0) { \
/* gran_offset is bogus. */ \
size_t obj_displ; \
base = (ptr_t)(hhdr -> hb_block); \
/* Mark from all objects, marked or */
/* not. Used to mark objects needed by */
/* reclaim notifier. */
+# endif
+# ifdef MARK_BIT_PER_GRANULE
+# define LARGE_BLOCK 0x10
# endif
unsigned short hb_last_reclaimed;
/* Value of GC_gc_no when block was */
/* LARGE_INV_SZ. */
# define LARGE_INV_SZ (1 << 16)
# else
- unsigned char hb_large_block;
short * hb_map; /* Essentially a table of remainders */
/* mod BYTES_TO_GRANULES(hb_sz), except */
/* for large blocks. See GC_obj_map. */
# ifdef MARK_BIT_PER_OBJ
GC_ASSERT(hhdr -> hb_inv_sz == LARGE_INV_SZ);
# else
- GC_ASSERT(hhdr -> hb_large_block &&
- hhdr -> hb_map[ANY_INDEX] == 1);
+ GC_ASSERT((hhdr -> hb_flags & LARGE_BLOCK) != 0
+ && hhdr -> hb_map[ANY_INDEX] == 1);
# endif
if (IS_UNCOLLECTABLE(obj_kind)) GC_non_gc_bytes += (sz - orig_sz);
/* Extra area is already cleared by GC_alloc_large_and_clear. */