#include "Updates.h"
#include "Stats.h"
#include "Schedule.h"
-#include "SchedAPI.h" // for ReverCAFs prototype
#include "Sanity.h"
#include "BlockAlloc.h"
#include "MBlock.h"
#include "ParTicky.h" // ToDo: move into Rts.h
#include "GCCompact.h"
#include "Signals.h"
+#include "STM.h"
#if defined(GRAN) || defined(PAR)
# include "GranSimRts.h"
# include "ParallelRts.h"
blockUserSignals();
#endif
+ // tell the STM to discard any cached closures its hoping to re-use
+ stmPreGCHook();
+
// tell the stats department that we've started a GC
stat_startGC();
case UPDATE_FRAME:
case STOP_FRAME:
case CATCH_FRAME:
+ case CATCH_STM_FRAME:
+ case CATCH_RETRY_FRAME:
+ case ATOMICALLY_FRAME:
// shouldn't see these
barf("evacuate: stack frame at %p\n", q);
return to;
#endif
+ case TREC_HEADER:
+ return copy(q,sizeofW(StgTRecHeader),stp);
+
+ case TVAR_WAIT_QUEUE:
+ return copy(q,sizeofW(StgTVarWaitQueue),stp);
+
+ case TVAR:
+ return copy(q,sizeofW(StgTVar),stp);
+
+ case TREC_CHUNK:
+ return copy(q,sizeofW(StgTRecChunk),stp);
+
default:
barf("evacuate: strange closure type %d", (int)(info->type));
}
StgThunkInfoTable *thunk_info;
thunk_info = itbl_to_thunk_itbl(info);
- scavenge_srt((StgClosure **)thunk_info->srt, thunk_info->i.srt_bitmap);
+ scavenge_srt((StgClosure **)GET_SRT(thunk_info), thunk_info->i.srt_bitmap);
}
STATIC_INLINE void
StgFunInfoTable *fun_info;
fun_info = itbl_to_fun_itbl(info);
- scavenge_srt((StgClosure **)fun_info->f.srt, fun_info->i.srt_bitmap);
+ scavenge_srt((StgClosure **)GET_FUN_SRT(fun_info), fun_info->i.srt_bitmap);
}
STATIC_INLINE void
StgRetInfoTable *ret_info;
ret_info = itbl_to_ret_itbl(info);
- scavenge_srt((StgClosure **)ret_info->srt, ret_info->i.srt_bitmap);
+ scavenge_srt((StgClosure **)GET_SRT(ret_info), ret_info->i.srt_bitmap);
}
/* -----------------------------------------------------------------------------
(StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
}
+ // scavange current transaction record
+ (StgClosure *)tso->trec = evacuate((StgClosure *)tso->trec);
+
// scavenge this thread's stack
scavenge_stack(tso->sp, &(tso->stack[tso->stack_size]));
}
size = BITMAP_SIZE(fun_info->f.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
- size = ((StgLargeBitmap *)fun_info->f.bitmap)->size;
- scavenge_large_bitmap(p, (StgLargeBitmap *)fun_info->f.bitmap, size);
+ size = GET_FUN_LARGE_BITMAP(fun_info)->size;
+ scavenge_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
p += size;
break;
default:
bitmap = BITMAP_BITS(fun_info->f.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
- scavenge_large_bitmap(p, (StgLargeBitmap *)fun_info->f.bitmap, size);
+ scavenge_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
p += size;
break;
case ARG_BCO:
}
#endif
+ case TVAR_WAIT_QUEUE:
+ {
+ StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ evac_gen = 0;
+ (StgClosure *)wq->waiting_tso = evacuate((StgClosure*)wq->waiting_tso);
+ (StgClosure *)wq->next_queue_entry = evacuate((StgClosure*)wq->next_queue_entry);
+ (StgClosure *)wq->prev_queue_entry = evacuate((StgClosure*)wq->prev_queue_entry);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)wq);
+ failed_to_evac = rtsFalse; // mutable
+ p += sizeofW(StgTVarWaitQueue);
+ break;
+ }
+
+ case TVAR:
+ {
+ StgTVar *tvar = ((StgTVar *) p);
+ evac_gen = 0;
+ (StgClosure *)tvar->current_value = evacuate((StgClosure*)tvar->current_value);
+ (StgClosure *)tvar->first_wait_queue_entry = evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)tvar);
+ failed_to_evac = rtsFalse; // mutable
+ p += sizeofW(StgTVar);
+ break;
+ }
+
+ case TREC_HEADER:
+ {
+ StgTRecHeader *trec = ((StgTRecHeader *) p);
+ evac_gen = 0;
+ (StgClosure *)trec->enclosing_trec = evacuate((StgClosure*)trec->enclosing_trec);
+ (StgClosure *)trec->current_chunk = evacuate((StgClosure*)trec->current_chunk);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)trec);
+ failed_to_evac = rtsFalse; // mutable
+ p += sizeofW(StgTRecHeader);
+ break;
+ }
+
+ case TREC_CHUNK:
+ {
+ StgWord i;
+ StgTRecChunk *tc = ((StgTRecChunk *) p);
+ TRecEntry *e = &(tc -> entries[0]);
+ evac_gen = 0;
+ (StgClosure *)tc->prev_chunk = evacuate((StgClosure*)tc->prev_chunk);
+ for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
+ (StgClosure *)e->tvar = evacuate((StgClosure*)e->tvar);
+ (StgClosure *)e->expected_value = evacuate((StgClosure*)e->expected_value);
+ (StgClosure *)e->new_value = evacuate((StgClosure*)e->new_value);
+ }
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)tc);
+ failed_to_evac = rtsFalse; // mutable
+ p += sizeofW(StgTRecChunk);
+ break;
+ }
+
default:
barf("scavenge: unimplemented/strange closure type %d @ %p",
info->type, p);
}
#endif // PAR
+ case TVAR_WAIT_QUEUE:
+ {
+ StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ evac_gen = 0;
+ (StgClosure *)wq->waiting_tso = evacuate((StgClosure*)wq->waiting_tso);
+ (StgClosure *)wq->next_queue_entry = evacuate((StgClosure*)wq->next_queue_entry);
+ (StgClosure *)wq->prev_queue_entry = evacuate((StgClosure*)wq->prev_queue_entry);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)wq);
+ failed_to_evac = rtsFalse; // mutable
+ break;
+ }
+
+ case TVAR:
+ {
+ StgTVar *tvar = ((StgTVar *) p);
+ evac_gen = 0;
+ (StgClosure *)tvar->current_value = evacuate((StgClosure*)tvar->current_value);
+ (StgClosure *)tvar->first_wait_queue_entry = evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)tvar);
+ failed_to_evac = rtsFalse; // mutable
+ break;
+ }
+
+ case TREC_CHUNK:
+ {
+ StgWord i;
+ StgTRecChunk *tc = ((StgTRecChunk *) p);
+ TRecEntry *e = &(tc -> entries[0]);
+ evac_gen = 0;
+ (StgClosure *)tc->prev_chunk = evacuate((StgClosure*)tc->prev_chunk);
+ for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
+ (StgClosure *)e->tvar = evacuate((StgClosure*)e->tvar);
+ (StgClosure *)e->expected_value = evacuate((StgClosure*)e->expected_value);
+ (StgClosure *)e->new_value = evacuate((StgClosure*)e->new_value);
+ }
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)tc);
+ failed_to_evac = rtsFalse; // mutable
+ break;
+ }
+
+ case TREC_HEADER:
+ {
+ StgTRecHeader *trec = ((StgTRecHeader *) p);
+ evac_gen = 0;
+ (StgClosure *)trec->enclosing_trec = evacuate((StgClosure*)trec->enclosing_trec);
+ (StgClosure *)trec->current_chunk = evacuate((StgClosure*)trec->current_chunk);
+ evac_gen = saved_evac_gen;
+ recordMutable((StgMutClosure *)trec);
+ failed_to_evac = rtsFalse; // mutable
+ break;
+ }
+
default:
barf("scavenge_mark_stack: unimplemented/strange closure type %d @ %p",
info->type, p);
}
#endif
+ case TVAR_WAIT_QUEUE:
+ {
+ StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ (StgClosure *)wq->waiting_tso = evacuate((StgClosure*)wq->waiting_tso);
+ (StgClosure *)wq->next_queue_entry = evacuate((StgClosure*)wq->next_queue_entry);
+ (StgClosure *)wq->prev_queue_entry = evacuate((StgClosure*)wq->prev_queue_entry);
+ p->mut_link = gen->mut_list;
+ gen->mut_list = p;
+ continue;
+ }
+
+ case TVAR:
+ {
+ StgTVar *tvar = ((StgTVar *) p);
+ (StgClosure *)tvar->current_value = evacuate((StgClosure*)tvar->current_value);
+ (StgClosure *)tvar->first_wait_queue_entry = evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ p->mut_link = gen->mut_list;
+ gen->mut_list = p;
+ continue;
+ }
+
+ case TREC_CHUNK:
+ {
+ StgWord i;
+ StgTRecChunk *tc = ((StgTRecChunk *) p);
+ TRecEntry *e = &(tc -> entries[0]);
+ (StgClosure *)tc->prev_chunk = evacuate((StgClosure*)tc->prev_chunk);
+ for (i = 0; i < tc -> next_entry_idx; i ++, e++ ) {
+ (StgClosure *)e->tvar = evacuate((StgClosure*)e->tvar);
+ (StgClosure *)e->expected_value = evacuate((StgClosure*)e->expected_value);
+ (StgClosure *)e->new_value = evacuate((StgClosure*)e->new_value);
+ }
+ p->mut_link = gen->mut_list;
+ gen->mut_list = p;
+ continue;
+ }
+
+ case TREC_HEADER:
+ {
+ StgTRecHeader *trec = ((StgTRecHeader *) p);
+ (StgClosure *)trec->enclosing_trec = evacuate((StgClosure*)trec->enclosing_trec);
+ (StgClosure *)trec->current_chunk = evacuate((StgClosure*)trec->current_chunk);
+ p->mut_link = gen->mut_list;
+ gen->mut_list = p;
+ continue;
+ }
+
default:
// shouldn't have anything else on the mutables list
barf("scavenge_mutable_list: strange object? %d", (int)(info->type));
continue;
// small bitmap (< 32 entries, or 64 on a 64-bit machine)
+ case CATCH_STM_FRAME:
+ case CATCH_RETRY_FRAME:
+ case ATOMICALLY_FRAME:
case STOP_FRAME:
case CATCH_FRAME:
case RET_SMALL:
p = scavenge_small_bitmap(p, size, bitmap);
follow_srt:
- scavenge_srt((StgClosure **)info->srt, info->i.srt_bitmap);
+ scavenge_srt((StgClosure **)GET_SRT(info), info->i.srt_bitmap);
continue;
case RET_BCO: {
{
nat size;
- size = info->i.layout.large_bitmap->size;
+ size = GET_LARGE_BITMAP(&info->i)->size;
p++;
- scavenge_large_bitmap(p, info->i.layout.large_bitmap, size);
+ scavenge_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size);
p += size;
// and don't forget to follow the SRT
goto follow_srt;
* same size as a BLACKHOLE in any case.
*/
if (bh_info->type != THUNK_SELECTOR) {
- for (i = np; i < np + nw; i++) {
- ((StgClosure *)bh)->payload[i] = 0;
+ for (i = 0; i < np + nw; i++) {
+ ((StgClosure *)bh)->payload[i] = INVALID_OBJECT;
}
}
}