Permalink
Browse files

[sgen] Break tracking weak references as early as possible.

Our tracking references code aimed to transform tracking references
into normal weak references the first time their targets became
unreachable.  It was implemented incorrectly though, and is not the
right thing to do in the first place anyway, because tracking
references have to keep tracking if the target is re-registered for
finalization.  The incorrect implementation inadvertently handled
re-registration correctly, but it kept the reference intact for one
garbage collection cycle too many.
  • Loading branch information...
1 parent 6b3b290 commit 3481f718fbb7b9bb0260158d056aafa2330390c1 @schani schani committed Feb 22, 2011
Showing with 12 additions and 9 deletions.
  1. +12 −9 mono/metadata/sgen-gc.c
@@ -4375,6 +4375,16 @@ null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int
for (entry = disappearing_link_hash [i]; entry;) {
char *object;
gboolean track = DISLINK_TRACK (entry);
+
+ /*
+ * Tracked references are processed after
+ * finalization handling whereas standard weak
+ * references are processed before. If an
+ * object is still not marked after finalization
+ * handling it means that it either doesn't have
+ * a finalizer or the finalizer has already run,
+ * so we must null a tracking reference.
+ */
if (track == before_finalization) {
prev = entry;
entry = entry->next;
@@ -4384,7 +4394,7 @@ null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int
object = DISLINK_OBJECT (entry);
if (object >= start && object < end && !major_collector.is_object_live (object)) {
- if (!track && object_is_fin_ready (object)) {
+ if (object_is_fin_ready (object)) {
void **p = entry->link;
DisappearingLink *old;
*p = NULL;
@@ -4431,14 +4441,7 @@ null_link_in_range (CopyOrMarkObjectFunc copy_func, char *start, char *end, int
continue;
} else {
- /* We set the track resurrection bit to
- * FALSE if the object is to be finalized
- * so that the object can be collected in
- * the next cycle (i.e. after it was
- * finalized).
- */
- *entry->link = HIDE_POINTER (copy,
- object_is_fin_ready (object) ? FALSE : track);
+ *entry->link = HIDE_POINTER (copy, track);
DEBUG (5, fprintf (gc_debug_file, "Updated dislink at %p to %p\n", entry->link, DISLINK_OBJECT (entry)));
}
}

0 comments on commit 3481f71

Please sign in to comment.