From e19525532a3877594e41b149b0548dc14f89e034 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sat, 10 Dec 2016 00:39:58 -0800 Subject: [PATCH] Port https://github.com/dotnet/coreclr/pull/8580 to CoreRT --- .../CompilerServices/ConditionalWeakTable.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs index 42bc2ebf44e..ef9feceea68 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs @@ -421,12 +421,18 @@ internal bool Remove(TKey key) int entryIndex = FindEntry(key, out value); if (entryIndex != -1) { + ref Entry entry = ref _entries[entryIndex]; + // // We do not free the handle here, as we may be racing with readers who already saw the hash code. // Instead, we simply overwrite the entry's hash code, so subsequent reads will ignore it. // The handle will be free'd in Container's finalizer, after the table is resized or discarded. // - Volatile.Write(ref _entries[entryIndex].hashCode, -1); + Volatile.Write(ref entry.hashCode, -1); + + // Also, clear the key to allow GC to collect objects pointed to by the entry + entry.depHnd.SetPrimary(null); + return true; } return false; @@ -757,6 +763,11 @@ public object GetPrimaryAndSecondary(out Object secondary) return RuntimeImports.RhHandleGetDependent(_handle, out secondary); } + public void SetPrimary(Object primary) + { + RuntimeImports.RhHandleSet(_handle, primary); + } + //---------------------------------------------------------------------- // Forces dependentHandle back to non-allocated state (if not already there) // and frees the handle if needed.