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 |