/* -----------------------------------------------------------------------------
Scavenge a block from the given scan pointer up to bd->free.
- evac_gen is set by the caller to be either zero (for a step in a
+ evac_step is set by the caller to be either zero (for a step in a
generation < N) or G where G is the generation of the step being
scavenged.
- We sometimes temporarily change evac_gen back to zero if we're
+ We sometimes temporarily change evac_step back to zero if we're
scavenging a mutable object where eager promotion isn't such a good
idea.
-------------------------------------------------------------------------- */
{
StgPtr p, q;
StgInfoTable *info;
- nat saved_evac_gen;
+ step *saved_evac_step;
p = scan;
debugTrace(DEBUG_gc, "scavenging block %p (gen %d, step %d) @ %p",
bd->start, bd->gen_no, bd->step->no, scan);
- gct->evac_gen = bd->gen_no;
- saved_evac_gen = gct->evac_gen;
+ gct->evac_step = bd->step;
+ saved_evac_step = gct->evac_step;
gct->failed_to_evac = rtsFalse;
// we might be evacuating into the very object that we're
case TVAR_WATCH_QUEUE:
{
StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&wq->closure);
evacuate((StgClosure **)&wq->next_queue_entry);
evacuate((StgClosure **)&wq->prev_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTVarWatchQueue);
break;
case TVAR:
{
StgTVar *tvar = ((StgTVar *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tvar->current_value);
evacuate((StgClosure **)&tvar->first_watch_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTVar);
break;
case TREC_HEADER:
{
StgTRecHeader *trec = ((StgTRecHeader *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&trec->enclosing_trec);
evacuate((StgClosure **)&trec->current_chunk);
evacuate((StgClosure **)&trec->invariants_to_check);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTRecHeader);
break;
StgWord i;
StgTRecChunk *tc = ((StgTRecChunk *) p);
TRecEntry *e = &(tc -> entries[0]);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tc->prev_chunk);
for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
evacuate((StgClosure **)&e->tvar);
evacuate((StgClosure **)&e->expected_value);
evacuate((StgClosure **)&e->new_value);
}
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTRecChunk);
break;
case ATOMIC_INVARIANT:
{
StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate(&invariant->code);
evacuate((StgClosure **)&invariant->last_execution);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgAtomicInvariant);
break;
case INVARIANT_CHECK_QUEUE:
{
StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&queue->invariant);
evacuate((StgClosure **)&queue->my_execution);
evacuate((StgClosure **)&queue->next_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgInvariantCheckQueue);
break;
{
StgPtr p, q;
StgInfoTable *info;
- nat saved_evac_gen;
+ step *saved_evac_step;
- gct->evac_gen = oldest_gen->no;
- saved_evac_gen = gct->evac_gen;
+ gct->evac_step = &oldest_gen->steps[0];
+ saved_evac_step = gct->evac_step;
linear_scan:
while (!mark_stack_empty()) {
case TVAR_WATCH_QUEUE:
{
StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&wq->closure);
evacuate((StgClosure **)&wq->next_queue_entry);
evacuate((StgClosure **)&wq->prev_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case TVAR:
{
StgTVar *tvar = ((StgTVar *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tvar->current_value);
evacuate((StgClosure **)&tvar->first_watch_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
StgWord i;
StgTRecChunk *tc = ((StgTRecChunk *) p);
TRecEntry *e = &(tc -> entries[0]);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tc->prev_chunk);
for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
evacuate((StgClosure **)&e->tvar);
evacuate((StgClosure **)&e->expected_value);
evacuate((StgClosure **)&e->new_value);
}
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case TREC_HEADER:
{
StgTRecHeader *trec = ((StgTRecHeader *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&trec->enclosing_trec);
evacuate((StgClosure **)&trec->current_chunk);
evacuate((StgClosure **)&trec->invariants_to_check);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case ATOMIC_INVARIANT:
{
StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate(&invariant->code);
evacuate((StgClosure **)&invariant->last_execution);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case INVARIANT_CHECK_QUEUE:
{
StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&queue->invariant);
evacuate((StgClosure **)&queue->my_execution);
evacuate((StgClosure **)&queue->next_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
if (gct->failed_to_evac) {
gct->failed_to_evac = rtsFalse;
- if (gct->evac_gen > 0) {
- recordMutableGen_GC((StgClosure *)q, &generations[gct->evac_gen]);
+ if (gct->evac_step) {
+ recordMutableGen_GC((StgClosure *)q, gct->evac_step->gen);
}
}
scavenge_one(StgPtr p)
{
const StgInfoTable *info;
- nat saved_evac_gen = gct->evac_gen;
+ step *saved_evac_step = gct->evac_step;
rtsBool no_luck;
ASSERT(LOOKS_LIKE_CLOSURE_PTR(p));
case TVAR_WATCH_QUEUE:
{
StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&wq->closure);
evacuate((StgClosure **)&wq->next_queue_entry);
evacuate((StgClosure **)&wq->prev_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case TVAR:
{
StgTVar *tvar = ((StgTVar *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tvar->current_value);
evacuate((StgClosure **)&tvar->first_watch_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case TREC_HEADER:
{
StgTRecHeader *trec = ((StgTRecHeader *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&trec->enclosing_trec);
evacuate((StgClosure **)&trec->current_chunk);
evacuate((StgClosure **)&trec->invariants_to_check);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
StgWord i;
StgTRecChunk *tc = ((StgTRecChunk *) p);
TRecEntry *e = &(tc -> entries[0]);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&tc->prev_chunk);
for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
evacuate((StgClosure **)&e->tvar);
evacuate((StgClosure **)&e->expected_value);
evacuate((StgClosure **)&e->new_value);
}
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case ATOMIC_INVARIANT:
{
StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate(&invariant->code);
evacuate((StgClosure **)&invariant->last_execution);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
case INVARIANT_CHECK_QUEUE:
{
StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
- gct->evac_gen = 0;
+ gct->evac_step = 0;
evacuate((StgClosure **)&queue->invariant);
evacuate((StgClosure **)&queue->my_execution);
evacuate((StgClosure **)&queue->next_queue_entry);
- gct->evac_gen = saved_evac_gen;
+ gct->evac_step = saved_evac_step;
gct->failed_to_evac = rtsTrue; // mutable
break;
}
bd = gen->saved_mut_list;
- gct->evac_gen = gen->no;
+ gct->evac_step = &gen->steps[0];
for (; bd != NULL; bd = bd->link) {
for (q = bd->start; q < bd->free; q++) {
p = (StgPtr)*q;
/* Always evacuate straight to the oldest generation for static
* objects */
- gct->evac_gen = oldest_gen->no;
+ gct->evac_step = &oldest_gen->steps[0];
/* keep going until we've scavenged all the objects on the linked
list... */
/*-----------------------------------------------------------------------------
scavenge the large object list.
- evac_gen set by caller; similar games played with evac_gen as with
+ evac_step set by caller; similar games played with evac_step as with
scavenge() - see comment at the top of scavenge(). Most large
- objects are (repeatedly) mutable, so most of the time evac_gen will
+ objects are (repeatedly) mutable, so most of the time evac_step will
be zero.
--------------------------------------------------------------------------- */
bdescr *bd;
StgPtr p;
- gct->evac_gen = ws->stp->gen_no;
+ gct->evac_step = ws->stp;
bd = ws->todo_large_objects;