if (HEAP_ALLOCED(q)) {
bd = Bdescr(q);
- // a handy way to discover whether the ptr is into the
- // compacted area of the old gen, is that the EVACUATED flag
- // is zero (it's non-zero for all the other areas of live
- // memory).
- if ((bd->flags & BF_EVACUATED) == 0)
+
+ if (bd->flags & BF_COMPACTED)
{
iptr = *q;
switch (GET_CLOSURE_TAG((StgClosure *)iptr))
// save any space in any case, and updating with an indirection is
// trickier in a non-collected gen: we would have to update the
// mutable list.
- if ((bd->gen_no > N) || (bd->flags & BF_EVACUATED)) {
+ if (bd->flags & BF_EVACUATED) {
unchain_thunk_selectors(prev_thunk_selector, (StgClosure *)p);
*q = (StgClosure *)p;
return;
bd = Bdescr((P_)q);
- if (bd->gen_no > N) {
- /* Can't evacuate this object, because it's in a generation
- * older than the ones we're collecting. Let's hope that it's
- * in gct->evac_step or older, or we will have to arrange to track
- * this pointer using the mutable list.
- */
- if (bd->step < gct->evac_step) {
- // nope
- gct->failed_to_evac = rtsTrue;
- TICK_GC_FAILED_PROMOTION();
- }
- return;
- }
-
if ((bd->flags & (BF_LARGE | BF_COMPACTED | BF_EVACUATED)) != 0) {
- /* pointer into to-space: just return it. This normally
- * shouldn't happen, but alllowing it makes certain things
- * slightly easier (eg. the mutable list can contain the same
- * object twice, for example).
- */
+ // pointer into to-space: just return it. It might be a pointer
+ // into a generation that we aren't collecting (> N), or it
+ // might just be a pointer into to-space. The latter doesn't
+ // happen often, but allowing it makes certain things a bit
+ // easier; e.g. scavenging an object is idempotent, so it's OK to
+ // have an object on the mutable list multiple times.
if (bd->flags & BF_EVACUATED) {
+ // We aren't copying this object, so we have to check
+ // whether it is already in the target generation. (this is
+ // the write barrier).
if (bd->step < gct->evac_step) {
gct->failed_to_evac = rtsTrue;
TICK_GC_FAILED_PROMOTION();
prev = NULL;
for (bd = ws->scavd_list; bd != NULL; bd = bd->link) {
- bd->flags &= ~BF_EVACUATED; // now from-space
ws->step->n_words += bd->free - bd->start;
prev = bd;
}
freeGroup(bd);
ws->n_part_blocks--;
} else {
- bd->flags &= ~BF_EVACUATED; // now from-space
ws->step->n_words += bd->free - bd->start;
prev = bd;
}
// for a compacted step, just shift the new to-space
// onto the front of the now-compacted existing blocks.
for (bd = stp->blocks; bd != NULL; bd = bd->link) {
- bd->flags &= ~BF_EVACUATED; // now from-space
stp->n_words += bd->free - bd->start;
}
// tack the new blocks on the end of the existing blocks
bd = next;
}
- // update the count of blocks used by large objects
- for (bd = stp->scavenged_large_objects; bd != NULL; bd = bd->link) {
- bd->flags &= ~BF_EVACUATED;
- }
stp->large_objects = stp->scavenged_large_objects;
stp->n_large_blocks = stp->n_scavenged_large_blocks;
*/
for (bd = stp->scavenged_large_objects; bd; bd = next) {
next = bd->link;
- bd->flags &= ~BF_EVACUATED;
dbl_link_onto(bd, &stp->large_objects);
}
stp->scavenged_large_objects = NULL;
stp->n_scavenged_large_blocks = 0;
- // mark the large objects as not evacuated yet
+ // mark the small objects as from-space
+ for (bd = stp->old_blocks; bd; bd = bd->link) {
+ bd->flags &= ~BF_EVACUATED;
+ }
+
+ // mark the large objects as from-space
for (bd = stp->large_objects; bd; bd = bd->link) {
bd->flags &= ~BF_EVACUATED;
}
// ignore closures in generations that we're not collecting.
bd = Bdescr((P_)q);
- if (bd->gen_no > N) {
- return p;
- }
// if it's a pointer into to-space, then we're done
if (bd->flags & BF_EVACUATED) {
alloc_todo_block (step_workspace *ws, nat size)
{
bdescr *bd, *hd, *tl;
- StgWord32 flags;
// Grab a part block if we have one, and it has enough room
if (ws->part_list != NULL &&
}
else
{
- // blocks in to-space in generations up to and including N
- // get the BF_EVACUATED flag.
- if (ws->step->gen_no <= N) {
- flags = BF_EVACUATED;
- } else {
- flags = 0;
- }
allocBlocks_sync(4, &hd, &tl,
- ws->step->gen_no, ws->step, flags);
+ ws->step->gen_no, ws->step, BF_EVACUATED);
tl->link = ws->part_list;
ws->part_list = hd->link;