Skip to content

Commit c42fe29

Browse files
[main] Source code updates from dotnet/runtime (#504)
Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
1 parent 6f2c658 commit c42fe29

File tree

93 files changed

+5148
-7368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+5148
-7368
lines changed

prereqs/git-info/runtime.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project>
33
<PropertyGroup>
4-
<GitCommitHash>e67e997094b65c8ed7289b00f2304288d8f75a12</GitCommitHash>
5-
<OfficialBuildId>20250509.6</OfficialBuildId>
6-
<OutputPackageVersion>10.0.0-preview.5.25259.6</OutputPackageVersion>
4+
<GitCommitHash>8b80947425177e7b500e13ec66d1b9936a67e5a5</GitCommitHash>
5+
<OfficialBuildId>20250511.2</OfficialBuildId>
6+
<OutputPackageVersion>10.0.0-preview.5.25261.2</OutputPackageVersion>
77
</PropertyGroup>
88
</Project>

src/runtime/docs/design/coreclr/botr/clr-abi.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,15 +376,17 @@ When an exception occurs, the VM is invoked to do some processing. If the except
376376

377377
The VM sets the frame register to be the same as the parent function. This allows the funclets to access local variables using frame-relative addresses.
378378

379-
For filter funclets and on CoreCLR/AMD64 for all funclets, all other register values that existed at the exception point in the corresponding "try" region are trashed on entry to the funclet. That is, the only registers that have known values are those of the funclet parameters and the frame register.
379+
For filter funclets, all other register values that existed at the exception point in the corresponding "try" region are trashed on entry to the funclet. That is, the only registers that have known values are those of the funclet parameters and the frame register.
380380

381-
For other funclets on all platforms except CoreCLR/AMD64, all non-volatile registers are restored to their values at the exception point. The JIT codegen [does not take advantage of it currently](https://github.com/dotnet/runtime/pull/114630#issuecomment-2810210759).
381+
For other funclets, all non-volatile registers are restored to their values at the exception point. The JIT codegen [does not take advantage of it currently](https://github.com/dotnet/runtime/pull/114630#issuecomment-2810210759).
382382

383383
### Registers on return from a funclet
384384

385385
When a funclet finishes execution, and the VM returns execution to the function (or an enclosing funclet, if there is EH clause nesting), the non-volatile registers are restored to the values they held at the exception point. Note that the volatile registers have been trashed.
386386

387-
Any register value changes made in the funclet are lost. If a funclet wants to make a variable change known to the main function (or the funclet that contains the "try" region), that variable change needs to be made to the shared main function stack frame.
387+
Any register value changes made in the funclet are lost. If a funclet wants to make a variable change known to the main function (or the funclet that contains the "try" region), that variable change needs to be made to the shared main function stack frame. This not a fundamental limitation. If necessary, the runtime can be updated to preserve non-volatile register changes made in funclets.
388+
389+
Funclets are not required to preserve non-volatile registers.
388390

389391
## Windows/x86 EH considerations
390392

src/runtime/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@
254254
<Compile Include="src\System\RuntimeType.GenericCache.cs" />
255255
</ItemGroup>
256256
<ItemGroup Condition="'$(FeatureComWrappers)' == 'true'">
257-
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComWrappers.cs" />
257+
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComWrappers.CoreCLR.cs" />
258+
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\TrackerObjectManager.CoreCLR.cs" />
258259
</ItemGroup>
259260
<ItemGroup Condition="'$(FeatureCominterop)' == 'true'">
260261
<Compile Include="$(CommonPath)System\Runtime\InteropServices\IDispatch.cs">

src/runtime/src/coreclr/System.Private.CoreLib/src/System/ComAwareWeakReference.CoreCLR.cs

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,56 @@ namespace System
1010
internal sealed partial class ComAwareWeakReference
1111
{
1212
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWeakRefToObject")]
13-
private static partial void ComWeakRefToObject(IntPtr pComWeakRef, long wrapperId, ObjectHandleOnStack retRcw);
13+
private static partial void ComWeakRefToObject(IntPtr pComWeakRef, ObjectHandleOnStack retRcw);
1414

15-
internal static object? ComWeakRefToObject(IntPtr pComWeakRef, long wrapperId)
15+
internal static object? ComWeakRefToObject(IntPtr pComWeakRef, object? context)
1616
{
17-
object? retRcw = null;
18-
ComWeakRefToObject(pComWeakRef, wrapperId, ObjectHandleOnStack.Create(ref retRcw));
19-
return retRcw;
17+
#if FEATURE_COMINTEROP
18+
if (context is null)
19+
{
20+
// This wrapper was not created by ComWrappers, so we try to rehydrate using built-in COM.
21+
object? retRcw = null;
22+
ComWeakRefToObject(pComWeakRef, ObjectHandleOnStack.Create(ref retRcw));
23+
return retRcw;
24+
}
25+
#endif // FEATURE_COMINTEROP
26+
27+
return ComWeakRefToComWrappersObject(pComWeakRef, context);
2028
}
2129

2230
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2331
internal static unsafe bool PossiblyComObject(object target)
2432
{
25-
// see: syncblk.h
26-
const int IS_HASHCODE_BIT_NUMBER = 26;
27-
const int BIT_SBLK_IS_HASHCODE = 1 << IS_HASHCODE_BIT_NUMBER;
28-
const int BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX = 0x08000000;
29-
30-
fixed (byte* pRawData = &target.GetRawData())
31-
{
32-
// The header is 4 bytes before MT field on all architectures
33-
int header = *(int*)(pRawData - sizeof(IntPtr) - sizeof(int));
34-
// common case: target does not have a syncblock, so there is no interop info
35-
return (header & (BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_IS_HASHCODE)) == BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX;
36-
}
33+
#if FEATURE_COMINTEROP
34+
return target is __ComObject || PossiblyComWrappersObject(target);
35+
#else // !FEATURE_COMINTEROP
36+
// If we are not using built-in COM, then we can only be a ComWrappers object.
37+
return PossiblyComWrappersObject(target);
38+
#endif // FEATURE_COMINTEROP
3739
}
3840

39-
[MethodImpl(MethodImplOptions.InternalCall)]
40-
internal static extern bool HasInteropInfo(object target);
41-
4241
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ObjectToComWeakRef")]
43-
private static partial IntPtr ObjectToComWeakRef(ObjectHandleOnStack retRcw, out long wrapperId);
42+
private static partial IntPtr ObjectToComWeakRef(ObjectHandleOnStack retRcw);
4443

45-
internal static nint ObjectToComWeakRef(object target, out long wrapperId)
44+
internal static nint ObjectToComWeakRef(object target, out object? context)
4645
{
47-
if (HasInteropInfo(target))
46+
#if FEATURE_COMINTEROP
47+
if (target is __ComObject)
48+
{
49+
// This object is using built-in COM, so use built-in COM to create the weak reference.
50+
context = null;
51+
return ObjectToComWeakRef(ObjectHandleOnStack.Create(ref target));
52+
}
53+
#endif // FEATURE_COMINTEROP
54+
55+
if (PossiblyComWrappersObject(target))
4856
{
49-
return ObjectToComWeakRef(ObjectHandleOnStack.Create(ref target), out wrapperId);
57+
return ComWrappersObjectToComWeakRef(target, out context);
5058
}
5159

52-
wrapperId = 0;
60+
// This object is not produced using built-in COM or ComWrappers
61+
// or is an aggregated object, so we cannot create a weak reference.
62+
context = null;
5363
return IntPtr.Zero;
5464
}
5565
}

src/runtime/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,6 @@ static void NotifyOfCrossThreadDependencySlow()
6565
[SuppressGCTransition]
6666
private static partial int IsManagedDebuggerAttached();
6767

68-
// Constants representing the importance level of messages to be logged.
69-
//
70-
// An attached debugger can enable or disable which messages will
71-
// actually be reported to the user through the debugger
72-
// services API. This info is communicated to the runtime so only
73-
// desired events are actually reported to the debugger.
74-
//
75-
// Constant representing the default category
76-
public static readonly string? DefaultCategory;
77-
7868
// Posts a message for the attached debugger. If there is no
7969
// debugger attached, has no effect. The debugger may or may not
8070
// report the message depending on its settings.

src/runtime/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ internal enum GC_ALLOC_FLAGS
106106
private static partial long GetTotalMemory();
107107

108108
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "GCInterface_Collect")]
109-
private static partial void _Collect(int generation, int mode);
109+
private static partial void _Collect(int generation, int mode, [MarshalAs(UnmanagedType.U1)] bool lowMemoryPressure);
110110

111111
[MethodImpl(MethodImplOptions.InternalCall)]
112112
private static extern int GetMaxGeneration();
@@ -174,7 +174,7 @@ public static void Collect(int generation)
174174
public static void Collect()
175175
{
176176
// -1 says to GC all generations.
177-
_Collect(-1, (int)InternalGCCollectionMode.Blocking);
177+
_Collect(-1, (int)InternalGCCollectionMode.Blocking, lowMemoryPressure: false);
178178
}
179179

180180
public static void Collect(int generation, GCCollectionMode mode)
@@ -189,6 +189,11 @@ public static void Collect(int generation, GCCollectionMode mode, bool blocking)
189189
}
190190

