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

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
ahe 2013/09/30 11:05:26 Extra line.
Johnni Winther 2013/10/01 11:21:48 Done.
741 Constant registerCompileTimeConstant(Constant constant,
742 TreeElements elements) {
743 registerCompileTimeConstantInternal(constant, elements);
744 for (Constant dependency in constant.getDependencies()) {
745 registerCompileTimeConstant(dependency, elements);
746 }
747 }
748
749 void registerCompileTimeConstantInternal(Constant constant,
750 TreeElements elements) {
751 DartType type = constant.computeType(compiler);
ahe 2013/09/30 11:05:26 Add todo to get rid of Constant.computeType?
Johnni Winther 2013/10/01 11:21:48 Done.
752 registerInstantiatedConstantType(type, elements);
753
754 if (constant.isFunction()) {
755 FunctionConstant function = constant;
756 compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element);
757 } else if (constant.isInterceptor()) {
758 // An interceptor constant references the class's prototype chain.
759 InterceptorConstant interceptor = constant;
760 registerInstantiatedConstantType(interceptor.dispatchedType, elements);
761 }
762 }
763
764 void registerInstantiatedConstantType(DartType type, TreeElements elements) {
765 Enqueuer enqueuer = compiler.enqueuer.codegen;
766 enqueuer.registerInstantiatedType(type, elements);
767 if (type is InterfaceType && !type.treatAsRaw &&
768 classNeedsRti(type.element)) {
769 enqueuer.registerStaticUse(getSetRuntimeTypeInfo());
770 }
771 if (type.element == typeImplementation) {
772 // If we use a type literal in a constant, the compile time
773 // constant emitter will generate a call to the createRuntimeType
774 // helper so we register a use of that.
775 enqueuer.registerStaticUse(getCreateRuntimeType());
776 }
777 }
778
779 void registerMetadataConstant(Constant constant, TreeElements elements) {
780 if (mustRetainMetadata) {
781 registerCompileTimeConstant(constant, elements);
782 } else {
783 metadataConstants.add(new Dependency(constant, elements));
784 }
785 }
786
748 void registerInstantiatedClass(ClassElement cls, 787 void registerInstantiatedClass(ClassElement cls,
749 Enqueuer enqueuer, 788 Enqueuer enqueuer,
750 TreeElements elements) { 789 TreeElements elements) {
751 if (!seenAnyClass) { 790 if (!seenAnyClass) {
752 seenAnyClass = true; 791 seenAnyClass = true;
753 if (enqueuer.isResolutionQueue) { 792 if (enqueuer.isResolutionQueue) {
754 // TODO(9577): Make it so that these are not needed when there are no 793 // TODO(9577): Make it so that these are not needed when there are no
755 // native classes. 794 // native classes.
756 enqueue(enqueuer, getNativeInterceptorMethod, elements); 795 enqueue(enqueuer, getNativeInterceptorMethod, elements);
757 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements); 796 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements);
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 1219
1181 void codegen(CodegenWorkItem work) { 1220 void codegen(CodegenWorkItem work) {
1182 Element element = work.element; 1221 Element element = work.element;
1183 var kind = element.kind; 1222 var kind = element.kind;
1184 if (kind == ElementKind.TYPEDEF) return; 1223 if (kind == ElementKind.TYPEDEF) return;
1185 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) { 1224 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) {
1186 // Work around a problem compiling JSNull's constructor. 1225 // Work around a problem compiling JSNull's constructor.
1187 return; 1226 return;
1188 } 1227 }
1189 if (kind.category == ElementCategory.VARIABLE) { 1228 if (kind.category == ElementCategory.VARIABLE) {
1190 Constant initialValue = compiler.constantHandler.compileWorkItem(work); 1229 Constant initialValue =
1230 compiler.constantHandler.getConstantForVariable(element);
1191 if (initialValue != null) { 1231 if (initialValue != null) {
1232 registerCompileTimeConstant(initialValue, work.resolutionTree);
1233 compiler.constantHandler.addCompileTimeConstantForEmission(
1234 initialValue);
1192 return; 1235 return;
1193 } else { 1236 } else {
1194 // If the constant-handler was not able to produce a result we have to 1237 // 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 1238 // go through the builder (below) to generate the lazy initializer for
1196 // the static variable. 1239 // the static variable.
1197 // We also need to register the use of the cyclic-error helper. 1240 // We also need to register the use of the cyclic-error helper.
1198 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper()); 1241 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper());
1199 } 1242 }
1200 } 1243 }
1201 1244
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 if (name == const SourceString('')) return false; 1648 if (name == const SourceString('')) return false;
1606 return symbolsUsed.contains(name.slowToString()); 1649 return symbolsUsed.contains(name.slowToString());
1607 } 1650 }
1608 1651
1609 bool get rememberLazies => isTreeShakingDisabled; 1652 bool get rememberLazies => isTreeShakingDisabled;
1610 1653
1611 bool retainMetadataOf(Element element) { 1654 bool retainMetadataOf(Element element) {
1612 if (mustRetainMetadata) hasRetainedMetadata = true; 1655 if (mustRetainMetadata) hasRetainedMetadata = true;
1613 if (mustRetainMetadata && isNeededForReflection(element)) { 1656 if (mustRetainMetadata && isNeededForReflection(element)) {
1614 for (MetadataAnnotation metadata in element.metadata) { 1657 for (MetadataAnnotation metadata in element.metadata) {
1615 metadata.ensureResolved(compiler) 1658 metadata.ensureResolved(compiler);
1616 .value.accept(new ConstantCopier(compiler.constantHandler)); 1659 compiler.constantHandler.addCompileTimeConstantForEmission(
1660 metadata.value);
1617 } 1661 }
1618 return true; 1662 return true;
1619 } 1663 }
1620 return false; 1664 return false;
1621 } 1665 }
1622 1666
1623 Future onLibraryLoaded(LibraryElement library, Uri uri) { 1667 Future onLibraryLoaded(LibraryElement library, Uri uri) {
1624 if (uri == Uri.parse('dart:_js_mirrors')) { 1668 if (uri == Uri.parse('dart:_js_mirrors')) {
1625 disableTreeShakingMarker = 1669 disableTreeShakingMarker =
1626 library.find(const SourceString('disableTreeShaking')); 1670 library.find(const SourceString('disableTreeShaking'));
1627 preserveMetadataMarker = 1671 preserveMetadataMarker =
1628 library.find(const SourceString('preserveMetadata')); 1672 library.find(const SourceString('preserveMetadata'));
1629 } else if (uri == Uri.parse('dart:_js_names')) { 1673 } else if (uri == Uri.parse('dart:_js_names')) {
1630 preserveNamesMarker = 1674 preserveNamesMarker =
1631 library.find(const SourceString('preserveNames')); 1675 library.find(const SourceString('preserveNames'));
1632 } 1676 }
1633 return new Future.value(); 1677 return new Future.value();
1634 } 1678 }
1635 1679
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, 1680 void registerMirrorUsage(Set<String> symbols,
1661 Set<Element> targets, 1681 Set<Element> targets,
1662 Set<Element> metaTargets) { 1682 Set<Element> metaTargets) {
1663 if (symbols == null && targets == null && metaTargets == null) { 1683 if (symbols == null && targets == null && metaTargets == null) {
1664 // The user didn't specify anything, or there are imports of 1684 // The user didn't specify anything, or there are imports of
1665 // 'dart:mirrors' without @MirrorsUsed. 1685 // 'dart:mirrors' without @MirrorsUsed.
1666 hasInsufficientMirrorsUsed = true; 1686 hasInsufficientMirrorsUsed = true;
1667 return; 1687 return;
1668 } 1688 }
1669 if (symbols != null) symbolsUsed.addAll(symbols); 1689 if (symbols != null) symbolsUsed.addAll(symbols);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 } 1790 }
1771 1791
1772 if (isTreeShakingDisabled) enqueuer.enqueueEverything(); 1792 if (isTreeShakingDisabled) enqueuer.enqueueEverything();
1773 1793
1774 if (mustPreserveNames) compiler.log('Preserving names.'); 1794 if (mustPreserveNames) compiler.log('Preserving names.');
1775 1795
1776 if (mustRetainMetadata) { 1796 if (mustRetainMetadata) {
1777 compiler.log('Retaining metadata.'); 1797 compiler.log('Retaining metadata.');
1778 1798
1779 compiler.libraries.values.forEach(retainMetadataOf); 1799 compiler.libraries.values.forEach(retainMetadataOf);
1780 for (Dependency dependency in metadataInstantiatedTypes) { 1800 for (Dependency dependency in metadataConstants) {
ngeoffray 2013/10/01 08:33:35 Why is that not covered by registerMetadataConstan
Johnni Winther 2013/10/01 11:21:48 This handles the late registration, when [mustReta
1781 registerMetadataInstantiatedType(dependency.type, dependency.user); 1801 registerCompileTimeConstant(
1802 dependency.constant, dependency.user);
1782 } 1803 }
1783 metadataInstantiatedTypes.clear(); 1804 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 } 1805 }
1793 } 1806 }
1794 } 1807 }
1795 1808
1796 /// Records that [type] is used by [user.element]. 1809 /// Records that [constant] is used by [user.element].
1797 class Dependency { 1810 class Dependency {
1798 final DartType type; 1811 final Constant constant;
1799 final TreeElements user; 1812 final TreeElements user;
1800 1813
1801 const Dependency(this.type, this.user); 1814 const Dependency(this.constant, this.user);
1802 } 1815 }
1803 1816
1804 /// Used to copy metadata to the the actual constant handler. 1817 /// Used to copy metadata to the the actual constant handler.
1805 class ConstantCopier implements ConstantVisitor { 1818 class ConstantCopier implements ConstantVisitor {
1806 final ConstantHandler target; 1819 final ConstantHandler target;
1807 1820
1808 ConstantCopier(this.target); 1821 ConstantCopier(this.target);
1809 1822
1810 void copy(/* Constant or List<Constant> */ value) { 1823 void copy(/* Constant or List<Constant> */ value) {
1811 if (value is Constant) { 1824 if (value is Constant) {
(...skipping 30 matching lines...) Expand all
1842 copy(constant.values); 1855 copy(constant.values);
1843 copy(constant.protoValue); 1856 copy(constant.protoValue);
1844 copy(constant); 1857 copy(constant);
1845 } 1858 }
1846 1859
1847 void visitConstructed(ConstructedConstant constant) { 1860 void visitConstructed(ConstructedConstant constant) {
1848 copy(constant.fields); 1861 copy(constant.fields);
1849 copy(constant); 1862 copy(constant);
1850 } 1863 }
1851 } 1864 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698