1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 1998-2008
5 * Functions called from outside the GC need to be separate from GC.c,
6 * because GC.c is compiled with register variable(s).
8 * ---------------------------------------------------------------------------*/
16 #include "Capability.h"
19 // DO NOT include "GCThread.h", we don't want the register variable
21 /* -----------------------------------------------------------------------------
22 isAlive determines whether the given closure is still alive (after
23 a garbage collection) or not. It returns the new address of the
24 closure if it is alive, or NULL otherwise.
26 NOTE: Use it before compaction only!
27 It untags and (if needed) retags pointers to closures.
28 -------------------------------------------------------------------------- */
31 isAlive(StgClosure *p)
33 const StgInfoTable *info;
39 /* The tag and the pointer are split, to be merged later when needed. */
40 tag = GET_CLOSURE_TAG(p);
43 ASSERT(LOOKS_LIKE_CLOSURE_PTR(q));
46 // ignore static closures
48 // ToDo: for static closures, check the static link field.
49 // Problem here is that we sometimes don't set the link field, eg.
50 // for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
52 if (!HEAP_ALLOCED(q)) {
56 // ignore closures in generations that we're not collecting.
59 // if it's a pointer into to-space, then we're done
60 if (bd->flags & BF_EVACUATED) {
64 // large objects use the evacuated flag
65 if (bd->flags & BF_LARGE) {
69 // check the mark bit for compacted steps
70 if ((bd->flags & BF_COMPACTED) && is_marked((P_)q,bd)) {
79 case IND_OLDGEN: // rely on compatible layout with StgInd
81 // follow indirections
82 p = ((StgInd *)q)->indirectee;
87 return ((StgEvacuated *)q)->evacuee;
90 if (((StgTSO *)q)->what_next == ThreadRelocated) {
91 p = (StgClosure *)((StgTSO *)q)->_link;
103 /* -----------------------------------------------------------------------------
105 -------------------------------------------------------------------------- */
112 for (c = (StgIndStatic *)revertible_caf_list; c != NULL;
113 c = (StgIndStatic *)c->static_link)
115 SET_INFO(c, c->saved_info);
116 c->saved_info = NULL;
117 // could, but not necessary: c->static_link = NULL;
119 revertible_caf_list = NULL;
123 markCAFs (evac_fn evac, void *user)
127 for (c = (StgIndStatic *)caf_list; c != NULL;
128 c = (StgIndStatic *)c->static_link)
130 evac(user, &c->indirectee);
132 for (c = (StgIndStatic *)revertible_caf_list; c != NULL;
133 c = (StgIndStatic *)c->static_link)
135 evac(user, &c->indirectee);