[kernel] Constant coverage recorded in dill
This adds the recorded constant coverage to the dill file.
runtimes for constant evaluation:
dart2js: No difference proven at 95.0% confidence
flutter gallery: No difference proven at 95.0% confidence
big internal app: No difference proven at 95.0% confidence
sdk sizes:
vm: ~0.0182%
dart2js: ~0.0137%
flutter: ~0.0197%
compile sizes:
dart2js: ~0.0179%
flutter gallery: ~0.0162%
big internal app: ~0.0414%
TEST=test was fixed.
Change-Id: I347751e4d96d4d62140d26ebe37960f46a0dfbfa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/171948
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index ad8d0b8..3a23482 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -808,8 +808,8 @@
isSynthetic: true,
isConst: isConst,
reference: referenceFrom?.reference)
- ..isNonNullableByDefault =
- cls.enclosingLibrary.isNonNullableByDefault,
+ ..isNonNullableByDefault = cls.enclosingLibrary.isNonNullableByDefault
+ ..fileUri = cls.fileUri,
// If the constructor is constant, the default values must be part of
// the outline expressions. We pass on the original constructor and
// cloned function nodes to ensure that the default values are computed
@@ -1254,6 +1254,15 @@
ticker.logMs("Evaluated constants");
constantCoverageForTesting = coverage;
+ coverage.constructorCoverage.forEach((Uri fileUri, Set<Reference> value) {
+ Source source = uriToSource[fileUri];
+ if (source != null && fileUri != null) {
+ source.constantCoverageConstructors ??= new Set<Reference>();
+ source.constantCoverageConstructors.addAll(value);
+ }
+ });
+ ticker.logMs("Added constant coverage");
+
if (loader.target.context.options
.isExperimentEnabledGlobally(ExperimentalFlag.valueClass)) {
valueClass.transformComponent(
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index cafad21..d2d2c47 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -99,6 +99,10 @@
List<UInt> lineStarts;
List<Byte> importUriUtf8Bytes;
+
+ // List of constructors evaluated *by* this library. Note that these can be
+ // in other libraries.
+ List<ConstructorReference> constructorCoverage;
}
type String {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 7b9ce66..2ba1722 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -9937,6 +9937,8 @@
final Uri fileUri;
+ Set<Reference> constantCoverageConstructors;
+
String cachedText;
Source(this.lineStarts, this.source, this.importUri, this.fileUri);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 5d9958f..9461731 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -841,7 +841,19 @@
String importUriString = readString();
Uri importUri =
importUriString.isEmpty ? null : Uri.parse(importUriString);
- uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri);
+
+ Set<Reference> coverageConstructors;
+ {
+ int constructorCoverageCount = readUInt30();
+ coverageConstructors =
+ constructorCoverageCount == 0 ? null : new Set<Reference>();
+ for (int j = 0; j < constructorCoverageCount; ++j) {
+ coverageConstructors.add(readMemberReference());
+ }
+ }
+
+ uriToSource[uri] = new Source(lineStarts, sourceCode, importUri, uri)
+ ..constantCoverageConstructors = coverageConstructors;
}
// Read index.
@@ -861,8 +873,32 @@
dst.addAll(src);
} else {
src.forEach((Uri key, Source value) {
- if (value.source.isNotEmpty || !dst.containsKey(key)) {
+ Source originalDestinationSource = dst[key];
+ Source mergeFrom;
+ Source mergeTo;
+ if (value.source.isNotEmpty || originalDestinationSource == null) {
dst[key] = value;
+ mergeFrom = originalDestinationSource;
+ mergeTo = value;
+ } else {
+ mergeFrom = value;
+ mergeTo = originalDestinationSource;
+ }
+
+ // TODO(jensj): Find out what the right thing to do is --- it probably
+ // depends on what we do if read the same library twice - do we merge or
+ // do we overwrite, and should we even support such a thing?
+
+ // Merge coverage. Note that mergeFrom might be null.
+ if (mergeTo.constantCoverageConstructors == null) {
+ mergeTo.constantCoverageConstructors =
+ mergeFrom?.constantCoverageConstructors;
+ } else if (mergeFrom?.constantCoverageConstructors == null) {
+ // Nothing to do.
+ } else {
+ // Bot are non-null: Merge.
+ mergeTo.constantCoverageConstructors
+ .addAll(mergeFrom.constantCoverageConstructors);
}
});
}
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 038a584..20881c8 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -794,19 +794,33 @@
writeByteList(source.source);
- List<int> lineStarts = source.lineStarts;
- writeUInt30(lineStarts.length);
- int previousLineStart = 0;
- for (int j = 0; j < lineStarts.length; ++j) {
- int lineStart = lineStarts[j];
- writeUInt30(lineStart - previousLineStart);
- previousLineStart = lineStart;
+ {
+ List<int> lineStarts = source.lineStarts;
+ writeUInt30(lineStarts.length);
+ int previousLineStart = 0;
+ for (int j = 0; j < lineStarts.length; ++j) {
+ int lineStart = lineStarts[j];
+ writeUInt30(lineStart - previousLineStart);
+ previousLineStart = lineStart;
+ }
}
String importUriAsString =
source.importUri == null ? "" : "${source.importUri}";
outputStringViaBuffer(importUriAsString, buffer);
+ {
+ Set<Reference> coverage = source.constantCoverageConstructors;
+ if (coverage == null || coverage.isEmpty) {
+ writeUInt30(0);
+ } else {
+ writeUInt30(coverage.length);
+ for (Reference reference in coverage) {
+ writeNonNullReference(reference);
+ }
+ }
+ }
+
i++;
}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 68688fd..06a0665 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1230,6 +1230,12 @@
void transform(Component component) {
component.transformChildren(this);
+ for (Source source in component.uriToSource.values) {
+ source?.constantCoverageConstructors?.removeWhere((Reference reference) {
+ Member node = reference.asMember;
+ return !shaker.isMemberUsed(node) && !_preserveSpecialMember(node);
+ });
+ }
}
@override