Skip to content

Commit 84e279d

Browse files
jensjohaCommit Queue
authored andcommitted
[CFE] Remove ~19 mb of allocations caused by iterators etc
* Remove ~2.8mb of iterators in SourceMethodBuilder * Remove ~0.7mb of iterators in calculateBounds * Remove ~1.7 mb of iterators in ClassMembersNodeBuilder.build * Remove ~1.9mb of iterators in BuilderFactory.computeBuildersByName * Remove ~3mb of iterables and iterators in findRecordUseAnnotation * Remove ~3mb of allocations from List.iterator in InferenceVisitorBase._inferInvocation * Another ~6.3mb of iterables in various places in chunks of ~100-800kb. Running a benchmark of the CFE compiling the CFE I get this: ``` msec task-clock:u: -5.9719% +/- 0.3845% (-342.77 +/- 22.07) (5739.61 -> 5396.84) page-faults:u: -2.6307% +/- 0.0630% (-2951.12 +/- 70.63) (112178.18 -> 109227.06) cycles:u: -6.1751% +/- 0.3921% (-1471343183.50 +/- 93434420.74) (23827045867.84 -> 22355702684.34) instructions:u: -5.0116% +/- 0.0006% (-1385443477.90 +/- 176957.44) (27644543467.86 -> 26259099989.96) branch-misses:u: -6.0357% +/- 1.7661% (-5562845.14 +/- 1627775.60) (92165665.40 -> 86602820.26) seconds time elapsed: -5.9868% +/- 0.3830% (-0.34 +/- 0.02) (5.75 -> 5.40) seconds user: -6.0365% +/- 0.4515% (-0.33 +/- 0.02) (5.47 -> 5.14) seconds sys: -4.6542% +/- 3.6415% (-0.01 +/- 0.01) (0.27 -> 0.26) Scavenge( new space) goes from 64 to 63 MarkSweep( promotion) goes from 9 to 8 Evacuate(store buffer) goes from 2 to 1 ``` Worth noticing, though, is that the before numbers (e.g. 5739.61 ms task-clock:u) is very close to the before numbers from https://dart-review.googlesource.com/c/sdk/+/438681 (5767.31 ms) and not the after numbers on that cl (5478.56 ms) --- so something weird is going on here. Change-Id: I67248bbde47900435ababcb1a2d5ecff2dde5c13 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/438722 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent 7b541da commit 84e279d

23 files changed

+151
-82
lines changed

