{
StgPtr to;
step_workspace *ws;
- bdescr *bd;
/* Find out where we're going, using the handy "to" pointer in
* the step of the source object. If it turns out we need to
/* chain a new block onto the to-space for the destination step if
* necessary.
*/
- bd = ws->todo_bd;
- to = bd->free;
- if (to + size >= bd->start + BLOCK_SIZE_W) {
- bd = gc_alloc_todo_block(ws);
- to = bd->free;
+
+ ASSERT(ws->todo_free >= ws->todo_bd->free && ws->todo_free <= ws->todo_lim);
+ to = ws->todo_free;
+ if (to + size >= ws->todo_lim) {
+ to = gc_alloc_todo_block(ws);
}
- bd->free = to + size;
+ ws->todo_free = to + size;
+ ASSERT(ws->todo_free >= ws->todo_bd->free && ws->todo_free <= ws->todo_lim);
return to;
}
-
+
/* -----------------------------------------------------------------------------
The evacuate() code
-------------------------------------------------------------------------- */
prev = NULL;
while (p)
{
- ASSERT(p->header.info == &stg_BLACKHOLE_info);
+ ASSERT(p->header.info == &stg_BLACKHOLE_info
+ || p->header.info == &stg_WHITEHOLE_info);
prev = (StgSelector*)((StgClosure *)p)->payload[0];
// Update the THUNK_SELECTOR with an indirection to the
// In threaded mode, we'll use WHITEHOLE to lock the selector
// thunk while we evaluate it.
{
- info_ptr = (StgInfoTable *)xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ info_ptr = xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
if (info_ptr == (W_)&stg_WHITEHOLE_info) {
do {
info_ptr = xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
#ifdef PROFILING
// For the purposes of LDV profiling, we have destroyed
// the original selector thunk, p.
- SET_INFO(p, info_ptr);
+ SET_INFO(p, (StgInfoTable *)info_ptr);
LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC((StgClosure *)p);
SET_INFO(p, &stg_BLACKHOLE_info);
#endif