| Index: pkg/compiler/lib/src/compiler.dart
|
| diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
|
| index 0bcc283efe75b538f027f0b83490fe37f70c3631..2aa02597e8dffd3d954f18c1b8cdc06214b13725 100644
|
| --- a/pkg/compiler/lib/src/compiler.dart
|
| +++ b/pkg/compiler/lib/src/compiler.dart
|
| @@ -32,7 +32,8 @@ import 'common/resolution.dart' show
|
| ResolutionImpact;
|
| import 'common/tasks.dart' show
|
| CompilerTask,
|
| - GenericTask;
|
| + GenericTask,
|
| + Measurer;
|
| import 'common/work.dart' show
|
| WorkItem;
|
| import 'compile_time_constants.dart';
|
| @@ -145,8 +146,122 @@ import 'world.dart' show
|
| World;
|
|
|
| abstract class Compiler {
|
| + // Constructor must be first to ensure [Measurer] is instantiated before
|
| + // other computations.
|
| + Compiler({this.enableTypeAssertions: false,
|
| + this.enableUserAssertions: false,
|
| + this.trustTypeAnnotations: false,
|
| + this.trustPrimitives: false,
|
| + bool disableTypeInferenceFlag: false,
|
| + this.maxConcreteTypeSize: 5,
|
| + this.enableMinification: false,
|
| + this.preserveUris: false,
|
| + this.enableNativeLiveTypeAnalysis: false,
|
| + bool emitJavaScript: true,
|
| + bool dart2dartMultiFile: false,
|
| + bool generateSourceMap: true,
|
| + bool analyzeAllFlag: false,
|
| + bool analyzeOnly: false,
|
| + this.analyzeMain: false,
|
| + bool analyzeSignaturesOnly: false,
|
| + this.preserveComments: false,
|
| + this.useCpsIr: false,
|
| + this.useFrequencyNamer: false,
|
| + this.verbose: false,
|
| + this.sourceMapUri: null,
|
| + this.outputUri: null,
|
| + this.buildId: UNDETERMINED_BUILD_ID,
|
| + this.deferredMapUri: null,
|
| + this.dumpInfo: false,
|
| + bool useStartupEmitter: false,
|
| + this.useContentSecurityPolicy: false,
|
| + bool hasIncrementalSupport: false,
|
| + this.enableExperimentalMirrors: false,
|
| + this.enableAssertMessage: false,
|
| + this.allowNativeExtensions: false,
|
| + this.generateCodeWithCompileTimeErrors: false,
|
| + this.testMode: false,
|
| + DiagnosticOptions diagnosticOptions,
|
| + api.CompilerOutput outputProvider,
|
| + List<String> strips: const [],
|
| + Backend makeBackend(Compiler compiler),
|
| + Measurer measurer})
|
| + : this.measurer = measurer == null ? new Measurer() : measurer,
|
| + this.disableTypeInferenceFlag =
|
| + disableTypeInferenceFlag || !emitJavaScript,
|
| + this.analyzeOnly =
|
| + analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag,
|
| + this.analyzeSignaturesOnly = analyzeSignaturesOnly,
|
| + this.analyzeAllFlag = analyzeAllFlag,
|
| + this.hasIncrementalSupport = hasIncrementalSupport,
|
| + cacheStrategy = new CacheStrategy(hasIncrementalSupport),
|
| + this.userOutputProvider = outputProvider == null
|
| + ? const NullCompilerOutput() : outputProvider {
|
| + if (hasIncrementalSupport) {
|
| + // TODO(ahe): This is too much. Any method from platform and package
|
| + // libraries can be inlined.
|
| + disableInlining = true;
|
| + }
|
| + world = new World(this);
|
| + // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and
|
| + // make its field final.
|
| + _reporter = new _CompilerDiagnosticReporter(this, diagnosticOptions);
|
| + _parsing = new _CompilerParsing(this);
|
| + _resolution = new _CompilerResolution(this);
|
| + _coreTypes = new _CompilerCoreTypes(_resolution);
|
| + types = new Types(_resolution);
|
| + tracer = new Tracer(this, this.outputProvider);
|
| +
|
| + if (verbose) {
|
| + progress = new Stopwatch()..start();
|
| + }
|
| +
|
| + // TODO(johnniwinther): Separate the dependency tracking from the enqueuing
|
| + // for global dependencies.
|
| + globalDependencies = new GlobalDependencyRegistry(this);
|
| +
|
| + if (makeBackend != null) {
|
| + backend = makeBackend(this);
|
| + } else if (emitJavaScript) {
|
| + js_backend.JavaScriptBackend jsBackend =
|
| + new js_backend.JavaScriptBackend(
|
| + this, generateSourceMap: generateSourceMap,
|
| + useStartupEmitter: useStartupEmitter);
|
| + backend = jsBackend;
|
| + } else {
|
| + backend = new dart_backend.DartBackend(this, strips,
|
| + multiFile: dart2dartMultiFile);
|
| + if (dumpInfo) {
|
| + throw new ArgumentError('--dump-info is not supported for dart2dart.');
|
| + }
|
| + }
|
| +
|
| + tasks = [
|
| + libraryLoader = new LibraryLoaderTask(this),
|
| + serialization = new SerializationTask(this),
|
| + scanner = new ScannerTask(this),
|
| + dietParser = new DietParserTask(this),
|
| + parser = new ParserTask(this),
|
| + patchParser = new PatchParserTask(this),
|
| + resolver = new ResolverTask(this, backend.constantCompilerTask),
|
| + closureToClassMapper = new closureMapping.ClosureTask(this),
|
| + checker = new TypeCheckerTask(this),
|
| + typesTask = new ti.TypesTask(this),
|
| + constants = backend.constantCompilerTask,
|
| + deferredLoadTask = new DeferredLoadTask(this),
|
| + mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
|
| + enqueuer = backend.makeEnqueuer(),
|
| + dumpInfoTask = new DumpInfoTask(this),
|
| + reuseLibraryTask = new GenericTask('Reuse library', this),
|
| + selfTask = new GenericTask('self', this),
|
| + ];
|
| +
|
| + tasks.addAll(backend.tasks);
|
| + }
|
| +
|
| + /// Helper instance for measurements in [CompilerTask].
|
| + final Measurer measurer;
|
|
|
| - final Stopwatch totalCompileTime = new Stopwatch();
|
| int nextFreeClassId = 0;
|
| World world;
|
| Types types;
|
| @@ -275,7 +390,6 @@ abstract class Compiler {
|
|
|
| Tracer tracer;
|
|
|
| - CompilerTask measuredTask;
|
| LibraryElement coreLibrary;
|
| LibraryElement asyncLibrary;
|
|
|
| @@ -368,6 +482,8 @@ abstract class Compiler {
|
|
|
| GenericTask reuseLibraryTask;
|
|
|
| + GenericTask selfTask;
|
| +
|
| /// The constant environment for the frontend interpretation of compile-time
|
| /// constants.
|
| ConstantEnvironment constants;
|
| @@ -414,114 +530,6 @@ abstract class Compiler {
|
| /// Set by the backend if real reflection is detected in use of dart:mirrors.
|
| bool disableTypeInferenceForMirrors = false;
|
|
|
| - Compiler({this.enableTypeAssertions: false,
|
| - this.enableUserAssertions: false,
|
| - this.trustTypeAnnotations: false,
|
| - this.trustPrimitives: false,
|
| - bool disableTypeInferenceFlag: false,
|
| - this.maxConcreteTypeSize: 5,
|
| - this.enableMinification: false,
|
| - this.preserveUris: false,
|
| - this.enableNativeLiveTypeAnalysis: false,
|
| - bool emitJavaScript: true,
|
| - bool dart2dartMultiFile: false,
|
| - bool generateSourceMap: true,
|
| - bool analyzeAllFlag: false,
|
| - bool analyzeOnly: false,
|
| - this.analyzeMain: false,
|
| - bool analyzeSignaturesOnly: false,
|
| - this.preserveComments: false,
|
| - this.useCpsIr: false,
|
| - this.useFrequencyNamer: false,
|
| - this.verbose: false,
|
| - this.sourceMapUri: null,
|
| - this.outputUri: null,
|
| - this.buildId: UNDETERMINED_BUILD_ID,
|
| - this.deferredMapUri: null,
|
| - this.dumpInfo: false,
|
| - bool useStartupEmitter: false,
|
| - this.useContentSecurityPolicy: false,
|
| - bool hasIncrementalSupport: false,
|
| - this.enableExperimentalMirrors: false,
|
| - this.enableAssertMessage: false,
|
| - this.allowNativeExtensions: false,
|
| - this.generateCodeWithCompileTimeErrors: false,
|
| - this.testMode: false,
|
| - DiagnosticOptions diagnosticOptions,
|
| - api.CompilerOutput outputProvider,
|
| - List<String> strips: const [],
|
| - Backend makeBackend(Compiler compiler)})
|
| - : this.disableTypeInferenceFlag =
|
| - disableTypeInferenceFlag || !emitJavaScript,
|
| - this.analyzeOnly =
|
| - analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag,
|
| - this.analyzeSignaturesOnly = analyzeSignaturesOnly,
|
| - this.analyzeAllFlag = analyzeAllFlag,
|
| - this.hasIncrementalSupport = hasIncrementalSupport,
|
| - cacheStrategy = new CacheStrategy(hasIncrementalSupport),
|
| - this.userOutputProvider = outputProvider == null
|
| - ? const NullCompilerOutput() : outputProvider {
|
| - if (hasIncrementalSupport) {
|
| - // TODO(ahe): This is too much. Any method from platform and package
|
| - // libraries can be inlined.
|
| - disableInlining = true;
|
| - }
|
| - world = new World(this);
|
| - // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and
|
| - // make its field final.
|
| - _reporter = new _CompilerDiagnosticReporter(this, diagnosticOptions);
|
| - _parsing = new _CompilerParsing(this);
|
| - _resolution = new _CompilerResolution(this);
|
| - _coreTypes = new _CompilerCoreTypes(_resolution);
|
| - types = new Types(_resolution);
|
| - tracer = new Tracer(this, this.outputProvider);
|
| -
|
| - if (verbose) {
|
| - progress = new Stopwatch()..start();
|
| - }
|
| -
|
| - // TODO(johnniwinther): Separate the dependency tracking from the enqueuing
|
| - // for global dependencies.
|
| - globalDependencies = new GlobalDependencyRegistry(this);
|
| -
|
| - if (makeBackend != null) {
|
| - backend = makeBackend(this);
|
| - } else if (emitJavaScript) {
|
| - js_backend.JavaScriptBackend jsBackend =
|
| - new js_backend.JavaScriptBackend(
|
| - this, generateSourceMap: generateSourceMap,
|
| - useStartupEmitter: useStartupEmitter);
|
| - backend = jsBackend;
|
| - } else {
|
| - backend = new dart_backend.DartBackend(this, strips,
|
| - multiFile: dart2dartMultiFile);
|
| - if (dumpInfo) {
|
| - throw new ArgumentError('--dump-info is not supported for dart2dart.');
|
| - }
|
| - }
|
| -
|
| - tasks = [
|
| - libraryLoader = new LibraryLoaderTask(this),
|
| - serialization = new SerializationTask(this),
|
| - scanner = new ScannerTask(this),
|
| - dietParser = new DietParserTask(this),
|
| - parser = new ParserTask(this),
|
| - patchParser = new PatchParserTask(this),
|
| - resolver = new ResolverTask(this, backend.constantCompilerTask),
|
| - closureToClassMapper = new closureMapping.ClosureTask(this),
|
| - checker = new TypeCheckerTask(this),
|
| - typesTask = new ti.TypesTask(this),
|
| - constants = backend.constantCompilerTask,
|
| - deferredLoadTask = new DeferredLoadTask(this),
|
| - mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
|
| - enqueuer = backend.makeEnqueuer(),
|
| - dumpInfoTask = new DumpInfoTask(this),
|
| - reuseLibraryTask = new GenericTask('Reuse library', this),
|
| - ];
|
| -
|
| - tasks.addAll(backend.tasks);
|
| - }
|
| -
|
| Universe get resolverWorld => enqueuer.resolution.universe;
|
| Universe get codegenWorld => enqueuer.codegen.universe;
|
|
|
| @@ -545,18 +553,18 @@ abstract class Compiler {
|
| //
|
| // The resulting future will complete with true if the compilation
|
| // succeded.
|
| - Future<bool> run(Uri uri) {
|
| - totalCompileTime.start();
|
| + Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () {
|
| + measurer.startWallClock();
|
|
|
| return new Future.sync(() => runInternal(uri))
|
| .catchError((error) => _reporter.onError(uri, error))
|
| .whenComplete(() {
|
| tracer.close();
|
| - totalCompileTime.stop();
|
| + measurer.stopWallClock();
|
| }).then((_) {
|
| return !compilationFailed;
|
| });
|
| - }
|
| + });
|
|
|
| /// This method is called immediately after the [LibraryElement] [library] has
|
| /// been created.
|
| @@ -960,7 +968,9 @@ abstract class Compiler {
|
| }
|
|
|
| /// Performs the compilation when all libraries have been loaded.
|
| - void compileLoadedLibraries() {
|
| + void compileLoadedLibraries()
|
| + => selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
|
| +
|
| computeMain();
|
|
|
| mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
|
| @@ -1057,7 +1067,7 @@ abstract class Compiler {
|
| }
|
|
|
| checkQueues();
|
| - }
|
| + });
|
|
|
| void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
|
| void enqueueAll(Element element) {
|
| @@ -1094,15 +1104,20 @@ abstract class Compiler {
|
| /**
|
| * Empty the [world] queue.
|
| */
|
| - void emptyQueue(Enqueuer world) {
|
| + void emptyQueue(Enqueuer world)
|
| + => selfTask.measureSubtask("Compiler.emptyQueue", () {
|
| world.forEach((WorkItem work) {
|
| - reporter.withCurrentElement(work.element, () {
|
| - world.applyImpact(work.element, work.run(this, world));
|
| - });
|
| + reporter.withCurrentElement(
|
| + work.element, () => selfTask.measureSubtask("world.applyImpact", () {
|
| + world.applyImpact(
|
| + work.element,
|
| + selfTask.measureSubtask("work.run", () => work.run(this, world)));
|
| + }));
|
| });
|
| - }
|
| + });
|
|
|
| - void processQueue(Enqueuer world, Element main) {
|
| + void processQueue(Enqueuer world, Element main)
|
| + => selfTask.measureSubtask("Compiler.processQueue", () {
|
| world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
|
| if (main != null && !main.isMalformed) {
|
| FunctionElement mainMethod = main;
|
| @@ -1127,7 +1142,7 @@ abstract class Compiler {
|
| world.queueIsClosed = true;
|
| backend.onQueueClosed();
|
| assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
|
| - }
|
| + });
|
|
|
| /**
|
| * Perform various checks of the queues. This includes checking that
|
| @@ -1169,7 +1184,8 @@ abstract class Compiler {
|
| }
|
| }
|
|
|
| - WorldImpact analyzeElement(Element element) {
|
| + WorldImpact analyzeElement(Element element)
|
| + => selfTask.measureSubtask("Compiler.analyzeElement", () {
|
| assert(invariant(element,
|
| element.impliesType ||
|
| element.isField ||
|
| @@ -1182,10 +1198,10 @@ abstract class Compiler {
|
| message: 'Element $element is not analyzable.'));
|
| assert(invariant(element, element.isDeclaration));
|
| return resolution.computeWorldImpact(element);
|
| - }
|
| + });
|
|
|
| - WorldImpact analyze(ResolutionWorkItem work,
|
| - ResolutionEnqueuer world) {
|
| + WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world)
|
| + => selfTask.measureSubtask("Compiler.analyze", () {
|
| assert(invariant(work.element, identical(world, enqueuer.resolution)));
|
| assert(invariant(work.element, !work.isAnalyzed,
|
| message: 'Element ${work.element} has already been analyzed'));
|
| @@ -1207,7 +1223,7 @@ abstract class Compiler {
|
| backend.onElementResolved(element, element.resolvedAst.elements);
|
| world.registerProcessedElement(element);
|
| return worldImpact;
|
| - }
|
| + });
|
|
|
| WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) {
|
| assert(invariant(work.element, identical(world, enqueuer.codegen)));
|
|
|