| 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 dart2js.compiler_base; | 5 library dart2js.compiler_base; |
| 6 | 6 |
| 7 import 'dart:async' show | 7 import 'dart:async' show |
| 8 EventSink, | 8 EventSink, |
| 9 Future; | 9 Future; |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 import 'common/registry.dart' show | 25 import 'common/registry.dart' show |
| 26 EagerRegistry, | 26 EagerRegistry, |
| 27 Registry; | 27 Registry; |
| 28 import 'common/resolution.dart' show | 28 import 'common/resolution.dart' show |
| 29 Parsing, | 29 Parsing, |
| 30 Resolution, | 30 Resolution, |
| 31 ResolutionWorkItem, | 31 ResolutionWorkItem, |
| 32 ResolutionImpact; | 32 ResolutionImpact; |
| 33 import 'common/tasks.dart' show | 33 import 'common/tasks.dart' show |
| 34 CompilerTask, | 34 CompilerTask, |
| 35 GenericTask; | 35 GenericTask, |
| 36 Measurer; |
| 36 import 'common/work.dart' show | 37 import 'common/work.dart' show |
| 37 WorkItem; | 38 WorkItem; |
| 38 import 'compile_time_constants.dart'; | 39 import 'compile_time_constants.dart'; |
| 39 import 'constants/values.dart'; | 40 import 'constants/values.dart'; |
| 40 import 'core_types.dart' show | 41 import 'core_types.dart' show |
| 41 CoreClasses, | 42 CoreClasses, |
| 42 CoreTypes; | 43 CoreTypes; |
| 43 import 'dart_backend/dart_backend.dart' as dart_backend; | 44 import 'dart_backend/dart_backend.dart' as dart_backend; |
| 44 import 'dart_types.dart' show | 45 import 'dart_types.dart' show |
| 45 DartType, | 46 DartType, |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 StaticUse; | 139 StaticUse; |
| 139 import 'universe/world_impact.dart' show | 140 import 'universe/world_impact.dart' show |
| 140 WorldImpact; | 141 WorldImpact; |
| 141 import 'util/util.dart' show | 142 import 'util/util.dart' show |
| 142 Link, | 143 Link, |
| 143 Setlet; | 144 Setlet; |
| 144 import 'world.dart' show | 145 import 'world.dart' show |
| 145 World; | 146 World; |
| 146 | 147 |
| 147 abstract class Compiler { | 148 abstract class Compiler { |
| 149 // Constructor must be first to ensure [Measurer] is instantiated before |
| 150 // other computations. |
| 151 Compiler({this.enableTypeAssertions: false, |
| 152 this.enableUserAssertions: false, |
| 153 this.trustTypeAnnotations: false, |
| 154 this.trustPrimitives: false, |
| 155 bool disableTypeInferenceFlag: false, |
| 156 this.maxConcreteTypeSize: 5, |
| 157 this.enableMinification: false, |
| 158 this.preserveUris: false, |
| 159 this.enableNativeLiveTypeAnalysis: false, |
| 160 bool emitJavaScript: true, |
| 161 bool dart2dartMultiFile: false, |
| 162 bool generateSourceMap: true, |
| 163 bool analyzeAllFlag: false, |
| 164 bool analyzeOnly: false, |
| 165 this.analyzeMain: false, |
| 166 bool analyzeSignaturesOnly: false, |
| 167 this.preserveComments: false, |
| 168 this.useCpsIr: false, |
| 169 this.useFrequencyNamer: false, |
| 170 this.verbose: false, |
| 171 this.sourceMapUri: null, |
| 172 this.outputUri: null, |
| 173 this.buildId: UNDETERMINED_BUILD_ID, |
| 174 this.deferredMapUri: null, |
| 175 this.dumpInfo: false, |
| 176 bool useStartupEmitter: false, |
| 177 this.useContentSecurityPolicy: false, |
| 178 bool hasIncrementalSupport: false, |
| 179 this.enableExperimentalMirrors: false, |
| 180 this.enableAssertMessage: false, |
| 181 this.allowNativeExtensions: false, |
| 182 this.generateCodeWithCompileTimeErrors: false, |
| 183 this.testMode: false, |
| 184 DiagnosticOptions diagnosticOptions, |
| 185 api.CompilerOutput outputProvider, |
| 186 List<String> strips: const [], |
| 187 Backend makeBackend(Compiler compiler), |
| 188 Measurer measurer}) |
| 189 : this.measurer = measurer == null ? new Measurer() : measurer, |
| 190 this.disableTypeInferenceFlag = |
| 191 disableTypeInferenceFlag || !emitJavaScript, |
| 192 this.analyzeOnly = |
| 193 analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag, |
| 194 this.analyzeSignaturesOnly = analyzeSignaturesOnly, |
| 195 this.analyzeAllFlag = analyzeAllFlag, |
| 196 this.hasIncrementalSupport = hasIncrementalSupport, |
| 197 cacheStrategy = new CacheStrategy(hasIncrementalSupport), |
| 198 this.userOutputProvider = outputProvider == null |
| 199 ? const NullCompilerOutput() : outputProvider { |
| 200 if (hasIncrementalSupport) { |
| 201 // TODO(ahe): This is too much. Any method from platform and package |
| 202 // libraries can be inlined. |
| 203 disableInlining = true; |
| 204 } |
| 205 world = new World(this); |
| 206 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and |
| 207 // make its field final. |
| 208 _reporter = new _CompilerDiagnosticReporter(this, diagnosticOptions); |
| 209 _parsing = new _CompilerParsing(this); |
| 210 _resolution = new _CompilerResolution(this); |
| 211 _coreTypes = new _CompilerCoreTypes(_resolution); |
| 212 types = new Types(_resolution); |
| 213 tracer = new Tracer(this, this.outputProvider); |
| 148 | 214 |
| 149 final Stopwatch totalCompileTime = new Stopwatch(); | 215 if (verbose) { |
| 216 progress = new Stopwatch()..start(); |
| 217 } |
| 218 |
| 219 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing |
| 220 // for global dependencies. |
| 221 globalDependencies = new GlobalDependencyRegistry(this); |
| 222 |
| 223 if (makeBackend != null) { |
| 224 backend = makeBackend(this); |
| 225 } else if (emitJavaScript) { |
| 226 js_backend.JavaScriptBackend jsBackend = |
| 227 new js_backend.JavaScriptBackend( |
| 228 this, generateSourceMap: generateSourceMap, |
| 229 useStartupEmitter: useStartupEmitter); |
| 230 backend = jsBackend; |
| 231 } else { |
| 232 backend = new dart_backend.DartBackend(this, strips, |
| 233 multiFile: dart2dartMultiFile); |
| 234 if (dumpInfo) { |
| 235 throw new ArgumentError('--dump-info is not supported for dart2dart.'); |
| 236 } |
| 237 } |
| 238 |
| 239 tasks = [ |
| 240 libraryLoader = new LibraryLoaderTask(this), |
| 241 serialization = new SerializationTask(this), |
| 242 scanner = new ScannerTask(this), |
| 243 dietParser = new DietParserTask(this), |
| 244 parser = new ParserTask(this), |
| 245 patchParser = new PatchParserTask(this), |
| 246 resolver = new ResolverTask(this, backend.constantCompilerTask), |
| 247 closureToClassMapper = new closureMapping.ClosureTask(this), |
| 248 checker = new TypeCheckerTask(this), |
| 249 typesTask = new ti.TypesTask(this), |
| 250 constants = backend.constantCompilerTask, |
| 251 deferredLoadTask = new DeferredLoadTask(this), |
| 252 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), |
| 253 enqueuer = backend.makeEnqueuer(), |
| 254 dumpInfoTask = new DumpInfoTask(this), |
| 255 reuseLibraryTask = new GenericTask('Reuse library', this), |
| 256 selfTask = new GenericTask('self', this), |
| 257 ]; |
| 258 |
| 259 tasks.addAll(backend.tasks); |
| 260 } |
| 261 |
| 262 /// Helper instance for measurements in [CompilerTask]. |
| 263 final Measurer measurer; |
| 264 |
| 150 int nextFreeClassId = 0; | 265 int nextFreeClassId = 0; |
| 151 World world; | 266 World world; |
| 152 Types types; | 267 Types types; |
| 153 _CompilerCoreTypes _coreTypes; | 268 _CompilerCoreTypes _coreTypes; |
| 154 _CompilerDiagnosticReporter _reporter; | 269 _CompilerDiagnosticReporter _reporter; |
| 155 _CompilerResolution _resolution; | 270 _CompilerResolution _resolution; |
| 156 _CompilerParsing _parsing; | 271 _CompilerParsing _parsing; |
| 157 | 272 |
| 158 final CacheStrategy cacheStrategy; | 273 final CacheStrategy cacheStrategy; |
| 159 | 274 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 383 |
| 269 List<Uri> librariesToAnalyzeWhenRun; | 384 List<Uri> librariesToAnalyzeWhenRun; |
| 270 | 385 |
| 271 /// The set of platform libraries reported as unsupported. | 386 /// The set of platform libraries reported as unsupported. |
| 272 /// | 387 /// |
| 273 /// For instance when importing 'dart:io' without '--categories=Server'. | 388 /// For instance when importing 'dart:io' without '--categories=Server'. |
| 274 Set<Uri> disallowedLibraryUris = new Setlet<Uri>(); | 389 Set<Uri> disallowedLibraryUris = new Setlet<Uri>(); |
| 275 | 390 |
| 276 Tracer tracer; | 391 Tracer tracer; |
| 277 | 392 |
| 278 CompilerTask measuredTask; | |
| 279 LibraryElement coreLibrary; | 393 LibraryElement coreLibrary; |
| 280 LibraryElement asyncLibrary; | 394 LibraryElement asyncLibrary; |
| 281 | 395 |
| 282 LibraryElement mainApp; | 396 LibraryElement mainApp; |
| 283 FunctionElement mainFunction; | 397 FunctionElement mainFunction; |
| 284 | 398 |
| 285 /// Initialized when dart:mirrors is loaded. | 399 /// Initialized when dart:mirrors is loaded. |
| 286 LibraryElement mirrorsLibrary; | 400 LibraryElement mirrorsLibrary; |
| 287 | 401 |
| 288 /// Initialized when dart:typed_data is loaded. | 402 /// Initialized when dart:typed_data is loaded. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 LibraryLoaderTask libraryLoader; | 475 LibraryLoaderTask libraryLoader; |
| 362 SerializationTask serialization; | 476 SerializationTask serialization; |
| 363 ResolverTask resolver; | 477 ResolverTask resolver; |
| 364 closureMapping.ClosureTask closureToClassMapper; | 478 closureMapping.ClosureTask closureToClassMapper; |
| 365 TypeCheckerTask checker; | 479 TypeCheckerTask checker; |
| 366 ti.TypesTask typesTask; | 480 ti.TypesTask typesTask; |
| 367 Backend backend; | 481 Backend backend; |
| 368 | 482 |
| 369 GenericTask reuseLibraryTask; | 483 GenericTask reuseLibraryTask; |
| 370 | 484 |
| 485 GenericTask selfTask; |
| 486 |
| 371 /// The constant environment for the frontend interpretation of compile-time | 487 /// The constant environment for the frontend interpretation of compile-time |
| 372 /// constants. | 488 /// constants. |
| 373 ConstantEnvironment constants; | 489 ConstantEnvironment constants; |
| 374 | 490 |
| 375 EnqueueTask enqueuer; | 491 EnqueueTask enqueuer; |
| 376 DeferredLoadTask deferredLoadTask; | 492 DeferredLoadTask deferredLoadTask; |
| 377 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 493 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
| 378 DumpInfoTask dumpInfoTask; | 494 DumpInfoTask dumpInfoTask; |
| 379 String buildId; | 495 String buildId; |
| 380 | 496 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 407 static const int PHASE_RESOLVING = 1; | 523 static const int PHASE_RESOLVING = 1; |
| 408 static const int PHASE_DONE_RESOLVING = 2; | 524 static const int PHASE_DONE_RESOLVING = 2; |
| 409 static const int PHASE_COMPILING = 3; | 525 static const int PHASE_COMPILING = 3; |
| 410 int phase; | 526 int phase; |
| 411 | 527 |
| 412 bool compilationFailed = false; | 528 bool compilationFailed = false; |
| 413 | 529 |
| 414 /// Set by the backend if real reflection is detected in use of dart:mirrors. | 530 /// Set by the backend if real reflection is detected in use of dart:mirrors. |
| 415 bool disableTypeInferenceForMirrors = false; | 531 bool disableTypeInferenceForMirrors = false; |
| 416 | 532 |
| 417 Compiler({this.enableTypeAssertions: false, | |
| 418 this.enableUserAssertions: false, | |
| 419 this.trustTypeAnnotations: false, | |
| 420 this.trustPrimitives: false, | |
| 421 bool disableTypeInferenceFlag: false, | |
| 422 this.maxConcreteTypeSize: 5, | |
| 423 this.enableMinification: false, | |
| 424 this.preserveUris: false, | |
| 425 this.enableNativeLiveTypeAnalysis: false, | |
| 426 bool emitJavaScript: true, | |
| 427 bool dart2dartMultiFile: false, | |
| 428 bool generateSourceMap: true, | |
| 429 bool analyzeAllFlag: false, | |
| 430 bool analyzeOnly: false, | |
| 431 this.analyzeMain: false, | |
| 432 bool analyzeSignaturesOnly: false, | |
| 433 this.preserveComments: false, | |
| 434 this.useCpsIr: false, | |
| 435 this.useFrequencyNamer: false, | |
| 436 this.verbose: false, | |
| 437 this.sourceMapUri: null, | |
| 438 this.outputUri: null, | |
| 439 this.buildId: UNDETERMINED_BUILD_ID, | |
| 440 this.deferredMapUri: null, | |
| 441 this.dumpInfo: false, | |
| 442 bool useStartupEmitter: false, | |
| 443 this.useContentSecurityPolicy: false, | |
| 444 bool hasIncrementalSupport: false, | |
| 445 this.enableExperimentalMirrors: false, | |
| 446 this.enableAssertMessage: false, | |
| 447 this.allowNativeExtensions: false, | |
| 448 this.generateCodeWithCompileTimeErrors: false, | |
| 449 this.testMode: false, | |
| 450 DiagnosticOptions diagnosticOptions, | |
| 451 api.CompilerOutput outputProvider, | |
| 452 List<String> strips: const [], | |
| 453 Backend makeBackend(Compiler compiler)}) | |
| 454 : this.disableTypeInferenceFlag = | |
| 455 disableTypeInferenceFlag || !emitJavaScript, | |
| 456 this.analyzeOnly = | |
| 457 analyzeOnly || analyzeSignaturesOnly || analyzeAllFlag, | |
| 458 this.analyzeSignaturesOnly = analyzeSignaturesOnly, | |
| 459 this.analyzeAllFlag = analyzeAllFlag, | |
| 460 this.hasIncrementalSupport = hasIncrementalSupport, | |
| 461 cacheStrategy = new CacheStrategy(hasIncrementalSupport), | |
| 462 this.userOutputProvider = outputProvider == null | |
| 463 ? const NullCompilerOutput() : outputProvider { | |
| 464 if (hasIncrementalSupport) { | |
| 465 // TODO(ahe): This is too much. Any method from platform and package | |
| 466 // libraries can be inlined. | |
| 467 disableInlining = true; | |
| 468 } | |
| 469 world = new World(this); | |
| 470 // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and | |
| 471 // make its field final. | |
| 472 _reporter = new _CompilerDiagnosticReporter(this, diagnosticOptions); | |
| 473 _parsing = new _CompilerParsing(this); | |
| 474 _resolution = new _CompilerResolution(this); | |
| 475 _coreTypes = new _CompilerCoreTypes(_resolution); | |
| 476 types = new Types(_resolution); | |
| 477 tracer = new Tracer(this, this.outputProvider); | |
| 478 | |
| 479 if (verbose) { | |
| 480 progress = new Stopwatch()..start(); | |
| 481 } | |
| 482 | |
| 483 // TODO(johnniwinther): Separate the dependency tracking from the enqueuing | |
| 484 // for global dependencies. | |
| 485 globalDependencies = new GlobalDependencyRegistry(this); | |
| 486 | |
| 487 if (makeBackend != null) { | |
| 488 backend = makeBackend(this); | |
| 489 } else if (emitJavaScript) { | |
| 490 js_backend.JavaScriptBackend jsBackend = | |
| 491 new js_backend.JavaScriptBackend( | |
| 492 this, generateSourceMap: generateSourceMap, | |
| 493 useStartupEmitter: useStartupEmitter); | |
| 494 backend = jsBackend; | |
| 495 } else { | |
| 496 backend = new dart_backend.DartBackend(this, strips, | |
| 497 multiFile: dart2dartMultiFile); | |
| 498 if (dumpInfo) { | |
| 499 throw new ArgumentError('--dump-info is not supported for dart2dart.'); | |
| 500 } | |
| 501 } | |
| 502 | |
| 503 tasks = [ | |
| 504 libraryLoader = new LibraryLoaderTask(this), | |
| 505 serialization = new SerializationTask(this), | |
| 506 scanner = new ScannerTask(this), | |
| 507 dietParser = new DietParserTask(this), | |
| 508 parser = new ParserTask(this), | |
| 509 patchParser = new PatchParserTask(this), | |
| 510 resolver = new ResolverTask(this, backend.constantCompilerTask), | |
| 511 closureToClassMapper = new closureMapping.ClosureTask(this), | |
| 512 checker = new TypeCheckerTask(this), | |
| 513 typesTask = new ti.TypesTask(this), | |
| 514 constants = backend.constantCompilerTask, | |
| 515 deferredLoadTask = new DeferredLoadTask(this), | |
| 516 mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this), | |
| 517 enqueuer = backend.makeEnqueuer(), | |
| 518 dumpInfoTask = new DumpInfoTask(this), | |
| 519 reuseLibraryTask = new GenericTask('Reuse library', this), | |
| 520 ]; | |
| 521 | |
| 522 tasks.addAll(backend.tasks); | |
| 523 } | |
| 524 | |
| 525 Universe get resolverWorld => enqueuer.resolution.universe; | 533 Universe get resolverWorld => enqueuer.resolution.universe; |
| 526 Universe get codegenWorld => enqueuer.codegen.universe; | 534 Universe get codegenWorld => enqueuer.codegen.universe; |
| 527 | 535 |
| 528 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; | 536 bool get hasBuildId => buildId != UNDETERMINED_BUILD_ID; |
| 529 | 537 |
| 530 bool get analyzeAll => analyzeAllFlag || compileAll; | 538 bool get analyzeAll => analyzeAllFlag || compileAll; |
| 531 | 539 |
| 532 bool get compileAll => false; | 540 bool get compileAll => false; |
| 533 | 541 |
| 534 bool get disableTypeInference { | 542 bool get disableTypeInference { |
| 535 return disableTypeInferenceFlag || compilationFailed; | 543 return disableTypeInferenceFlag || compilationFailed; |
| 536 } | 544 } |
| 537 | 545 |
| 538 int getNextFreeClassId() => nextFreeClassId++; | 546 int getNextFreeClassId() => nextFreeClassId++; |
| 539 | 547 |
| 540 void unimplemented(Spannable spannable, String methodName) { | 548 void unimplemented(Spannable spannable, String methodName) { |
| 541 reporter.internalError(spannable, "$methodName not implemented."); | 549 reporter.internalError(spannable, "$methodName not implemented."); |
| 542 } | 550 } |
| 543 | 551 |
| 544 // Compiles the dart script at [uri]. | 552 // Compiles the dart script at [uri]. |
| 545 // | 553 // |
| 546 // The resulting future will complete with true if the compilation | 554 // The resulting future will complete with true if the compilation |
| 547 // succeded. | 555 // succeded. |
| 548 Future<bool> run(Uri uri) { | 556 Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () { |
| 549 totalCompileTime.start(); | 557 measurer.startWallClock(); |
| 550 | 558 |
| 551 return new Future.sync(() => runInternal(uri)) | 559 return new Future.sync(() => runInternal(uri)) |
| 552 .catchError((error) => _reporter.onError(uri, error)) | 560 .catchError((error) => _reporter.onError(uri, error)) |
| 553 .whenComplete(() { | 561 .whenComplete(() { |
| 554 tracer.close(); | 562 tracer.close(); |
| 555 totalCompileTime.stop(); | 563 measurer.stopWallClock(); |
| 556 }).then((_) { | 564 }).then((_) { |
| 557 return !compilationFailed; | 565 return !compilationFailed; |
| 558 }); | 566 }); |
| 559 } | 567 }); |
| 560 | 568 |
| 561 /// This method is called immediately after the [LibraryElement] [library] has | 569 /// This method is called immediately after the [LibraryElement] [library] has |
| 562 /// been created. | 570 /// been created. |
| 563 /// | 571 /// |
| 564 /// Use this callback method to store references to specific libraries. | 572 /// Use this callback method to store references to specific libraries. |
| 565 /// Note that [library] has not been scanned yet, nor has its imports/exports | 573 /// Note that [library] has not been scanned yet, nor has its imports/exports |
| 566 /// been resolved. | 574 /// been resolved. |
| 567 void onLibraryCreated(LibraryElement library) { | 575 void onLibraryCreated(LibraryElement library) { |
| 568 Uri uri = library.canonicalUri; | 576 Uri uri = library.canonicalUri; |
| 569 if (uri == Uris.dart_core) { | 577 if (uri == Uris.dart_core) { |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 return null; | 961 return null; |
| 954 } | 962 } |
| 955 fullyEnqueueLibrary(library, enqueuer.resolution); | 963 fullyEnqueueLibrary(library, enqueuer.resolution); |
| 956 emptyQueue(enqueuer.resolution); | 964 emptyQueue(enqueuer.resolution); |
| 957 enqueuer.resolution.logSummary(reporter.log); | 965 enqueuer.resolution.logSummary(reporter.log); |
| 958 return library; | 966 return library; |
| 959 }); | 967 }); |
| 960 } | 968 } |
| 961 | 969 |
| 962 /// Performs the compilation when all libraries have been loaded. | 970 /// Performs the compilation when all libraries have been loaded. |
| 963 void compileLoadedLibraries() { | 971 void compileLoadedLibraries() |
| 972 => selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
| 973 |
| 964 computeMain(); | 974 computeMain(); |
| 965 | 975 |
| 966 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 976 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
| 967 | 977 |
| 968 // In order to see if a library is deferred, we must compute the | 978 // In order to see if a library is deferred, we must compute the |
| 969 // compile-time constants that are metadata. This means adding | 979 // compile-time constants that are metadata. This means adding |
| 970 // something to the resolution queue. So we cannot wait with | 980 // something to the resolution queue. So we cannot wait with |
| 971 // this until after the resolution queue is processed. | 981 // this until after the resolution queue is processed. |
| 972 deferredLoadTask.beforeResolution(this); | 982 deferredLoadTask.beforeResolution(this); |
| 973 | 983 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 enqueuer.codegen.logSummary(reporter.log); | 1060 enqueuer.codegen.logSummary(reporter.log); |
| 1051 | 1061 |
| 1052 int programSize = backend.assembleProgram(); | 1062 int programSize = backend.assembleProgram(); |
| 1053 | 1063 |
| 1054 if (dumpInfo) { | 1064 if (dumpInfo) { |
| 1055 dumpInfoTask.reportSize(programSize); | 1065 dumpInfoTask.reportSize(programSize); |
| 1056 dumpInfoTask.dumpInfo(); | 1066 dumpInfoTask.dumpInfo(); |
| 1057 } | 1067 } |
| 1058 | 1068 |
| 1059 checkQueues(); | 1069 checkQueues(); |
| 1060 } | 1070 }); |
| 1061 | 1071 |
| 1062 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 1072 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
| 1063 void enqueueAll(Element element) { | 1073 void enqueueAll(Element element) { |
| 1064 fullyEnqueueTopLevelElement(element, world); | 1074 fullyEnqueueTopLevelElement(element, world); |
| 1065 } | 1075 } |
| 1066 library.implementation.forEachLocalMember(enqueueAll); | 1076 library.implementation.forEachLocalMember(enqueueAll); |
| 1067 } | 1077 } |
| 1068 | 1078 |
| 1069 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 1079 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
| 1070 if (element.isClass) { | 1080 if (element.isClass) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1087 for (MetadataAnnotation metadata in library.metadata) { | 1097 for (MetadataAnnotation metadata in library.metadata) { |
| 1088 metadata.ensureResolved(resolution); | 1098 metadata.ensureResolved(resolution); |
| 1089 } | 1099 } |
| 1090 } | 1100 } |
| 1091 } | 1101 } |
| 1092 } | 1102 } |
| 1093 | 1103 |
| 1094 /** | 1104 /** |
| 1095 * Empty the [world] queue. | 1105 * Empty the [world] queue. |
| 1096 */ | 1106 */ |
| 1097 void emptyQueue(Enqueuer world) { | 1107 void emptyQueue(Enqueuer world) |
| 1108 => selfTask.measureSubtask("Compiler.emptyQueue", () { |
| 1098 world.forEach((WorkItem work) { | 1109 world.forEach((WorkItem work) { |
| 1099 reporter.withCurrentElement(work.element, () { | 1110 reporter.withCurrentElement( |
| 1100 world.applyImpact(work.element, work.run(this, world)); | 1111 work.element, () => selfTask.measureSubtask("world.applyImpact", () { |
| 1101 }); | 1112 world.applyImpact( |
| 1113 work.element, |
| 1114 selfTask.measureSubtask("work.run", () => work.run(this, world))); |
| 1115 })); |
| 1102 }); | 1116 }); |
| 1103 } | 1117 }); |
| 1104 | 1118 |
| 1105 void processQueue(Enqueuer world, Element main) { | 1119 void processQueue(Enqueuer world, Element main) |
| 1120 => selfTask.measureSubtask("Compiler.processQueue", () { |
| 1106 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 1121 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); |
| 1107 if (main != null && !main.isMalformed) { | 1122 if (main != null && !main.isMalformed) { |
| 1108 FunctionElement mainMethod = main; | 1123 FunctionElement mainMethod = main; |
| 1109 mainMethod.computeType(resolution); | 1124 mainMethod.computeType(resolution); |
| 1110 if (mainMethod.functionSignature.parameterCount != 0) { | 1125 if (mainMethod.functionSignature.parameterCount != 0) { |
| 1111 // The first argument could be a list of strings. | 1126 // The first argument could be a list of strings. |
| 1112 backend.listImplementation.ensureResolved(resolution); | 1127 backend.listImplementation.ensureResolved(resolution); |
| 1113 backend.registerInstantiatedType( | 1128 backend.registerInstantiatedType( |
| 1114 backend.listImplementation.rawType, world, globalDependencies); | 1129 backend.listImplementation.rawType, world, globalDependencies); |
| 1115 backend.stringImplementation.ensureResolved(resolution); | 1130 backend.stringImplementation.ensureResolved(resolution); |
| 1116 backend.registerInstantiatedType( | 1131 backend.registerInstantiatedType( |
| 1117 backend.stringImplementation.rawType, world, globalDependencies); | 1132 backend.stringImplementation.rawType, world, globalDependencies); |
| 1118 | 1133 |
| 1119 backend.registerMainHasArguments(world); | 1134 backend.registerMainHasArguments(world); |
| 1120 } | 1135 } |
| 1121 world.addToWorkList(main); | 1136 world.addToWorkList(main); |
| 1122 } | 1137 } |
| 1123 if (verbose) { | 1138 if (verbose) { |
| 1124 progress.reset(); | 1139 progress.reset(); |
| 1125 } | 1140 } |
| 1126 emptyQueue(world); | 1141 emptyQueue(world); |
| 1127 world.queueIsClosed = true; | 1142 world.queueIsClosed = true; |
| 1128 backend.onQueueClosed(); | 1143 backend.onQueueClosed(); |
| 1129 assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); | 1144 assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); |
| 1130 } | 1145 }); |
| 1131 | 1146 |
| 1132 /** | 1147 /** |
| 1133 * Perform various checks of the queues. This includes checking that | 1148 * Perform various checks of the queues. This includes checking that |
| 1134 * the queues are empty (nothing was added after we stopped | 1149 * the queues are empty (nothing was added after we stopped |
| 1135 * processing the queues). Also compute the number of methods that | 1150 * processing the queues). Also compute the number of methods that |
| 1136 * were resolved, but not compiled (aka excess resolution). | 1151 * were resolved, but not compiled (aka excess resolution). |
| 1137 */ | 1152 */ |
| 1138 checkQueues() { | 1153 checkQueues() { |
| 1139 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 1154 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| 1140 world.forEach((WorkItem work) { | 1155 world.forEach((WorkItem work) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1162 } | 1177 } |
| 1163 } | 1178 } |
| 1164 reporter.log('Excess resolution work: ${resolved.length}.'); | 1179 reporter.log('Excess resolution work: ${resolved.length}.'); |
| 1165 for (Element e in resolved) { | 1180 for (Element e in resolved) { |
| 1166 reporter.reportWarningMessage(e, | 1181 reporter.reportWarningMessage(e, |
| 1167 MessageKind.GENERIC, | 1182 MessageKind.GENERIC, |
| 1168 {'text': 'Warning: $e resolved but not compiled.'}); | 1183 {'text': 'Warning: $e resolved but not compiled.'}); |
| 1169 } | 1184 } |
| 1170 } | 1185 } |
| 1171 | 1186 |
| 1172 WorldImpact analyzeElement(Element element) { | 1187 WorldImpact analyzeElement(Element element) |
| 1188 => selfTask.measureSubtask("Compiler.analyzeElement", () { |
| 1173 assert(invariant(element, | 1189 assert(invariant(element, |
| 1174 element.impliesType || | 1190 element.impliesType || |
| 1175 element.isField || | 1191 element.isField || |
| 1176 element.isFunction || | 1192 element.isFunction || |
| 1177 element.isConstructor || | 1193 element.isConstructor || |
| 1178 element.isGetter || | 1194 element.isGetter || |
| 1179 element.isSetter, | 1195 element.isSetter, |
| 1180 message: 'Unexpected element kind: ${element.kind}')); | 1196 message: 'Unexpected element kind: ${element.kind}')); |
| 1181 assert(invariant(element, element is AnalyzableElement, | 1197 assert(invariant(element, element is AnalyzableElement, |
| 1182 message: 'Element $element is not analyzable.')); | 1198 message: 'Element $element is not analyzable.')); |
| 1183 assert(invariant(element, element.isDeclaration)); | 1199 assert(invariant(element, element.isDeclaration)); |
| 1184 return resolution.computeWorldImpact(element); | 1200 return resolution.computeWorldImpact(element); |
| 1185 } | 1201 }); |
| 1186 | 1202 |
| 1187 WorldImpact analyze(ResolutionWorkItem work, | 1203 WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) |
| 1188 ResolutionEnqueuer world) { | 1204 => selfTask.measureSubtask("Compiler.analyze", () { |
| 1189 assert(invariant(work.element, identical(world, enqueuer.resolution))); | 1205 assert(invariant(work.element, identical(world, enqueuer.resolution))); |
| 1190 assert(invariant(work.element, !work.isAnalyzed, | 1206 assert(invariant(work.element, !work.isAnalyzed, |
| 1191 message: 'Element ${work.element} has already been analyzed')); | 1207 message: 'Element ${work.element} has already been analyzed')); |
| 1192 if (shouldPrintProgress) { | 1208 if (shouldPrintProgress) { |
| 1193 // TODO(ahe): Add structured diagnostics to the compiler API and | 1209 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 1194 // use it to separate this from the --verbose option. | 1210 // use it to separate this from the --verbose option. |
| 1195 if (phase == PHASE_RESOLVING) { | 1211 if (phase == PHASE_RESOLVING) { |
| 1196 reporter.log( | 1212 reporter.log( |
| 1197 'Resolved ${enqueuer.resolution.processedElements.length} ' | 1213 'Resolved ${enqueuer.resolution.processedElements.length} ' |
| 1198 'elements.'); | 1214 'elements.'); |
| 1199 progress.reset(); | 1215 progress.reset(); |
| 1200 } | 1216 } |
| 1201 } | 1217 } |
| 1202 AstElement element = work.element; | 1218 AstElement element = work.element; |
| 1203 if (world.hasBeenProcessed(element)) { | 1219 if (world.hasBeenProcessed(element)) { |
| 1204 return const WorldImpact(); | 1220 return const WorldImpact(); |
| 1205 } | 1221 } |
| 1206 WorldImpact worldImpact = analyzeElement(element); | 1222 WorldImpact worldImpact = analyzeElement(element); |
| 1207 backend.onElementResolved(element, element.resolvedAst.elements); | 1223 backend.onElementResolved(element, element.resolvedAst.elements); |
| 1208 world.registerProcessedElement(element); | 1224 world.registerProcessedElement(element); |
| 1209 return worldImpact; | 1225 return worldImpact; |
| 1210 } | 1226 }); |
| 1211 | 1227 |
| 1212 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { | 1228 WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
| 1213 assert(invariant(work.element, identical(world, enqueuer.codegen))); | 1229 assert(invariant(work.element, identical(world, enqueuer.codegen))); |
| 1214 if (shouldPrintProgress) { | 1230 if (shouldPrintProgress) { |
| 1215 // TODO(ahe): Add structured diagnostics to the compiler API and | 1231 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 1216 // use it to separate this from the --verbose option. | 1232 // use it to separate this from the --verbose option. |
| 1217 reporter.log( | 1233 reporter.log( |
| 1218 'Compiled ${enqueuer.codegen.generatedCode.length} methods.'); | 1234 'Compiled ${enqueuer.codegen.generatedCode.length} methods.'); |
| 1219 progress.reset(); | 1235 progress.reset(); |
| 1220 } | 1236 } |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2079 if (_otherDependencies == null) { | 2095 if (_otherDependencies == null) { |
| 2080 _otherDependencies = new Setlet<Element>(); | 2096 _otherDependencies = new Setlet<Element>(); |
| 2081 } | 2097 } |
| 2082 _otherDependencies.add(element.implementation); | 2098 _otherDependencies.add(element.implementation); |
| 2083 } | 2099 } |
| 2084 | 2100 |
| 2085 Iterable<Element> get otherDependencies { | 2101 Iterable<Element> get otherDependencies { |
| 2086 return _otherDependencies != null ? _otherDependencies : const <Element>[]; | 2102 return _otherDependencies != null ? _otherDependencies : const <Element>[]; |
| 2087 } | 2103 } |
| 2088 } | 2104 } |
| OLD | NEW |