diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs index d8ae1363c73af2..22e8b674b57f95 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CachedInterfaceDispatch.cs @@ -113,6 +113,10 @@ private static IntPtr RhResolveDynamicInterfaceCastableDispatchOnType(MethodTabl return result; } + [Intrinsic] + [AnalysisCharacteristic] + private static extern bool DynamicInterfaceCastablePresent(); + private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, ref DispatchCellInfo cellInfo) { // Type of object we're dispatching on. @@ -125,7 +129,7 @@ private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void* cell, cellInfo.InterfaceSlot, flags: default, ppGenericContext: null); - if (pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable) + if (DynamicInterfaceCastablePresent() && pTargetCode == IntPtr.Zero && pInstanceType->IsIDynamicInterfaceCastable) { // Dispatch not resolved through normal dispatch map, try using the IDynamicInterfaceCastable // This will either give us the appropriate result, or throw. diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/ThrowHelpers.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/ThrowHelpers.cs index 3ee1884b129af7..e52c8a598ace00 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/ThrowHelpers.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/ThrowHelpers.cs @@ -57,10 +57,5 @@ private static void ThrowArgumentOutOfRangeException() // exception doesn't exist in MRT: throw PlatformNotSupportedException() instead throw new PlatformNotSupportedException(); } - - private static void ThrowFeatureBodyRemoved() - { - throw new NotSupportedException(); - } } } 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 6db8c5a1c5bf98..e9e3462effb868 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 @@ -240,6 +240,7 @@ + diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj index 0b82467b1a942e..9801d32020121b 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj +++ b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj @@ -212,6 +212,7 @@ Common\System\Runtime\InteropServices\IDynamicInterfaceCastable.cs + diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 20a0a0ebd5a3f7..a73ef4a1fbefc9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -28,6 +28,11 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact { DependencyList dependencyList = base.ComputeNonRelocationBasedDependencies(factory); + if (_type.IsIDynamicInterfaceCastable) + { + dependencyList.Add(factory.AnalysisCharacteristic("DynamicInterfaceCastablePresent"), "Implements IDynamicInterfaceCastable"); + } + // Ensure that we track the metadata type symbol if we are working with a constructed type symbol. // The emitter will ensure we don't emit both, but this allows us assert that we only generate // relocs to nodes we emit. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs index 18fdd2f65550eb..adca2e9baa475c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs @@ -150,7 +150,6 @@ ILScanResults IILScanner.Scan() _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceInterface), "Not tracked by scanner"); _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceClass), "Not tracked by scanner"); _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.IsInstanceOfException), "Not tracked by scanner"); - _dependencyGraph.AddRoot(_nodeFactory.MethodEntrypoint(_nodeFactory.TypeSystemContext.GetHelperEntryPoint("ThrowHelpers", "ThrowFeatureBodyRemoved")), "Substitution for methods removed based on scanning"); _dependencyGraph.ComputeMarkedNodes(); @@ -277,34 +276,6 @@ public ReadOnlyFieldPolicy GetReadOnlyFieldPolicy() return new ScannedReadOnlyPolicy(MarkedNodes); } - public BodyAndFieldSubstitutions GetBodyAndFieldSubstitutions() - { - Dictionary bodySubstitutions = []; - - bool hasIDynamicInterfaceCastableType = false; - - foreach (var type in ConstructedEETypes) - { - if (type.IsIDynamicInterfaceCastable) - { - hasIDynamicInterfaceCastableType = true; - break; - } - } - - if (!hasIDynamicInterfaceCastableType) - { - // We can't easily trim out some of the IDynamicInterfaceCastable infrastructure because - // the callers do type checks based on flags on the MethodTable instead of an actual type cast. - // Trim out the logic that we can't do easily here. - TypeDesc iDynamicInterfaceCastableType = _factory.TypeSystemContext.SystemModule.GetKnownType("System.Runtime.InteropServices", "IDynamicInterfaceCastable"); - MethodDesc getDynamicInterfaceImplementationMethod = iDynamicInterfaceCastableType.GetKnownMethod("GetDynamicInterfaceImplementation", null); - bodySubstitutions.Add(getDynamicInterfaceImplementationMethod, BodySubstitution.ThrowingBody); - } - - return new BodyAndFieldSubstitutions(bodySubstitutions, []); - } - public TypeMapManager GetTypeMapManager() { return new ScannedTypeMapManager(_factory); diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 04795875d6d071..73330f1384842e 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -530,10 +530,6 @@ void RunScanner() interopStubManager = scanResults.GetInteropStubManager(interopStateManager, pinvokePolicy); - substitutions.AppendFrom(scanResults.GetBodyAndFieldSubstitutions()); - - substitutionProvider = new SubstitutionProvider(logger, featureSwitches, substitutions); - ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager, metadataManager, scanResults.GetAnalysisCharacteristics()); // Use a more precise IL provider that uses whole program analysis for dead branch elimination