Skip to content

Commit 4772b5d

Browse files
ComWrappers test that allocate object can't inline (#85583)
* ComWrappers test that allocate object can't inline There are some JIT stress settings that aggressively inline functions, regardless of size/complexity. This inlining can perturb the subtle GC assumptions inherent in the COM wrappers tests.
1 parent dc796f7 commit 4772b5d

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

src/tests/Interop/COM/ComWrappers/API/Program.cs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static void ForceGC()
123123
}
124124
}
125125

126+
[MethodImpl(MethodImplOptions.NoInlining)]
126127
static void ValidateComInterfaceCreation()
127128
{
128129
Console.WriteLine($"Running {nameof(ValidateComInterfaceCreation)}...");
@@ -156,6 +157,7 @@ static void ValidateComInterfaceCreation()
156157
Assert.Equal(0, count);
157158
}
158159

160+
[MethodImpl(MethodImplOptions.NoInlining)]
159161
static void ValidateComInterfaceCreationRoundTrip()
160162
{
161163
Console.WriteLine($"Running {nameof(ValidateComInterfaceCreationRoundTrip)}...");
@@ -212,6 +214,7 @@ static IntPtr CreateObjectAndGetComInterface()
212214
// Just because one use of a COM interface returned from GetOrCreateComInterfaceForObject
213215
// hits zero ref count does not mean future calls to GetOrCreateComInterfaceForObject
214216
// should return an unusable object.
217+
[MethodImpl(MethodImplOptions.NoInlining)]
215218
static void ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree()
216219
{
217220
Console.WriteLine($"Running {nameof(ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree)}...");
@@ -247,6 +250,7 @@ unsafe static void CallSetValue(TestComWrappers wrappers, Test testInstance, int
247250
}
248251
}
249252

253+
[MethodImpl(MethodImplOptions.NoInlining)]
250254
static void ValidateFallbackQueryInterface()
251255
{
252256
Console.WriteLine($"Running {nameof(ValidateFallbackQueryInterface)}...");
@@ -300,36 +304,42 @@ static void ValidateCreateObjectCachingScenario()
300304
Assert.NotEqual(trackerObj1, trackerObj3);
301305
}
302306

303-
// Make sure that if one wrapper is GCed, another can be created.
304-
static void ValidateCreateObjectGcBehavior()
307+
// Verify that if a GC nulls the contents of a weak GCHandle but has not yet
308+
// run finializers to remove that GCHandle from the cache, the state of the system is valid.
309+
static void ValidateCreateObjectWeakHandleCacheCleanUp()
305310
{
306-
Console.WriteLine($"Running {nameof(ValidateCreateObjectCachingScenario)}...");
311+
Console.WriteLine($"Running {nameof(ValidateCreateObjectWeakHandleCacheCleanUp)}...");
307312

308313
var cw = new TestComWrappers();
309314

310315
// Get an object from a tracker runtime.
311316
IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject();
312317

313318
// Create the first native object wrapper and run the GC.
314-
CreateObject();
319+
CreateObject(cw, trackerObjRaw);
320+
321+
// Only attempt to run the GC, don't wait for the finalizer. We do this
322+
// because of the multiple phase clean-up for ComWrappers caches.
323+
// See weak GC handles in the NativeAOT scenario.
315324
GC.Collect();
316325

317326
// Try to create another wrapper for the same object. The above GC
318-
// may have collected parts of the ComWrapper cache, but this should
319-
// still work.
320-
CreateObject();
327+
// may have collected parts of the ComWrapper cache, but not fully
328+
// cleared the contents of the cache.
329+
CreateObject(cw, trackerObjRaw);
321330
ForceGC();
322331

323332
Marshal.Release(trackerObjRaw);
324333

325334
[MethodImpl(MethodImplOptions.NoInlining)]
326-
void CreateObject()
335+
static void CreateObject(ComWrappers cw, IntPtr trackerObj)
327336
{
328-
var obj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.None);
337+
var obj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObj, CreateObjectFlags.None);
329338
Assert.NotNull(obj);
330339
}
331340
}
332341

342+
[MethodImpl(MethodImplOptions.NoInlining)]
333343
static void ValidateMappingAPIs()
334344
{
335345
Console.WriteLine($"Running {nameof(ValidateMappingAPIs)}...");
@@ -383,6 +393,7 @@ static void ValidateMappingAPIs()
383393
Marshal.Release(unmanagedObjIUnknown);
384394
}
385395

396+
[MethodImpl(MethodImplOptions.NoInlining)]
386397
static void ValidateWrappersInstanceIsolation()
387398
{
388399
Console.WriteLine($"Running {nameof(ValidateWrappersInstanceIsolation)}...");
@@ -808,7 +819,7 @@ static int Main()
808819
ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree();
809820
ValidateFallbackQueryInterface();
810821
ValidateCreateObjectCachingScenario();
811-
ValidateCreateObjectGcBehavior();
822+
ValidateCreateObjectWeakHandleCacheCleanUp();
812823
ValidateMappingAPIs();
813824
ValidateWrappersInstanceIsolation();
814825
ValidatePrecreatedExternalWrapper();

0 commit comments

Comments
 (0)