Skip to content

Commit ebaf490

Browse files
committed
[Mono] Implement eager finalization of WeakReference
1 parent 19c5d17 commit ebaf490

File tree

6 files changed

+21
-20
lines changed

6 files changed

+21
-20
lines changed

src/libraries/System.Private.CoreLib/src/System/WeakReference.T.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@ private T? Target
130130
}
131131
}
132132

133-
// eager finalization is NYI on Mono
134-
#if !MONO
135133
// Note: While WeakReference<T> is formally a finalizable type, the finalizer does not actually run.
136134
// Instead the instances are treated specially in GC when scanning for no longer strongly-reachable
137135
// finalizable objects.
@@ -142,21 +140,6 @@ private T? Target
142140
}
143141
#pragma warning restore CA1821 // Remove empty Finalizers
144142

145-
#else
146-
// Free all system resources associated with this reference.
147-
~WeakReference()
148-
{
149-
IntPtr handle = Handle;
150-
if (handle != default(IntPtr))
151-
{
152-
GCHandle.InternalFree(handle);
153-
154-
// keep the bit that indicates whether this reference was tracking resurrection
155-
_handleAndKind &= TracksResurrectionBit;
156-
}
157-
}
158-
#endif
159-
160143
#endif
161144
}
162145
}

src/libraries/System.Private.CoreLib/src/System/WeakReference.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,7 @@ public virtual object? Target
150150
// Unlike WeakReference<T> case, the instance could be of a derived type and
151151
// in such case it is finalized via a finalizer.
152152

153-
// eager finalization is NYI on Mono
154-
#if !MONO
155153
Debug.Assert(this.GetType() != typeof(WeakReference));
156-
#endif
157154

158155
IntPtr handle = Handle;
159156
if (handle != default(IntPtr))

src/mono/mono/metadata/class-internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,8 @@ typedef struct {
921921
MonoClass *generic_ienumerator_class;
922922
MonoClass *alc_class;
923923
MonoClass *appcontext_class;
924+
MonoClass *weakreference_class;
925+
MonoClass *generic_weakreference_class;
924926
} MonoDefaults;
925927

926928
/* If you need a MonoType, use one of the mono_get_*_type () functions in class-inlines.h */

src/mono/mono/metadata/domain.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ mono_init_internal (const char *root_domain_name)
290290
mono_defaults.alc_class = mono_class_get_assembly_load_context_class ();
291291
mono_defaults.appcontext_class = mono_class_try_load_from_name (mono_defaults.corlib, "System", "AppContext");
292292

293+
mono_defaults.weakreference_class = mono_class_try_load_from_name (
294+
mono_defaults.corlib, "System", "WeakReference");
295+
mono_defaults.generic_weakreference_class = mono_class_try_load_from_name (
296+
mono_defaults.corlib, "System", "WeakReference`1");
297+
293298
// in the past we got a filename as the root_domain_name so try to get the basename
294299
domain->friendly_name = g_path_get_basename (root_domain_name);
295300

src/mono/mono/metadata/gc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ mono_gc_run_finalize (void *obj, void *data)
249249
return;
250250
}
251251

252+
if (o->vtable->klass == mono_defaults.weakreference_class ||
253+
o->vtable->klass == mono_defaults.generic_weakreference_class) {
254+
MonoWeakReference *wr = (MonoWeakReference*)o;
255+
MonoGCHandle gc_handle = (MonoGCHandle)(wr->handleAndKind & ~(gsize)1);
256+
mono_gchandle_free_internal (gc_handle);
257+
wr->handleAndKind &= (gsize)1;
258+
return;
259+
}
260+
252261
if (m_class_get_image (mono_object_class (o)) == mono_defaults.corlib && !strcmp (o_name, "DynamicMethod") && finalizing_root_domain) {
253262
/*
254263
* These can't be finalized during unloading/shutdown, since that would

src/mono/mono/metadata/object-internals.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,11 @@ typedef struct {
651651
guint32 intType;
652652
} MonoClassInterfaceAttribute;
653653

654+
typedef struct {
655+
MonoObject object;
656+
gsize handleAndKind;
657+
} MonoWeakReference;
658+
654659
/* Safely access System.Delegate from native code */
655660
TYPED_HANDLE_DECL (MonoDelegate);
656661

0 commit comments

Comments
 (0)