Skip to content

Commit c8465dd

Browse files
authored
Move Untracked_Release to native code to avoid problems during shutdown (#115489)
1 parent 24954fb commit c8465dd

File tree

10 files changed

+134
-96
lines changed

10 files changed

+134
-96
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.CoreCLR.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ public static unsafe void GetIUnknownImpl(out IntPtr fpQueryInterface, out IntPt
2626
[SuppressGCTransition]
2727
private static partial void GetIUnknownImplInternal(out IntPtr fpQueryInterface, out IntPtr fpAddRef, out IntPtr fpRelease);
2828

29+
internal static unsafe void GetUntrackedIUnknownImpl(out delegate* unmanaged[MemberFunction]<IntPtr, uint> fpAddRef, out delegate* unmanaged[MemberFunction]<IntPtr, uint> fpRelease)
30+
{
31+
fpAddRef = fpRelease = GetUntrackedAddRefRelease();
32+
}
33+
34+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_GetUntrackedAddRefRelease")]
35+
[SuppressGCTransition]
36+
private static unsafe partial delegate* unmanaged[MemberFunction]<IntPtr, uint> GetUntrackedAddRefRelease();
37+
2938
internal static IntPtr DefaultIUnknownVftblPtr { get; } = CreateDefaultIUnknownVftbl();
3039
internal static IntPtr TaggedImplVftblPtr { get; } = CreateTaggedImplVftbl();
3140
internal static IntPtr DefaultIReferenceTrackerTargetVftblPtr { get; } = CreateDefaultIReferenceTrackerTargetVftbl();

src/coreclr/nativeaot/Runtime/HandleTableHelpers.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,12 @@ EXTERN_C uint32_t __stdcall RhIUnknown_AddRef(void* pComThis)
134134
ManagedObjectWrapper* wrapper = ToManagedObjectWrapper(pComThis);
135135
return wrapper->AddRef();
136136
}
137+
138+
//
139+
// Release is implemented in native code so that it does not need to synchronize with the GC. This is important because Xaml
140+
// can invoke this Release during shutdown, and we don't want to synchronize with the GC at that time.
141+
//
142+
EXTERN_C uint32_t __stdcall RhUntracked_AddRefRelease(void*)
143+
{
144+
return 1;
145+
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,26 @@ private static IntPtr AllocateRefCountedHandle(ManagedObjectWrapperHolder holder
5151
/// <param name="fpRelease">Function pointer to Release.</param>
5252
public static unsafe void GetIUnknownImpl(out IntPtr fpQueryInterface, out IntPtr fpAddRef, out IntPtr fpRelease)
5353
{
54-
fpQueryInterface = (IntPtr)(delegate* unmanaged<IntPtr, Guid*, IntPtr*, int>)&ComWrappers.IUnknown_QueryInterface;
54+
fpQueryInterface = (IntPtr)(delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int>)&ComWrappers.IUnknown_QueryInterface;
5555
fpAddRef = (IntPtr)(delegate*<IntPtr, uint>)&RuntimeImports.RhIUnknown_AddRef; // Implemented in C/C++ to avoid GC transitions
56-
fpRelease = (IntPtr)(delegate* unmanaged<IntPtr, uint>)&ComWrappers.IUnknown_Release;
56+
fpRelease = (IntPtr)(delegate* unmanaged[MemberFunction]<IntPtr, uint>)&ComWrappers.IUnknown_Release;
5757
}
5858

59-
[UnmanagedCallersOnly]
59+
internal static unsafe void GetUntrackedIUnknownImpl(out delegate* unmanaged[MemberFunction]<IntPtr, uint> fpAddRef, out delegate* unmanaged[MemberFunction]<IntPtr, uint> fpRelease)
60+
{
61+
// Implemented in C/C++ to avoid GC transitions during shutdown
62+
fpAddRef = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)(void*)(delegate*<IntPtr, uint>)&RuntimeImports.RhUntracked_AddRefRelease;
63+
fpRelease = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)(void*)(delegate*<IntPtr, uint>)&RuntimeImports.RhUntracked_AddRefRelease;
64+
}
65+
66+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
6067
internal static unsafe int IUnknown_QueryInterface(IntPtr pThis, Guid* guid, IntPtr* ppObject)
6168
{
6269
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
6370
return wrapper->QueryInterface(in *guid, out *ppObject);
6471
}
6572

66-
[UnmanagedCallersOnly]
73+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
6774
internal static unsafe uint IUnknown_Release(IntPtr pThis)
6875
{
6976
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
@@ -75,7 +82,7 @@ private static IntPtr GetTaggedImplCurrentVersion()
7582
{
7683
unsafe
7784
{
78-
return (IntPtr)(delegate* unmanaged<IntPtr, IntPtr, int>)&VtableImplementations.ITaggedImpl_IsCurrentVersion;
85+
return (IntPtr)(delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int>)&VtableImplementations.ITaggedImpl_IsCurrentVersion;
7986
}
8087
}
8188

@@ -95,28 +102,28 @@ private static class VtableImplementations
95102
{
96103
public unsafe struct IUnknownVftbl
97104
{
98-
public delegate* unmanaged<IntPtr, Guid*, IntPtr*, int> QueryInterface;
99-
public delegate* unmanaged<IntPtr, int> AddRef;
100-
public delegate* unmanaged<IntPtr, uint> Release;
105+
public delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int> QueryInterface;
106+
public delegate* unmanaged[MemberFunction]<IntPtr, int> AddRef;
107+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Release;
101108
}
102109

103110
public unsafe struct IReferenceTrackerTargetVftbl
104111
{
105-
public delegate* unmanaged<IntPtr, Guid*, IntPtr*, int> QueryInterface;
106-
public delegate* unmanaged<IntPtr, int> AddRef;
107-
public delegate* unmanaged<IntPtr, uint> Release;
108-
public delegate* unmanaged<IntPtr, uint> AddRefFromReferenceTracker;
109-
public delegate* unmanaged<IntPtr, uint> ReleaseFromReferenceTracker;
110-
public delegate* unmanaged<IntPtr, uint> Peg;
111-
public delegate* unmanaged<IntPtr, uint> Unpeg;
112+
public delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int> QueryInterface;
113+
public delegate* unmanaged[MemberFunction]<IntPtr, int> AddRef;
114+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Release;
115+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> AddRefFromReferenceTracker;
116+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> ReleaseFromReferenceTracker;
117+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Peg;
118+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Unpeg;
112119
}
113120

114121
public unsafe struct ITaggedImplVftbl
115122
{
116-
public delegate* unmanaged<IntPtr, Guid*, IntPtr*, int> QueryInterface;
117-
public delegate* unmanaged<IntPtr, int> AddRef;
118-
public delegate* unmanaged<IntPtr, uint> Release;
119-
public delegate* unmanaged<IntPtr, IntPtr, int> IsCurrentVersion;
123+
public delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int> QueryInterface;
124+
public delegate* unmanaged[MemberFunction]<IntPtr, int> AddRef;
125+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Release;
126+
public delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int> IsCurrentVersion;
120127
}
121128

122129
[FixedAddressValueType]
@@ -128,45 +135,45 @@ public unsafe struct ITaggedImplVftbl
128135
[FixedAddressValueType]
129136
public static readonly ITaggedImplVftbl ITaggedImpl;
130137

131-
[UnmanagedCallersOnly]
138+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
132139
internal static unsafe int IReferenceTrackerTarget_QueryInterface(IntPtr pThis, Guid* guid, IntPtr* ppObject)
133140
{
134141
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
135142
return wrapper->QueryInterfaceForTracker(in *guid, out *ppObject);
136143
}
137144

138-
[UnmanagedCallersOnly]
145+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
139146
internal static unsafe uint IReferenceTrackerTarget_AddRefFromReferenceTracker(IntPtr pThis)
140147
{
141148
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
142149
return wrapper->AddRefFromReferenceTracker();
143150
}
144151

145-
[UnmanagedCallersOnly]
152+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
146153
internal static unsafe uint IReferenceTrackerTarget_ReleaseFromReferenceTracker(IntPtr pThis)
147154
{
148155
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
149156
return wrapper->ReleaseFromReferenceTracker();
150157
}
151158

152-
[UnmanagedCallersOnly]
159+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
153160
internal static unsafe uint IReferenceTrackerTarget_Peg(IntPtr pThis)
154161
{
155162
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
156163
return wrapper->Peg();
157164
}
158165

159-
[UnmanagedCallersOnly]
166+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
160167
internal static unsafe uint IReferenceTrackerTarget_Unpeg(IntPtr pThis)
161168
{
162169
ManagedObjectWrapper* wrapper = ComInterfaceDispatch.ToManagedObjectWrapper((ComInterfaceDispatch*)pThis);
163170
return wrapper->Unpeg();
164171
}
165172

166-
[UnmanagedCallersOnly]
173+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
167174
internal static unsafe int ITaggedImpl_IsCurrentVersion(IntPtr pThis, IntPtr version)
168175
{
169-
return version == (IntPtr)(delegate* unmanaged<IntPtr, IntPtr, int>)&ITaggedImpl_IsCurrentVersion
176+
return version == (IntPtr)(delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int>)&ITaggedImpl_IsCurrentVersion
170177
? HResults.S_OK
171178
: HResults.E_FAIL;
172179
}
@@ -179,21 +186,21 @@ static unsafe VtableImplementations()
179186
fpAddRef: out *(nint*)&((IUnknownVftbl*)Unsafe.AsPointer(ref IUnknown))->AddRef,
180187
fpRelease: out *(nint*)&((IUnknownVftbl*)Unsafe.AsPointer(ref IUnknown))->Release);
181188

182-
IReferenceTrackerTarget.QueryInterface = (delegate* unmanaged<IntPtr, Guid*, IntPtr*, int>)&IReferenceTrackerTarget_QueryInterface;
189+
IReferenceTrackerTarget.QueryInterface = (delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int>)&IReferenceTrackerTarget_QueryInterface;
183190
GetIUnknownImpl(
184191
fpQueryInterface: out _,
185192
fpAddRef: out *(nint*)&((IReferenceTrackerTargetVftbl*)Unsafe.AsPointer(ref IReferenceTrackerTarget))->AddRef,
186193
fpRelease: out *(nint*)&((IReferenceTrackerTargetVftbl*)Unsafe.AsPointer(ref IReferenceTrackerTarget))->Release);
187-
IReferenceTrackerTarget.AddRefFromReferenceTracker = (delegate* unmanaged<IntPtr, uint>)&IReferenceTrackerTarget_AddRefFromReferenceTracker;
188-
IReferenceTrackerTarget.ReleaseFromReferenceTracker = (delegate* unmanaged<IntPtr, uint>)&IReferenceTrackerTarget_ReleaseFromReferenceTracker;
189-
IReferenceTrackerTarget.Peg = (delegate* unmanaged<IntPtr, uint>)&IReferenceTrackerTarget_Peg;
190-
IReferenceTrackerTarget.Unpeg = (delegate* unmanaged<IntPtr, uint>)&IReferenceTrackerTarget_Unpeg;
194+
IReferenceTrackerTarget.AddRefFromReferenceTracker = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)&IReferenceTrackerTarget_AddRefFromReferenceTracker;
195+
IReferenceTrackerTarget.ReleaseFromReferenceTracker = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)&IReferenceTrackerTarget_ReleaseFromReferenceTracker;
196+
IReferenceTrackerTarget.Peg = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)&IReferenceTrackerTarget_Peg;
197+
IReferenceTrackerTarget.Unpeg = (delegate* unmanaged[MemberFunction]<IntPtr, uint>)&IReferenceTrackerTarget_Unpeg;
191198

