[CFE] Don't create new 'unknown' FunctionTypes for each TypeInferrerImpl

When compiling "compile.dart" this creates ~17% fewer FunctionTypes
(from almost 263k to a little over 217k).

Change-Id: I0090c287ce427b298897846de03679f562223e63
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298581
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Jens Johansen 2023-04-27 07:14:51 +00:00 committed by Commit Queue
parent ea2d6a7659
commit f72b7ae86f
2 changed files with 73 additions and 21 deletions

View file

@ -329,6 +329,10 @@ abstract class TypeInferenceEngine {
/// kernel objects. /// kernel objects.
class TypeInferenceEngineImpl extends TypeInferenceEngine { class TypeInferenceEngineImpl extends TypeInferenceEngine {
final Benchmarker? benchmarker; final Benchmarker? benchmarker;
final FunctionType unknownFunctionNonNullable =
new FunctionType(const [], const DynamicType(), Nullability.nonNullable);
final FunctionType unknownFunctionLegacy =
new FunctionType(const [], const DynamicType(), Nullability.legacy);
TypeInferenceEngineImpl(Instrumentation? instrumentation, this.benchmarker) TypeInferenceEngineImpl(Instrumentation? instrumentation, this.benchmarker)
: super(instrumentation); : super(instrumentation);
@ -345,11 +349,28 @@ class TypeInferenceEngineImpl extends TypeInferenceEngine {
new AssignedVariables<TreeNode, VariableDeclaration>(); new AssignedVariables<TreeNode, VariableDeclaration>();
} }
if (benchmarker == null) { if (benchmarker == null) {
return new TypeInferrerImpl(this, uri, false, thisType, library, return new TypeInferrerImpl(
assignedVariables, dataForTesting); this,
uri,
false,
thisType,
library,
assignedVariables,
dataForTesting,
unknownFunctionNonNullable,
unknownFunctionLegacy);
} }
return new TypeInferrerImplBenchmarked(this, uri, false, thisType, library, return new TypeInferrerImplBenchmarked(
assignedVariables, dataForTesting, benchmarker!); this,
uri,
false,
thisType,
library,
assignedVariables,
dataForTesting,
benchmarker!,
unknownFunctionNonNullable,
unknownFunctionLegacy);
} }
@override @override
@ -364,11 +385,28 @@ class TypeInferenceEngineImpl extends TypeInferenceEngine {
new AssignedVariables<TreeNode, VariableDeclaration>(); new AssignedVariables<TreeNode, VariableDeclaration>();
} }
if (benchmarker == null) { if (benchmarker == null) {
return new TypeInferrerImpl(this, uri, true, thisType, library, return new TypeInferrerImpl(
assignedVariables, dataForTesting); this,
uri,
true,
thisType,
library,
assignedVariables,
dataForTesting,
unknownFunctionNonNullable,
unknownFunctionLegacy);
} }
return new TypeInferrerImplBenchmarked(this, uri, true, thisType, library, return new TypeInferrerImplBenchmarked(
assignedVariables, dataForTesting, benchmarker!); this,
uri,
true,
thisType,
library,
assignedVariables,
dataForTesting,
benchmarker!,
unknownFunctionNonNullable,
unknownFunctionLegacy);
} }
} }

View file

@ -139,11 +139,14 @@ class TypeInferrerImpl implements TypeInferrer {
this.thisType, this.thisType,
this.libraryBuilder, this.libraryBuilder,
this.assignedVariables, this.assignedVariables,
this.dataForTesting) this.dataForTesting,
FunctionType unknownFunctionNonNullable,
FunctionType unknownFunctionLegacy)
// ignore: unnecessary_null_comparison // ignore: unnecessary_null_comparison
: assert(libraryBuilder != null), : assert(libraryBuilder != null),
unknownFunction = new FunctionType( unknownFunction = libraryBuilder.isNonNullableByDefault
const [], const DynamicType(), libraryBuilder.nonNullable), ? unknownFunctionNonNullable
: unknownFunctionLegacy,
instrumentation = isTopLevel ? null : engine.instrumentation, instrumentation = isTopLevel ? null : engine.instrumentation,
typeSchemaEnvironment = engine.typeSchemaEnvironment, typeSchemaEnvironment = engine.typeSchemaEnvironment,
operations = new OperationsCfe(engine.typeSchemaEnvironment, operations = new OperationsCfe(engine.typeSchemaEnvironment,
@ -305,16 +308,27 @@ class TypeInferrerImplBenchmarked implements TypeInferrer {
final Benchmarker benchmarker; final Benchmarker benchmarker;
TypeInferrerImplBenchmarked( TypeInferrerImplBenchmarked(
TypeInferenceEngine engine, TypeInferenceEngine engine,
Uri uriForInstrumentation, Uri uriForInstrumentation,
bool topLevel, bool topLevel,
InterfaceType? thisType, InterfaceType? thisType,
SourceLibraryBuilder library, SourceLibraryBuilder library,
AssignedVariables<TreeNode, VariableDeclaration> assignedVariables, AssignedVariables<TreeNode, VariableDeclaration> assignedVariables,
InferenceDataForTesting? dataForTesting, InferenceDataForTesting? dataForTesting,
this.benchmarker) this.benchmarker,
: impl = new TypeInferrerImpl(engine, uriForInstrumentation, topLevel, FunctionType unknownFunctionNonNullable,
thisType, library, assignedVariables, dataForTesting); FunctionType unknownFunctionLegacy,
) : impl = new TypeInferrerImpl(
engine,
uriForInstrumentation,
topLevel,
thisType,
library,
assignedVariables,
dataForTesting,
unknownFunctionNonNullable,
unknownFunctionLegacy,
);
@override @override
bool get isTopLevel => impl.isTopLevel; bool get isTopLevel => impl.isTopLevel;