Skip to content

Commit 2da0155

Browse files
Reuse characteristic mechanism for IDynIntfCastable trimming (#118884)
Implements suggestion from #118769 (comment). We could probably replace `CanHaveDynamicInterfaceImplementations` with this too, but we'd need to make it so that characteristics are available in `Compilation` class. They are currently hidden in `SubstitutionILProvider`.
1 parent f416a19 commit 2da0155

File tree

7 files changed

+12
-39
lines changed

7 files changed

+12
-39
lines changed

src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ private static IntPtr RhResolveDynamicInterfaceCastableDispatchOnType(MethodTabl
113113
return result;
114114
}
115115

116+
[Intrinsic]
117+
[AnalysisCharacteristic]
118+
private static extern bool DynamicInterfaceCastablePresent();
119+
116120
private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo)
117121
{
118122
// Type of object we're dispatching on.
@@ -125,7 +129,7 @@ private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell,
125129
cellInfo.InterfaceSlot,
126130
flags: default,
127131
ppGenericContext: null);
128-
if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable)
132+
if (DynamicInterfaceCastablePresent() && pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable)
129133
{
130134
// Dispatch not resolved through normal dispatch map, try using the IDynamicInterfaceCastable
131135
// This will either give us the appropriate result, or throw.

src/coreclr/nativeaot/Runtime.Base/src/System/ThrowHelpers.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,5 @@ private static void ThrowArgumentOutOfRangeException()
5757
// exception doesn't exist in MRT: throw PlatformNotSupportedException() instead
5858
throw new PlatformNotSupportedException();
5959
}
60-
61-
private static void ThrowFeatureBodyRemoved()
62-
{
63-
throw new NotSupportedException();
64-
}
6560
}
6661
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@
240240
<Compile Include="System\ValueType.cs" />
241241
<Compile Include="System\Runtime\RuntimeExportAttribute.cs" />
242242
<Compile Include="System\Runtime\RuntimeImportAttribute.cs" />
243+
<Compile Include="System\Runtime\CompilerServices\AnalysisCharacteristicAttribute.cs" />
243244
<Compile Include="System\Runtime\CompilerServices\ClassConstructorRunner.cs" />
244245
<Compile Include="System\Runtime\CompilerServices\RuntimeHelpers.NativeAot.cs" />
245246
</ItemGroup>

src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
<Compile Include="$(LibrariesProjectRoot)\System.Private.CoreLib\src\System\Runtime\InteropServices\IDynamicInterfaceCastable.cs">
213213
<Link>Common\System\Runtime\InteropServices\IDynamicInterfaceCastable.cs</Link>
214214
</Compile>
215+
<Compile Include="..\..\System.Private.CoreLib\src\System\Runtime\CompilerServices\AnalysisCharacteristicAttribute.cs" />
215216
<Compile Include="Internal\Runtime\MethodTable.Runtime.cs" />
216217
<Compile Include="System\Runtime\CompilerServices\CastCache.cs" />
217218
<Compile Include="System\Runtime\CompilerServices\ClassConstructorRunner.cs" />

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
2828
{
2929
DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory);
3030

31+
if (_type.IsIDynamicInterfaceCastable)
32+
{
33+
dependencyList.Add(factory.AnalysisCharacteristic("DynamicInterfaceCastablePresent"), "Implements IDynamicInterfaceCastable");
34+
}
35+
3136
// Ensure that we track the metadata type symbol if we are working with a constructed type symbol.
3237
// The emitter will ensure we don't emit both, but this allows us assert that we only generate
3338
// relocs to nodes we emit.

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ ILScanResults IILScanner.Scan()
150150
_dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceInterface), "Not tracked by scanner");
151151
_dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceClass), "Not tracked by scanner");
152152
_dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.IsInstanceOfException), "Not tracked by scanner");
153-
_dependencyGraph.AddRoot(_nodeFactory.MethodEntrypoint(_nodeFactory.TypeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowFeatureBodyRemoved")), "Substitution for methods removed based on scanning");
154153

155154
_dependencyGraph.ComputeMarkedNodes();
156155

@@ -277,34 +276,6 @@ public ReadOnlyFieldPolicy GetReadOnlyFieldPolicy()
277276
return new ScannedReadOnlyPolicy(MarkedNodes);
278277
}
279278

280-
public BodyAndFieldSubstitutions GetBodyAndFieldSubstitutions()
281-
{
282-
Dictionary<MethodDesc, BodySubstitution> bodySubstitutions = [];
283-
284-
bool hasIDynamicInterfaceCastableType = false;
285-
286-
foreach (var type in ConstructedEETypes)
287-
{
288-
if (type.IsIDynamicInterfaceCastable)
289-
{
290-
hasIDynamicInterfaceCastableType = true;
291-
break;
292-
}
293-
}
294-
295-
if (!hasIDynamicInterfaceCastableType)
296-
{
297-
// We can't easily trim out some of the IDynamicInterfaceCastable infrastructure because
298-
// the callers do type checks based on flags on the MethodTable instead of an actual type cast.
299-
// Trim out the logic that we can't do easily here.
300-
TypeDesc iDynamicInterfaceCastableType = _factory.TypeSystemContext.SystemModule.GetKnownType("System.Runtime.InteropServices", "IDynamicInterfaceCastable");
301-
MethodDesc getDynamicInterfaceImplementationMethod = iDynamicInterfaceCastableType.GetKnownMethod("GetDynamicInterfaceImplementation", null);
302-
bodySubstitutions.Add(getDynamicInterfaceImplementationMethod, BodySubstitution.ThrowingBody);
303-
}
304-
305-
return new BodyAndFieldSubstitutions(bodySubstitutions, []);
306-
}
307-
308279
public TypeMapManager GetTypeMapManager()
309280
{
310281
return new ScannedTypeMapManager(_factory);

src/coreclr/tools/aot/ILCompiler/Program.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,10 +530,6 @@ void RunScanner()
530530

531531
interopStubManager = scanResults.GetInteropStubManager(interopStateManager, pinvokePolicy);
532532

533-
substitutions.AppendFrom(scanResults.GetBodyAndFieldSubstitutions());
534-
535-
substitutionProvider = new SubstitutionProvider(logger, featureSwitches, substitutions);
536-
537533
ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager, metadataManager, scanResults.GetAnalysisCharacteristics());
538534

539535
// Use a more precise IL provider that uses whole program analysis for dead branch elimination

0 commit comments

Comments
 (0)