| 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 | 5 |
| 6 /** | 6 /** |
| 7 * If true, print a warning for each method that was resolved, but not | 7 * If true, print a warning for each method that was resolved, but not |
| 8 * compiled. | 8 * compiled. |
| 9 */ | 9 */ |
| 10 const bool REPORT_EXCESS_RESOLUTION = false; | 10 const bool REPORT_EXCESS_RESOLUTION = false; |
| 11 | 11 |
| 12 /** | 12 /** |
| 13 * If true, trace information on pass2 optimizations. | |
| 14 */ | |
| 15 const bool REPORT_PASS2_OPTIMIZATIONS = false; | |
| 16 | |
| 17 /** | |
| 18 * If true, dump the inferred types after compilation. | 13 * If true, dump the inferred types after compilation. |
| 19 */ | 14 */ |
| 20 const bool DUMP_INFERRED_TYPES = false; | 15 const bool DUMP_INFERRED_TYPES = false; |
| 21 | 16 |
| 22 /** | 17 /** |
| 23 * A string to identify the revision or build. | 18 * A string to identify the revision or build. |
| 24 * | 19 * |
| 25 * This ID is displayed if the compiler crashes and in verbose mode, and is | 20 * This ID is displayed if the compiler crashes and in verbose mode, and is |
| 26 * an aid in reproducing bug reports. | 21 * an aid in reproducing bug reports. |
| 27 * | 22 * |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 static const SourceString START_ROOT_ISOLATE = | 164 static const SourceString START_ROOT_ISOLATE = |
| 170 const SourceString('startRootIsolate'); | 165 const SourceString('startRootIsolate'); |
| 171 bool enabledNoSuchMethod = false; | 166 bool enabledNoSuchMethod = false; |
| 172 bool enabledRuntimeType = false; | 167 bool enabledRuntimeType = false; |
| 173 | 168 |
| 174 Stopwatch progress; | 169 Stopwatch progress; |
| 175 | 170 |
| 176 static const int PHASE_SCANNING = 0; | 171 static const int PHASE_SCANNING = 0; |
| 177 static const int PHASE_RESOLVING = 1; | 172 static const int PHASE_RESOLVING = 1; |
| 178 static const int PHASE_COMPILING = 2; | 173 static const int PHASE_COMPILING = 2; |
| 179 static const int PHASE_RECOMPILING = 3; | |
| 180 int phase; | 174 int phase; |
| 181 | 175 |
| 182 bool compilationFailed = false; | 176 bool compilationFailed = false; |
| 183 | 177 |
| 184 bool hasCrashed = false; | 178 bool hasCrashed = false; |
| 185 | 179 |
| 186 Compiler([this.tracer = const Tracer(), | 180 Compiler([this.tracer = const Tracer(), |
| 187 this.enableTypeAssertions = false, | 181 this.enableTypeAssertions = false, |
| 188 this.enableUserAssertions = false, | 182 this.enableUserAssertions = false, |
| 189 this.enableMinification = false, | 183 this.enableMinification = false, |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 log('Inferring types...'); | 557 log('Inferring types...'); |
| 564 typesTask.onResolutionComplete(); | 558 typesTask.onResolutionComplete(); |
| 565 | 559 |
| 566 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 560 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
| 567 // should know this. | 561 // should know this. |
| 568 world.populate(); | 562 world.populate(); |
| 569 | 563 |
| 570 log('Compiling...'); | 564 log('Compiling...'); |
| 571 phase = PHASE_COMPILING; | 565 phase = PHASE_COMPILING; |
| 572 processQueue(enqueuer.codegen, main); | 566 processQueue(enqueuer.codegen, main); |
| 573 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} " | |
| 574 "methods..."); | |
| 575 phase = PHASE_RECOMPILING; | |
| 576 processRecompilationQueue(enqueuer.codegen); | |
| 577 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | 567 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 578 | 568 |
| 579 if (compilationFailed) return; | 569 if (compilationFailed) return; |
| 580 | 570 |
| 581 backend.assembleProgram(); | 571 backend.assembleProgram(); |
| 582 | 572 |
| 583 checkQueues(); | 573 checkQueues(); |
| 584 } | 574 } |
| 585 | 575 |
| 586 void processQueue(Enqueuer world, Element main) { | 576 void processQueue(Enqueuer world, Element main) { |
| 587 backend.processNativeClasses(world, libraries.getValues()); | 577 backend.processNativeClasses(world, libraries.getValues()); |
| 588 world.addToWorkList(main); | 578 world.addToWorkList(main); |
| 589 progress.reset(); | 579 progress.reset(); |
| 590 world.forEach((WorkItem work) { | 580 world.forEach((WorkItem work) { |
| 591 withCurrentElement(work.element, () => work.run(this, world)); | 581 withCurrentElement(work.element, () => work.run(this, world)); |
| 592 }); | 582 }); |
| 593 world.queueIsClosed = true; | 583 world.queueIsClosed = true; |
| 594 if (compilationFailed) return; | 584 if (compilationFailed) return; |
| 595 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 585 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 596 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | 586 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { |
| 597 print("Inferred argument types:"); | 587 print("Inferred argument types:"); |
| 598 print("------------------------"); | 588 print("------------------------"); |
| 599 backend.argumentTypes.dump(); | 589 backend.argumentTypes.dump(); |
| 600 print(""); | 590 print(""); |
| 601 print("Inferred return types:"); | 591 print("Inferred return types:"); |
| 602 print("----------------------"); | 592 print("----------------------"); |
| 603 backend.dumpReturnTypes(); | 593 backend.dumpReturnTypes(); |
| 594 print("Inferred field types:"); |
| 595 print("------------------------"); |
| 596 backend.fieldTypes.dump(); |
| 604 } | 597 } |
| 605 } | 598 } |
| 606 | 599 |
| 607 void processRecompilationQueue(Enqueuer world) { | |
| 608 assert(phase == PHASE_RECOMPILING); | |
| 609 while (!world.recompilationCandidates.isEmpty()) { | |
| 610 WorkItem work = world.recompilationCandidates.next(); | |
| 611 CodeBuffer oldCode = world.universe.generatedCode[work.element]; | |
| 612 world.universe.generatedCode.remove(work.element); | |
| 613 world.universe.generatedBailoutCode.remove(work.element); | |
| 614 withCurrentElement(work.element, () => work.run(this, world)); | |
| 615 CodeBuffer newCode = world.universe.generatedCode[work.element]; | |
| 616 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) { | |
| 617 log("Pass 2 optimization:"); | |
| 618 log("Before:\n$oldCode"); | |
| 619 log("After:\n$newCode"); | |
| 620 } | |
| 621 } | |
| 622 } | |
| 623 | |
| 624 /** | 600 /** |
| 625 * Perform various checks of the queues. This includes checking that | 601 * Perform various checks of the queues. This includes checking that |
| 626 * the queues are empty (nothing was added after we stopped | 602 * the queues are empty (nothing was added after we stopped |
| 627 * processing the queues). Also compute the number of methods that | 603 * processing the queues). Also compute the number of methods that |
| 628 * were resolved, but not compiled (aka excess resolution). | 604 * were resolved, but not compiled (aka excess resolution). |
| 629 */ | 605 */ |
| 630 checkQueues() { | 606 checkQueues() { |
| 631 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 607 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| 632 world.forEach((WorkItem work) { | 608 world.forEach((WorkItem work) { |
| 633 internalErrorOnElement(work.element, "Work list is not empty."); | 609 internalErrorOnElement(work.element, "Work list is not empty."); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 result = analyzeElement(element); | 691 result = analyzeElement(element); |
| 716 enqueuer.resolution.resolvedElements[element] = result; | 692 enqueuer.resolution.resolvedElements[element] = result; |
| 717 return result; | 693 return result; |
| 718 } | 694 } |
| 719 | 695 |
| 720 void codegen(WorkItem work, Enqueuer world) { | 696 void codegen(WorkItem work, Enqueuer world) { |
| 721 if (world !== enqueuer.codegen) return null; | 697 if (world !== enqueuer.codegen) return null; |
| 722 if (progress.elapsedInMs() > 500) { | 698 if (progress.elapsedInMs() > 500) { |
| 723 // TODO(ahe): Add structured diagnostics to the compiler API and | 699 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 724 // use it to separate this from the --verbose option. | 700 // use it to separate this from the --verbose option. |
| 725 if (phase == PHASE_COMPILING) { | 701 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 726 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | |
| 727 } else { | |
| 728 log('Recompiled ${world.recompilationCandidates.processed} methods.'); | |
| 729 } | |
| 730 progress.reset(); | 702 progress.reset(); |
| 731 } | 703 } |
| 732 backend.codegen(work); | 704 backend.codegen(work); |
| 733 } | 705 } |
| 734 | 706 |
| 735 DartType resolveTypeAnnotation(Element element, | 707 DartType resolveTypeAnnotation(Element element, |
| 736 TypeAnnotation annotation) { | 708 TypeAnnotation annotation) { |
| 737 return resolver.resolveTypeAnnotation(element, annotation); | 709 return resolver.resolveTypeAnnotation(element, annotation); |
| 738 } | 710 } |
| 739 | 711 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 final endOffset = end.charOffset + end.slowCharCount; | 915 final endOffset = end.charOffset + end.slowCharCount; |
| 944 | 916 |
| 945 // [begin] and [end] might be the same for the same empty token. This | 917 // [begin] and [end] might be the same for the same empty token. This |
| 946 // happens for instance when scanning '$$'. | 918 // happens for instance when scanning '$$'. |
| 947 assert(endOffset >= beginOffset); | 919 assert(endOffset >= beginOffset); |
| 948 return f(beginOffset, endOffset); | 920 return f(beginOffset, endOffset); |
| 949 } | 921 } |
| 950 | 922 |
| 951 String toString() => 'SourceSpan($uri, $begin, $end)'; | 923 String toString() => 'SourceSpan($uri, $begin, $end)'; |
| 952 } | 924 } |
| OLD | NEW |