192199
GetIUnknownImpl(
193200
fpQueryInterface: out *(nint*)&((ITaggedImplVftbl*)Unsafe.AsPointer(ref ITaggedImpl))->QueryInterface,
194201
fpAddRef: out *(nint*)&((ITaggedImplVftbl*)Unsafe.AsPointer(ref ITaggedImpl))->AddRef,
195202
fpRelease: out *(nint*)&((ITaggedImplVftbl*)Unsafe.AsPointer(ref ITaggedImpl))->Release);
196-
ITaggedImpl.IsCurrentVersion = (delegate* unmanaged<IntPtr, IntPtr, int>)&ITaggedImpl_IsCurrentVersion;
203+
ITaggedImpl.IsCurrentVersion = (delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int>)&ITaggedImpl_IsCurrentVersion;
197204
}
198205
}
199206
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/TrackerObjectManager.NativeAot.cs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ internal static unsafe class FindReferenceTargetsCallback
204204
{
205205
internal static GCHandle s_currentRootObjectHandle;
206206

207-
[UnmanagedCallersOnly]
207+
#pragma warning disable CS3016
208+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
209+
#pragma warning restore CS3016
208210
private static unsafe int IFindReferenceTargetsCallback_QueryInterface(IntPtr pThis, Guid* guid, IntPtr* ppObject)
209211
{
210212
if (*guid == IID_IFindReferenceTargetsCallback || *guid == IID_IUnknown)
@@ -218,7 +220,9 @@ private static unsafe int IFindReferenceTargetsCallback_QueryInterface(IntPtr pT
218220
}
219221
}
220222

221-
[UnmanagedCallersOnly]
223+
#pragma warning disable CS3016
224+
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
225+
#pragma warning restore CS3016
222226
private static unsafe int IFindReferenceTargetsCallback_FoundTrackerTarget(IntPtr pThis, IntPtr referenceTrackerTarget)
223227
{
224228
if (referenceTrackerTarget == IntPtr.Zero)
@@ -235,22 +239,12 @@ private static unsafe int IFindReferenceTargetsCallback_FoundTrackerTarget(IntPt
235239
return HResults.S_OK;
236240
}
237241

238-
private static unsafe IntPtr CreateDefaultIFindReferenceTargetsCallbackVftbl()
239-
{
240-
IntPtr* vftbl = (IntPtr*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(FindReferenceTargetsCallback), 4 * sizeof(IntPtr));
241-
vftbl[0] = (IntPtr)(delegate* unmanaged<IntPtr, Guid*, IntPtr*, int>)&IFindReferenceTargetsCallback_QueryInterface;
242-
vftbl[1] = (IntPtr)(delegate* unmanaged<IntPtr, uint>)&ComWrappers.Untracked_AddRef;
243-
vftbl[2] = (IntPtr)(delegate* unmanaged<IntPtr, uint>)&ComWrappers.Untracked_Release;
244-
vftbl[3] = (IntPtr)(delegate* unmanaged<IntPtr, IntPtr, int>)&IFindReferenceTargetsCallback_FoundTrackerTarget;
245-
return (IntPtr)vftbl;
246-
}
247-
248242
internal struct ReferenceTargetsVftbl
249243
{
250-
public delegate* unmanaged<IntPtr, Guid*, IntPtr*, int> QueryInterface;
251-
public delegate* unmanaged<IntPtr, uint> AddRef;
252-
public delegate* unmanaged<IntPtr, uint> Release;
253-
public delegate* unmanaged<IntPtr, IntPtr, int> FoundTrackerTarget;
244+
public delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int> QueryInterface;
245+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> AddRef;
246+
public delegate* unmanaged[MemberFunction]<IntPtr, uint> Release;
247+
public delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int> FoundTrackerTarget;
254248
}
255249

256250
[FixedAddressValueType]
@@ -261,8 +255,7 @@ internal struct ReferenceTargetsVftbl
261255
static FindReferenceTargetsCallback()
262256
#pragma warning restore CA1810 // Initialize reference type static fields inline
263257
{
264-
Vftbl.AddRef = &Untracked_AddRef;
265-
Vftbl.Release = &Untracked_Release;
258+
ComWrappers.GetUntrackedIUnknownImpl(out Vftbl.AddRef, out Vftbl.Release);
266259
Vftbl.QueryInterface = &IFindReferenceTargetsCallback_QueryInterface;
267260
Vftbl.FoundTrackerTarget = &IFindReferenceTargetsCallback_FoundTrackerTarget;
268261
}

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,16 @@ internal enum GcRestrictedCalloutKind
510510
)]
511511
internal static extern uint RhIUnknown_AddRef(nint pThis);
512512

