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 * ---------------------------------------------------------------------------*/
10 #include "PosixSource.h"
17 #include "Capability.h"
20 // DO NOT include "GCThread.h", we don't want the register variable
22 /* -----------------------------------------------------------------------------
23 isAlive determines whether the given closure is still alive (after
24 a garbage collection) or not. It returns the new address of the
25 closure if it is alive, or NULL otherwise.
27 NOTE: Use it before compaction only!
28 It untags and (if needed) retags pointers to closures.
29 -------------------------------------------------------------------------- */
32 isAlive(StgClosure *p)
34 const StgInfoTable *info;
40 /* The tag and the pointer are split, to be merged later when needed. */
41 tag = GET_CLOSURE_TAG(p);
44 ASSERT(LOOKS_LIKE_CLOSURE_PTR(q));
46 // ignore static closures
48 // ToDo: This means we never look through IND_STATIC, which means
49 // isRetainer needs to handle the IND_STATIC case rather than
52 // ToDo: for static closures, check the static link field.
53 // Problem here is that we sometimes don't set the link field, eg.
54 // for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
56 if (!HEAP_ALLOCED_GC(q)) {
60 // ignore closures in generations that we're not collecting.
63 // if it's a pointer into to-space, then we're done
64 if (bd->flags & BF_EVACUATED) {
68 // large objects use the evacuated flag
69 if (bd->flags & BF_LARGE) {
70 if (get_itbl(q)->type == TSO &&
71 ((StgTSO *)p)->what_next == ThreadRelocated) {
72 p = (StgClosure *)((StgTSO *)p)->_link;
78 // check the mark bit for compacted steps
79 if ((bd->flags & BF_MARKED) && is_marked((P_)q,bd)) {
83 info = q->header.info;
85 if (IS_FORWARDING_PTR(info)) {
87 return (StgClosure*)UN_FORWARDING_PTR(info);
90 info = INFO_PTR_TO_STRUCT(info);
97 // follow indirections
98 p = ((StgInd *)q)->indirectee;
102 if (((StgTSO *)q)->what_next == ThreadRelocated) {
103 p = (StgClosure *)((StgTSO *)q)->_link;
115 /* -----------------------------------------------------------------------------
117 -------------------------------------------------------------------------- */
124 for (c = (StgIndStatic *)revertible_caf_list;
125 c != (StgIndStatic *)END_OF_STATIC_LIST;
126 c = (StgIndStatic *)c->static_link)
128 SET_INFO(c, c->saved_info);
129 c->saved_info = NULL;
130 // could, but not necessary: c->static_link = NULL;
132 revertible_caf_list = END_OF_STATIC_LIST;
136 markCAFs (evac_fn evac, void *user)
140 for (c = (StgIndStatic *)caf_list;
141 c != (StgIndStatic*)END_OF_STATIC_LIST;
142 c = (StgIndStatic *)c->static_link)
144 evac(user, &c->indirectee);
146 for (c = (StgIndStatic *)revertible_caf_list;
147 c != (StgIndStatic*)END_OF_STATIC_LIST;
148 c = (StgIndStatic *)c->static_link)
150 evac(user, &c->indirectee);