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

Unified Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 804903004: Refactor LibraryUpdater to prepare for parts. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years 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
« no previous file with comments | « dart/pkg/dart2js_incremental/lib/dart2js_incremental.dart ('k') | dart/site/try/poi/poi.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/pkg/dart2js_incremental/lib/library_updater.dart
diff --git a/dart/pkg/dart2js_incremental/lib/library_updater.dart b/dart/pkg/dart2js_incremental/lib/library_updater.dart
index b7d41e0090fd5a160c335473171e34bc9382cb1a..737dd202d51f32faddc510bb4ed8ad05a71ac52b 100644
--- a/dart/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/dart/pkg/dart2js_incremental/lib/library_updater.dart
@@ -83,6 +83,9 @@ import 'diff.dart' show
Difference,
computeDifference;
+import 'dart2js_incremental.dart' show
+ IncrementalCompiler;
+
typedef void Logger(message);
typedef bool Reuser(
@@ -103,8 +106,45 @@ class FailedUpdate {
}
}
-// TODO(ahe): Generalize this class. For now only works for Compiler.mainApp,
-// and only if that library has exactly one compilation unit.
+abstract class _IncrementalCompilerContext {
+ IncrementalCompiler incrementalCompiler;
+
+ Set<ClassElementX> _emittedClasses;
+
+ Set<ClassElementX> _directlyInstantiatedClasses;
+
+ Set<ConstantValue> _compiledConstants;
+}
+
+class IncrementalCompilerContext extends _IncrementalCompilerContext {
+ final Set<Uri> _uriWithUpdates = new Set<Uri>();
+
+ void set incrementalCompiler(IncrementalCompiler value) {
+ if (super.incrementalCompiler != null) {
+ throw new StateError("Can't set [incrementalCompiler] more than once.");
+ }
Johnni Winther 2014/12/16 11:22:52 You need to do super.incrementalCompiler = value
ahe 2014/12/16 12:04:31 Done.
+ }
+
+ void registerUriWithUpdates(Iterable<Uri> uris) {
+ _uriWithUpdates.addAll(uris);
+ }
+
+ void _captureState(Compiler compiler) {
+ _emittedClasses = new Set.from(compiler.backend.emitter.neededClasses);
+
+ _directlyInstantiatedClasses =
+ new Set.from(compiler.codegenWorld.directlyInstantiatedClasses);
+
+ List<ConstantValue> constants =
+ compiler.backend.emitter.outputConstantLists[
+ compiler.deferredLoadTask.mainOutputUnit];
+ if (constants == null) constants = <ConstantValue>[];
+ _compiledConstants = new Set<ConstantValue>.identity()..addAll(constants);
+ }
+
+ bool _uriHasUpdate(Uri uri) => _uriWithUpdates.contains(uri);
+}
+
class LibraryUpdater extends JsFeatures {
final Compiler compiler;
@@ -114,10 +154,6 @@ class LibraryUpdater extends JsFeatures {
final Logger logVerbose;
- // TODO(ahe): Get rid of this field. It assumes that only one library has
- // changed.
- final Uri uri;
-
final List<Update> updates = <Update>[];
final List<FailedUpdate> _failedUpdates = <FailedUpdate>[];
@@ -129,50 +165,37 @@ class LibraryUpdater extends JsFeatures {
final Set<ClassElementX> _classesWithSchemaChanges =
new Set<ClassElementX>();
- final Set<ClassElementX> _emittedClasses;
-
- final Set<ClassElementX> _directlyInstantiatedClasses;
-
- final Set<ConstantValue> _compiledConstants;
+ final IncrementalCompilerContext _context;
bool _hasComputedNeeds = false;
+ bool _hasCapturedCompilerState = false;
+
LibraryUpdater(
- Compiler compiler,
+ this.compiler,
this.inputProvider,
- this.uri,
this.logTime,
- this.logVerbose)
- : this.compiler = compiler,
- _emittedClasses = _getEmittedClasses(compiler),
- _directlyInstantiatedClasses =
- _getDirectlyInstantiatedClasses(compiler),
- _compiledConstants = _getEmittedConstants(compiler);
+ this.logVerbose,
+ this._context) {
+ // TODO(ahe): Would like to remove this from the constructor. However, the
+ // state must be captured before calling [reuseCompiler].
+ // Proper solution might be: [reuseCompiler] should not clear the sets that
+ // are captured in [IncrementalCompilerContext._captureState].
+ _ensureCompilerStateCaptured();
+ }
/// Returns the classes emitted by [compiler].
- static Set<ClassElementX> _getEmittedClasses(Compiler compiler) {
- if (compiler == null) return null;
- return new Set.from(compiler.backend.emitter.neededClasses);
- }
+ Set<ClassElementX> get _emittedClasses => _context._emittedClasses;
- /// Returns the directly instantantiated classes seen by [compiler].
- static Set<ClassElementX> _getDirectlyInstantiatedClasses(Compiler compiler) {
- if (compiler == null) return null;
- return new Set.from(compiler.codegenWorld.directlyInstantiatedClasses);
+ /// Returns the directly instantantiated classes seen by [compiler] (this
+ /// includes interfaces and may be different from [_emittedClasses] that only
+ /// includes interfaces used in type tests).
+ Set<ClassElementX> get _directlyInstantiatedClasses {
+ return _context._directlyInstantiatedClasses;
}
/// Returns the constants emitted by [compiler].
- static Set<ConstantValue> _getEmittedConstants(Compiler compiler) {
- if (compiler != null) {
- List<ConstantValue> constants =
- compiler.backend.emitter.outputConstantLists[
- compiler.deferredLoadTask.mainOutputUnit];
- if (constants != null) {
- return new Set<ConstantValue>.identity()..addAll(constants);
- }
- }
- return null;
- }
+ Set<ConstantValue> get _compiledConstants => _context._compiledConstants;
/// When [true], updates must be applied (using [applyUpdates]) before the
/// [compiler]'s state correctly reflects the updated program.
@@ -182,16 +205,38 @@ class LibraryUpdater extends JsFeatures {
/// Used as tear-off passed to [LibraryLoaderTask.resetAsync].
Future<bool> reuseLibrary(LibraryElement library) {
+ _ensureCompilerStateCaptured();
assert(compiler != null);
- if (library.isPlatformLibrary || library.isPackageLibrary) {
- logTime('Reusing $library.');
+ if (library.isPlatformLibrary) {
+ logTime('Reusing $library (assumed read-only).');
return new Future.value(true);
- } else if (library != compiler.mainApp) {
- return new Future.value(false);
}
- return inputProvider(uri).then((bytes) {
- return canReuseLibrary(library, bytes);
- });
+ for (CompilationUnitElementX unit in library.compilationUnits) {
+ Uri uri = unit.script.resourceUri;
+ if (_context._uriHasUpdate(uri)) {
+ if (!library.compilationUnits.tail.isEmpty) {
+ // TODO(ahe): Remove this restriction.
+ cannotReuse(library, "Multiple compilation units not supported.");
+ return new Future.value(true);
+ }
+ return inputProvider(uri).then((bytes) {
+ return canReuseLibrary(library, bytes);
+ });
+ }
+ }
+
+ logTime("Reusing $library, source didn't change.");
+ // Source code of [library] wasn't changed.
+ return new Future.value(true);
+ }
+
+ void _ensureCompilerStateCaptured() {
+ // TODO(ahe): [compiler] shouldn't be null, remove the following line.
+ if (compiler == null) return;
+
+ if (_hasCapturedCompilerState) return;
+ _context._captureState(compiler);
+ _hasCapturedCompilerState = true;
}
/// Returns true if [library] can be reused.
@@ -199,19 +244,11 @@ class LibraryUpdater extends JsFeatures {
/// This methods also computes the [updates] (patches) needed to have
/// [library] reflect the modifications in [bytes].
bool canReuseLibrary(LibraryElement library, bytes) {
- logTime('Attempting to reuse mainApp.');
+ logTime('Attempting to reuse ${library}.');
String newSource = bytes is String ? bytes : UTF8.decode(bytes);
logTime('Decoded UTF8');
- // TODO(ahe): Can't use compiler.mainApp in general.
- if (false && newSource == compiler.mainApp.compilationUnit.script.text) {
- // TODO(ahe): Need to update the compilationUnit's source code when
- // doing incremental analysis for this to work.
- logTime("Source didn't change");
- return true;
- }
-
- logTime("Source did change");
+ Uri uri = library.entryCompilationUnit.script.resourceUri;
Script sourceScript = new Script(
uri, uri, new StringSourceFile('$uri', newSource));
var dartPrivacyIsBroken = compiler.libraryLoader;
« no previous file with comments | « dart/pkg/dart2js_incremental/lib/dart2js_incremental.dart ('k') | dart/site/try/poi/poi.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698