513+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
514+
[RuntimeImport(RuntimeLibrary,
515+
#if TARGET_WINDOWS && TARGET_X86
516+
"_RhUntracked_AddRefRelease@4"
517+
#else
518+
"RhUntracked_AddRefRelease"
519+
#endif
520+
)]
521+
internal static extern uint RhUntracked_AddRefRelease(nint pThis);
522+
513523
#if FEATURE_OBJCMARSHAL
514524
[MethodImplAttribute(MethodImplOptions.InternalCall)]
515525
[RuntimeImport(RuntimeLibrary, "RhRegisterObjectiveCMarshalBeginEndCallback")]

src/coreclr/vm/interoplibinterface_comwrappers.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,4 +614,23 @@ extern "C" CLR_BOOL QCALLTYPE TrackerObjectManager_IsGlobalPeggingEnabled()
614614
return InteropLibImports::GetGlobalPeggingState();
615615
}
616616

617+
// Some of our "Untracked" COM objects may be owned by static globals
618+
// in client code. We need to ensure that we don't try executing a managed
619+
// method for the first time when the process is shutting down.
620+
// Therefore, we need to provide unmanaged implementations of AddRef and Release.
621+
namespace
622+
{
623+
int STDMETHODCALLTYPE Untracked_AddRefRelease(void*)
624+
{
625+
return 1;
626+
}
627+
}
628+
629+
extern "C" void* QCALLTYPE ComWrappers_GetUntrackedAddRefRelease()
630+
{
631+
QCALL_CONTRACT_NO_GC_TRANSITION;
632+
633+
return (void*)Untracked_AddRefRelease;
634+
}
635+
617636
#endif // FEATURE_COMWRAPPERS

