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 "GCTDecl.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
) {
73 // check the mark bit for compacted steps
74 if ((bd
->flags
& BF_MARKED
) && is_marked((P_
)q
,bd
)) {
78 info
= q
->header
.info
;
80 if (IS_FORWARDING_PTR(info
)) {
82 return TAG_CLOSURE(tag
,(StgClosure
*)UN_FORWARDING_PTR(info
));
85 info
= INFO_PTR_TO_STRUCT(info
);
92 // follow indirections
93 p
= ((StgInd
*)q
)->indirectee
;
103 /* -----------------------------------------------------------------------------
105 -------------------------------------------------------------------------- */
112 for (c
= (StgIndStatic
*)revertible_caf_list
;
113 c
!= (StgIndStatic
*)END_OF_STATIC_LIST
;
114 c
= (StgIndStatic
*)c
->static_link
)
116 SET_INFO((StgClosure
*)c
, c
->saved_info
);
117 c
->saved_info
= NULL
;
118 // could, but not necessary: c->static_link = NULL;
120 revertible_caf_list
= END_OF_STATIC_LIST
;
124 markCAFs (evac_fn evac
, void *user
)
128 for (c
= (StgIndStatic
*)caf_list
;
129 c
!= (StgIndStatic
*)END_OF_STATIC_LIST
;
130 c
= (StgIndStatic
*)c
->static_link
)
132 evac(user
, &c
->indirectee
);
134 for (c
= (StgIndStatic
*)revertible_caf_list
;
135 c
!= (StgIndStatic
*)END_OF_STATIC_LIST
;
136 c
= (StgIndStatic
*)c
->static_link
)
138 evac(user
, &c
->indirectee
);