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
));
45 // ignore static closures
47 // ToDo: for static closures, check the static link field.
48 // Problem here is that we sometimes don't set the link field, eg.
49 // for static closures with an empty SRT or CONSTR_STATIC_NOCAFs.
51 if (!HEAP_ALLOCED(q
)) {
55 // ignore closures in generations that we're not collecting.
58 // if it's a pointer into to-space, then we're done
59 if (bd
->flags
& BF_EVACUATED
) {
63 // large objects use the evacuated flag
64 if (bd
->flags
& BF_LARGE
) {
65 if (get_itbl(q
)->type
== TSO
&&
66 ((StgTSO
*)p
)->what_next
== ThreadRelocated
) {
67 p
= (StgClosure
*)((StgTSO
*)p
)->_link
;
73 // check the mark bit for compacted steps
74 if ((bd
->flags
& BF_COMPACTED
) && is_marked((P_
)q
,bd
)) {
78 info
= q
->header
.info
;
80 if (IS_FORWARDING_PTR(info
)) {
82 return (StgClosure
*)UN_FORWARDING_PTR(info
);
85 info
= INFO_PTR_TO_STRUCT(info
);
92 case IND_OLDGEN
: // rely on compatible layout with StgInd
94 // follow indirections
95 p
= ((StgInd
*)q
)->indirectee
;
99 if (((StgTSO
*)q
)->what_next
== ThreadRelocated
) {
100 p
= (StgClosure
*)((StgTSO
*)q
)->_link
;
112 /* -----------------------------------------------------------------------------
114 -------------------------------------------------------------------------- */
121 for (c
= (StgIndStatic
*)revertible_caf_list
; c
!= NULL
;
122 c
= (StgIndStatic
*)c
->static_link
)
124 SET_INFO(c
, c
->saved_info
);
125 c
->saved_info
= NULL
;
126 // could, but not necessary: c->static_link = NULL;
128 revertible_caf_list
= NULL
;
132 markCAFs (evac_fn evac
, void *user
)
136 for (c
= (StgIndStatic
*)caf_list
; c
!= NULL
;
137 c
= (StgIndStatic
*)c
->static_link
)
139 evac(user
, &c
->indirectee
);
141 for (c
= (StgIndStatic
*)revertible_caf_list
; c
!= NULL
;
142 c
= (StgIndStatic
*)c
->static_link
)
144 evac(user
, &c
->indirectee
);