src/coreclr/vm/interoplibinterface_comwrappers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ extern "C" void QCALLTYPE ComWrappers_GetIUnknownImpl(
3131
_Out_ void** fpAddRef,
3232
_Out_ void** fpRelease);
3333

34+
extern "C" void* QCALLTYPE ComWrappers_GetUntrackedAddRefRelease();
35+
3436
extern "C" void* QCALLTYPE ComWrappers_AllocateRefCountedHandle(_In_ QCall::ObjectHandleOnStack obj);
3537

3638
extern "C" void const* QCALLTYPE ComWrappers_GetIReferenceTrackerTargetVftbl();

src/coreclr/vm/qcallentrypoints.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ static const Entry s_QCall[] =
424424
DllImportEntry(ReflectionSerialization_GetCreateUninitializedObjectInfo)
425425
#if defined(FEATURE_COMWRAPPERS)
426426
DllImportEntry(ComWrappers_GetIUnknownImpl)
427+
DllImportEntry(ComWrappers_GetUntrackedAddRefRelease)
427428
DllImportEntry(ComWrappers_AllocateRefCountedHandle)
428429
DllImportEntry(ComWrappers_GetIReferenceTrackerTargetVftbl)
429430
DllImportEntry(ComWrappers_GetTaggedImpl)

