Skip to content

Commit 17ecf63

Browse files
authored
Reduce binary size in agile reference context cache (#1468)
1 parent 02e8556 commit 17ecf63

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/WinRT.Runtime/ObjectReference.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,9 @@ internal sealed class ObjectReferenceWithContext<
609609
private readonly IntPtr _contextCallbackPtr;
610610
private readonly IntPtr _contextToken;
611611

612-
private volatile ConcurrentDictionary<IntPtr, ObjectReference<T>> __cachedContext;
613-
private ConcurrentDictionary<IntPtr, ObjectReference<T>> CachedContext => __cachedContext ?? Make_CachedContext();
614-
private ConcurrentDictionary<IntPtr, ObjectReference<T>> Make_CachedContext()
612+
private volatile ConcurrentDictionary<IntPtr, IObjectReference> __cachedContext;
613+
private ConcurrentDictionary<IntPtr, IObjectReference> CachedContext => __cachedContext ?? Make_CachedContext();
614+
private ConcurrentDictionary<IntPtr, IObjectReference> Make_CachedContext()
615615
{
616616
global::System.Threading.Interlocked.CompareExchange(ref __cachedContext, new(), null);
617617
return __cachedContext;
@@ -702,9 +702,15 @@ private ObjectReference<T> GetCurrentContext()
702702
return null;
703703
}
704704

705-
return CachedContext.GetOrAdd(currentContext, CreateForCurrentContext);
705+
// We use a non-generic map of just <IntPtr, IObjectReference> values, to avoid all generic instantiations
706+
// of ConcurrentDictionary<,> and transitively dependent types for every vtable type T, since it's not
707+
// something we actually need. Because the cache is private and we're the only ones using it, we can
708+
// just store the per-context agile references as IObjectReference values, and then cast them on return.
709+
IObjectReference objectReference = CachedContext.GetOrAdd(currentContext, CreateForCurrentContext);
706710

707-
ObjectReference<T> CreateForCurrentContext(IntPtr _)
711+
return Unsafe.As<ObjectReference<T>>(objectReference);
712+
713+
IObjectReference CreateForCurrentContext(IntPtr _)
708714
{
709715
var agileReference = AgileReference;
710716
// We may fail to switch context and thereby not get an agile reference.

0 commit comments

Comments
 (0)