191191
public static void Collect(int generation, GCCollectionMode mode, bool blocking, bool compacting)
192+
{
193+
Collect(generation, mode, blocking, compacting, lowMemoryPressure: false);
194+
}
195+
196+
internal static void Collect(int generation, GCCollectionMode mode, bool blocking, bool compacting, bool lowMemoryPressure)
192197
{
193198
ArgumentOutOfRangeException.ThrowIfNegative(generation);
194199

@@ -197,7 +202,6 @@ public static void Collect(int generation, GCCollectionMode mode, bool blocking,
197202
throw new ArgumentOutOfRangeException(nameof(mode), SR.ArgumentOutOfRange_Enum);
198203
}
199204

200-
201205
int iInternalModes = 0;
202206

203207
if (mode == GCCollectionMode.Optimized)
@@ -222,7 +226,9 @@ public static void Collect(int generation, GCCollectionMode mode, bool blocking,
222226
}
223227

224228
if (compacting)
229+
{
225230
iInternalModes |= (int)InternalGCCollectionMode.Compacting;
231+
}
226232

227233
if (blocking)
228234
{
@@ -233,7 +239,7 @@ public static void Collect(int generation, GCCollectionMode mode, bool blocking,
233239
iInternalModes |= (int)InternalGCCollectionMode.NonBlocking;
234240
}
235241

236-
_Collect(generation, iInternalModes);
242+
_Collect(generation, (int)iInternalModes, lowMemoryPressure);
237243
}
238244

239245
public static int CollectionCount(int generation)
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Threading;
5+
using System.Runtime.CompilerServices;
6+
using System.Collections.Generic;
7+
using System.Collections.Concurrent;
8+
9+
namespace System.Runtime.InteropServices
10+
{
11+
/// <summary>
12+
/// Class for managing wrappers of COM IUnknown types.
13+
/// </summary>
14+
public abstract partial class ComWrappers
15+
{
16+
/// <summary>
17+
/// Get the runtime provided IUnknown implementation.
18+
/// </summary>
19+
/// <param name="fpQueryInterface">Function pointer to QueryInterface.</param>
20+
/// <param name="fpAddRef">Function pointer to AddRef.</param>
21+
/// <param name="fpRelease">Function pointer to Release.</param>
22+
public static unsafe void GetIUnknownImpl(out IntPtr fpQueryInterface, out IntPtr fpAddRef, out IntPtr fpRelease)
23+
=> GetIUnknownImplInternal(out fpQueryInterface, out fpAddRef, out fpRelease);
24+
25+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_GetIUnknownImpl")]
26+
[SuppressGCTransition]
27+
private static partial void GetIUnknownImplInternal(out IntPtr fpQueryInterface, out IntPtr fpAddRef, out IntPtr fpRelease);
28+
29+
internal static IntPtr DefaultIUnknownVftblPtr { get; } = CreateDefaultIUnknownVftbl();
30+
internal static IntPtr TaggedImplVftblPtr { get; } = CreateTaggedImplVftbl();
31+
internal static IntPtr DefaultIReferenceTrackerTargetVftblPtr { get; } = CreateDefaultIReferenceTrackerTargetVftbl();
32+
33+
private static unsafe IntPtr CreateDefaultIUnknownVftbl()
34+
{
35+
IntPtr* vftbl = (IntPtr*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappers), 3 * sizeof(IntPtr));
36+
GetIUnknownImpl(out vftbl[0], out vftbl[1], out vftbl[2]);
37+
return (IntPtr)vftbl;
38+
}
39+
40+
private static unsafe IntPtr CreateTaggedImplVftbl()
41+
{
42+
IntPtr* vftbl = (IntPtr*)RuntimeHelpers.AllocateTypeAssociatedMemory(typeof(ComWrappers), 4 * sizeof(IntPtr));
43+
GetIUnknownImpl(out vftbl[0], out vftbl[1], out vftbl[2]);
44+
vftbl[3] = GetTaggedImplCurrentVersion();
45+
return (IntPtr)vftbl;
46+
}
47+
48+
internal static int CallICustomQueryInterface(ManagedObjectWrapperHolder holder, ref Guid iid, out IntPtr ppObject)
49+
{
50+
if (holder.WrappedObject is ICustomQueryInterface customQueryInterface)
51+
{
52+
return (int)customQueryInterface.GetInterface(ref iid, out ppObject);
53+
}
54+
55+
ppObject = IntPtr.Zero;
56+
return -1; // See TryInvokeICustomQueryInterfaceResult
57+
}
58+
59+
internal static IntPtr GetOrCreateComInterfaceForObjectWithGlobalMarshallingInstance(object obj)
60+
{
61+
try
62+
{
63+
return s_globalInstanceForMarshalling is null
64+
? IntPtr.Zero
65+
: s_globalInstanceForMarshalling.GetOrCreateComInterfaceForObject(obj, CreateComInterfaceFlags.TrackerSupport);
66+
}
67+
catch (ArgumentException)
68+
{
69+
// We've failed to create a COM interface for the object.
70+
// Fallback to built-in COM.
71+
return IntPtr.Zero;
72+
}
73+
}
74+
75+
internal static object? GetOrCreateObjectForComInstanceWithGlobalMarshallingInstance(IntPtr comObject, CreateObjectFlags flags)
76+
{
77+
try
78+
{
79+
return s_globalInstanceForMarshalling?.GetOrCreateObjectForComInstance(comObject, flags);
80+
}
81+
catch (ArgumentNullException)
82+
{
83+
// We've failed to create a managed object for the COM instance.
84+
// Fallback to built-in COM.
85+
return null;
86+
}
87+
}
88+
89+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_GetIReferenceTrackerTargetVftbl")]
90+
[SuppressGCTransition]
91+
private static partial IntPtr GetDefaultIReferenceTrackerTargetVftbl();
92+
93+
private static IntPtr CreateDefaultIReferenceTrackerTargetVftbl()
94+
=> GetDefaultIReferenceTrackerTargetVftbl();
95+
96+
private static IntPtr GetTaggedImplCurrentVersion()
97+
{
98+
return GetTaggedImpl();
99+
}
100+
101+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_GetTaggedImpl")]
102+
[SuppressGCTransition]
103+
private static partial IntPtr GetTaggedImpl();
104+
105+
internal sealed partial class ManagedObjectWrapperHolder
106+
{
107+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_RegisterIsRootedCallback")]
108+
private static partial void RegisterIsRootedCallback();
109+
110+
private static IntPtr AllocateRefCountedHandle(ManagedObjectWrapperHolder holder)
111+
{
112+
return AllocateRefCountedHandle(ObjectHandleOnStack.Create(ref holder));
113+
}
114+
115+
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ComWrappers_AllocateRefCountedHandle")]
116+
private static partial IntPtr AllocateRefCountedHandle(ObjectHandleOnStack obj);
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)