src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ public object GetOrRegisterObjectForComInstance(IntPtr externalComObject, Create
965965
}
966966

967967
IntPtr currentVersion = GetTaggedImplCurrentVersion();
968-
int hr = ((delegate* unmanaged<IntPtr, IntPtr, int>)(*(*(void***)implMaybe + 3 /* ITaggedImpl.IsCurrentVersion slot */)))(implMaybe, currentVersion);
968+
int hr = ((delegate* unmanaged[MemberFunction]<IntPtr, IntPtr, int>)(*(*(void***)implMaybe + 3 /* ITaggedImpl.IsCurrentVersion slot */)))(implMaybe, currentVersion);
969969
Marshal.Release(implMaybe);
970970
if (hr != 0)
971971
{
@@ -1445,26 +1445,13 @@ internal static IntPtr GetOrCreateTrackerTarget(IntPtr externalComObject)
14451445
return s_globalInstanceForTrackerSupport.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport);
14461446
}
14471447

1448-
// Lifetime maintained by stack - we don't care about ref counts
1449-
[UnmanagedCallersOnly]
1450-
internal static unsafe uint Untracked_AddRef(IntPtr _)
1451-
{
1452-
return 1;
1453-
}
1454-
1455-
[UnmanagedCallersOnly]
1456-
internal static unsafe uint Untracked_Release(IntPtr _)
1457-
{
1458-
return 1;
1459-
}
1460-
14611448
// Wrapper for IWeakReference
14621449
private static unsafe class IWeakReference
14631450
{
14641451
public static int Resolve(IntPtr pThis, Guid guid, out IntPtr inspectable)
14651452
{
14661453
fixed (IntPtr* inspectablePtr = &inspectable)
1467-
return (*(delegate* unmanaged<IntPtr, Guid*, IntPtr*, int>**)pThis)[3](pThis, &guid, inspectablePtr);
1454+
return (*(delegate* unmanaged[MemberFunction]<IntPtr, Guid*, IntPtr*, int>**)pThis)[3](pThis, &guid, inspectablePtr);
14681455
}
14691456
}
14701457

@@ -1474,7 +1461,7 @@ private static unsafe class IWeakReferenceSource
14741461
public static int GetWeakReference(IntPtr pThis, out IntPtr weakReference)
14751462
{
14761463
fixed (IntPtr* weakReferencePtr = &weakReference)
1477-
return (*(delegate* unmanaged<IntPtr, IntPtr*, int>**)pThis)[3](pThis, weakReferencePtr);
1464+
return (*(delegate* unmanaged[MemberFunction]<IntPtr, IntPtr*, int>**)pThis)[3](pThis, weakReferencePtr);
14781465
}
14791466
}
14801467

0 commit comments

Comments
 (0)