Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComWrappers test that allocate object can't inline #85583

Merged
merged 2 commits into from
May 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/tests/Interop/COM/ComWrappers/API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static void ForceGC()
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateComInterfaceCreation()
{
Console.WriteLine($"Running {nameof(ValidateComInterfaceCreation)}...");
Expand Down Expand Up @@ -156,6 +157,7 @@ static void ValidateComInterfaceCreation()
Assert.Equal(0, count);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateComInterfaceCreationRoundTrip()
{
Console.WriteLine($"Running {nameof(ValidateComInterfaceCreationRoundTrip)}...");
Expand Down Expand Up @@ -212,6 +214,7 @@ static IntPtr CreateObjectAndGetComInterface()
// Just because one use of a COM interface returned from GetOrCreateComInterfaceForObject
// hits zero ref count does not mean future calls to GetOrCreateComInterfaceForObject
// should return an unusable object.
[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree()
{
Console.WriteLine($"Running {nameof(ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree)}...");
Expand Down Expand Up @@ -247,6 +250,7 @@ unsafe static void CallSetValue(TestComWrappers wrappers, Test testInstance, int
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateFallbackQueryInterface()
{
Console.WriteLine($"Running {nameof(ValidateFallbackQueryInterface)}...");
Expand Down Expand Up @@ -300,36 +304,42 @@ static void ValidateCreateObjectCachingScenario()
Assert.NotEqual(trackerObj1, trackerObj3);
}

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

var cw = new TestComWrappers();

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

// Create the first native object wrapper and run the GC.
CreateObject();
CreateObject(cw, trackerObjRaw);

// Only attempt to run the GC, don't wait for the finalizer. We do this
// because of the multiple phase clean-up for ComWrappers caches.
// See weak GC handles in the NativeAOT scenario.
GC.Collect();
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved

// Try to create another wrapper for the same object. The above GC
// may have collected parts of the ComWrapper cache, but this should
// still work.
CreateObject();
// may have collected parts of the ComWrapper cache, but not fully
// cleared the contents of the cache.
CreateObject(cw, trackerObjRaw);
ForceGC();

Marshal.Release(trackerObjRaw);

[MethodImpl(MethodImplOptions.NoInlining)]
void CreateObject()
static void CreateObject(ComWrappers cw, IntPtr trackerObj)
{
var obj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.None);
var obj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObj, CreateObjectFlags.None);
Assert.NotNull(obj);
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateMappingAPIs()
{
Console.WriteLine($"Running {nameof(ValidateMappingAPIs)}...");
Expand Down Expand Up @@ -383,6 +393,7 @@ static void ValidateMappingAPIs()
Marshal.Release(unmanagedObjIUnknown);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void ValidateWrappersInstanceIsolation()
{
Console.WriteLine($"Running {nameof(ValidateWrappersInstanceIsolation)}...");
Expand Down Expand Up @@ -808,7 +819,7 @@ static int Main()
ValidateCreatingAComInterfaceForObjectAfterTheFirstIsFree();
ValidateFallbackQueryInterface();
ValidateCreateObjectCachingScenario();
ValidateCreateObjectGcBehavior();
ValidateCreateObjectWeakHandleCacheCleanUp();
ValidateMappingAPIs();
ValidateWrappersInstanceIsolation();
ValidatePrecreatedExternalWrapper();
Expand Down