Skip to content

Commit e099ef5

Browse files
authored
[r2r] Enable generic cycles detection by default (#128957)
1 parent 2f1131b commit e099ef5

14 files changed

Lines changed: 52 additions & 26 deletions

File tree

src/coreclr/tools/Common/Compiler/DependencyAnalysis/GVMDependenciesNode.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,12 @@ public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependenci
170170
}
171171
else
172172
{
173-
dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(canonImpl), null, "ImplementingMethodInstantiation"));
173+
#if READYTORUN
174+
if (!factory.CanBeInGenericCycle(canonImpl))
175+
#endif
176+
{
177+
dynamicDependencies.Add(new CombinedDependencyListEntry(factory.GVMDependencies(canonImpl), null, "ImplementingMethodInstantiation"));
178+
}
174179
}
175180

176181
#if !READYTORUN
@@ -265,15 +270,7 @@ private static DependencyNodeCore<NodeFactory> GetVirtualMethodImplNode(NodeFact
265270
if (!factory.CompilationModuleGroup.ContainsMethodBody(method, false))
266271
return null;
267272

268-
try
269-
{
270-
factory.DetectGenericCycles(method, method);
271-
return factory.CompiledMethodNode(method);
272-
}
273-
catch (TypeSystemException)
274-
{
275-
return null;
276-
}
273+
return factory.CompiledMethodNode(method);
277274
#endif
278275
}
279276
}

src/coreclr/tools/Common/Compiler/GenericCycleDetection/ModuleCycleInfo.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,15 @@ private bool FormsCycle(TypeSystemEntity entity, out ModuleCycleInfo cycleInfo)
230230
}
231231
}
232232

