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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
8 | 8 |
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 String name = namer.getInterceptorName(getInterceptorMethod, classes); | 698 String name = namer.getInterceptorName(getInterceptorMethod, classes); |
699 if (classes.contains(jsInterceptorClass)) { | 699 if (classes.contains(jsInterceptorClass)) { |
700 // We can't use a specialized [getInterceptorMethod], so we make | 700 // We can't use a specialized [getInterceptorMethod], so we make |
701 // sure we emit the one with all checks. | 701 // sure we emit the one with all checks. |
702 specializedGetInterceptors[name] = interceptedClasses; | 702 specializedGetInterceptors[name] = interceptedClasses; |
703 } else { | 703 } else { |
704 specializedGetInterceptors[name] = classes; | 704 specializedGetInterceptors[name] = classes; |
705 } | 705 } |
706 } | 706 } |
707 | 707 |
708 void registerCompileTimeConstant(Constant constant, Registry registry) { | 708 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { |
709 registerCompileTimeConstantInternal(constant, registry); | 709 registerCompileTimeConstantInternal(constant, registry); |
710 for (Constant dependency in constant.getDependencies()) { | 710 for (ConstantValue dependency in constant.getDependencies()) { |
711 registerCompileTimeConstant(dependency, registry); | 711 registerCompileTimeConstant(dependency, registry); |
712 } | 712 } |
713 } | 713 } |
714 | 714 |
715 void registerCompileTimeConstantInternal(Constant constant, | 715 void registerCompileTimeConstantInternal(ConstantValue constant, |
716 Registry registry) { | 716 Registry registry) { |
717 DartType type = constant.computeType(compiler); | 717 DartType type = constant.computeType(compiler); |
718 registerInstantiatedConstantType(type, registry); | 718 registerInstantiatedConstantType(type, registry); |
719 | 719 |
720 if (constant.isFunction) { | 720 if (constant.isFunction) { |
721 FunctionConstant function = constant; | 721 FunctionConstantValue function = constant; |
722 registry.registerGetOfStaticFunction(function.element); | 722 registry.registerGetOfStaticFunction(function.element); |
723 } else if (constant.isInterceptor) { | 723 } else if (constant.isInterceptor) { |
724 // An interceptor constant references the class's prototype chain. | 724 // An interceptor constant references the class's prototype chain. |
725 InterceptorConstant interceptor = constant; | 725 InterceptorConstantValue interceptor = constant; |
726 registerInstantiatedConstantType(interceptor.dispatchedType, registry); | 726 registerInstantiatedConstantType(interceptor.dispatchedType, registry); |
727 } else if (constant.isType) { | 727 } else if (constant.isType) { |
728 enqueueInResolution(getCreateRuntimeType(), registry); | 728 enqueueInResolution(getCreateRuntimeType(), registry); |
729 registry.registerInstantiation(typeImplementation.rawType); | 729 registry.registerInstantiation(typeImplementation.rawType); |
730 } | 730 } |
731 } | 731 } |
732 | 732 |
733 void registerInstantiatedConstantType(DartType type, Registry registry) { | 733 void registerInstantiatedConstantType(DartType type, Registry registry) { |
734 DartType instantiatedType = | 734 DartType instantiatedType = |
735 type.isFunctionType ? compiler.functionClass.rawType : type; | 735 type.isFunctionType ? compiler.functionClass.rawType : type; |
736 if (type is InterfaceType) { | 736 if (type is InterfaceType) { |
737 registry.registerInstantiation(instantiatedType); | 737 registry.registerInstantiation(instantiatedType); |
738 if (!type.treatAsRaw && classNeedsRti(type.element)) { | 738 if (!type.treatAsRaw && classNeedsRti(type.element)) { |
739 registry.registerStaticInvocation(getSetRuntimeTypeInfo()); | 739 registry.registerStaticInvocation(getSetRuntimeTypeInfo()); |
740 } | 740 } |
741 if (type.element == typeImplementation) { | 741 if (type.element == typeImplementation) { |
742 // If we use a type literal in a constant, the compile time | 742 // If we use a type literal in a constant, the compile time |
743 // constant emitter will generate a call to the createRuntimeType | 743 // constant emitter will generate a call to the createRuntimeType |
744 // helper so we register a use of that. | 744 // helper so we register a use of that. |
745 registry.registerStaticInvocation(getCreateRuntimeType()); | 745 registry.registerStaticInvocation(getCreateRuntimeType()); |
746 } | 746 } |
747 } | 747 } |
748 } | 748 } |
749 | 749 |
750 void registerMetadataConstant(MetadataAnnotation metadata, | 750 void registerMetadataConstant(MetadataAnnotation metadata, |
751 Element annotatedElement, | 751 Element annotatedElement, |
752 Registry registry) { | 752 Registry registry) { |
753 assert(registry.isForResolution); | 753 assert(registry.isForResolution); |
754 Constant constant = constants.getConstantForMetadata(metadata).value; | 754 ConstantValue constant = constants.getConstantForMetadata(metadata).value; |
755 registerCompileTimeConstant(constant, registry); | 755 registerCompileTimeConstant(constant, registry); |
756 metadataConstants.add(new Dependency(constant, annotatedElement)); | 756 metadataConstants.add(new Dependency(constant, annotatedElement)); |
757 } | 757 } |
758 | 758 |
759 void registerInstantiatedClass(ClassElement cls, | 759 void registerInstantiatedClass(ClassElement cls, |
760 Enqueuer enqueuer, | 760 Enqueuer enqueuer, |
761 Registry registry) { | 761 Registry registry) { |
762 if (!cls.typeVariables.isEmpty) { | 762 if (!cls.typeVariables.isEmpty) { |
763 typeVariableHandler.registerClassWithTypeVariables(cls); | 763 typeVariableHandler.registerClassWithTypeVariables(cls); |
764 } | 764 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 | 1147 |
1148 void codegen(CodegenWorkItem work) { | 1148 void codegen(CodegenWorkItem work) { |
1149 Element element = work.element; | 1149 Element element = work.element; |
1150 var kind = element.kind; | 1150 var kind = element.kind; |
1151 if (kind == ElementKind.TYPEDEF) return; | 1151 if (kind == ElementKind.TYPEDEF) return; |
1152 if (element.isConstructor && element.enclosingClass == jsNullClass) { | 1152 if (element.isConstructor && element.enclosingClass == jsNullClass) { |
1153 // Work around a problem compiling JSNull's constructor. | 1153 // Work around a problem compiling JSNull's constructor. |
1154 return; | 1154 return; |
1155 } | 1155 } |
1156 if (kind.category == ElementCategory.VARIABLE) { | 1156 if (kind.category == ElementCategory.VARIABLE) { |
1157 ConstExp initialValue = constants.getConstantForVariable(element); | 1157 ConstantExpression initialValue = constants.getConstantForVariable(element
); |
1158 if (initialValue != null) { | 1158 if (initialValue != null) { |
1159 registerCompileTimeConstant(initialValue.value, work.registry); | 1159 registerCompileTimeConstant(initialValue.value, work.registry); |
1160 constants.addCompileTimeConstantForEmission(initialValue.value); | 1160 constants.addCompileTimeConstantForEmission(initialValue.value); |
1161 // We don't need to generate code for static or top-level | 1161 // We don't need to generate code for static or top-level |
1162 // variables. For instance variables, we may need to generate | 1162 // variables. For instance variables, we may need to generate |
1163 // the checked setter. | 1163 // the checked setter. |
1164 if (Elements.isStaticOrTopLevel(element)) return; | 1164 if (Elements.isStaticOrTopLevel(element)) return; |
1165 } else { | 1165 } else { |
1166 // If the constant-handler was not able to produce a result we have to | 1166 // If the constant-handler was not able to produce a result we have to |
1167 // go through the builder (below) to generate the lazy initializer for | 1167 // go through the builder (below) to generate the lazy initializer for |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 if (hasInsufficientMirrorsUsed) return mustPreserveNames; | 1604 if (hasInsufficientMirrorsUsed) return mustPreserveNames; |
1605 if (name == '') return false; | 1605 if (name == '') return false; |
1606 return symbolsUsed.contains(name); | 1606 return symbolsUsed.contains(name); |
1607 } | 1607 } |
1608 | 1608 |
1609 bool retainMetadataOf(Element element) { | 1609 bool retainMetadataOf(Element element) { |
1610 if (mustRetainMetadata) hasRetainedMetadata = true; | 1610 if (mustRetainMetadata) hasRetainedMetadata = true; |
1611 if (mustRetainMetadata && referencedFromMirrorSystem(element)) { | 1611 if (mustRetainMetadata && referencedFromMirrorSystem(element)) { |
1612 for (MetadataAnnotation metadata in element.metadata) { | 1612 for (MetadataAnnotation metadata in element.metadata) { |
1613 metadata.ensureResolved(compiler); | 1613 metadata.ensureResolved(compiler); |
1614 Constant constant = constants.getConstantForMetadata(metadata).value; | 1614 ConstantValue constant = |
| 1615 constants.getConstantForMetadata(metadata).value; |
1615 constants.addCompileTimeConstantForEmission(constant); | 1616 constants.addCompileTimeConstantForEmission(constant); |
1616 } | 1617 } |
1617 return true; | 1618 return true; |
1618 } | 1619 } |
1619 return false; | 1620 return false; |
1620 } | 1621 } |
1621 | 1622 |
1622 void onLibraryCreated(LibraryElement library) { | 1623 void onLibraryCreated(LibraryElement library) { |
1623 Uri uri = library.canonicalUri; | 1624 Uri uri = library.canonicalUri; |
1624 if (uri == DART_JS_HELPER) { | 1625 if (uri == DART_JS_HELPER) { |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 * of a type that is used as a meta target for reflection. | 1874 * of a type that is used as a meta target for reflection. |
1874 */ | 1875 */ |
1875 bool matchesMirrorsMetaTarget(Element element) { | 1876 bool matchesMirrorsMetaTarget(Element element) { |
1876 if (metaTargetsUsed.isEmpty) return false; | 1877 if (metaTargetsUsed.isEmpty) return false; |
1877 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { | 1878 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { |
1878 MetadataAnnotation metadata = link.head; | 1879 MetadataAnnotation metadata = link.head; |
1879 // TODO(kasperl): It would be nice if we didn't have to resolve | 1880 // TODO(kasperl): It would be nice if we didn't have to resolve |
1880 // all metadata but only stuff that potentially would match one | 1881 // all metadata but only stuff that potentially would match one |
1881 // of the used meta targets. | 1882 // of the used meta targets. |
1882 metadata.ensureResolved(compiler); | 1883 metadata.ensureResolved(compiler); |
1883 Constant value = metadata.constant.value; | 1884 ConstantValue value = metadata.constant.value; |
1884 if (value == null) continue; | 1885 if (value == null) continue; |
1885 DartType type = value.computeType(compiler); | 1886 DartType type = value.computeType(compiler); |
1886 if (metaTargetsUsed.contains(type.element)) return true; | 1887 if (metaTargetsUsed.contains(type.element)) return true; |
1887 } | 1888 } |
1888 return false; | 1889 return false; |
1889 } | 1890 } |
1890 | 1891 |
1891 /** | 1892 /** |
1892 * Visits all classes and computes whether its members are needed for | 1893 * Visits all classes and computes whether its members are needed for |
1893 * reflection. | 1894 * reflection. |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 | 2146 |
2146 void onElementResolved(Element element, TreeElements elements) { | 2147 void onElementResolved(Element element, TreeElements elements) { |
2147 LibraryElement library = element.library; | 2148 LibraryElement library = element.library; |
2148 if (!library.isPlatformLibrary && !library.canUseNative) return; | 2149 if (!library.isPlatformLibrary && !library.canUseNative) return; |
2149 bool hasNoInline = false; | 2150 bool hasNoInline = false; |
2150 bool hasNoThrows = false; | 2151 bool hasNoThrows = false; |
2151 bool hasNoSideEffects = false; | 2152 bool hasNoSideEffects = false; |
2152 for (MetadataAnnotation metadata in element.metadata) { | 2153 for (MetadataAnnotation metadata in element.metadata) { |
2153 metadata.ensureResolved(compiler); | 2154 metadata.ensureResolved(compiler); |
2154 if (!metadata.constant.value.isConstructedObject) continue; | 2155 if (!metadata.constant.value.isConstructedObject) continue; |
2155 ObjectConstant value = metadata.constant.value; | 2156 ObjectConstantValue value = metadata.constant.value; |
2156 ClassElement cls = value.type.element; | 2157 ClassElement cls = value.type.element; |
2157 if (cls == noInlineClass) { | 2158 if (cls == noInlineClass) { |
2158 hasNoInline = true; | 2159 hasNoInline = true; |
2159 if (VERBOSE_OPTIMIZER_HINTS) { | 2160 if (VERBOSE_OPTIMIZER_HINTS) { |
2160 compiler.reportHint(element, | 2161 compiler.reportHint(element, |
2161 MessageKind.GENERIC, | 2162 MessageKind.GENERIC, |
2162 {'text': "Cannot inline"}); | 2163 {'text': "Cannot inline"}); |
2163 } | 2164 } |
2164 inlineCache.markAsNonInlinable(element); | 2165 inlineCache.markAsNonInlinable(element); |
2165 } else if (cls == noThrowsClass) { | 2166 } else if (cls == noThrowsClass) { |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2409 assert(registry.isForResolution); | 2410 assert(registry.isForResolution); |
2410 // Make sure that _internals.Symbol.validated is registered. | 2411 // Make sure that _internals.Symbol.validated is registered. |
2411 assert(backend.compiler.symbolValidatedConstructor != null); | 2412 assert(backend.compiler.symbolValidatedConstructor != null); |
2412 registerBackendStaticInvocation( | 2413 registerBackendStaticInvocation( |
2413 backend.compiler.symbolValidatedConstructor, registry); | 2414 backend.compiler.symbolValidatedConstructor, registry); |
2414 } | 2415 } |
2415 } | 2416 } |
2416 | 2417 |
2417 /// Records that [constant] is used by the element behind [registry]. | 2418 /// Records that [constant] is used by the element behind [registry]. |
2418 class Dependency { | 2419 class Dependency { |
2419 final Constant constant; | 2420 final ConstantValue constant; |
2420 final Element annotatedElement; | 2421 final Element annotatedElement; |
2421 | 2422 |
2422 const Dependency(this.constant, this.annotatedElement); | 2423 const Dependency(this.constant, this.annotatedElement); |
2423 } | 2424 } |
OLD | NEW |