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