[sgen] Make GC handles table lock-free.
[mono.git] / mono / sgen / sgen-fin-weak-hash.c
index 5bf77c4fde3972a29581dad5846d6a264c7a8ec5..0f222a1fa556e92ed259c629a9a74a8538acff2c 100644 (file)
@@ -634,28 +634,35 @@ sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, G
  * Returns whether to remove the link from its hash.
  */
 static gpointer
-null_link_if_necessary (gpointer *hidden_entry, GCHandleType handle_type, gpointer user)
+null_link_if_necessary (gpointer obj_untyped, GCHandleType handle_type, gpointer user)
 {
+       GCObject *obj = obj_untyped;
+       const gboolean is_weak = GC_HANDLE_TYPE_IS_WEAK (handle_type);
        ScanCopyContext *ctx = (ScanCopyContext *)user;
-       gpointer entry = REVEAL_POINTER (*hidden_entry);
-       char *copy = entry;
-       gboolean entry_in_nursery = ptr_in_nursery (entry);
-       if (sgen_get_current_collection_generation () == GENERATION_NURSERY && !entry_in_nursery)
-               return *hidden_entry;
-       /* Clear link if object is ready for finalization. */
-       if (sgen_gc_is_object_ready_for_finalization (entry)) {
-               return NULL;
+       char *copy = (char *)obj;
+       g_assert (obj);
+       if (major_collector.is_object_live ((char *)obj))
+               return MONO_GC_HANDLE_OBJECT_POINTER (obj, is_weak);
+       /*
+       gboolean obj_in_nursery = ptr_in_nursery (obj);
+       if (sgen_get_current_collection_generation () == GENERATION_NURSERY && !obj_in_nursery)
+               return GC_HANDLE_OBJECT_POINTER (obj);
+       */
+       /* Clear link if object is ready for finalization. This check may be redundant wrt is_object_live(). */
+       if (sgen_gc_is_object_ready_for_finalization (obj)) {
+               /* binary_protocol_dislink_update (hidden_entry, entry, 0); */
+               return MONO_GC_HANDLE_DOMAIN_POINTER (mono_object_domain (obj), is_weak);
        }
        ctx->ops->copy_or_mark_object ((void **)&copy, ctx->queue);
        g_assert (copy);
-       /* Update pointer if it's moved. */
-       binary_protocol_dislink_update (hidden_entry, copy, handle_type == HANDLE_WEAK_TRACK);
-       return HIDE_POINTER (copy);
+       /* binary_protocol_dislink_update (hidden_entry, copy, handle_type == HANDLE_WEAK_TRACK); */
+       /* Update link if object was moved. */
+       return MONO_GC_HANDLE_OBJECT_POINTER (copy, is_weak);
 }
 
 /* LOCKING: requires that the GC lock is held */
 void
-sgen_null_link_in_range (int generation, gboolean before_finalization, ScanCopyContext ctx, gboolean track)
+sgen_null_link_in_range (int generation, ScanCopyContext ctx, gboolean track)
 {
        mono_gchandle_iterate (track ? HANDLE_WEAK_TRACK : HANDLE_WEAK, generation, null_link_if_necessary, &ctx);
 }
@@ -666,18 +673,16 @@ typedef struct {
 } WeakLinkAlivePredicateClosure;
 
 static gpointer
-null_link_if (gpointer *hidden_entry, GCHandleType handle_type, gpointer user)
+null_link_if (gpointer obj_untyped, GCHandleType handle_type, gpointer user)
 {
+       GCObject *obj = obj_untyped;
        /* Strictly speaking, function pointers are not guaranteed to have the same size as data pointers. */
        WeakLinkAlivePredicateClosure *closure = (WeakLinkAlivePredicateClosure *)user;
-       gpointer entry = REVEAL_POINTER (*hidden_entry);
-       if (!entry)
-               return NULL;
-       if (closure->predicate ((MonoObject*)entry, closure->data)) {
-               binary_protocol_dislink_update (hidden_entry, NULL, 0);
+       if (closure->predicate (obj, closure->data)) {
+               /* binary_protocol_dislink_update (hidden_entry, NULL, 0); */
                return NULL;
        }
-       return *hidden_entry;
+       return MONO_GC_HANDLE_OBJECT_POINTER (obj, GC_HANDLE_TYPE_IS_WEAK (handle_type));
 }
 
 /* LOCKING: requires that the GC lock is held */