Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Unified Diff: pkg/front_end/lib/src/incremental_kernel_generator_impl.dart

Issue 2976003002: Implement IncrementalKernelGeneratorImpl using KernelDriver. (Closed)
Patch Set: Add comments. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/incremental_kernel_generator_impl.dart
diff --git a/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart b/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart
index daff92492b7f5bf6d67378210c91de80962cfde9..e73b95c6267260370fe4be21a7248e1e7062d736 100644
--- a/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/incremental_kernel_generator_impl.dart
@@ -4,23 +4,13 @@
import 'dart:async';
-import 'package:front_end/file_system.dart';
import 'package:front_end/incremental_kernel_generator.dart';
-import 'package:front_end/src/base/api_signature.dart';
import 'package:front_end/src/base/performace_logger.dart';
import 'package:front_end/src/base/processed_options.dart';
-import 'package:front_end/src/fasta/dill/dill_library_builder.dart';
-import 'package:front_end/src/fasta/dill/dill_target.dart';
-import 'package:front_end/src/fasta/kernel/kernel_target.dart';
-import 'package:front_end/src/fasta/kernel/utils.dart';
-import 'package:front_end/src/fasta/ticker.dart';
import 'package:front_end/src/fasta/translate_uri.dart';
-import 'package:front_end/src/incremental/byte_store.dart';
import 'package:front_end/src/incremental/file_state.dart';
-import 'package:kernel/binary/ast_from_binary.dart';
+import 'package:front_end/src/incremental/kernel_driver.dart';
import 'package:kernel/kernel.dart' hide Source;
-import 'package:kernel/target/targets.dart' show TargetFlags;
-import 'package:kernel/target/vm_fasta.dart' show VmFastaTarget;
import 'package:meta/meta.dart';
/// Implementation of [IncrementalKernelGenerator].
@@ -34,48 +24,30 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 1;
- /// The compiler options, such as the [FileSystem], the SDK dill location,
- /// etc.
- final ProcessedOptions _options;
-
- /// The object that knows how to resolve "package:" and "dart:" URIs.
- final TranslateUri _uriTranslator;
-
/// The logger to report compilation progress.
final PerformanceLog _logger;
- /// The byte storage to get and put serialized data.
- final ByteStore _byteStore;
-
/// The URI of the program entry point.
final Uri _entryPoint;
/// The function to notify when files become used or unused, or `null`.
final WatchUsedFilesFn _watchFn;
- /// The salt to mix into all hashes used as keys for serialized data.
- List<int> _salt;
-
- /// The current file system state.
- FileSystemState _fsState;
+ /// TODO(scheglov) document
+ KernelDriver _driver;
/// Latest compilation signatures produced by [computeDelta] for libraries.
final Map<Uri, String> _latestSignature = {};
- /// The set of absolute file URIs that were reported through [invalidate]
- /// and not checked for actual changes yet.
- final Set<Uri> _invalidatedFiles = new Set<Uri>();
-
/// The object that provides additional information for tests.
- final _TestView _testView = new _TestView();
+ _TestView _testView;
IncrementalKernelGeneratorImpl(
- this._options, this._uriTranslator, this._entryPoint,
+ ProcessedOptions options, TranslateUri uriTranslator, this._entryPoint,
{WatchUsedFilesFn watch})
- : _logger = _options.logger,
- _byteStore = _options.byteStore,
+ : _logger = options.logger,
_watchFn = watch {
- _computeSalt();
+ _testView = new _TestView(this);
Future<Null> onFileAdded(Uri uri) {
if (_watchFn != null) {
@@ -84,8 +56,9 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator {
return new Future.value();
}
- _fsState = new FileSystemState(_options.byteStore, _options.fileSystem,
- _uriTranslator, _salt, onFileAdded);
+ _driver = new KernelDriver(_logger, options.fileSystem, options.byteStore,
+ uriTranslator, options.strongMode,
+ fileAddedFn: onFileAdded);
}
/// Return the object that provides additional information for tests.
@@ -95,41 +68,15 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator {
@override
Future<DeltaProgram> computeDelta() async {
return await _logger.runAsync('Compute delta', () async {
- await _refreshInvalidatedFiles();
-
- // Ensure that the graph starting at the entry point is ready.
- FileState entryLibrary =
- await _logger.runAsync('Build graph of files', () async {
- return await _fsState.getFile(_entryPoint);
- });
-
- List<LibraryCycle> cycles = _logger.run('Compute library cycles', () {
- List<LibraryCycle> cycles = entryLibrary.topologicalOrder;
- _logger.writeln('Computed ${cycles.length} cycles.');
- return cycles;
- });
-
- CanonicalName nameRoot = new CanonicalName.root();
- DillTarget dillTarget = new DillTarget(
- new Ticker(isVerbose: false),
- _uriTranslator,
- new VmFastaTarget(new TargetFlags(strongMode: _options.strongMode)));
+ KernelResult kernelResult = await _driver.getKernel(_entryPoint);
+ List<LibraryCycleResult> results = kernelResult.results;
- List<_LibraryCycleResult> results = [];
- _testView.compiledCycles.clear();
- await _logger.runAsync('Compute results for cycles', () async {
- for (LibraryCycle cycle in cycles) {
- _LibraryCycleResult result =
- await _compileCycle(nameRoot, dillTarget, cycle);
- results.add(result);
- }
- });
-
- Program program = new Program(nameRoot: nameRoot);
+ // The file graph might have changed, perform GC.
+ await _gc();
// The set of affected library cycles (have different signatures).
final affectedLibraryCycles = new Set<LibraryCycle>();
- for (_LibraryCycleResult result in results) {
+ for (LibraryCycleResult result in results) {
for (Library library in result.kernelLibraries) {
Uri uri = library.importUri;
if (_latestSignature[uri] != result.signature) {
@@ -153,7 +100,8 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator {
affectedLibraryCycles.forEach(gatherVmRequiredLibraryCycles);
// Add required libraries.
- for (_LibraryCycleResult result in results) {
+ Program program = new Program(nameRoot: kernelResult.nameRoot);
+ for (LibraryCycleResult result in results) {
if (vmRequiredLibraryCycles.contains(result.cycle)) {
for (Library library in result.kernelLibraries) {
program.libraries.add(library);
@@ -180,214 +128,31 @@ class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator {
@override
void invalidate(Uri uri) {
- _invalidatedFiles.add(uri);
+ _driver.invalidate(uri);
}
@override
void invalidateAll() {
- _invalidatedFiles.addAll(_fsState.fileUris);
+ _driver.invalidateAll();
}
- /// Ensure that [dillTarget] includes the [cycle] libraries. It already
- /// contains all the libraries that sorted before the given [cycle] in
- /// topological order. Return the result with the cycle libraries.
- Future<_LibraryCycleResult> _compileCycle(
- CanonicalName nameRoot, DillTarget dillTarget, LibraryCycle cycle) async {
- return _logger.runAsync('Compile cycle $cycle', () async {
- String signature = _getCycleSignature(cycle);
-
- _logger.writeln('Signature: $signature.');
- var kernelKey = '$signature.kernel';
-
- // We need kernel libraries for these URIs.
- var libraryUris = new Set<Uri>();
- var libraryUriToFile = <Uri, FileState>{};
- for (FileState library in cycle.libraries) {
- Uri uri = library.uri;
- libraryUris.add(uri);
- libraryUriToFile[uri] = library;
- }
-
- Future<Null> appendNewDillLibraries(Program program) async {
- List<DillLibraryBuilder> libraryBuilders = dillTarget.loader
- .appendLibraries(program, (uri) => libraryUris.contains(uri));
-
- // Compute local scopes.
- await dillTarget.buildOutlines();
-
- // Compute export scopes.
- _computeExportScopes(dillTarget, libraryUriToFile, libraryBuilders);
- }
-
- // Check if there is already a bundle with these libraries.
- List<int> bytes = _byteStore.get(kernelKey);
- if (bytes != null) {
- return _logger.runAsync('Read serialized libraries', () async {
- var program = new Program(nameRoot: nameRoot);
- var reader = new BinaryBuilder(bytes);
- reader.readProgram(program);
-
- await appendNewDillLibraries(program);
-
- return new _LibraryCycleResult(cycle, signature, program.libraries);
- });
- }
-
- // Create KernelTarget and configure it for compiling the cycle URIs.
- KernelTarget kernelTarget =
- new KernelTarget(_fsState.fileSystemView, dillTarget, _uriTranslator);
- for (FileState library in cycle.libraries) {
- kernelTarget.read(library.uri);
- }
-
- // Compile the cycle libraries into a new full program.
- Program program = await _logger
- .runAsync('Compile ${cycle.libraries.length} libraries', () async {
- await kernelTarget.buildOutlines(nameRoot: nameRoot);
- return await kernelTarget.buildProgram();
- });
- _testView.compiledCycles.add(cycle);
-
- // Add newly compiled libraries into DILL.
- await appendNewDillLibraries(program);
-
- List<Library> kernelLibraries = program.libraries
- .where((library) => libraryUris.contains(library.importUri))
- .toList();
-
- _logger.run('Serialize ${kernelLibraries.length} libraries', () {
- program.uriToSource.clear();
- List<int> bytes =
- serializeProgram(program, filter: kernelLibraries.contains);
- _byteStore.put(kernelKey, bytes);
- _logger.writeln('Stored ${bytes.length} bytes.');
- });
-
- return new _LibraryCycleResult(cycle, signature, kernelLibraries);
- });
- }
-
- /// Compute exports scopes for a new strongly connected cycle of [libraries].
- /// The [dillTarget] can be used to access libraries from previous cycles.
- /// TODO(scheglov) Remove/replace this when Kernel has export scopes.
- void _computeExportScopes(DillTarget dillTarget,
- Map<Uri, FileState> uriToFile, List<DillLibraryBuilder> libraries) {
- bool wasChanged = false;
- do {
- wasChanged = false;
- for (DillLibraryBuilder library in libraries) {
- FileState file = uriToFile[library.uri];
- for (NamespaceExport export in file.exports) {
- DillLibraryBuilder exportedLibrary =
- dillTarget.loader.read(export.library.uri, -1, accessor: library);
- if (exportedLibrary != null) {
- exportedLibrary.exports.forEach((name, member) {
- if (export.isExposed(name) &&
- library.addToExportScope(name, member)) {
- wasChanged = true;
- }
- });
- } else {
- // TODO(scheglov) How to handle this?
- }
- }
- }
- } while (wasChanged);
- }
-
- /// Compute salt and put into [_salt].
- void _computeSalt() {
- var saltBuilder = new ApiSignature();
- saltBuilder.addInt(DATA_VERSION);
- saltBuilder.addBool(_options.strongMode);
- saltBuilder.addString(_entryPoint.toString());
- _salt = saltBuilder.toByteList();
- }
-
- String _getCycleSignature(LibraryCycle cycle) {
- bool hasMixinApplication =
- cycle.libraries.any((library) => library.hasMixinApplicationLibrary);
- var signatureBuilder = new ApiSignature();
- signatureBuilder.addBytes(_salt);
- Set<FileState> transitiveFiles = cycle.libraries
- .map((library) => library.transitiveFiles)
- .expand((files) => files)
- .toSet();
- signatureBuilder.addInt(transitiveFiles.length);
-
- // Append API signatures of transitive files.
- for (var file in transitiveFiles) {
- signatureBuilder.addBytes(file.uriBytes);
- // TODO(scheglov): Stop using content hashes here, when Kernel stops
- // copying methods of mixed-in classes.
- // https://github.com/dart-lang/sdk/issues/29881
- if (hasMixinApplication) {
- signatureBuilder.addBytes(file.contentHash);
- } else {
- signatureBuilder.addBytes(file.apiSignature);
- }
- }
-
- // Append content hashes of the cycle files.
- for (var library in cycle.libraries) {
- signatureBuilder.addBytes(library.contentHash);
- for (var part in library.partFiles) {
- signatureBuilder.addBytes(part.contentHash);
+ /// TODO(scheglov) document
+ Future<Null> _gc() async {
+ var removedFiles = _driver.fsState.gc(_entryPoint);
+ if (removedFiles.isNotEmpty && _watchFn != null) {
+ for (var removedFile in removedFiles) {
+ await _watchFn(removedFile.fileUri, false);
}
}
-
- return signatureBuilder.toHex();
- }
-
- /// Refresh all the invalidated files and update dependencies.
- Future<Null> _refreshInvalidatedFiles() async {
- await _logger.runAsync('Refresh invalidated files', () async {
- // Create a copy to avoid concurrent modifications.
- var invalidatedFiles = _invalidatedFiles.toList();
- _invalidatedFiles.clear();
-
- // Refresh the files.
- for (var fileUri in invalidatedFiles) {
- var file = _fsState.getFileByFileUri(fileUri);
- if (file != null) {
- _logger.writeln('Refresh $fileUri');
- await file.refresh();
- }
- }
-
- // The file graph might have changed, perform GC.
- var removedFiles = _fsState.gc(_entryPoint);
- if (removedFiles.isNotEmpty && _watchFn != null) {
- for (var removedFile in removedFiles) {
- await _watchFn(removedFile.fileUri, false);
- }
- }
- });
}
}
-/// Compilation result for a library cycle.
-class _LibraryCycleResult {
- final LibraryCycle cycle;
-
- /// The signature of the result.
- ///
- /// It is based on the full content of the libraries in the [cycle], and
- /// either API signatures of the transitive dependencies (usually), or
- /// the full content of them (in the [cycle] has a library with a mixin
- /// application).
- final String signature;
-
- /// Kernel libraries for libraries in the [cycle]. Bodies of dependencies
- /// are not included, but but references to those dependencies are included.
- final List<Library> kernelLibraries;
-
- _LibraryCycleResult(this.cycle, this.signature, this.kernelLibraries);
-}
-
@visibleForTesting
class _TestView {
- /// The list of [LibraryCycle]s compiled for the last delta.
- /// It does not include libraries which were read from the cache.
- final List<LibraryCycle> compiledCycles = [];
+ final IncrementalKernelGeneratorImpl _generator;
+
+ _TestView(this._generator);
+
+ /// The [KernelDriver] that is used to actually compile.
+ KernelDriver get driver => _generator._driver;
}
« no previous file with comments | « pkg/front_end/lib/src/incremental/kernel_driver.dart ('k') | pkg/front_end/test/incremental_kernel_generator_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698