233+
/// <summary>
234+
/// Returns true if the given entity (method or type definition) could be part of a
235+
/// generic cycle.
236+
/// </summary>
237+
public bool CanBeInCycle(TypeSystemEntity entity)
238+
{
239+
return FormsCycle(entity, out _);
240+
}
241+
233242
public void DetectCycle(TypeSystemEntity owner, TypeSystemEntity referent)
234243
{
235244
// This allows to disable cycle detection completely (typically for perf reasons as the algorithm is pretty slow)

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ protected override DependencyList ComputeNonRelocationBasedDependencies(NodeFact
8585
{
8686
// Because methods with generic parameters are already compiled in their canonical form, we are only interested in finding
8787
// instantiations of virtual methods that have at least one non-canonical argument (aka a valuetype).
88-
if (HasNonCanonicalInstantiationArguments(canonMethod))
88+
if (HasNonCanonicalInstantiationArguments(canonMethod) && !factory.CanBeInGenericCycle(Method))
8989
{
9090
list = list ?? new DependencyList();
9191
list.Add(factory.GVMDependencies(Method), "Virtual dispatch dependency");

src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,15 @@ public void DetectGenericCycles(TypeSystemEntity caller, TypeSystemEntity callee
12771277
_genericCycleDetector?.DetectCycle(caller, callee);
12781278
}
12791279

1280+
public bool CanBeInGenericCycle(MethodDesc method)
1281+
{
1282+
if (_genericCycleDetector is null)
1283+
return false;
1284+
1285+
MethodDesc methodDefinition = method.GetTypicalMethodDefinition();
1286+
return _genericCycleDetector.CanBeInCycle(methodDefinition);
1287+
}
1288+
12801289
public Utf8String GetSymbolAlternateName(ISymbolNode node, out bool isHidden)
12811290
{
12821291
isHidden = false;

src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ internal class Crossgen2RootCommand : RootCommand
8888
new("--imagebase") { Description = SR.ImageBase };
8989
public Option<string> TargetArchitecture { get; } =
9090
new("--targetarch") { Description = SR.TargetArchOption };
91-
public Option<bool> EnableGenericCycleDetection { get; } =
92-
new("--enable-generic-cycle-detection") { Description = SR.EnableGenericCycleDetection };
9391
public Option<int> GenericCycleDepthCutoff { get; } =
9492
new("--maxgenericcycle") { DefaultValueFactory = _ => ReadyToRunCompilerContext.DefaultGenericCycleDepthCutoff, Description = SR.GenericCycleDepthCutoff };
9593
public Option<int> GenericCycleBreadthCutoff { get; } =
@@ -197,7 +195,6 @@ public Crossgen2RootCommand(string[] args) : base(SR.Crossgen2BannerText)
197195
Options.Add(SupportIbc);
198196
Options.Add(Resilient);
199197
Options.Add(ImageBase);
200-
Options.Add(EnableGenericCycleDetection);
201198
Options.Add(GenericCycleDepthCutoff);
202199
Options.Add(GenericCycleBreadthCutoff);
203200
Options.Add(TargetArchitecture);

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,12 +679,9 @@ private void RunSingleCompilation(Dictionary<string, string> inFilePaths, Instru
679679
.UseCompilationRoots(compilationRoots)
680680
.UseOptimizationMode(optimizationMode);
681681

682-
if (Get(_command.EnableGenericCycleDetection))
683-
{
684-
builder.UseGenericCycleDetection(
685-
depthCutoff: Get(_command.GenericCycleDepthCutoff),
686-
breadthCutoff: Get(_command.GenericCycleBreadthCutoff));
687-
}
682+
builder.UseGenericCycleDetection(
683+
depthCutoff: Get(_command.GenericCycleDepthCutoff),
684+
breadthCutoff: Get(_command.GenericCycleBreadthCutoff));
688685

689686
builder.UsePrintReproInstructions(CreateReproArgumentString);
690687

src/coreclr/tools/aot/crossgen2/Properties/Resources.resx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,6 @@
423423
<data name="TypeValidation" xml:space="preserve">
424424
<value>Configure the runtime's behavior around validating the correctness of types defined in assemblies compiled via crossgen2</value>
425425
</data>
426-
<data name="EnableGenericCycleDetection" xml:space="preserve">
427-
<value>Perform generic cycle detection during compilation (incurs longer compilation time)</value>
428-
</data>
429426
<data name="GenericCycleBreadthCutoff" xml:space="preserve">
430427
<value>Total number of occurrences of potentially cyclic generic types within a generic type to cut off</value>
431428
</data>

src/tests/Loader/classloader/generics/Instantiation/Negative/param02.ilproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk.IL">
22
<PropertyGroup>
3+
<!-- Needed for CrossGenTest -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
35
<CLRTestPriority>1</CLRTestPriority>
6+
7+
<!-- Crossgen is not intended to serve as an IL verifier, and is not designed to provide error semantics on bad input. -->
8+
<CrossGenTest>false</CrossGenTest>
49
</PropertyGroup>
510
<ItemGroup>
611
<Compile Include="param02.il" />

src/tests/Loader/classloader/generics/Instantiation/Negative/param04.ilproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk.IL">
22
<PropertyGroup>
3+
<!-- Needed for CrossGenTest -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
35
<CLRTestPriority>1</CLRTestPriority>
6+
7+
<!-- Crossgen is not intended to serve as an IL verifier, and is not designed to provide error semantics on bad input. -->
8+
<CrossGenTest>false</CrossGenTest>
49
</PropertyGroup>
510
<ItemGroup>
611
<Compile Include="param04.il" />

src/tests/Loader/classloader/generics/Instantiation/Negative/param06.ilproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<Project Sdk="Microsoft.NET.Sdk.IL">
22
<PropertyGroup>
3+
<!-- Needed for CrossGenTest -->
4+
<RequiresProcessIsolation>true</RequiresProcessIsolation>
35
<CLRTestPriority>1</CLRTestPriority>
6+
7+
<!-- Crossgen is not intended to serve as an IL verifier, and is not designed to provide error semantics on bad input. -->
8+
<CrossGenTest>false</CrossGenTest>
49
</PropertyGroup>
510
<ItemGroup>
611
<Compile Include="param06.il" />

0 commit comments

Comments
 (0)