Better diagnostic when entering a GC'd CAF
Currently a GC'd CAF contains a dangling pointer, so entering it will result in a segfault or some other random failure. It would be better to give a useful diagnostic in this case (see #3900 (closed)), not only to detect when
keepCAFs is needed, but also to help find bugs in the code generator's SRT table generation and GC bugs.
Here is one way it could be done. We use the static link field of a static closure to indicate whether the closure is live or not:
- link field is non-zero if and only if the closure was reachable at the last GC, otherwise it is zero
IND_STATIC closure has a zero link field, then we know for sure that the closure pointed to by the
IND_STATIC is invalid and entering the
IND_STATIC should give a helpful error message.
To implement this:
- on entering a CAF, set the link field to 1.
- at the beginning of (major) GC, set all the link fields for static closures that were reachable during the last major GC to zero
- during GC, link fields for reachable static closures get set to non-zero as they are linked onto first the static_objects list and then the scavenged_static_objects list.
One problem is that this scheme means traversing and writing to all the static closures at the beginning of GC, when some of them may be dead, and many will not be in the cache. The current way of doing this at the end of GC is better from a cache perspective. To refine the above approach, we could do the extra zeroing phase at the beginning of GC for
IND_STATIC closures only, and the others would get the current treatment.