@@ -12,9 +12,6 @@ namespace System.Runtime.InteropServices
1212{
1313 internal static partial class TrackerObjectManager
1414 {
15- [ FixedAddressValueType ]
16- internal static readonly unsafe IntPtr s_findReferencesTargetCallback = ( IntPtr ) Unsafe . AsPointer ( in FindReferenceTargetsCallback . Vftbl ) ;
17-
1815 internal static volatile IntPtr s_trackerManager ;
1916 internal static volatile bool s_hasTrackingStarted ;
2017 internal static volatile bool s_isGlobalPeggingOn = true ;
@@ -163,9 +160,8 @@ internal static unsafe void WalkExternalTrackerObjects()
163160 if ( nativeObjectWrapper != null &&
164161 nativeObjectWrapper . TrackerObject != IntPtr . Zero )
165162 {
166- FindReferenceTargetsCallback . s_currentRootObjectHandle = nativeObjectWrapper . ProxyHandle ;
167- int hr = IReferenceTracker . FindTrackerTargets ( nativeObjectWrapper . TrackerObject , ( IntPtr ) Unsafe . AsPointer ( in s_findReferencesTargetCallback ) ) ;
168- FindReferenceTargetsCallback . s_currentRootObjectHandle = default ;
163+ FindReferenceTargetsCallback . Instance callback = new ( nativeObjectWrapper . ProxyHandle ) ;
164+ int hr = IReferenceTracker . FindTrackerTargets ( nativeObjectWrapper . TrackerObject , ( IntPtr ) ( void * ) & callback ) ;
169165 if ( hr < 0 )
170166 {
171167 walkFailed = true ;
@@ -202,7 +198,20 @@ internal static void DetachNonPromotedObjects()
202198 // Callback implementation of IFindReferenceTargetsCallback
203199 internal static unsafe class FindReferenceTargetsCallback
204200 {
205- internal static GCHandle s_currentRootObjectHandle ;
201+ // Define an on-stack compatible COM instance to avoid allocating
202+ // a temporary instance.
203+ [ StructLayout ( LayoutKind . Sequential ) ]
204+ internal ref struct Instance
205+ {
206+ private readonly IntPtr _vtable ; // First field is IUnknown based vtable.
207+ public GCHandle RootObject ;
208+
209+ public Instance ( GCHandle handle )
210+ {
211+ _vtable = ( IntPtr ) Unsafe . AsPointer ( in FindReferenceTargetsCallback . Vftbl ) ;
212+ RootObject = handle ;
213+ }
214+ }
206215
207216#pragma warning disable CS3016
208217 [ UnmanagedCallersOnly ( CallConvs = [ typeof ( CallConvMemberFunction ) ] ) ]
@@ -230,7 +239,7 @@ private static unsafe int IFindReferenceTargetsCallback_FoundTrackerTarget(IntPt
230239 return HResults . E_POINTER ;
231240 }
232241
233- object sourceObject = s_currentRootObjectHandle . Target ! ;
242+ object sourceObject = ( ( FindReferenceTargetsCallback . Instance * ) pThis ) -> RootObject . Target ! ;
234243
235244 if ( ! TryGetObject ( referenceTrackerTarget , out object ? targetObject ) )
236245 {
0 commit comments