#ifndef CMINUSMINUS
typedef struct bdescr_ {
- StgPtr start; /* start addr of memory */
- StgPtr free; /* first free byte of memory */
- struct bdescr_ *link; /* used for chaining blocks together */
- union {
- struct bdescr_ *back; /* used (occasionally) for doubly-linked lists*/
- StgWord *bitmap;
- StgPtr scan; /* scan pointer for copying GC */
- } u;
- unsigned int gen_no; /* generation */
- struct step_ *step; /* step */
- StgWord32 blocks; /* no. of blocks (if grp head, 0 otherwise) */
- StgWord32 flags; /* block is in to-space */
+ StgPtr start; /* start addr of memory */
+ StgPtr free; /* first free byte of memory */
+ struct bdescr_ *link; /* used for chaining blocks together */
+ union {
+ struct bdescr_ *back; /* used (occasionally) for doubly-linked lists*/
+ StgWord *bitmap;
+ StgPtr scan; /* scan pointer for copying GC */
+ } u;
+
+ struct step_ *step; /* step */
+ struct step_ *dest; /* destination step */
+
+ StgWord32 blocks; /* no. of blocks (if grp head, 0 otherwise) */
+
+ StgWord16 gen_no;
+ StgWord16 flags; /* block flags, see below */
#if SIZEOF_VOID_P == 8
- StgWord32 _padding[2];
+ StgWord32 _padding[2];
#else
- StgWord32 _padding[0];
+ StgWord32 _padding[0];
#endif
} bdescr;
#endif
/* (needed when dynamic libraries are used). */
extern rtsBool keepCAFs;
+INLINE_HEADER void initBdescr(bdescr *bd, step *step)
+{
+ bd->step = step;
+ bd->gen_no = step->gen_no;
+ bd->dest = step->to;
+}
+
#endif /* RTS_STORAGE_GC_H */
bd->gen_no = 0;
bd->step = NULL;
+ bd->dest = NULL;
bd->flags = 0;
bd->free = bd->start;
bd->link = arena->current;
{
bdescr *x;
for (x = bd; x < bd + blocks; x++) {
- x->step = cap->r.rNursery;
- x->gen_no = 0;
+ initBdescr(x,cap->r.rNursery);
+ x->free = x->start;
x->flags = 0;
}
}
StgInd_indirectee(p1) = p2; \
prim %write_barrier() []; \
bd = Bdescr(p1); \
- if (bdescr_gen_no(bd) != 0 :: CInt) { \
+ if (bdescr_gen_no(bd) != 0 :: bits16) { \
recordMutableCap(p1, TO_W_(bdescr_gen_no(bd)), R1); \
SET_INFO(p1, stg_IND_OLDGEN_info); \
LDV_RECORD_CREATE(p1); \
bd->flags
bd->gen_no
bd->step
+ bd->dest
Exceptions: we don't maintain invariants for all the blocks within a
group on the free list, because it is expensive to modify every
ws = &gct->steps[new_stp->abs_no];
bd->flags |= BF_EVACUATED;
- bd->step = new_stp;
- bd->gen_no = new_stp->gen_no;
+ initBdescr(bd, new_stp);
// If this is a block of pinned objects, we don't have to scan
// these objects, because they aren't allowed to contain any
return;
}
- stp = bd->step->to;
+ stp = bd->dest;
info = q->header.info;
if (IS_FORWARDING_PTR(info))
// check whether it was updated in the meantime.
*q = (StgClosure *)p;
if (evac) {
- copy(q,(const StgInfoTable *)info_ptr,(StgClosure *)p,THUNK_SELECTOR_sizeW(),bd->step->to);
+ copy(q,(const StgInfoTable *)info_ptr,(StgClosure *)p,THUNK_SELECTOR_sizeW(),bd->dest);
}
unchain_thunk_selectors(prev_thunk_selector, *q);
return;
} else {
bd = allocBlock_sync();
}
- bd->step = ws->step;
- bd->gen_no = ws->step->gen_no;
+ initBdescr(bd, ws->step);
bd->flags = BF_EVACUATED;
bd->u.scan = bd->free = bd->start;
}
if (tail != NULL) {
tail->u.back = bd;
}
- bd->step = stp;
- bd->gen_no = 0;
+ initBdescr(bd, stp);
bd->flags = 0;
bd->free = bd->start;
tail = bd;
dbl_link_onto(bd, &stp->large_objects);
stp->n_large_blocks += bd->blocks; // might be larger than req_blocks
alloc_blocks += bd->blocks;
- bd->gen_no = g->no;
- bd->step = stp;
+ initBdescr(bd, stp);
bd->flags = BF_LARGE;
bd->free = bd->start + n;
ret = bd->start;
bd = stp->blocks;
if (bd == NULL || bd->free + n > bd->start + BLOCK_SIZE_W) {
bd = allocBlock();
- bd->gen_no = g->no;
- bd->step = stp;
+ initBdescr(bd, stp);
bd->flags = 0;
bd->link = stp->blocks;
stp->blocks = bd;
dbl_link_onto(new_bd, &g0s0->large_objects);
g0s0->n_large_blocks += new_bd->blocks;
- new_bd->gen_no = g0s0->no;
- new_bd->step = g0s0;
+ initBdescr(new_bd, g0s0);
new_bd->flags = BF_LARGE;
new_bd->free = bd->free;
ASSERT(new_bd->free <= new_bd->start + new_bd->blocks * BLOCK_SIZE_W);
bd = allocBlock();
cap->r.rNursery->n_blocks++;
RELEASE_SM_LOCK;
- bd->gen_no = 0;
- bd->step = cap->r.rNursery;
+ initBdescr(bd, cap->r.rNursery);
bd->flags = 0;
// NO: alloc_blocks++;
// calcAllocated() uses the size of the nursery, and we've
pinned_object_block = bd = allocBlock();
dbl_link_onto(bd, &g0s0->large_objects);
g0s0->n_large_blocks++;
- bd->gen_no = 0;
- bd->step = g0s0;
+ initBdescr(bd, g0s0);
bd->flags = BF_PINNED | BF_LARGE;
bd->free = bd->start;
alloc_blocks++;