Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Boemer <sbomer@gmail.com>2022-08-18 01:50:53 +0300
committerGitHub <noreply@github.com>2022-08-18 01:50:53 +0300
commitbc1f05f234bf70219687c255587e79439de9d6ee (patch)
treeb1b654b9cdb9836d73df1bd2effbef5d334c585e
parentc42e3cb42f354b13cd0414d0a4a1729146042583 (diff)
Don't track current field of state machines (#2979)
There was a performance problem where we were tracking all possible returned values throughout the method, since we were treating them the same as hoisted locals. I'm sure it's still possible to come up with testcases that show bad performance (for example assigning many arrays to a hoisted local in the same iterator), but this should at least fix the immediate issue encountered in runtime.
-rw-r--r--src/linker/Linker.Dataflow/CompilerGeneratedNames.cs13
-rw-r--r--src/linker/Linker.Dataflow/CompilerGeneratedState.cs14
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs4
-rw-r--r--test/Mono.Linker.Tests/TestCasesRunner/ILVerifier.cs14
-rw-r--r--test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs4
5 files changed, 34 insertions, 15 deletions
diff --git a/src/linker/Linker.Dataflow/CompilerGeneratedNames.cs b/src/linker/Linker.Dataflow/CompilerGeneratedNames.cs
index 46e6c9764..afdb716f5 100644
--- a/src/linker/Linker.Dataflow/CompilerGeneratedNames.cs
+++ b/src/linker/Linker.Dataflow/CompilerGeneratedNames.cs
@@ -34,6 +34,19 @@ namespace Mono.Linker.Dataflow
return typeName.Length > i + 1 && typeName[i + 1] == 'd';
}
+ internal static bool IsStateMachineCurrentField (string fieldName)
+ {
+ if (!IsGeneratedMemberName (fieldName))
+ return false;
+
+ int i = fieldName.LastIndexOf ('>');
+ if (i == -1)
+ return false;
+
+ // Current field is <>2__current
+ return fieldName.Length > i + 1 && fieldName[i + 1] == '2';
+ }
+
internal static bool IsGeneratedType (string name) => IsStateMachineType (name) || IsLambdaDisplayClass (name);
internal static bool IsLambdaOrLocalFunction (string methodName) => IsLambdaMethod (methodName) || IsLocalFunction (methodName);
diff --git a/src/linker/Linker.Dataflow/CompilerGeneratedState.cs b/src/linker/Linker.Dataflow/CompilerGeneratedState.cs
index 3213f49fd..3033cef70 100644
--- a/src/linker/Linker.Dataflow/CompilerGeneratedState.cs
+++ b/src/linker/Linker.Dataflow/CompilerGeneratedState.cs
@@ -55,10 +55,16 @@ namespace Mono.Linker.Dataflow
public static bool IsHoistedLocal (FieldDefinition field)
{
- // Treat all fields on compiler-generated types as hoisted locals.
- // This avoids depending on the name mangling scheme for hoisted locals.
- var declaringTypeName = field.DeclaringType.Name;
- return CompilerGeneratedNames.IsLambdaDisplayClass (declaringTypeName) || CompilerGeneratedNames.IsStateMachineType (declaringTypeName);
+ if (CompilerGeneratedNames.IsLambdaDisplayClass (field.DeclaringType.Name))
+ return true;
+
+ if (CompilerGeneratedNames.IsStateMachineType (field.DeclaringType.Name)) {
+ // Don't track the "current" field which is used for state machine return values,
+ // because this can be expensive to track.
+ return !CompilerGeneratedNames.IsStateMachineCurrentField (field.Name);
+ }
+
+ return false;
}
// "Nested function" refers to lambdas and local functions.
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs
index 53032ae72..90b2c53bf 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/CompilerGeneratedCodeDataflow.cs
@@ -210,8 +210,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
FlowParameterAcrossYieldReturn ();
FlowUnannotatedParameterAcrossYieldReturn ();
FlowAcrossYieldReturnWithBackwardsBranch ();
-
- foreach (var o in ReturnManyObjects ());
+
+ foreach (var o in ReturnManyObjects ()) ;
}
}
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ILVerifier.cs b/test/Mono.Linker.Tests/TestCasesRunner/ILVerifier.cs
index bf935cc22..d9d4b8a43 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/ILVerifier.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/ILVerifier.cs
@@ -14,13 +14,13 @@ using Mono.Linker.Tests.Extensions;
#nullable enable
namespace Mono.Linker.Tests.TestCasesRunner
{
- class ILVerifier : ILVerify.IResolver
+ sealed class ILVerifier : ILVerify.IResolver
{
- Verifier _verifier;
- NPath _assemblyFolder;
- NPath _frameworkFolder;
- Dictionary<string, PEReader> _assemblyCache;
- AssemblyLoadContext _alc;
+ readonly Verifier _verifier;
+ readonly NPath _assemblyFolder;
+ readonly NPath _frameworkFolder;
+ readonly Dictionary<string, PEReader> _assemblyCache;
+ readonly AssemblyLoadContext _alc;
public IEnumerable<VerificationResult> Results { get; private set; }
@@ -123,7 +123,7 @@ namespace Mono.Linker.Tests.TestCasesRunner
PEReader? ILVerify.IResolver.ResolveModule (AssemblyName referencingModule, string fileName)
=> Resolve (Path.GetFileNameWithoutExtension (fileName));
- public string GetErrorMessage (VerificationResult result)
+ public static string GetErrorMessage (VerificationResult result)
{
return $"IL Verification error:\n{result.Message}";
}
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
index ccb76575f..4a7de6de6 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
@@ -55,7 +55,7 @@ namespace Mono.Linker.Tests.TestCasesRunner
foreach (var result in verifier.Results) {
if (result.Code == ILVerify.VerifierError.None)
continue;
- Assert.Fail (verifier.GetErrorMessage (result));
+ Assert.Fail (ILVerifier.GetErrorMessage (result));
}
}
@@ -1122,7 +1122,7 @@ namespace Mono.Linker.Tests.TestCasesRunner
return false;
}
- static IEnumerable<CustomAttribute> GetCustomAttributes (ICustomAttributeProvider caProvider, string attributeName )
+ static IEnumerable<CustomAttribute> GetCustomAttributes (ICustomAttributeProvider caProvider, string attributeName)
{
if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null)
return assembly.EntryPoint.DeclaringType.CustomAttributes