diff --git a/src/coreclr/nativeaot/Directory.Build.props b/src/coreclr/nativeaot/Directory.Build.props
index dce8e37c32fe38..ebfa725e4efd2c 100644
--- a/src/coreclr/nativeaot/Directory.Build.props
+++ b/src/coreclr/nativeaot/Directory.Build.props
@@ -56,6 +56,7 @@
true
+ FEATURE_COMWRAPPERS;$(DefineConstants)
false
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs
index 1ae7d4e7753de6..3c9d6c86ffc323 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs
@@ -60,14 +60,14 @@ internal static class InternalCalls
// Force a garbage collection.
[RuntimeExport("RhCollect")]
- internal static void RhCollect(int generation, InternalGCCollectionMode mode)
+ internal static void RhCollect(int generation, InternalGCCollectionMode mode, bool lowMemoryP = false)
{
- RhpCollect(generation, mode);
+ RhpCollect(generation, mode, lowMemoryP);
}
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
- private static extern void RhpCollect(int generation, InternalGCCollectionMode mode);
+ private static extern void RhpCollect(int generation, InternalGCCollectionMode mode, bool lowMemoryP);
[RuntimeExport("RhGetGcTotalMemory")]
internal static long RhGetGcTotalMemory()
diff --git a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp
index 681a63e8fb9ab1..8ba49e1f2dad7d 100644
--- a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp
+++ b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp
@@ -25,7 +25,7 @@
#include "threadstore.inl"
#include "thread.inl"
-EXTERN_C NATIVEAOT_API void __cdecl RhpCollect(uint32_t uGeneration, uint32_t uMode)
+EXTERN_C NATIVEAOT_API void __cdecl RhpCollect(uint32_t uGeneration, uint32_t uMode, UInt32_BOOL lowMemoryP)
{
// This must be called via p/invoke rather than RuntimeImport to make the stack crawlable.
@@ -35,7 +35,7 @@ EXTERN_C NATIVEAOT_API void __cdecl RhpCollect(uint32_t uGeneration, uint32_t uM
pCurThread->DisablePreemptiveMode();
ASSERT(!pCurThread->IsDoNotTriggerGcSet());
- GCHeapUtilities::GetGCHeap()->GarbageCollect(uGeneration, FALSE, uMode);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(uGeneration, lowMemoryP, uMode);
pCurThread->EnablePreemptiveMode();
}
@@ -128,6 +128,11 @@ COOP_PINVOKE_HELPER(int32_t, RhSetGcLatencyMode, (int32_t newLatencyMode))
return GCHeapUtilities::GetGCHeap()->SetGcLatencyMode(newLatencyMode);
}
+COOP_PINVOKE_HELPER(FC_BOOL_RET, RhIsPromoted, (OBJECTREF obj))
+{
+ FC_RETURN_BOOL(GCHeapUtilities::GetGCHeap()->IsPromoted(obj));
+}
+
COOP_PINVOKE_HELPER(FC_BOOL_RET, RhIsServerGc, ())
{
FC_RETURN_BOOL(GCHeapUtilities::IsServerHeap());
diff --git a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
index 5c5e20e3c7d195..3d0990962b7c99 100644
--- a/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
+++ b/src/coreclr/nativeaot/Runtime/gcrhenv.cpp
@@ -989,15 +989,19 @@ bool GCToEEInterface::EagerFinalized(Object* obj)
// Managed code should not be running.
ASSERT(GCHeapUtilities::GetGCHeap()->IsGCInProgressHelper());
- // the lowermost 1 bit is reserved for storing additional info about the handle
- const uintptr_t HandleTagBits = 1;
+ // the lowermost 2 bits are reserved for storing additional info about the handle
+ // we can use these bits because handle is at least 4 byte aligned
+ const uintptr_t HandleTagBits = 3;
WeakReference* weakRefObj = (WeakReference*)obj;
OBJECTHANDLE handle = (OBJECTHANDLE)(weakRefObj->m_taggedHandle & ~HandleTagBits);
- _ASSERTE((weakRefObj->m_taggedHandle & 2) == 0);
- HandleType handleType = (weakRefObj->m_taggedHandle & 1) ? HandleType::HNDTYPE_WEAK_LONG : HandleType::HNDTYPE_WEAK_SHORT;
+ HandleType handleType = (weakRefObj->m_taggedHandle & 2) ?
+ HandleType::HNDTYPE_STRONG :
+ (weakRefObj->m_taggedHandle & 1) ?
+ HandleType::HNDTYPE_WEAK_LONG :
+ HandleType::HNDTYPE_WEAK_SHORT;
// keep the bit that indicates whether this reference was tracking resurrection, clear the rest.
- weakRefObj->m_taggedHandle &= HandleTagBits;
+ weakRefObj->m_taggedHandle &= (uintptr_t)1;
GCHandleUtilities::GetGCHandleManager()->DestroyHandleOfType(handle, handleType);
return true;
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index 13cd0a531e3a2a..9652509dc831bd 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -210,6 +210,7 @@
+
@@ -273,6 +274,9 @@
Interop\Windows\Ole32\Interop.CoGetApartmentType.cs
+
+ Interop\Windows\Ole32\Interop.CoGetContextToken.cs
+
Interop\Windows\OleAut32\Interop.VariantClear.cs
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ComAwareWeakReference.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ComAwareWeakReference.NativeAot.cs
index 42916dad1ed5b1..d95eab971603a2 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ComAwareWeakReference.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ComAwareWeakReference.NativeAot.cs
@@ -2,32 +2,47 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Runtime.CompilerServices;
#if FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
-#pragma warning disable IDE0060
-
namespace System
{
internal sealed partial class ComAwareWeakReference
{
- internal static object? ComWeakRefToObject(IntPtr pComWeakRef, long wrapperId)
+ // We don't want to consult ComWrappers if no RCW objects have been created.
+ // In addition we don't want a direct reference to ComWrappers to allow for better
+ // trimming. So we instead make use of delegates that ComWrappers registers when
+ // it is used.
+ private static unsafe delegate* s_comWeakRefToObjectCallback;
+ private static unsafe delegate*