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
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-rw-r--r--src/linker/Linker.Dataflow/CompilerGeneratedNames.cs13
-rw-r--r--src/linker/Linker.Dataflow/CompilerGeneratedState.cs14
2 files changed, 23 insertions, 4 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.