diff options
author | Sven Boemer <sbomer@gmail.com> | 2022-08-18 01:50:53 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-18 01:50:53 +0300 |
commit | bc1f05f234bf70219687c255587e79439de9d6ee (patch) | |
tree | b1b654b9cdb9836d73df1bd2effbef5d334c585e /src | |
parent | c42e3cb42f354b13cd0414d0a4a1729146042583 (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.cs | 13 | ||||
-rw-r--r-- | src/linker/Linker.Dataflow/CompilerGeneratedState.cs | 14 |
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. |