#endif
#include "Trace.h"
#include "RetainerProfile.h"
+#include "RaiseAsync.h"
#include <string.h>
copied += mut_list_size;
debugTrace(DEBUG_gc,
- "mut_list_size: %ld (%d vars, %d arrays, %d others)",
- mut_list_size * sizeof(W_),
+ "mut_list_size: %lu (%d vars, %d arrays, %d others)",
+ (unsigned long)(mut_list_size * sizeof(W_)),
mutlist_MUTVARS, mutlist_MUTARRS, mutlist_OTHERS);
}
}
return q;
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
/* no need to put these on the static linked list, they don't need
* to be scavenged.
case TREC_HEADER:
return copy(q,sizeofW(StgTRecHeader),stp);
- case TVAR_WAIT_QUEUE:
- return copy(q,sizeofW(StgTVarWaitQueue),stp);
+ case TVAR_WATCH_QUEUE:
+ return copy(q,sizeofW(StgTVarWatchQueue),stp);
case TVAR:
return copy(q,sizeofW(StgTVar),stp);
case TREC_CHUNK:
return copy(q,sizeofW(StgTRecChunk),stp);
+ case ATOMIC_INVARIANT:
+ return copy(q,sizeofW(StgAtomicInvariant),stp);
+
+ case INVARIANT_CHECK_QUEUE:
+ return copy(q,sizeofW(StgInvariantCheckQueue),stp);
+
default:
barf("evacuate: strange closure type %d", (int)(info->type));
}
) {
tso->block_info.closure = evacuate(tso->block_info.closure);
}
- if ( tso->blocked_exceptions != NULL ) {
- tso->blocked_exceptions =
- (StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
- }
+ tso->blocked_exceptions =
+ (StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
// We don't always chase the link field: TSOs on the blackhole
// queue are not automatically alive, so the link field is a
}
#endif
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
{
- StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
evac_gen = 0;
- wq->waiting_tso = (StgTSO *)evacuate((StgClosure*)wq->waiting_tso);
- wq->next_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->next_queue_entry);
- wq->prev_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
+ wq->closure = (StgClosure*)evacuate((StgClosure*)wq->closure);
+ wq->next_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->next_queue_entry);
+ wq->prev_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
- p += sizeofW(StgTVarWaitQueue);
+ p += sizeofW(StgTVarWatchQueue);
break;
}
StgTVar *tvar = ((StgTVar *) p);
evac_gen = 0;
tvar->current_value = evacuate((StgClosure*)tvar->current_value);
- tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ tvar->first_watch_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)tvar->first_watch_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTVar);
evac_gen = 0;
trec->enclosing_trec = (StgTRecHeader *)evacuate((StgClosure*)trec->enclosing_trec);
trec->current_chunk = (StgTRecChunk *)evacuate((StgClosure*)trec->current_chunk);
+ trec->invariants_to_check = (StgInvariantCheckQueue *)evacuate((StgClosure*)trec->invariants_to_check);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
p += sizeofW(StgTRecHeader);
break;
}
+ case ATOMIC_INVARIANT:
+ {
+ StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
+ evac_gen = 0;
+ invariant->code = (StgClosure *)evacuate(invariant->code);
+ invariant->last_execution = (StgTRecHeader *)evacuate((StgClosure*)invariant->last_execution);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ p += sizeofW(StgAtomicInvariant);
+ break;
+ }
+
+ case INVARIANT_CHECK_QUEUE:
+ {
+ StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
+ evac_gen = 0;
+ queue->invariant = (StgAtomicInvariant *)evacuate((StgClosure*)queue->invariant);
+ queue->my_execution = (StgTRecHeader *)evacuate((StgClosure*)queue->my_execution);
+ queue->next_queue_entry = (StgInvariantCheckQueue *)evacuate((StgClosure*)queue->next_queue_entry);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ p += sizeofW(StgInvariantCheckQueue);
+ break;
+ }
+
default:
barf("scavenge: unimplemented/strange closure type %d @ %p",
info->type, p);
}
#endif /* PAR */
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
{
- StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
evac_gen = 0;
- wq->waiting_tso = (StgTSO *)evacuate((StgClosure*)wq->waiting_tso);
- wq->next_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->next_queue_entry);
- wq->prev_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
+ wq->closure = (StgClosure*)evacuate((StgClosure*)wq->closure);
+ wq->next_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->next_queue_entry);
+ wq->prev_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
StgTVar *tvar = ((StgTVar *) p);
evac_gen = 0;
tvar->current_value = evacuate((StgClosure*)tvar->current_value);
- tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ tvar->first_watch_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)tvar->first_watch_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
evac_gen = 0;
trec->enclosing_trec = (StgTRecHeader *)evacuate((StgClosure*)trec->enclosing_trec);
trec->current_chunk = (StgTRecChunk *)evacuate((StgClosure*)trec->current_chunk);
+ trec->invariants_to_check = (StgInvariantCheckQueue *)evacuate((StgClosure*)trec->invariants_to_check);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
}
+ case ATOMIC_INVARIANT:
+ {
+ StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
+ evac_gen = 0;
+ invariant->code = (StgClosure *)evacuate(invariant->code);
+ invariant->last_execution = (StgTRecHeader *)evacuate((StgClosure*)invariant->last_execution);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ break;
+ }
+
+ case INVARIANT_CHECK_QUEUE:
+ {
+ StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
+ evac_gen = 0;
+ queue->invariant = (StgAtomicInvariant *)evacuate((StgClosure*)queue->invariant);
+ queue->my_execution = (StgTRecHeader *)evacuate((StgClosure*)queue->my_execution);
+ queue->next_queue_entry = (StgInvariantCheckQueue *)evacuate((StgClosure*)queue->next_queue_entry);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ break;
+ }
+
default:
barf("scavenge_mark_stack: unimplemented/strange closure type %d @ %p",
info->type, p);
}
#endif
- case TVAR_WAIT_QUEUE:
+ case TVAR_WATCH_QUEUE:
{
- StgTVarWaitQueue *wq = ((StgTVarWaitQueue *) p);
+ StgTVarWatchQueue *wq = ((StgTVarWatchQueue *) p);
evac_gen = 0;
- wq->waiting_tso = (StgTSO *)evacuate((StgClosure*)wq->waiting_tso);
- wq->next_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->next_queue_entry);
- wq->prev_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
+ wq->closure = (StgClosure*)evacuate((StgClosure*)wq->closure);
+ wq->next_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->next_queue_entry);
+ wq->prev_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)wq->prev_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
StgTVar *tvar = ((StgTVar *) p);
evac_gen = 0;
tvar->current_value = evacuate((StgClosure*)tvar->current_value);
- tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+ tvar->first_watch_queue_entry = (StgTVarWatchQueue *)evacuate((StgClosure*)tvar->first_watch_queue_entry);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
evac_gen = 0;
trec->enclosing_trec = (StgTRecHeader *)evacuate((StgClosure*)trec->enclosing_trec);
trec->current_chunk = (StgTRecChunk *)evacuate((StgClosure*)trec->current_chunk);
+ trec->invariants_to_check = (StgInvariantCheckQueue *)evacuate((StgClosure*)trec->invariants_to_check);
evac_gen = saved_evac_gen;
failed_to_evac = rtsTrue; // mutable
break;
break;
}
+ case ATOMIC_INVARIANT:
+ {
+ StgAtomicInvariant *invariant = ((StgAtomicInvariant *) p);
+ evac_gen = 0;
+ invariant->code = (StgClosure *)evacuate(invariant->code);
+ invariant->last_execution = (StgTRecHeader *)evacuate((StgClosure*)invariant->last_execution);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ break;
+ }
+
+ case INVARIANT_CHECK_QUEUE:
+ {
+ StgInvariantCheckQueue *queue = ((StgInvariantCheckQueue *) p);
+ evac_gen = 0;
+ queue->invariant = (StgAtomicInvariant *)evacuate((StgClosure*)queue->invariant);
+ queue->my_execution = (StgTRecHeader *)evacuate((StgClosure*)queue->my_execution);
+ queue->next_queue_entry = (StgInvariantCheckQueue *)evacuate((StgClosure*)queue->next_queue_entry);
+ evac_gen = saved_evac_gen;
+ failed_to_evac = rtsTrue; // mutable
+ break;
+ }
+
case IND_OLDGEN:
case IND_OLDGEN_PERM:
case IND_STATIC:
nat weight_pending = 0;
rtsBool prev_was_update_frame;
+ // Check to see whether we have threads waiting to raise
+ // exceptions, and we're not blocking exceptions, or are blocked
+ // interruptibly. This is important; if a thread is running with
+ // TSO_BLOCKEX and becomes blocked interruptibly, this is the only
+ // place we ensure that the blocked_exceptions get a chance.
+ maybePerformBlockedException (cap, tso);
+ if (tso->what_next == ThreadKilled) { return; }
+
stack_end = &tso->stack[tso->stack_size];
frame = (StgClosure *)tso->sp;
if (closure_IND(bh) || bh->header.info == &stg_BLACKHOLE_info) {
debugTrace(DEBUG_squeeze,
"suspending duplicate work: %ld words of stack",
- (StgPtr)frame - tso->sp);
+ (long)((StgPtr)frame - tso->sp));
// If this closure is already an indirection, then
// suspend the computation up to this point: