[CFE] Cache checkInheritanceConflict calculation
When compiling a big internal app with the NNBD SDK there's a big time
regression. This is a first "poor-mans fix" that "fixes" it via caching
which probably is not the best solution, but does the trick.
Without change
==============
Without NNBD platform:
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --target=dart2js --platform=out/ReleaseX64/dart2js_platform.dill -v bigapp.dart
[...]
0:00:14.238352: Built class hierarchy in 1663ms.
[...]
0:00:55.871356: Wrote component to bigapp.dart.dill in 5690ms.
With NNBD platform:
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --target=dart2js --platform=out/ReleaseX64NNBD/dart2js_platform.dill -v bigapp.dart
[...]
0:04:41.842548: Built class hierarchy in 268716ms.
[...]
0:05:22.120455: Wrote component to bigapp.dart.dill in 5407ms.
So: Big regression; it takes almost 4.5 minutes to built the class
hierarchy and almost as long extra to compile as a whole.
With change
===========
Without NNBD platform:
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --target=dart2js --platform=out/ReleaseX64/dart2js_platform.dill -v bigapp.dart
[...]
0:00:15.255893: Built class hierarchy in 2175ms.
[...]
0:00:55.203753: Wrote component to bigapp.dart.dill in 5306ms.
So: Without the NNBD platform there's basically no change.
With NNBD platform:
$ out/ReleaseX64/dart pkg/front_end/tool/_fasta/compile.dart --target=dart2js --platform=out/ReleaseX64NNBD/dart2js_platform.dill -v bigapp.dart
[...]
0:00:15.864901: Built class hierarchy in 2574ms.
[...]
0:00:55.640201: Wrote component to bigapp.dart.dill in 5363ms.
So: With the NNBD platform, the speedup is significant and there's basically no
change between using the NNBD platform or not.
Change-Id: I74993710a34f08f69421b03f2682ff8418af7599
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/141982
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index c080b03..71e1485de 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -340,6 +340,9 @@
Types types;
+ Map<ClassMember, Map<ClassMember, ClassMember>> inheritanceConflictCache =
+ new Map.identity();
+
ClassHierarchyBuilder(this.objectClassBuilder, this.loader, this.coreTypes)
: objectClass = objectClassBuilder.cls,
futureClass = coreTypes.futureClass,
@@ -354,6 +357,7 @@
substitutions.clear();
_overrideChecks.clear();
_delayedTypeComputations.clear();
+ inheritanceConflictCache.clear();
}
void registerDelayedTypeComputation(DelayedTypeComputation computation) {
@@ -640,12 +644,18 @@
classBuilder.library.loader == hierarchy.loader;
ClassMember checkInheritanceConflict(ClassMember a, ClassMember b) {
+ hierarchy.inheritanceConflictCache[a] ??= new Map.identity();
+ if (hierarchy.inheritanceConflictCache[a].containsKey(b)) {
+ return hierarchy.inheritanceConflictCache[a][b];
+ }
+
if (a.hasDeclarations) {
ClassMember result;
for (int i = 0; i < a.declarations.length; i++) {
ClassMember d = checkInheritanceConflict(a.declarations[i], b);
result ??= d;
}
+ hierarchy.inheritanceConflictCache[a][b] = result;
return result;
}
if (b.hasDeclarations) {
@@ -654,12 +664,15 @@
ClassMember d = checkInheritanceConflict(a, b.declarations[i]);
result ??= d;
}
+ hierarchy.inheritanceConflictCache[a][b] = result;
return result;
}
if (isInheritanceConflict(a, b)) {
reportInheritanceConflict(a, b);
+ hierarchy.inheritanceConflictCache[a][b] = a;
return a;
}
+ hierarchy.inheritanceConflictCache[a][b] = null;
return null;
}