@@ -12,9 +12,6 @@ namespace System.Runtime.InteropServices
12
12
{
13
13
internal static partial class TrackerObjectManager
14
14
{
15
- [ FixedAddressValueType ]
16
- internal static readonly unsafe IntPtr s_findReferencesTargetCallback = ( IntPtr ) Unsafe . AsPointer ( in FindReferenceTargetsCallback . Vftbl ) ;
17
-
18
15
internal static volatile IntPtr s_trackerManager ;
19
16
internal static volatile bool s_hasTrackingStarted ;
20
17
internal static volatile bool s_isGlobalPeggingOn = true ;
@@ -163,9 +160,8 @@ internal static unsafe void WalkExternalTrackerObjects()
163
160
if ( nativeObjectWrapper != null &&
164
161
nativeObjectWrapper . TrackerObject != IntPtr . Zero )
165
162
{
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 ) ;
169
165
if ( hr < 0 )
170
166
{
171
167
walkFailed = true ;
@@ -202,7 +198,20 @@ internal static void DetachNonPromotedObjects()
202
198
// Callback implementation of IFindReferenceTargetsCallback
203
199
internal static unsafe class FindReferenceTargetsCallback
204
200
{
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
+ }
206
215
207
216
#pragma warning disable CS3016
208
217
[ UnmanagedCallersOnly ( CallConvs = [ typeof ( CallConvMemberFunction ) ] ) ]
@@ -230,7 +239,7 @@ private static unsafe int IFindReferenceTargetsCallback_FoundTrackerTarget(IntPt
230
239
return HResults . E_POINTER ;
231
240
}
232
241
233
- object sourceObject = s_currentRootObjectHandle . Target ! ;
242
+ object sourceObject = ( ( FindReferenceTargetsCallback . Instance * ) pThis ) -> RootObject . Target ! ;
234
243
235
244
if ( ! TryGetObject ( referenceTrackerTarget , out object ? targetObject ) )
236
245
{
0 commit comments