From 66e569cf6bee18d94a3c719020a2adce353db015 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Tue, 18 Oct 2022 18:44:19 +0300 Subject: [PATCH] [mono][sgen] Fix detection of weakref objects Comparison with klass mono_defaults.generic_weakreference_class was broken because that class is a generic class while the objects have as a class generic instantiations of that so the comparison would fail. Simplify the code by adding a new gc bit where we can use name comparison. --- src/mono/mono/metadata/class-internals.h | 2 -- src/mono/mono/metadata/domain.c | 5 ----- src/mono/mono/metadata/sgen-mono.c | 9 +++++++-- src/mono/mono/sgen/sgen-gc.h | 1 + 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index 68a21cdf9d4f3f..d0158da21a67c6 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -921,8 +921,6 @@ typedef struct { MonoClass *generic_ienumerator_class; MonoClass *alc_class; MonoClass *appcontext_class; - MonoClass *weakreference_class; - MonoClass *generic_weakreference_class; } MonoDefaults; /* If you need a MonoType, use one of the mono_get_*_type () functions in class-inlines.h */ diff --git a/src/mono/mono/metadata/domain.c b/src/mono/mono/metadata/domain.c index 94d1de3be3336e..8519cf409c54bc 100644 --- a/src/mono/mono/metadata/domain.c +++ b/src/mono/mono/metadata/domain.c @@ -290,11 +290,6 @@ mono_init_internal (const char *root_domain_name) mono_defaults.alc_class = mono_class_get_assembly_load_context_class (); mono_defaults.appcontext_class = mono_class_try_load_from_name (mono_defaults.corlib, "System", "AppContext"); - mono_defaults.weakreference_class = mono_class_try_load_from_name ( - mono_defaults.corlib, "System", "WeakReference"); - mono_defaults.generic_weakreference_class = mono_class_try_load_from_name ( - mono_defaults.corlib, "System", "WeakReference`1"); - // in the past we got a filename as the root_domain_name so try to get the basename domain->friendly_name = g_path_get_basename (root_domain_name); diff --git a/src/mono/mono/metadata/sgen-mono.c b/src/mono/mono/metadata/sgen-mono.c index 64f8bda2b27642..0d0cb4b33d4576 100644 --- a/src/mono/mono/metadata/sgen-mono.c +++ b/src/mono/mono/metadata/sgen-mono.c @@ -444,6 +444,12 @@ mono_gc_get_vtable_bits (MonoClass *klass) if (fin_callbacks.is_class_finalization_aware (klass)) res |= SGEN_GC_BIT_FINALIZER_AWARE; } + + if (m_class_get_image (klass) == mono_defaults.corlib && + strcmp (m_class_get_name_space (klass), "System") == 0 && + strncmp (m_class_get_name (klass), "WeakReference", 13) == 0) + res |= SGEN_GC_BIT_WEAKREF; + return res; } @@ -457,8 +463,7 @@ is_finalization_aware (MonoObject *obj) gboolean sgen_client_object_finalize_eagerly (GCObject *obj) { - if (obj->vtable->klass == mono_defaults.weakreference_class || - obj->vtable->klass == mono_defaults.generic_weakreference_class) { + if (obj->vtable->gc_bits & SGEN_GC_BIT_WEAKREF) { MonoWeakReference *wr = (MonoWeakReference*)obj; MonoGCHandle gc_handle = (MonoGCHandle)(wr->handleAndKind & ~(gsize)1); mono_gchandle_free_internal (gc_handle); diff --git a/src/mono/mono/sgen/sgen-gc.h b/src/mono/mono/sgen/sgen-gc.h index 4e18fce08babc8..b6cfea916aab0a 100644 --- a/src/mono/mono/sgen/sgen-gc.h +++ b/src/mono/mono/sgen/sgen-gc.h @@ -300,6 +300,7 @@ enum { SGEN_GC_BIT_BRIDGE_OBJECT = 1, SGEN_GC_BIT_BRIDGE_OPAQUE_OBJECT = 2, SGEN_GC_BIT_FINALIZER_AWARE = 4, + SGEN_GC_BIT_WEAKREF = 8, }; void sgen_gc_init (void)