| 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 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 static const SourceString START_ROOT_ISOLATE = | 172 static const SourceString START_ROOT_ISOLATE = |
| 178 const SourceString('startRootIsolate'); | 173 const SourceString('startRootIsolate'); |
| 179 bool enabledNoSuchMethod = false; | 174 bool enabledNoSuchMethod = false; |
| 180 bool enabledRuntimeType = false; | 175 bool enabledRuntimeType = false; |
| 181 | 176 |
| 182 Stopwatch progress; | 177 Stopwatch progress; |
| 183 | 178 |
| 184 static const int PHASE_SCANNING = 0; | 179 static const int PHASE_SCANNING = 0; |
| 185 static const int PHASE_RESOLVING = 1; | 180 static const int PHASE_RESOLVING = 1; |
| 186 static const int PHASE_COMPILING = 2; | 181 static const int PHASE_COMPILING = 2; |
| 187 static const int PHASE_RECOMPILING = 3; | |
| 188 int phase; | 182 int phase; |
| 189 | 183 |
| 190 bool compilationFailed = false; | 184 bool compilationFailed = false; |
| 191 | 185 |
| 192 bool hasCrashed = false; | 186 bool hasCrashed = false; |
| 193 | 187 |
| 194 Compiler([this.tracer = const Tracer(), | 188 Compiler([this.tracer = const Tracer(), |
| 195 this.enableTypeAssertions = false, | 189 this.enableTypeAssertions = false, |
| 196 this.enableUserAssertions = false, | 190 this.enableUserAssertions = false, |
| 197 this.enableMinification = false, | 191 this.enableMinification = false, |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 log('Inferring types...'); | 565 log('Inferring types...'); |
| 572 typesTask.onResolutionComplete(); | 566 typesTask.onResolutionComplete(); |
| 573 | 567 |
| 574 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 568 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
| 575 // should know this. | 569 // should know this. |
| 576 world.populate(); | 570 world.populate(); |
| 577 | 571 |
| 578 log('Compiling...'); | 572 log('Compiling...'); |
| 579 phase = PHASE_COMPILING; | 573 phase = PHASE_COMPILING; |
| 580 processQueue(enqueuer.codegen, main); | 574 processQueue(enqueuer.codegen, main); |
| 581 log("Recompiling ${enqueuer.codegen.recompilationCandidates.length} " | |
| 582 "methods..."); | |
| 583 phase = PHASE_RECOMPILING; | |
| 584 processRecompilationQueue(enqueuer.codegen); | |
| 585 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | 575 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 586 | 576 |
| 587 if (compilationFailed) return; | 577 if (compilationFailed) return; |
| 588 | 578 |
| 589 backend.assembleProgram(); | 579 backend.assembleProgram(); |
| 590 | 580 |
| 591 checkQueues(); | 581 checkQueues(); |
| 592 } | 582 } |
| 593 | 583 |
| 594 void processQueue(Enqueuer world, Element main) { | 584 void processQueue(Enqueuer world, Element main) { |
| 595 backend.processNativeClasses(world, libraries.getValues()); | 585 backend.processNativeClasses(world, libraries.getValues()); |
| 596 world.addToWorkList(main); | 586 world.addToWorkList(main); |
| 597 progress.reset(); | 587 progress.reset(); |
| 598 world.forEach((WorkItem work) { | 588 world.forEach((WorkItem work) { |
| 599 withCurrentElement(work.element, () => work.run(this, world)); | 589 withCurrentElement(work.element, () => work.run(this, world)); |
| 600 }); | 590 }); |
| 601 world.queueIsClosed = true; | 591 world.queueIsClosed = true; |
| 602 if (compilationFailed) return; | 592 if (compilationFailed) return; |
| 603 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 593 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 604 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | 594 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { |
| 605 print("Inferred argument types:"); | 595 print("Inferred argument types:"); |
| 606 print("------------------------"); | 596 print("------------------------"); |
| 607 backend.argumentTypes.dump(); | 597 backend.argumentTypes.dump(); |
| 608 print(""); | 598 print(""); |
| 609 print("Inferred return types:"); | 599 print("Inferred return types:"); |
| 610 print("----------------------"); | 600 print("----------------------"); |
| 611 backend.dumpReturnTypes(); | 601 backend.dumpReturnTypes(); |
| 602 print(""); |
| 603 print("Inferred field types:"); |
| 604 print("------------------------"); |
| 605 backend.fieldTypes.dump(); |
| 606 print(""); |
| 612 } | 607 } |
| 613 } | 608 } |
| 614 | 609 |
| 615 void processRecompilationQueue(Enqueuer world) { | |
| 616 assert(phase == PHASE_RECOMPILING); | |
| 617 while (!world.recompilationCandidates.isEmpty()) { | |
| 618 WorkItem work = world.recompilationCandidates.next(); | |
| 619 Element element = work.element; | |
| 620 CodeBuffer oldCode = world.universe.generatedCode[element]; | |
| 621 world.universe.generatedCode.remove(element); | |
| 622 world.universe.generatedBailoutCode.remove(element); | |
| 623 withCurrentElement(element, () => work.run(this, world)); | |
| 624 CodeBuffer newCode = world.universe.generatedCode[element]; | |
| 625 if (REPORT_PASS2_OPTIMIZATIONS && newCode != oldCode) { | |
| 626 log("Pass 2 optimization:"); | |
| 627 log("Before:\n$oldCode"); | |
| 628 log("After:\n$newCode"); | |
| 629 } | |
| 630 } | |
| 631 } | |
| 632 | |
| 633 /** | 610 /** |
| 634 * Perform various checks of the queues. This includes checking that | 611 * Perform various checks of the queues. This includes checking that |
| 635 * the queues are empty (nothing was added after we stopped | 612 * the queues are empty (nothing was added after we stopped |
| 636 * processing the queues). Also compute the number of methods that | 613 * processing the queues). Also compute the number of methods that |
| 637 * were resolved, but not compiled (aka excess resolution). | 614 * were resolved, but not compiled (aka excess resolution). |
| 638 */ | 615 */ |
| 639 checkQueues() { | 616 checkQueues() { |
| 640 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 617 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| 641 world.forEach((WorkItem work) { | 618 world.forEach((WorkItem work) { |
| 642 internalErrorOnElement(work.element, "Work list is not empty."); | 619 internalErrorOnElement(work.element, "Work list is not empty."); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 assert(invariant(element, element.isDeclaration)); | 703 assert(invariant(element, element.isDeclaration)); |
| 727 enqueuer.resolution.resolvedElements[element] = result; | 704 enqueuer.resolution.resolvedElements[element] = result; |
| 728 return result; | 705 return result; |
| 729 } | 706 } |
| 730 | 707 |
| 731 void codegen(WorkItem work, Enqueuer world) { | 708 void codegen(WorkItem work, Enqueuer world) { |
| 732 if (world !== enqueuer.codegen) return null; | 709 if (world !== enqueuer.codegen) return null; |
| 733 if (progress.elapsedInMs() > 500) { | 710 if (progress.elapsedInMs() > 500) { |
| 734 // TODO(ahe): Add structured diagnostics to the compiler API and | 711 // TODO(ahe): Add structured diagnostics to the compiler API and |
| 735 // use it to separate this from the --verbose option. | 712 // use it to separate this from the --verbose option. |
| 736 if (phase == PHASE_COMPILING) { | 713 log('Compiled ${codegenWorld.generatedCode.length} methods.'); |
| 737 log('Compiled ${codegenWorld.generatedCode.length} methods.'); | |
| 738 } else { | |
| 739 log('Recompiled ${world.recompilationCandidates.processed} methods.'); | |
| 740 } | |
| 741 progress.reset(); | 714 progress.reset(); |
| 742 } | 715 } |
| 743 backend.codegen(work); | 716 backend.codegen(work); |
| 744 } | 717 } |
| 745 | 718 |
| 746 DartType resolveTypeAnnotation(Element element, | 719 DartType resolveTypeAnnotation(Element element, |
| 747 TypeAnnotation annotation) { | 720 TypeAnnotation annotation) { |
| 748 return resolver.resolveTypeAnnotation(element, annotation); | 721 return resolver.resolveTypeAnnotation(element, annotation); |
| 749 } | 722 } |
| 750 | 723 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 * information in the generated error message. | 948 * information in the generated error message. |
| 976 */ | 949 */ |
| 977 bool invariant(Spannable spannable, var condition, {String message: null}) { | 950 bool invariant(Spannable spannable, var condition, {String message: null}) { |
| 978 // TODO(johnniwinther): Use [spannable] and [message] to provide better | 951 // TODO(johnniwinther): Use [spannable] and [message] to provide better |
| 979 // information on assertion errors. | 952 // information on assertion errors. |
| 980 if (condition is Function){ | 953 if (condition is Function){ |
| 981 condition = condition(); | 954 condition = condition(); |
| 982 } | 955 } |
| 983 return spannable != null && condition; | 956 return spannable != null && condition; |
| 984 } | 957 } |
| OLD | NEW |