Chromium Code Reviews| 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 = constants.getConstantForMetadata(metadata).valu e; |
|
sigurdm
2014/10/01 07:46:47
Long line
Johnni Winther
2014/10/01 08:21:23
Done.
| |
| 1615 constants.addCompileTimeConstantForEmission(constant); | 1615 constants.addCompileTimeConstantForEmission(constant); |
| 1616 } | 1616 } |
| 1617 return true; | 1617 return true; |
| 1618 } | 1618 } |
| 1619 return false; | 1619 return false; |
| 1620 } | 1620 } |
| 1621 | 1621 |
| 1622 void onLibraryCreated(LibraryElement library) { | 1622 void onLibraryCreated(LibraryElement library) { |
| 1623 Uri uri = library.canonicalUri; | 1623 Uri uri = library.canonicalUri; |
| 1624 if (uri == DART_JS_HELPER) { | 1624 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. | 1873 * of a type that is used as a meta target for reflection. |
| 1874 */ | 1874 */ |
| 1875 bool matchesMirrorsMetaTarget(Element element) { | 1875 bool matchesMirrorsMetaTarget(Element element) { |
| 1876 if (metaTargetsUsed.isEmpty) return false; | 1876 if (metaTargetsUsed.isEmpty) return false; |
| 1877 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { | 1877 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { |
| 1878 MetadataAnnotation metadata = link.head; | 1878 MetadataAnnotation metadata = link.head; |
| 1879 // TODO(kasperl): It would be nice if we didn't have to resolve | 1879 // TODO(kasperl): It would be nice if we didn't have to resolve |
| 1880 // all metadata but only stuff that potentially would match one | 1880 // all metadata but only stuff that potentially would match one |
| 1881 // of the used meta targets. | 1881 // of the used meta targets. |
| 1882 metadata.ensureResolved(compiler); | 1882 metadata.ensureResolved(compiler); |
| 1883 Constant value = metadata.constant.value; | 1883 ConstantValue value = metadata.constant.value; |
| 1884 if (value == null) continue; | 1884 if (value == null) continue; |
| 1885 DartType type = value.computeType(compiler); | 1885 DartType type = value.computeType(compiler); |
| 1886 if (metaTargetsUsed.contains(type.element)) return true; | 1886 if (metaTargetsUsed.contains(type.element)) return true; |
| 1887 } | 1887 } |
| 1888 return false; | 1888 return false; |
| 1889 } | 1889 } |
| 1890 | 1890 |
| 1891 /** | 1891 /** |
| 1892 * Visits all classes and computes whether its members are needed for | 1892 * Visits all classes and computes whether its members are needed for |
| 1893 * reflection. | 1893 * reflection. |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2145 | 2145 |
| 2146 void onElementResolved(Element element, TreeElements elements) { | 2146 void onElementResolved(Element element, TreeElements elements) { |
| 2147 LibraryElement library = element.library; | 2147 LibraryElement library = element.library; |
| 2148 if (!library.isPlatformLibrary && !library.canUseNative) return; | 2148 if (!library.isPlatformLibrary && !library.canUseNative) return; |
| 2149 bool hasNoInline = false; | 2149 bool hasNoInline = false; |
| 2150 bool hasNoThrows = false; | 2150 bool hasNoThrows = false; |
| 2151 bool hasNoSideEffects = false; | 2151 bool hasNoSideEffects = false; |
| 2152 for (MetadataAnnotation metadata in element.metadata) { | 2152 for (MetadataAnnotation metadata in element.metadata) { |
| 2153 metadata.ensureResolved(compiler); | 2153 metadata.ensureResolved(compiler); |
| 2154 if (!metadata.constant.value.isConstructedObject) continue; | 2154 if (!metadata.constant.value.isConstructedObject) continue; |
| 2155 ObjectConstant value = metadata.constant.value; | 2155 ObjectConstantValue value = metadata.constant.value; |
| 2156 ClassElement cls = value.type.element; | 2156 ClassElement cls = value.type.element; |
| 2157 if (cls == noInlineClass) { | 2157 if (cls == noInlineClass) { |
| 2158 hasNoInline = true; | 2158 hasNoInline = true; |
| 2159 if (VERBOSE_OPTIMIZER_HINTS) { | 2159 if (VERBOSE_OPTIMIZER_HINTS) { |
| 2160 compiler.reportHint(element, | 2160 compiler.reportHint(element, |
| 2161 MessageKind.GENERIC, | 2161 MessageKind.GENERIC, |
| 2162 {'text': "Cannot inline"}); | 2162 {'text': "Cannot inline"}); |
| 2163 } | 2163 } |
| 2164 inlineCache.markAsNonInlinable(element); | 2164 inlineCache.markAsNonInlinable(element); |
| 2165 } else if (cls == noThrowsClass) { | 2165 } else if (cls == noThrowsClass) { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2409 assert(registry.isForResolution); | 2409 assert(registry.isForResolution); |
| 2410 // Make sure that _internals.Symbol.validated is registered. | 2410 // Make sure that _internals.Symbol.validated is registered. |
| 2411 assert(backend.compiler.symbolValidatedConstructor != null); | 2411 assert(backend.compiler.symbolValidatedConstructor != null); |
| 2412 registerBackendStaticInvocation( | 2412 registerBackendStaticInvocation( |
| 2413 backend.compiler.symbolValidatedConstructor, registry); | 2413 backend.compiler.symbolValidatedConstructor, registry); |
| 2414 } | 2414 } |
| 2415 } | 2415 } |
| 2416 | 2416 |
| 2417 /// Records that [constant] is used by the element behind [registry]. | 2417 /// Records that [constant] is used by the element behind [registry]. |
| 2418 class Dependency { | 2418 class Dependency { |
| 2419 final Constant constant; | 2419 final ConstantValue constant; |
| 2420 final Element annotatedElement; | 2420 final Element annotatedElement; |
| 2421 | 2421 |
| 2422 const Dependency(this.constant, this.annotatedElement); | 2422 const Dependency(this.constant, this.annotatedElement); |
| 2423 } | 2423 } |
| OLD | NEW |