Skip to content

Commit 37193fd

Browse files
Don't track current field of state machines (#74216)
Port of dotnet/linker#2979 Fixes #73048. Co-authored-by: Michal Strehovský <[email protected]>
1 parent c7cab43 commit 37193fd

File tree

4 files changed

+47
-8
lines changed

4 files changed

+47
-8
lines changed

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedNames.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ internal static bool IsStateMachineType(string typeName)
3636
return typeName.Length > i + 1 && typeName[i + 1] == 'd';
3737
}
3838

39+
internal static bool IsStateMachineCurrentField(string fieldName)
40+
{
41+
if (!IsGeneratedMemberName(fieldName))
42+
return false;
43+
44+
int i = fieldName.LastIndexOf('>');
45+
if (i == -1)
46+
return false;
47+
48+
// Current field is <>2__current
49+
return fieldName.Length > i + 1 && fieldName[i + 1] == '2';
50+
}
51+
3952
internal static bool IsGeneratedType(string name) => IsStateMachineType(name) || IsLambdaDisplayClass(name);
4053

4154
internal static bool IsLambdaOrLocalFunction(string methodName) => IsLambdaMethod(methodName) || IsLocalFunction(methodName);

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/CompilerGeneratedState.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,10 +500,17 @@ static IEnumerable<MetadataType> GetCompilerGeneratedNestedTypes(MetadataType ty
500500

501501
public static bool IsHoistedLocal(FieldDesc field)
502502
{
503-
// Treat all fields on compiler-generated types as hoisted locals.
504-
// This avoids depending on the name mangling scheme for hoisted locals.
505-
var declaringTypeName = field.OwningType.Name;
506-
return CompilerGeneratedNames.IsLambdaDisplayClass(declaringTypeName) || CompilerGeneratedNames.IsStateMachineType(declaringTypeName);
503+
if (CompilerGeneratedNames.IsLambdaDisplayClass(field.OwningType.Name))
504+
return true;
505+
506+
if (CompilerGeneratedNames.IsStateMachineType(field.OwningType.Name))
507+
{
508+
// Don't track the "current" field which is used for state machine return values,
509+
// because this can be expensive to track.
510+
return !CompilerGeneratedNames.IsStateMachineCurrentField(field.Name);
511+
}
512+
513+
return false;
507514
}
508515

509516
// "Nested function" refers to lambdas and local functions.

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/CompilerGeneratedNames.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ internal static bool IsStateMachineType (string typeName)
3434
return typeName.Length > i + 1 && typeName[i + 1] == 'd';
3535
}
3636

37+
internal static bool IsStateMachineCurrentField (string fieldName)
38+
{
39+
if (!IsGeneratedMemberName (fieldName))
40+
return false;
41+
42+
int i = fieldName.LastIndexOf ('>');
43+
if (i == -1)
44+
return false;
45+
46+
// Current field is <>2__current
47+
return fieldName.Length > i + 1 && fieldName[i + 1] == '2';
48+
}
49+
3750
internal static bool IsGeneratedType (string name) => IsStateMachineType (name) || IsLambdaDisplayClass (name);
3851

3952
internal static bool IsLambdaOrLocalFunction (string methodName) => IsLambdaMethod (methodName) || IsLocalFunction (methodName);

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReferenceSource/CompilerGeneratedState.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,16 @@ static IEnumerable<TypeDefinition> GetCompilerGeneratedNestedTypes (TypeDefiniti
5555

5656
public static bool IsHoistedLocal (FieldDefinition field)
5757
{
58-
// Treat all fields on compiler-generated types as hoisted locals.
59-
// This avoids depending on the name mangling scheme for hoisted locals.
60-
var declaringTypeName = field.DeclaringType.Name;
61-
return CompilerGeneratedNames.IsLambdaDisplayClass (declaringTypeName) || CompilerGeneratedNames.IsStateMachineType (declaringTypeName);
58+
if (CompilerGeneratedNames.IsLambdaDisplayClass (field.DeclaringType.Name))
59+
return true;
60+
61+
if (CompilerGeneratedNames.IsStateMachineType (field.DeclaringType.Name)) {
62+
// Don't track the "current" field which is used for state machine return values,
63+
// because this can be expensive to track.
64+
return !CompilerGeneratedNames.IsStateMachineCurrentField (field.Name);
65+
}
66+
67+
return false;
6268
}
6369

6470
// "Nested function" refers to lambdas and local functions.

0 commit comments

Comments
 (0)