Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(512)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart

Issue 24282005: Move compile-time constant registrations to the backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 part of js_backend; 5 part of js_backend;
6 6
7 class JavaScriptItemCompilationContext extends ItemCompilationContext { 7 class JavaScriptItemCompilationContext extends ItemCompilationContext {
8 final Set<HInstruction> boundsChecked; 8 final Set<HInstruction> boundsChecked;
9 9
10 JavaScriptItemCompilationContext() 10 JavaScriptItemCompilationContext()
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 312
313 /// True if a call to preserveNames has been seen. 313 /// True if a call to preserveNames has been seen.
314 bool mustPreserveNames = false; 314 bool mustPreserveNames = false;
315 315
316 /// True if a call to disableTreeShaking has been seen. 316 /// True if a call to disableTreeShaking has been seen.
317 bool isTreeShakingDisabled = false; 317 bool isTreeShakingDisabled = false;
318 318
319 /// True if there isn't sufficient @MirrorsUsed data. 319 /// True if there isn't sufficient @MirrorsUsed data.
320 bool hasInsufficientMirrorsUsed = false; 320 bool hasInsufficientMirrorsUsed = false;
321 321
322 /// List of instantiated types from metadata. If metadata must be preserved, 322 /// List of constants from metadata. If metadata must be preserved,
323 /// these types must registered. 323 /// these constants must be registered.
324 final List<Dependency> metadataInstantiatedTypes = <Dependency>[]; 324 final List<Dependency> metadataConstants = <Dependency>[];
325
326 /// List of elements used from metadata. If metadata must be preserved,
327 /// these elements must be compiled.
328 final List<Element> metadataStaticUse = <Element>[];
329
330 /// List of tear-off functions referenced from metadata. If metadata must be
331 /// preserved, these elements must be compiled.
332 final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[];
333 325
334 /// List of symbols that the user has requested for reflection. 326 /// List of symbols that the user has requested for reflection.
335 final Set<String> symbolsUsed = new Set<String>(); 327 final Set<String> symbolsUsed = new Set<String>();
336 328
337 /// List of elements that the user has requested for reflection. 329 /// List of elements that the user has requested for reflection.
338 final Set<Element> targetsUsed = new Set<Element>(); 330 final Set<Element> targetsUsed = new Set<Element>();
339 331
340 /// List of annotations provided by user that indicate that the annotated 332 /// List of annotations provided by user that indicate that the annotated
341 /// element must be retained. 333 /// element must be retained.
342 final Set<Element> metaTargetsUsed = new Set<Element>(); 334 final Set<Element> metaTargetsUsed = new Set<Element>();
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 String name = namer.getInterceptorName(getInterceptorMethod, classes); 730 String name = namer.getInterceptorName(getInterceptorMethod, classes);
739 if (classes.contains(jsInterceptorClass)) { 731 if (classes.contains(jsInterceptorClass)) {
740 // We can't use a specialized [getInterceptorMethod], so we make 732 // We can't use a specialized [getInterceptorMethod], so we make
741 // sure we emit the one with all checks. 733 // sure we emit the one with all checks.
742 specializedGetInterceptors[name] = interceptedClasses; 734 specializedGetInterceptors[name] = interceptedClasses;
743 } else { 735 } else {
744 specializedGetInterceptors[name] = classes; 736 specializedGetInterceptors[name] = classes;
745 } 737 }
746 } 738 }
747 739
740 Constant registerCompileTimeConstant(Constant constant,
741 TreeElements elements) {
742 registerCompileTimeConstantInternal(constant, elements);
743 for (Constant dependency in constant.getDependencies()) {
744 registerCompileTimeConstant(dependency, elements);
745 }
746 }
747
748 void registerCompileTimeConstantInternal(Constant constant,
749 TreeElements elements) {
750 DartType type = constant.computeType(compiler);
751 registerInstantiatedConstantType(type, elements);
752
753 if (constant.isFunction()) {
754 FunctionConstant function = constant;
755 compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element);
756 } else if (constant.isInterceptor()) {
757 // An interceptor constant references the class's prototype chain.
758 InterceptorConstant interceptor = constant;
759 registerInstantiatedConstantType(interceptor.dispatchedType, elements);
760 }
761 }
762
763 void registerInstantiatedConstantType(DartType type, TreeElements elements) {
764 Enqueuer enqueuer = compiler.enqueuer.codegen;
765 enqueuer.registerInstantiatedType(type, elements);
766 if (type is InterfaceType && !type.treatAsRaw &&
767 classNeedsRti(type.element)) {
768 enqueuer.registerStaticUse(getSetRuntimeTypeInfo());
769 }
770 if (type.element == typeImplementation) {
771 // If we use a type literal in a constant, the compile time
772 // constant emitter will generate a call to the createRuntimeType
773 // helper so we register a use of that.
774 enqueuer.registerStaticUse(getCreateRuntimeType());
775 }
776 }
777
778 void registerMetadataConstant(Constant constant, TreeElements elements) {
779 if (mustRetainMetadata) {
780 registerCompileTimeConstant(constant, elements);
781 } else {
782 metadataConstants.add(new Dependency(constant, elements));
783 }
784 }
785
748 void registerInstantiatedClass(ClassElement cls, 786 void registerInstantiatedClass(ClassElement cls,
749 Enqueuer enqueuer, 787 Enqueuer enqueuer,
750 TreeElements elements) { 788 TreeElements elements) {
751 if (!seenAnyClass) { 789 if (!seenAnyClass) {
752 seenAnyClass = true; 790 seenAnyClass = true;
753 if (enqueuer.isResolutionQueue) { 791 if (enqueuer.isResolutionQueue) {
754 // TODO(9577): Make it so that these are not needed when there are no 792 // TODO(9577): Make it so that these are not needed when there are no
755 // native classes. 793 // native classes.
756 enqueue(enqueuer, getNativeInterceptorMethod, elements); 794 enqueue(enqueuer, getNativeInterceptorMethod, elements);
757 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements); 795 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 1218
1181 void codegen(CodegenWorkItem work) { 1219 void codegen(CodegenWorkItem work) {
1182 Element element = work.element; 1220 Element element = work.element;
1183 var kind = element.kind; 1221 var kind = element.kind;
1184 if (kind == ElementKind.TYPEDEF) return; 1222 if (kind == ElementKind.TYPEDEF) return;
1185 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) { 1223 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) {
1186 // Work around a problem compiling JSNull's constructor. 1224 // Work around a problem compiling JSNull's constructor.
1187 return; 1225 return;
1188 } 1226 }
1189 if (kind.category == ElementCategory.VARIABLE) { 1227 if (kind.category == ElementCategory.VARIABLE) {
1190 Constant initialValue = compiler.constantHandler.compileWorkItem(work); 1228 Constant initialValue =
1229 compiler.constantHandler.getConstantForVariable(element);
1191 if (initialValue != null) { 1230 if (initialValue != null) {
1231 registerCompileTimeConstant(initialValue, work.resolutionTree);
1232 compiler.constantHandler.addCompileTimeConstantForEmission(
1233 initialValue);
1192 return; 1234 return;
1193 } else { 1235 } else {
1194 // If the constant-handler was not able to produce a result we have to 1236 // If the constant-handler was not able to produce a result we have to
1195 // go through the builder (below) to generate the lazy initializer for 1237 // go through the builder (below) to generate the lazy initializer for
1196 // the static variable. 1238 // the static variable.
1197 // We also need to register the use of the cyclic-error helper. 1239 // We also need to register the use of the cyclic-error helper.
1198 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper()); 1240 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper());
1199 } 1241 }
1200 } 1242 }
1201 1243
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 if (name == const SourceString('')) return false; 1647 if (name == const SourceString('')) return false;
1606 return symbolsUsed.contains(name.slowToString()); 1648 return symbolsUsed.contains(name.slowToString());
1607 } 1649 }
1608 1650
1609 bool get rememberLazies => isTreeShakingDisabled; 1651 bool get rememberLazies => isTreeShakingDisabled;
1610 1652
1611 bool retainMetadataOf(Element element) { 1653 bool retainMetadataOf(Element element) {
1612 if (mustRetainMetadata) hasRetainedMetadata = true; 1654 if (mustRetainMetadata) hasRetainedMetadata = true;
1613 if (mustRetainMetadata && isNeededForReflection(element)) { 1655 if (mustRetainMetadata && isNeededForReflection(element)) {
1614 for (MetadataAnnotation metadata in element.metadata) { 1656 for (MetadataAnnotation metadata in element.metadata) {
1615 metadata.ensureResolved(compiler) 1657 metadata.ensureResolved(compiler);
1616 .value.accept(new ConstantCopier(compiler.constantHandler)); 1658 compiler.constantHandler.addCompileTimeConstantForEmission(
1659 metadata.value);
1617 } 1660 }
1618 return true; 1661 return true;
1619 } 1662 }
1620 return false; 1663 return false;
1621 } 1664 }
1622 1665
1623 Future onLibraryLoaded(LibraryElement library, Uri uri) { 1666 Future onLibraryLoaded(LibraryElement library, Uri uri) {
1624 if (uri == Uri.parse('dart:_js_mirrors')) { 1667 if (uri == Uri.parse('dart:_js_mirrors')) {
1625 disableTreeShakingMarker = 1668 disableTreeShakingMarker =
1626 library.find(const SourceString('disableTreeShaking')); 1669 library.find(const SourceString('disableTreeShaking'));
1627 preserveMetadataMarker = 1670 preserveMetadataMarker =
1628 library.find(const SourceString('preserveMetadata')); 1671 library.find(const SourceString('preserveMetadata'));
1629 } else if (uri == Uri.parse('dart:_js_names')) { 1672 } else if (uri == Uri.parse('dart:_js_names')) {
1630 preserveNamesMarker = 1673 preserveNamesMarker =
1631 library.find(const SourceString('preserveNames')); 1674 library.find(const SourceString('preserveNames'));
1632 } 1675 }
1633 return new Future.value(); 1676 return new Future.value();
1634 } 1677 }
1635 1678
1636 void registerMetadataInstantiatedType(DartType type, TreeElements elements) {
1637 if (mustRetainMetadata) {
1638 compiler.constantHandler.registerInstantiatedType(type, elements);
1639 } else {
1640 metadataInstantiatedTypes.add(new Dependency(type, elements));
1641 }
1642 }
1643
1644 void registerMetadataStaticUse(Element element) {
1645 if (mustRetainMetadata) {
1646 compiler.constantHandler.registerStaticUse(element);
1647 } else {
1648 metadataStaticUse.add(element);
1649 }
1650 }
1651
1652 void registerMetadataGetOfStaticFunction(FunctionElement element) {
1653 if (mustRetainMetadata) {
1654 compiler.constantHandler.registerGetOfStaticFunction(element);
1655 } else {
1656 metadataGetOfStaticFunction.add(element);
1657 }
1658 }
1659
1660 void registerMirrorUsage(Set<String> symbols, 1679 void registerMirrorUsage(Set<String> symbols,
1661 Set<Element> targets, 1680 Set<Element> targets,
1662 Set<Element> metaTargets) { 1681 Set<Element> metaTargets) {
1663 if (symbols == null && targets == null && metaTargets == null) { 1682 if (symbols == null && targets == null && metaTargets == null) {
1664 // The user didn't specify anything, or there are imports of 1683 // The user didn't specify anything, or there are imports of
1665 // 'dart:mirrors' without @MirrorsUsed. 1684 // 'dart:mirrors' without @MirrorsUsed.
1666 hasInsufficientMirrorsUsed = true; 1685 hasInsufficientMirrorsUsed = true;
1667 return; 1686 return;
1668 } 1687 }
1669 if (symbols != null) symbolsUsed.addAll(symbols); 1688 if (symbols != null) symbolsUsed.addAll(symbols);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 } 1789 }
1771 1790
1772 if (isTreeShakingDisabled) enqueuer.enqueueEverything(); 1791 if (isTreeShakingDisabled) enqueuer.enqueueEverything();
1773 1792
1774 if (mustPreserveNames) compiler.log('Preserving names.'); 1793 if (mustPreserveNames) compiler.log('Preserving names.');
1775 1794
1776 if (mustRetainMetadata) { 1795 if (mustRetainMetadata) {
1777 compiler.log('Retaining metadata.'); 1796 compiler.log('Retaining metadata.');
1778 1797
1779 compiler.libraries.values.forEach(retainMetadataOf); 1798 compiler.libraries.values.forEach(retainMetadataOf);
1780 for (Dependency dependency in metadataInstantiatedTypes) { 1799 for (Dependency dependency in metadataConstants) {
1781 registerMetadataInstantiatedType(dependency.type, dependency.user); 1800 registerCompileTimeConstant(
1801 dependency.constant, dependency.user);
1782 } 1802 }
1783 metadataInstantiatedTypes.clear(); 1803 metadataConstants.clear();
1784 for (Element e in metadataStaticUse) {
1785 registerMetadataStaticUse(e);
1786 }
1787 metadataStaticUse.clear();
1788 for (Element e in metadataGetOfStaticFunction) {
1789 registerMetadataGetOfStaticFunction(e);
1790 }
1791 metadataGetOfStaticFunction.clear();
1792 } 1804 }
1793 } 1805 }
1794 } 1806 }
1795 1807
1796 /// Records that [type] is used by [user.element]. 1808 /// Records that [constant] is used by [user.element].
1797 class Dependency { 1809 class Dependency {
1798 final DartType type; 1810 final Constant constant;
1799 final TreeElements user; 1811 final TreeElements user;
1800 1812
1801 const Dependency(this.type, this.user); 1813 const Dependency(this.constant, this.user);
1802 } 1814 }
1803 1815
1804 /// Used to copy metadata to the the actual constant handler. 1816 /// Used to copy metadata to the the actual constant handler.
1805 class ConstantCopier implements ConstantVisitor { 1817 class ConstantCopier implements ConstantVisitor {
1806 final ConstantHandler target; 1818 final ConstantHandler target;
1807 1819
1808 ConstantCopier(this.target); 1820 ConstantCopier(this.target);
1809 1821
1810 void copy(/* Constant or List<Constant> */ value) { 1822 void copy(/* Constant or List<Constant> */ value) {
1811 if (value is Constant) { 1823 if (value is Constant) {
(...skipping 30 matching lines...) Expand all
1842 copy(constant.values); 1854 copy(constant.values);
1843 copy(constant.protoValue); 1855 copy(constant.protoValue);
1844 copy(constant); 1856 copy(constant);
1845 } 1857 }
1846 1858
1847 void visitConstructed(ConstructedConstant constant) { 1859 void visitConstructed(ConstructedConstant constant) {
1848 copy(constant.fields); 1860 copy(constant.fields);
1849 copy(constant); 1861 copy(constant);
1850 } 1862 }
1851 } 1863 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/enqueue.dart ('k') | sdk/lib/_internal/compiler/implementation/mirrors_used.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698