pkg/front_end/lib/src/fragment/constructor/declaration.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ mixin _ConstructorDeclarationMixin
138138
@override
139139
FormalParameterBuilder? getFormal(Identifier identifier) {
140140
if (formals != null) {
141-
for (FormalParameterBuilder formal in formals!) {
141+
List<FormalParameterBuilder> formals = this.formals!;
142+
for (int i = 0; i < formals.length; i++) {
143+
FormalParameterBuilder formal = formals[i];
142144
if (formal.isWildcard &&
143145
identifier.name == '_' &&
144146
formal.fileOffset == identifier.nameOffset) {

pkg/front_end/lib/src/fragment/method/encoding.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ mixin _DirectMethodEncodingMixin implements MethodEncoding {
254254
return new FormalParameterScope(parent: parent);
255255
}
256256
Map<String, VariableBuilder> local = {};
257-
for (FormalParameterBuilder formal in formals) {
257+
for (int i = 0; i < formals.length; i++) {
258+
FormalParameterBuilder formal = formals[i];
258259
if (formal.isWildcard) {
259260
continue;
260261
}
@@ -270,7 +271,8 @@ mixin _DirectMethodEncodingMixin implements MethodEncoding {
270271
.build(libraryBuilder, TypeUse.returnType, hierarchy: hierarchy);
271272
List<FormalParameterBuilder>? declaredFormals = _fragment.declaredFormals;
272273
if (declaredFormals != null) {
273-
for (FormalParameterBuilder formal in declaredFormals) {
274+
for (int i = 0; i < declaredFormals.length; i++) {
275+
FormalParameterBuilder formal = declaredFormals[i];
274276
formal.type
275277
.build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
276278
}

pkg/front_end/lib/src/fragment/util.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ void buildFormalsForOutlineExpressions(
8181
{required LookupScope scope,
8282
required bool isClassInstanceMember}) {
8383
if (formals != null) {
84-
for (FormalParameterBuilder formal in formals) {
84+
for (int i = 0; i < formals.length; i++) {
85+
FormalParameterBuilder formal = formals[i];
8586
buildFormalForOutlineExpressions(
8687
libraryBuilder, declarationBuilder, formal,
8788
scope: scope, isClassInstanceMember: isClassInstanceMember);

pkg/front_end/lib/src/kernel/body_builder.dart

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6251,7 +6251,8 @@ class BodyBuilder extends StackListenerImpl
62516251
if (named.isNotEmpty) {
62526252
Set<String?> parameterNames =
62536253
new Set.of(function.namedParameters.map((a) => a.name));
6254-
for (NamedExpression argument in named) {
6254+
for (int i = 0; i < named.length; i++) {
6255+
NamedExpression argument = named[i];
62556256
if (!parameterNames.contains(argument.name)) {
62566257
return cfe.templateNoSuchNamedParameter
62576258
.withArguments(argument.name)
@@ -6261,7 +6262,8 @@ class BodyBuilder extends StackListenerImpl
62616262
}
62626263
if (function.namedParameters.isNotEmpty) {
62636264
Set<String> argumentNames = new Set.of(named.map((a) => a.name));
6264-
for (VariableDeclaration parameter in function.namedParameters) {
6265+
for (int i = 0; i < function.namedParameters.length; i++) {
6266+
VariableDeclaration parameter = function.namedParameters[i];
62656267
if (parameter.isRequired && !argumentNames.contains(parameter.name)) {
62666268
return cfe.templateValueForRequiredParameterNotProvidedError
62676269
.withArguments(parameter.name!)
@@ -6321,7 +6323,8 @@ class BodyBuilder extends StackListenerImpl
63216323
if (named.isNotEmpty) {
63226324
Set<String> names =
63236325
new Set.of(function.namedParameters.map((a) => a.name));
6324-
for (NamedExpression argument in named) {
6326+
for (int i = 0; i < named.length; i++) {
6327+
NamedExpression argument = named[i];
63256328
if (!names.contains(argument.name)) {
63266329
return cfe.templateNoSuchNamedParameter
63276330
.withArguments(argument.name)
@@ -6331,7 +6334,8 @@ class BodyBuilder extends StackListenerImpl
63316334
}
63326335
if (function.namedParameters.isNotEmpty) {
63336336
Set<String> argumentNames = new Set.of(named.map((a) => a.name));
6334-
for (NamedType parameter in function.namedParameters) {
6337+
for (int i = 0; i < function.namedParameters.length; i++) {
6338+
NamedType parameter = function.namedParameters[i];
63356339
if (parameter.isRequired && !argumentNames.contains(parameter.name)) {
63366340
return cfe.templateValueForRequiredParameterNotProvidedError
63376341
.withArguments(parameter.name)

pkg/front_end/lib/src/kernel/body_builder_context.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ abstract class BodyBuilderContext {
125125
/// member whose body is being built.
126126
FormalParameterBuilder? getFormalParameterByName(Identifier identifier) {
127127
if (formals != null) {
128-
for (FormalParameterBuilder formal in formals!) {
128+
List<FormalParameterBuilder> formals = this.formals!;
129+
for (int i = 0; i < formals.length; i++) {
130+
FormalParameterBuilder formal = formals[i];
129131
if (formal.isWildcard &&
130132
identifier.name == '_' &&
131133
formal.fileOffset == identifier.nameOffset) {

pkg/front_end/lib/src/kernel/constant_evaluator.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2737,7 +2737,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
27372737
// We therefore reset it before each call, combine it and set it correctly
27382738
// at the end.
27392739
bool wasOrBecameUnevaluated = seenUnevaluatedChild;
2740-
for (Expression element in node.expressions) {
2740+
for (int i = 0; i < node.expressions.length; i++) {
2741+
Expression element = node.expressions[i];
27412742
seenUnevaluatedChild = false;
27422743
AbortConstant? error = builder.add(element);
27432744
wasOrBecameUnevaluated |= seenUnevaluatedChild;
@@ -4965,7 +4966,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
49654966
// We therefore reset it before each call, combine it and set it correctly
49664967
// at the end.
49674968
bool wasOrBecameUnevaluated = seenUnevaluatedChild;
4968-
for (NamedExpression pair in named) {
4969+
for (int i = 0; i < named.length; i++) {
4970+
NamedExpression pair = named[i];
49694971
if (_gotError != null) return null;
49704972
seenUnevaluatedChild = false;
49714973
Constant constant = _evaluateSubexpression(pair.value);

pkg/front_end/lib/src/kernel/hierarchy/members_node.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,9 @@ class ClassMembersNodeBuilder extends MembersNodeBuilder {
584584
classBuilder.filteredMembersIterator(includeDuplicates: false);
585585
while (iterator.moveNext()) {
586586
MemberBuilder memberBuilder = iterator.current;
587-
for (ClassMember classMember in memberBuilder.localMembers) {
587+
List<ClassMember> localMembers = memberBuilder.localMembers;
588+
for (int i = 0; i < localMembers.length; i++) {
589+
ClassMember classMember = localMembers[i];
588590
Name name = classMember.name;
589591
if (classMember.isAbstract) {
590592
_hasInterfaces = true;
@@ -601,7 +603,9 @@ class ClassMembersNodeBuilder extends MembersNodeBuilder {
601603
userNoSuchMethodMember = classMember;
602604
}
603605
}
604-
for (ClassMember classMember in memberBuilder.localSetters) {
606+
List<ClassMember> localSetters = memberBuilder.localSetters;
607+
for (int i = 0; i < localSetters.length; i++) {
608+
ClassMember classMember = localSetters[i];
605609
Name name = classMember.name;
606610
if (classMember.isAbstract) {
607611
_hasInterfaces = true;
@@ -632,7 +636,9 @@ class ClassMembersNodeBuilder extends MembersNodeBuilder {
632636
if (memberBuilder.isStatic) {
633637
continue;
634638
}
635-
for (ClassMember classMember in memberBuilder.localMembers) {
639+
List<ClassMember> localMembers = memberBuilder.localMembers;
640+
for (int i = 0; i < localMembers.length; i++) {
641+
ClassMember classMember = localMembers[i];
636642
Name name = classMember.name;
637643
if (classMember.isAbstract || classMember.isNoSuchMethodForwarder) {
638644
_hasInterfaces = true;
@@ -649,7 +655,9 @@ class ClassMembersNodeBuilder extends MembersNodeBuilder {
649655
userNoSuchMethodMember ??= classMember;
650656
}
651657
}
652-
for (ClassMember classMember in memberBuilder.localSetters) {
658+
List<ClassMember> localSetters = memberBuilder.localSetters;
659+
for (int i = 0; i < localSetters.length; i++) {
660+
ClassMember classMember = localSetters[i];
653661
Name name = classMember.name;
654662
if (classMember.isAbstract || classMember.isNoSuchMethodForwarder) {
655663
_hasInterfaces = true;

pkg/front_end/lib/src/kernel/invalid_type.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class _InvalidTypeFinder implements DartTypeVisitor1<bool, Set<TypedefType>> {
4545
@override
4646
bool visitInterfaceType(
4747
InterfaceType node, Set<TypedefType> visitedTypedefs) {
48-
for (DartType typeArgument in node.typeArguments) {
48+
for (int i = 0; i < node.typeArguments.length; i++) {
49+
DartType typeArgument = node.typeArguments[i];
4950
if (typeArgument.accept1(this, visitedTypedefs)) return true;
5051
}
5152
return false;

pkg/front_end/lib/src/kernel/record_use.dart

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,19 @@ import 'constant_evaluator.dart' show ErrorReporter;
1414

1515
/// Get all of the `@RecordUse` annotations from `package:meta`
1616
/// that are attached to the specified [node].
17-
Iterable<InstanceConstant> findRecordUseAnnotation(Annotatable node) =>
18-
node.annotations
19-
.whereType<ConstantExpression>()
20-
.map((expression) => expression.constant)
21-
.whereType<InstanceConstant>()
22-
.where((instance) => isRecordUse(instance.classNode));
17+
Iterable<InstanceConstant> findRecordUseAnnotation(Annotatable node) {
18+
List<InstanceConstant>? result;
19+
for (int i = 0; i < node.annotations.length; i++) {
20+
Expression annotation = node.annotations[i];
21+
if (annotation is! ConstantExpression) continue;
22+
Constant constant = annotation.constant;
23+
if (constant is! InstanceConstant) continue;
24+
if (!isRecordUse(constant.classNode)) continue;
25+
// Coverage-ignore-block(suite): Not run.
26+
(result ??= []).add(constant);
27+
}
28+
return result ?? const [];
29+
}
2330

2431
// Coverage-ignore(suite): Not run.
2532
bool hasRecordUseAnnotation(Annotatable node) =>

pkg/front_end/lib/src/kernel/static_weak_references.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class StaticWeakReferences {
2929

3030
static bool isAnnotatedWithWeakReferencePragma(
3131
Annotatable node, CoreTypes coreTypes) {
32-
for (Expression annotation in node.annotations) {
32+
List<Expression> annotations = node.annotations;
33+
for (int i = 0; i < annotations.length; i++) {
34+
Expression annotation = annotations[i];
3335
if (annotation is ConstantExpression) {
3436
Constant constant = annotation.constant;
3537
if (constant is InstanceConstant) {

0 commit comments

Comments
 (0)