Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library leg_apiimpl; | 5 library leg_apiimpl; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import 'package:package_config/packages.dart'; | 10 import 'package:package_config/packages.dart'; |
| 11 import 'package:package_config/packages_file.dart' as pkgs; | 11 import 'package:package_config/packages_file.dart' as pkgs; |
| 12 import 'package:package_config/src/packages_impl.dart' show | 12 import 'package:package_config/src/packages_impl.dart' show |
| 13 MapPackages, | 13 MapPackages, |
| 14 NonFilePackagesDirectoryPackages; | 14 NonFilePackagesDirectoryPackages; |
| 15 import 'package:package_config/src/util.dart' show | 15 import 'package:package_config/src/util.dart' show |
| 16 checkValidPackageUri; | 16 checkValidPackageUri; |
| 17 | 17 |
| 18 import '../compiler_new.dart' as api; | 18 import '../compiler_new.dart' as api; |
| 19 import 'commandline_options.dart'; | 19 import 'commandline_options.dart'; |
| 20 import 'common.dart'; | 20 import 'common.dart'; |
| 21 import 'common/tasks.dart' show | 21 import 'common/tasks.dart' show |
| 22 GenericTask; | 22 GenericTask, |
| 23 Measurer; | |
| 23 import 'common/backend_api.dart' show | 24 import 'common/backend_api.dart' show |
| 24 Backend; | 25 Backend; |
| 25 import 'compiler.dart'; | 26 import 'compiler.dart'; |
| 26 import 'diagnostics/diagnostic_listener.dart' show | 27 import 'diagnostics/diagnostic_listener.dart' show |
| 27 DiagnosticOptions; | 28 DiagnosticOptions; |
| 28 import 'diagnostics/messages.dart' show | 29 import 'diagnostics/messages.dart' show |
| 29 Message; | 30 Message; |
| 30 import 'elements/elements.dart' as elements; | 31 import 'elements/elements.dart' as elements; |
| 31 import 'io/source_file.dart'; | 32 import 'io/source_file.dart'; |
| 32 import 'platform_configuration.dart' as platform_configuration; | 33 import 'platform_configuration.dart' as platform_configuration; |
| 33 import 'script.dart'; | 34 import 'script.dart'; |
| 34 | 35 |
| 35 const bool forceIncrementalSupport = | 36 const bool forceIncrementalSupport = |
| 36 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | 37 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
| 37 | 38 |
| 38 /// Locations of the platform descriptor files relative to the library root. | 39 /// Locations of the platform descriptor files relative to the library root. |
| 39 const String _clientPlatform = "lib/dart_client.platform"; | 40 const String _clientPlatform = "lib/dart_client.platform"; |
| 40 const String _serverPlatform = "lib/dart_server.platform"; | 41 const String _serverPlatform = "lib/dart_server.platform"; |
| 41 const String _sharedPlatform = "lib/dart_shared.platform"; | 42 const String _sharedPlatform = "lib/dart_shared.platform"; |
| 42 const String _dart2dartPlatform = "lib/dart2dart.platform"; | 43 const String _dart2dartPlatform = "lib/dart2dart.platform"; |
| 43 | 44 |
| 44 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the | 45 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the |
| 45 /// sources. | 46 /// sources. |
| 46 class CompilerImpl extends Compiler { | 47 class CompilerImpl extends Compiler { |
| 47 api.CompilerInput provider; | 48 // Constructor must be first to ensure [Measurer] is instantiated before |
| 48 api.CompilerDiagnostics handler; | 49 // other computations. |
| 49 final Uri platformConfigUri; | |
| 50 final Uri packageConfig; | |
| 51 final Uri packageRoot; | |
| 52 final api.PackagesDiscoveryProvider packagesDiscoveryProvider; | |
| 53 Packages packages; | |
| 54 List<String> options; | |
| 55 Map<String, dynamic> environment; | |
| 56 bool mockableLibraryUsed = false; | |
| 57 | |
| 58 /// A mapping of the dart: library-names to their location. | |
| 59 /// | |
| 60 /// Initialized in [setupSdk]. | |
| 61 Map<String, Uri> sdkLibraries; | |
| 62 | |
| 63 GenericTask userHandlerTask; | |
| 64 GenericTask userProviderTask; | |
| 65 GenericTask userPackagesDiscoveryTask; | |
| 66 | |
| 67 Uri get libraryRoot => platformConfigUri.resolve("."); | |
| 68 | |
| 69 CompilerImpl(this.provider, | 50 CompilerImpl(this.provider, |
| 70 api.CompilerOutput outputProvider, | 51 api.CompilerOutput outputProvider, |
| 71 this.handler, | 52 this.handler, |
| 72 Uri libraryRoot, | 53 Uri libraryRoot, |
| 73 this.packageRoot, | 54 this.packageRoot, |
| 74 List<String> options, | 55 List<String> options, |
| 75 this.environment, | 56 this.environment, |
| 76 [this.packageConfig, | 57 [this.packageConfig, |
| 77 this.packagesDiscoveryProvider, | 58 this.packagesDiscoveryProvider, |
| 78 Backend makeBackend(Compiler compiler)]) | 59 Backend makeBackend(Compiler compiler), |
| 79 : this.options = options, | 60 Measurer measurer]) |
| 80 this.platformConfigUri = resolvePlatformConfig(libraryRoot, options), | 61 : super( // Call super first to ensure Measurer is instantiated first. |
|
floitsch
2016/01/07 14:40:39
Tbh I would prefer if super stays last, and you ju
ahe
2016/01/08 09:02:01
Code removed, but FWIW, I can't use a factory cons
| |
| 81 super( | 62 measurer: measurer == null ? new Measurer() : measurer, |
|
floitsch
2016/01/07 14:40:39
measurer ?? new Measurer()
ahe
2016/01/08 09:02:01
Code removed.
| |
| 82 outputProvider: outputProvider, | 63 outputProvider: outputProvider, |
| 83 enableTypeAssertions: hasOption(options, Flags.enableCheckedMode), | 64 enableTypeAssertions: hasOption(options, Flags.enableCheckedMode), |
| 84 enableUserAssertions: hasOption(options, Flags.enableCheckedMode), | 65 enableUserAssertions: hasOption(options, Flags.enableCheckedMode), |
| 85 trustTypeAnnotations: | 66 trustTypeAnnotations: |
| 86 hasOption(options, Flags.trustTypeAnnotations), | 67 hasOption(options, Flags.trustTypeAnnotations), |
| 87 trustPrimitives: | 68 trustPrimitives: |
| 88 hasOption(options, Flags.trustPrimitives), | 69 hasOption(options, Flags.trustPrimitives), |
| 89 enableMinification: hasOption(options, Flags.minify), | 70 enableMinification: hasOption(options, Flags.minify), |
| 90 useFrequencyNamer: | 71 useFrequencyNamer: |
| 91 !hasOption(options, Flags.noFrequencyBasedMinification), | 72 !hasOption(options, Flags.noFrequencyBasedMinification), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 hasOption(options, Flags.showPackageWarnings)), | 110 hasOption(options, Flags.showPackageWarnings)), |
| 130 enableExperimentalMirrors: | 111 enableExperimentalMirrors: |
| 131 hasOption(options, Flags.enableExperimentalMirrors), | 112 hasOption(options, Flags.enableExperimentalMirrors), |
| 132 enableAssertMessage: | 113 enableAssertMessage: |
| 133 hasOption(options, Flags.enableAssertMessage), | 114 hasOption(options, Flags.enableAssertMessage), |
| 134 generateCodeWithCompileTimeErrors: | 115 generateCodeWithCompileTimeErrors: |
| 135 hasOption(options, Flags.generateCodeWithCompileTimeErrors), | 116 hasOption(options, Flags.generateCodeWithCompileTimeErrors), |
| 136 testMode: hasOption(options, Flags.testMode), | 117 testMode: hasOption(options, Flags.testMode), |
| 137 allowNativeExtensions: | 118 allowNativeExtensions: |
| 138 hasOption(options, Flags.allowNativeExtensions), | 119 hasOption(options, Flags.allowNativeExtensions), |
| 139 makeBackend: makeBackend) { | 120 makeBackend: makeBackend), |
| 121 this.options = options, | |
| 122 this.platformConfigUri = resolvePlatformConfig(libraryRoot, options) { | |
| 140 tasks.addAll([ | 123 tasks.addAll([ |
| 141 userHandlerTask = new GenericTask('Diagnostic handler', this), | 124 userHandlerTask = new GenericTask('Diagnostic handler', this), |
| 142 userProviderTask = new GenericTask('Input provider', this), | 125 userProviderTask = new GenericTask('Input provider', this), |
| 143 userPackagesDiscoveryTask = | 126 userPackagesDiscoveryTask = |
| 144 new GenericTask('Package discovery', this), | 127 new GenericTask('Package discovery', this), |
| 145 ]); | 128 ]); |
| 146 if (libraryRoot == null) { | 129 if (libraryRoot == null) { |
| 147 throw new ArgumentError("[libraryRoot] is null."); | 130 throw new ArgumentError("[libraryRoot] is null."); |
| 148 } | 131 } |
| 149 if (!libraryRoot.path.endsWith("/")) { | 132 if (!libraryRoot.path.endsWith("/")) { |
| 150 throw new ArgumentError("[libraryRoot] must end with a /."); | 133 throw new ArgumentError("[libraryRoot] must end with a /."); |
| 151 } | 134 } |
| 152 if (packageRoot != null && packageConfig != null) { | 135 if (packageRoot != null && packageConfig != null) { |
| 153 throw new ArgumentError("Only one of [packageRoot] or [packageConfig] " | 136 throw new ArgumentError("Only one of [packageRoot] or [packageConfig] " |
| 154 "may be given."); | 137 "may be given."); |
| 155 } | 138 } |
| 156 if (packageRoot != null && !packageRoot.path.endsWith("/")) { | 139 if (packageRoot != null && !packageRoot.path.endsWith("/")) { |
| 157 throw new ArgumentError("[packageRoot] must end with a /."); | 140 throw new ArgumentError("[packageRoot] must end with a /."); |
| 158 } | 141 } |
| 159 if (!analyzeOnly) { | 142 if (!analyzeOnly) { |
| 160 if (allowNativeExtensions) { | 143 if (allowNativeExtensions) { |
| 161 throw new ArgumentError( | 144 throw new ArgumentError( |
| 162 "${Flags.allowNativeExtensions} is only supported in combination " | 145 "${Flags.allowNativeExtensions} is only supported in combination " |
| 163 "with ${Flags.analyzeOnly}"); | 146 "with ${Flags.analyzeOnly}"); |
| 164 } | 147 } |
| 165 } | 148 } |
| 166 } | 149 } |
| 167 | 150 |
| 151 api.CompilerInput provider; | |
| 152 api.CompilerDiagnostics handler; | |
| 153 final Uri platformConfigUri; | |
| 154 final Uri packageConfig; | |
| 155 final Uri packageRoot; | |
| 156 final api.PackagesDiscoveryProvider packagesDiscoveryProvider; | |
| 157 Packages packages; | |
| 158 List<String> options; | |
| 159 Map<String, dynamic> environment; | |
| 160 bool mockableLibraryUsed = false; | |
| 161 | |
| 162 /// A mapping of the dart: library-names to their location. | |
| 163 /// | |
| 164 /// Initialized in [setupSdk]. | |
| 165 Map<String, Uri> sdkLibraries; | |
| 166 | |
| 167 GenericTask userHandlerTask; | |
| 168 GenericTask userProviderTask; | |
| 169 GenericTask userPackagesDiscoveryTask; | |
| 170 | |
| 171 Uri get libraryRoot => platformConfigUri.resolve("."); | |
| 172 | |
| 168 static String extractStringOption(List<String> options, | 173 static String extractStringOption(List<String> options, |
| 169 String prefix, | 174 String prefix, |
| 170 String defaultValue) { | 175 String defaultValue) { |
| 171 for (String option in options) { | 176 for (String option in options) { |
| 172 if (option.startsWith(prefix)) { | 177 if (option.startsWith(prefix)) { |
| 173 return option.substring(prefix.length); | 178 return option.substring(prefix.length); |
| 174 } | 179 } |
| 175 } | 180 } |
| 176 return defaultValue; | 181 return defaultValue; |
| 177 } | 182 } |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 node, | 409 node, |
| 405 MessageKind.LIBRARY_NOT_FOUND, | 410 MessageKind.LIBRARY_NOT_FOUND, |
| 406 {'resolvedUri': uri}); | 411 {'resolvedUri': uri}); |
| 407 return null; | 412 return null; |
| 408 }); | 413 }); |
| 409 } | 414 } |
| 410 | 415 |
| 411 Future<elements.LibraryElement> analyzeUri( | 416 Future<elements.LibraryElement> analyzeUri( |
| 412 Uri uri, | 417 Uri uri, |
| 413 {bool skipLibraryWithPartOfTag: true}) { | 418 {bool skipLibraryWithPartOfTag: true}) { |
| 414 List<Future> setupFutures = new List<Future>(); | 419 return new Future(() => (sdkLibraries == null) ? setupSdk() : null) |
| 415 if (sdkLibraries == null) { | 420 .then((_) => packages == null ? setupPackages(uri) : null) |
| 416 setupFutures.add(setupSdk()); | 421 .then((_) => super.analyzeUri(uri)); |
| 417 } | |
| 418 if (packages == null) { | |
| 419 setupFutures.add(setupPackages(uri)); | |
| 420 } | |
| 421 return Future.wait(setupFutures).then((_) => super.analyzeUri(uri)); | |
| 422 } | 422 } |
| 423 | 423 |
| 424 Future setupPackages(Uri uri) { | 424 Future setupPackages(Uri uri) { |
| 425 if (packageRoot != null) { | 425 if (packageRoot != null) { |
| 426 // Use "non-file" packages because the file version requires a [Directory] | 426 // Use "non-file" packages because the file version requires a [Directory] |
| 427 // and we can't depend on 'dart:io' classes. | 427 // and we can't depend on 'dart:io' classes. |
| 428 packages = new NonFilePackagesDirectoryPackages(packageRoot); | 428 packages = new NonFilePackagesDirectoryPackages(packageRoot); |
| 429 } else if (packageConfig != null) { | 429 } else if (packageConfig != null) { |
| 430 return callUserProvider(packageConfig).then((packageConfigContents) { | 430 return callUserProvider(packageConfig).then((packageConfigContents) { |
| 431 if (packageConfigContents is String) { | 431 if (packageConfigContents is String) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 466 sdkLibraries = mapping; | 466 sdkLibraries = mapping; |
| 467 }); | 467 }); |
| 468 } else { | 468 } else { |
| 469 // The incremental compiler sets up the sdk before run. | 469 // The incremental compiler sets up the sdk before run. |
| 470 // Therefore this will be called a second time. | 470 // Therefore this will be called a second time. |
| 471 return new Future.value(null); | 471 return new Future.value(null); |
| 472 } | 472 } |
| 473 } | 473 } |
| 474 | 474 |
| 475 Future<bool> run(Uri uri) { | 475 Future<bool> run(Uri uri) { |
| 476 log('Using platform configuration at ${platformConfigUri}'); | 476 Duration setupDuration = measurer.wallClock.elapsed; |
| 477 return selfTask.measureSubtask("CompilerImpl.run", () { | |
| 478 log('Using platform configuration at ${platformConfigUri}'); | |
| 477 | 479 |
| 478 return Future.wait([setupSdk(), setupPackages(uri)]).then((_) { | 480 return setupSdk().then((_) => setupPackages(uri)).then((_) { |
| 479 assert(sdkLibraries != null); | 481 assert(sdkLibraries != null); |
| 480 assert(packages != null); | 482 assert(packages != null); |
| 481 | 483 return super.run(uri); |
| 482 return super.run(uri).then((bool success) { | 484 }).then((bool success) { |
| 483 int cumulated = 0; | 485 StringBuffer timings = new StringBuffer(); |
| 486 timings.writeln("Timings:"); | |
| 487 Duration totalDuration = measurer.wallClock.elapsed; | |
| 488 Duration asyncDuration = measurer.asyncWallClock.elapsed; | |
| 489 Duration cumulatedDuration = Duration.ZERO; | |
| 484 for (final task in tasks) { | 490 for (final task in tasks) { |
| 485 int elapsed = task.timing; | 491 String running = task.isRunning ? "*" : ""; |
| 486 if (elapsed != 0) { | 492 Duration duration = task.duration; |
| 487 cumulated += elapsed; | 493 if (duration != Duration.ZERO) { |
| 488 log('${task.name} took ${elapsed}msec'); | 494 cumulatedDuration += duration; |
| 495 timings.writeln( | |
| 496 ' $running${task.name} took' | |
| 497 ' ${duration.inMilliseconds}msec'); | |
| 489 for (String subtask in task.subtasks) { | 498 for (String subtask in task.subtasks) { |
| 490 int subtime = task.getSubtaskTime(subtask); | 499 int subtime = task.getSubtaskTime(subtask); |
| 491 log('${task.name} > $subtask took ${subtime}msec'); | 500 String running = task.getSubtaskIsRunning(subtask) ? "*" : ""; |
| 501 timings.writeln( | |
| 502 ' $running${task.name} > $subtask took ${subtime}msec'); | |
| 492 } | 503 } |
| 493 } | 504 } |
| 494 } | 505 } |
| 495 int total = totalCompileTime.elapsedMilliseconds; | 506 Duration unaccountedDuration = |
| 496 log('Total compile-time ${total}msec;' | 507 totalDuration - cumulatedDuration - setupDuration - asyncDuration; |
| 497 ' unaccounted ${total - cumulated}msec'); | 508 Double percent = unaccountedDuration.inMilliseconds * 100 |
|
floitsch
2016/01/07 14:40:39
double is lower case.
ahe
2016/01/08 09:02:02
Done.
| |
| 509 / totalDuration.inMilliseconds; | |
| 510 timings.write( | |
| 511 ' Total compile-time ${totalDuration.inMilliseconds}msec;' | |
| 512 ' setup ${setupDuration.inMilliseconds}msec;' | |
| 513 ' async ${asyncDuration.inMilliseconds}msec;' | |
| 514 ' unaccounted ${unaccountedDuration.inMilliseconds}msec' | |
| 515 ' (${percent.toStringAsFixed(2)}%)'); | |
| 516 log("$timings"); | |
| 498 return success; | 517 return success; |
| 499 }); | 518 }); |
| 500 }); | 519 }); |
| 501 } | 520 } |
| 502 | 521 |
| 503 void reportDiagnostic(DiagnosticMessage message, | 522 void reportDiagnostic(DiagnosticMessage message, |
| 504 List<DiagnosticMessage> infos, | 523 List<DiagnosticMessage> infos, |
| 505 api.Diagnostic kind) { | 524 api.Diagnostic kind) { |
| 506 _reportDiagnosticMessage(message, kind); | 525 _reportDiagnosticMessage(message, kind); |
| 507 for (DiagnosticMessage info in infos) { | 526 for (DiagnosticMessage info in infos) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 536 }); | 555 }); |
| 537 } catch (ex, s) { | 556 } catch (ex, s) { |
| 538 diagnoseCrashInUserCode( | 557 diagnoseCrashInUserCode( |
| 539 'Uncaught exception in diagnostic handler', ex, s); | 558 'Uncaught exception in diagnostic handler', ex, s); |
| 540 rethrow; | 559 rethrow; |
| 541 } | 560 } |
| 542 } | 561 } |
| 543 | 562 |
| 544 Future callUserProvider(Uri uri) { | 563 Future callUserProvider(Uri uri) { |
| 545 try { | 564 try { |
| 546 return userProviderTask.measure(() => provider.readFromUri(uri)); | 565 return userProviderTask.measureIo(() => provider.readFromUri(uri)); |
| 547 } catch (ex, s) { | 566 } catch (ex, s) { |
| 548 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s); | 567 diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s); |
| 549 rethrow; | 568 rethrow; |
| 550 } | 569 } |
| 551 } | 570 } |
| 552 | 571 |
| 553 Future<Packages> callUserPackagesDiscovery(Uri uri) { | 572 Future<Packages> callUserPackagesDiscovery(Uri uri) { |
| 554 try { | 573 try { |
| 555 return userPackagesDiscoveryTask.measure( | 574 return userPackagesDiscoveryTask.measureIo( |
| 556 () => packagesDiscoveryProvider(uri)); | 575 () => packagesDiscoveryProvider(uri)); |
| 557 } catch (ex, s) { | 576 } catch (ex, s) { |
| 558 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s); | 577 diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s); |
| 559 rethrow; | 578 rethrow; |
| 560 } | 579 } |
| 561 } | 580 } |
| 562 | 581 |
| 563 fromEnvironment(String name) => environment[name]; | 582 fromEnvironment(String name) => environment[name]; |
| 564 | 583 |
| 565 Uri lookupLibraryUri(String libraryName) { | 584 Uri lookupLibraryUri(String libraryName) { |
| 566 assert(invariant(NO_LOCATION_SPANNABLE, | 585 assert(invariant(NO_LOCATION_SPANNABLE, |
| 567 sdkLibraries != null, message: "setupSdk() has not been run")); | 586 sdkLibraries != null, message: "setupSdk() has not been run")); |
| 568 return sdkLibraries[libraryName]; | 587 return sdkLibraries[libraryName]; |
| 569 } | 588 } |
| 570 | 589 |
| 571 Uri resolvePatchUri(String libraryName) { | 590 Uri resolvePatchUri(String libraryName) { |
| 572 return backend.resolvePatchUri(libraryName, platformConfigUri); | 591 return backend.resolvePatchUri(libraryName, platformConfigUri); |
| 573 } | 592 } |
| 574 } | 593 } |
| OLD | NEW |