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

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

Issue 340783011: Take inheritance into account when computing the elements accessible by mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebased + fixes Created 6 years, 5 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 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 static final Uri DART_JS_MIRRORS = 61 static final Uri DART_JS_MIRRORS =
62 new Uri(scheme: 'dart', path: '_js_mirrors'); 62 new Uri(scheme: 'dart', path: '_js_mirrors');
63 static final Uri DART_JS_NAMES = 63 static final Uri DART_JS_NAMES =
64 new Uri(scheme: 'dart', path: '_js_names'); 64 new Uri(scheme: 'dart', path: '_js_names');
65 static final Uri DART_ISOLATE_HELPER = 65 static final Uri DART_ISOLATE_HELPER =
66 new Uri(scheme: 'dart', path: '_isolate_helper'); 66 new Uri(scheme: 'dart', path: '_isolate_helper');
67 67
68 static const String INVOKE_ON = '_getCachedInvocation'; 68 static const String INVOKE_ON = '_getCachedInvocation';
69 static const String START_ROOT_ISOLATE = 'startRootIsolate'; 69 static const String START_ROOT_ISOLATE = 'startRootIsolate';
70 70
71 /// Set of classes that need to be considered for reflection although not
72 /// otherwise visible during resolution.
73 Iterable<ClassElement> get classesRequiredForReflection {
74 // TODO(herhut): Clean this up when classes needed for rti are tracked.
75 return [closureClass, jsIndexableClass];
76 }
77
71 SsaBuilderTask builder; 78 SsaBuilderTask builder;
72 SsaOptimizerTask optimizer; 79 SsaOptimizerTask optimizer;
73 SsaCodeGeneratorTask generator; 80 SsaCodeGeneratorTask generator;
74 CodeEmitterTask emitter; 81 CodeEmitterTask emitter;
75 82
76 /** 83 /**
77 * The generated code as a js AST for compiled methods. 84 * The generated code as a js AST for compiled methods.
78 */ 85 */
79 Map<Element, jsAst.Expression> get generatedCode { 86 Map<Element, jsAst.Expression> get generatedCode {
80 return compiler.enqueuer.codegen.generatedCode; 87 return compiler.enqueuer.codegen.generatedCode;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 /// True if a call to disableTreeShaking has been seen. 287 /// True if a call to disableTreeShaking has been seen.
281 bool isTreeShakingDisabled = false; 288 bool isTreeShakingDisabled = false;
282 289
283 /// True if there isn't sufficient @MirrorsUsed data. 290 /// True if there isn't sufficient @MirrorsUsed data.
284 bool hasInsufficientMirrorsUsed = false; 291 bool hasInsufficientMirrorsUsed = false;
285 292
286 /// List of constants from metadata. If metadata must be preserved, 293 /// List of constants from metadata. If metadata must be preserved,
287 /// these constants must be registered. 294 /// these constants must be registered.
288 final List<Dependency> metadataConstants = <Dependency>[]; 295 final List<Dependency> metadataConstants = <Dependency>[];
289 296
290 /// List of symbols that the user has requested for reflection.
291 final Set<String> symbolsUsed = new Set<String>();
292
293 /// List of elements that the user has requested for reflection. 297 /// List of elements that the user has requested for reflection.
294 final Set<Element> targetsUsed = new Set<Element>(); 298 final Set<Element> targetsUsed = new Set<Element>();
295 299
296 /// List of annotations provided by user that indicate that the annotated 300 /// List of annotations provided by user that indicate that the annotated
297 /// element must be retained. 301 /// element must be retained.
298 final Set<Element> metaTargetsUsed = new Set<Element>(); 302 final Set<Element> metaTargetsUsed = new Set<Element>();
299 303
304 /// Set of methods that are needed by reflection. Computed using
305 /// [computeMembersNeededForReflection] on first use.
306 Iterable<Element> _membersNeededForReflection = null;
307 Iterable<Element> get membersNeededForReflection {
308 assert(_membersNeededForReflection != null);
309 return _membersNeededForReflection;
310 }
311
312 /// List of symbols that the user has requested for reflection.
313 final Set<String> symbolsUsed = new Set<String>();
314
300 /// List of elements that the backend may use. 315 /// List of elements that the backend may use.
301 final Set<Element> helpersUsed = new Set<Element>(); 316 final Set<Element> helpersUsed = new Set<Element>();
302 317
303
304 /// Set of typedefs that are used as type literals. 318 /// Set of typedefs that are used as type literals.
305 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); 319 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>();
306 320
307 /// All the checked mode helpers. 321 /// All the checked mode helpers.
308 static const checkedModeHelpers = CheckedModeHelper.helpers; 322 static const checkedModeHelpers = CheckedModeHelper.helpers;
309 323
310 // Checked mode helpers indexed by name. 324 // Checked mode helpers indexed by name.
311 Map<String, CheckedModeHelper> checkedModeHelperByName = 325 Map<String, CheckedModeHelper> checkedModeHelperByName =
312 new Map<String, CheckedModeHelper>.fromIterable( 326 new Map<String, CheckedModeHelper>.fromIterable(
313 checkedModeHelpers, 327 checkedModeHelpers,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 if (invokedReflectively(element.enclosingElement)) return true; 399 if (invokedReflectively(element.enclosingElement)) return true;
386 } 400 }
387 401
388 if (element.isField) { 402 if (element.isField) {
389 if (Elements.isStaticOrTopLevel(element) 403 if (Elements.isStaticOrTopLevel(element)
390 && (element.isFinal || element.isConst)) { 404 && (element.isFinal || element.isConst)) {
391 return false; 405 return false;
392 } 406 }
393 } 407 }
394 408
395 return isNeededForReflection(element.declaration); 409 return isAccessibleByReflection(element.declaration);
396 } 410 }
397 411
398 bool canBeUsedForGlobalOptimizations(Element element) { 412 bool canBeUsedForGlobalOptimizations(Element element) {
399 return !usedByBackend(element) && !invokedReflectively(element); 413 return !usedByBackend(element) && !invokedReflectively(element);
400 } 414 }
401 415
402 bool isInterceptorClass(ClassElement element) { 416 bool isInterceptorClass(ClassElement element) {
403 if (element == null) return false; 417 if (element == null) return false;
404 if (Elements.isNativeOrExtendsNative(element)) return true; 418 if (Elements.isNativeOrExtendsNative(element)) return true;
405 if (interceptedClasses.contains(element)) return true; 419 if (interceptedClasses.contains(element)) return true;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 if (e != null) enqueue(world, e, registry); 804 if (e != null) enqueue(world, e, registry);
791 } 805 }
792 if (TRACE_CALLS) { 806 if (TRACE_CALLS) {
793 traceHelper = findHelper('traceHelper'); 807 traceHelper = findHelper('traceHelper');
794 assert(traceHelper != null); 808 assert(traceHelper != null);
795 enqueueInResolution(traceHelper, registry); 809 enqueueInResolution(traceHelper, registry);
796 } 810 }
797 registerCheckedModeHelpers(registry); 811 registerCheckedModeHelpers(registry);
798 } 812 }
799 813
800 onResolutionComplete() => rti.computeClassesNeedingRti(); 814 onResolutionComplete() {
815 computeMembersNeededForReflection();
816 rti.computeClassesNeedingRti();
817 }
801 818
802 void registerGetRuntimeTypeArgument(Registry registry) { 819 void registerGetRuntimeTypeArgument(Registry registry) {
803 enqueueInResolution(getGetRuntimeTypeArgument(), registry); 820 enqueueInResolution(getGetRuntimeTypeArgument(), registry);
804 enqueueInResolution(getGetTypeArgumentByIndex(), registry); 821 enqueueInResolution(getGetTypeArgumentByIndex(), registry);
805 enqueueInResolution(getCopyTypeArguments(), registry); 822 enqueueInResolution(getCopyTypeArguments(), registry);
806 } 823 }
807 824
808 void registerGenericCallMethod(Element callMethod, 825 void registerGenericCallMethod(Element callMethod,
809 Enqueuer enqueuer, Registry registry) { 826 Enqueuer enqueuer, Registry registry) {
810 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { 827 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 symbolsUsed.add(name); 1455 symbolsUsed.add(name);
1439 if (name.endsWith('=')) { 1456 if (name.endsWith('=')) {
1440 symbolsUsed.add(name.substring(0, name.length - 1)); 1457 symbolsUsed.add(name.substring(0, name.length - 1));
1441 } 1458 }
1442 } 1459 }
1443 1460
1444 /// Called when [:new Symbol(...):] is seen. 1461 /// Called when [:new Symbol(...):] is seen.
1445 void registerNewSymbol(Registry registry) { 1462 void registerNewSymbol(Registry registry) {
1446 } 1463 }
1447 1464
1448 /// Should [element] (a getter) be retained for reflection? 1465 /// Should [element] (a getter) that would normally not be generated due to
1449 bool shouldRetainGetter(Element element) => isNeededForReflection(element); 1466 /// treeshaking be retained for reflection?
1467 bool shouldRetainGetter(Element element) {
1468 return isTreeShakingDisabled && isAccessibleByReflection(element);
1469 }
1450 1470
1451 /// Should [element] (a setter) be retained for reflection? 1471 /// Should [element] (a setter) hat would normally not be generated due to
1452 bool shouldRetainSetter(Element element) => isNeededForReflection(element); 1472 /// treeshaking be retained for reflection?
1473 bool shouldRetainSetter(Element element) {
1474 return isTreeShakingDisabled && isAccessibleByReflection(element);
1475 }
1453 1476
1454 /// Should [name] be retained for reflection? 1477 /// Should [name] be retained for reflection?
1455 bool shouldRetainName(String name) { 1478 bool shouldRetainName(String name) {
1456 if (hasInsufficientMirrorsUsed) return mustPreserveNames; 1479 if (hasInsufficientMirrorsUsed) return mustPreserveNames;
1457 if (name == '') return false; 1480 if (name == '') return false;
1458 return symbolsUsed.contains(name); 1481 return symbolsUsed.contains(name);
1459 } 1482 }
1460 1483
1461 bool get rememberLazies => isTreeShakingDisabled; 1484 bool get rememberLazies => isTreeShakingDisabled;
1462 1485
1463 bool retainMetadataOf(Element element) { 1486 bool retainMetadataOf(Element element) {
1464 if (mustRetainMetadata) hasRetainedMetadata = true; 1487 if (mustRetainMetadata) hasRetainedMetadata = true;
1465 if (mustRetainMetadata && isNeededForReflection(element)) { 1488 if (mustRetainMetadata && referencedFromMirrorSystem(element)) {
1466 for (MetadataAnnotation metadata in element.metadata) { 1489 for (MetadataAnnotation metadata in element.metadata) {
1467 metadata.ensureResolved(compiler); 1490 metadata.ensureResolved(compiler);
1468 Constant constant = constants.getConstantForMetadata(metadata); 1491 Constant constant = constants.getConstantForMetadata(metadata);
1469 constants.addCompileTimeConstantForEmission(constant); 1492 constants.addCompileTimeConstantForEmission(constant);
1470 } 1493 }
1471 return true; 1494 return true;
1472 } 1495 }
1473 return false; 1496 return false;
1474 } 1497 }
1475 1498
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 /** 1705 /**
1683 * Returns `true` if [element] can be accessed through reflection, that is, 1706 * Returns `true` if [element] can be accessed through reflection, that is,
1684 * is in the set of elements covered by a `MirrorsUsed` annotation. 1707 * is in the set of elements covered by a `MirrorsUsed` annotation.
1685 * 1708 *
1686 * This property is used to tag emitted elements with a marker which is 1709 * This property is used to tag emitted elements with a marker which is
1687 * checked by the runtime system to throw an exception if an element is 1710 * checked by the runtime system to throw an exception if an element is
1688 * accessed (invoked, get, set) that is not accessible for the reflective 1711 * accessed (invoked, get, set) that is not accessible for the reflective
1689 * system. 1712 * system.
1690 */ 1713 */
1691 bool isAccessibleByReflection(Element element) { 1714 bool isAccessibleByReflection(Element element) {
1692 // TODO(ahe): This isn't sufficient: simply importing dart:mirrors 1715 if (element.isClass) {
1693 // causes hasInsufficientMirrorsUsed to become true. 1716 element = getDartClass(element);
1694 if (hasInsufficientMirrorsUsed) return true; 1717 }
1695 return isNeededForReflection(element); 1718 // We have to treat closure classes specially here, as they only come into
1719 // existence after [membersNeededForReflection] has been computed.
1720 if (element is SynthesizedCallMethodElementX) {
1721 SynthesizedCallMethodElementX closure = element;
1722 element = closure.expression;
1723 } else if (element is ClosureClassElement) {
1724 ClosureClassElement closure = element;
1725 element = closure.methodElement;
1726 }
1727 return membersNeededForReflection.contains(element);
1696 } 1728 }
1697 1729
1698 /** 1730 /**
1699 * Returns `true` if the emitter must emit the element even though there 1731 * Returns true if the element has to be resolved due to a mirrorsUsed
1700 * is no direct use in the program, but because the reflective system may 1732 * annotation. If we have insufficient mirrors used annotations, we only
1701 * need to access it. 1733 * keep additonal elements if treeshaking has been disabled.
1702 */ 1734 */
1703 bool isNeededForReflection(Element element) { 1735 bool requiredByMirrorSystem(Element element) {
1704 if (!isTreeShakingDisabled) return false; 1736 return hasInsufficientMirrorsUsed && isTreeShakingDisabled ||
1705 element = getDartClass(element); 1737 matchesMirrorsMetaTarget(element) ||
1706 if (hasInsufficientMirrorsUsed) return isTreeShakingDisabled; 1738 targetsUsed.contains(element);
1707 /// Record the name of [element] in [symbolsUsed]. Return true for 1739 }
1708 /// convenience.
1709 bool registerNameOf(Element element) {
1710 symbolsUsed.add(element.name);
1711 if (element.isConstructor) {
1712 symbolsUsed.add(element.enclosingClass.name);
1713 }
1714 return true;
1715 }
1716 1740
1717 Element enclosing = element.enclosingElement; 1741 /**
1718 if (enclosing != null && isNeededForReflection(enclosing)) { 1742 * Returns true if the element matches a mirrorsUsed annotation. If
1719 return registerNameOf(element); 1743 * we have insufficient mirrorsUsed information, this returns true for
1720 } 1744 * all elements, as they might all be potentially referenced.
1745 */
1746 bool referencedFromMirrorSystem(Element element, [recursive = true]) {
1747 Element enclosing = recursive ? element.enclosingElement : null;
1721 1748
1722 if (isNeededThroughMetaTarget(element)) { 1749 return hasInsufficientMirrorsUsed ||
1723 return registerNameOf(element); 1750 matchesMirrorsMetaTarget(element) ||
1724 } 1751 targetsUsed.contains(element) ||
1725 1752 (enclosing != null && referencedFromMirrorSystem(enclosing));
1726 if (!targetsUsed.isEmpty && targetsUsed.contains(element)) {
1727 return registerNameOf(element);
1728 }
1729
1730 // TODO(kasperl): Consider caching this information. It is consulted
1731 // multiple times because of the way we deal with the enclosing element.
1732 return false;
1733 } 1753 }
1734 1754
1735 /** 1755 /**
1736 * Returns `true` if the element is needed because it has an annotation 1756 * Returns `true` if the element is needed because it has an annotation
1737 * of a type that is used as a meta target for reflection. 1757 * of a type that is used as a meta target for reflection.
1738 */ 1758 */
1739 bool isNeededThroughMetaTarget(Element element) { 1759 bool matchesMirrorsMetaTarget(Element element) {
1740 if (metaTargetsUsed.isEmpty) return false; 1760 if (metaTargetsUsed.isEmpty) return false;
1741 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { 1761 for (Link link = element.metadata; !link.isEmpty; link = link.tail) {
1742 MetadataAnnotation metadata = link.head; 1762 MetadataAnnotation metadata = link.head;
1743 // TODO(kasperl): It would be nice if we didn't have to resolve 1763 // TODO(kasperl): It would be nice if we didn't have to resolve
1744 // all metadata but only stuff that potentially would match one 1764 // all metadata but only stuff that potentially would match one
1745 // of the used meta targets. 1765 // of the used meta targets.
1746 metadata.ensureResolved(compiler); 1766 metadata.ensureResolved(compiler);
1747 Constant value = metadata.value; 1767 Constant value = metadata.value;
1748 if (value == null) continue; 1768 if (value == null) continue;
1749 DartType type = value.computeType(compiler); 1769 DartType type = value.computeType(compiler);
1750 if (metaTargetsUsed.contains(type.element)) return true; 1770 if (metaTargetsUsed.contains(type.element)) return true;
1751 } 1771 }
1752 return false; 1772 return false;
1753 } 1773 }
1754 1774
1775 /**
1776 * Visits all classes and computes whether its members are needed for
1777 * reflection.
1778 *
1779 * We have to precompute this set as we cannot easily answer the need for
1780 * reflection locally when looking at the member: We lack the information by
1781 * which classes a member is inherited. Called after resolution is complete.
1782 *
1783 * We filter out private libraries here, as their elements should not
1784 * be visible by reflection unless some other interfaces makes them
1785 * accessible.
1786 */
1787 computeMembersNeededForReflection() {
1788 if (_membersNeededForReflection != null) return;
1789 if (compiler.mirrorsLibrary == null) {
1790 _membersNeededForReflection = const [];
1791 }
1792 // Compute a mapping from class to the closures it contains, so we
1793 // can include the correct ones when including the class.
1794 Map<ClassElement, List<Element>> closureMap =
1795 new Map<ClassElement, List<Element>>();
1796 for (FunctionElement closure in compiler.resolverWorld.allClosures) {
1797 closureMap.putIfAbsent(closure.enclosingClass, () => []).add(closure);
1798 }
1799 bool foundClosure = false;
1800 Set<Element> reflectableMembers = new Set<Element>();
1801 ResolutionEnqueuer resolution = compiler.enqueuer.resolution;
1802 for (ClassElement cls in resolution.universe.instantiatedClasses) {
1803 // Do not process internal classes.
1804 if (cls.library.isInternalLibrary || cls.isInjected) continue;
1805 if (referencedFromMirrorSystem(cls)) {
1806 Set<Name> memberNames = new LinkedHashSet<Name>(
1807 equals: (Name a, Name b) => a.isSimilarTo(b),
1808 hashCode: (Name a) => a.similarHashCode);
1809 // 1) the class (should be live)
1810 assert(invariant(cls, resolution.isLive(cls)));
1811 reflectableMembers.add(cls);
1812 // 2) its constructors (if live)
1813 cls.constructors.forEach((Element constructor) {
1814 if (resolution.isLive(constructor)) {
1815 reflectableMembers.add(constructor);
1816 }
1817 });
1818 // 3) all members, including fields via getter/setters (if live)
1819 cls.forEachClassMember((Member member) {
1820 if (resolution.isLive(member.element)) {
1821 memberNames.add(member.name);
1822 reflectableMembers.add(member.element);
1823 }
1824 });
1825 // 4) all overriding members of subclasses/subtypes (should be live)
1826 if (compiler.world.hasAnySubtype(cls)) {
1827 for (ClassElement subcls in compiler.world.subtypesOf(cls)) {
1828 subcls.forEachClassMember((Member member) {
1829 if (memberNames.contains(member.name)) {
1830 assert(invariant(member.element,
1831 resolution.isLive(member.element)));
1832 reflectableMembers.add(member.element);
1833 }
1834 });
1835 }
1836 }
1837 // 5) all its closures
1838 List<Element> closures = closureMap[cls];
1839 if (closures != null) {
1840 reflectableMembers.addAll(closures);
1841 foundClosure = true;
1842 }
1843 } else {
1844 // check members themselves
1845 cls.constructors.forEach((ConstructorElement element) {
1846 if (!compiler.enqueuer.resolution.isLive(element)) return;
1847 if (referencedFromMirrorSystem(element, false)) {
1848 reflectableMembers.add(element);
1849 }
1850 });
1851 cls.forEachClassMember((Member member) {
1852 if (!compiler.enqueuer.resolution.isLive(member.element)) return;
1853 if (referencedFromMirrorSystem(member.element, false)) {
1854 reflectableMembers.add(member.element);
1855 }
1856 });
1857 // Also add in closures. Those might be reflectable is their enclosing
1858 // member is.
1859 List<Element> closures = closureMap[cls];
1860 if (closures != null) {
1861 for (Element closure in closures) {
1862 if (referencedFromMirrorSystem(closure.enclosingMember, false)) {
1863 reflectableMembers.add(closure);
1864 foundClosure = true;
1865 }
1866 }
1867 }
1868 }
1869 }
1870 // We also need top-level non-class elements like static functions and
1871 // global fields. We use the resolution queue to decide which elements are
1872 // part of the live world.
1873 for (LibraryElement lib in compiler.libraryLoader.libraries) {
1874 if (lib.isInternalLibrary) continue;
1875 lib.forEachLocalMember((Element member) {
1876 if (!member.isClass &&
1877 compiler.enqueuer.resolution.isLive(member) &&
1878 referencedFromMirrorSystem(member)) {
1879 reflectableMembers.add(member);
1880 }
1881 });
1882 }
1883 // And closures inside top-level elements that do not have a surrounding
1884 // class. These will be in the [:null:] bucket of the [closureMap].
1885 if (closureMap.containsKey(null)) {
1886 for (Element closure in closureMap[null]) {
1887 if (referencedFromMirrorSystem(closure)) {
1888 reflectableMembers.add(closure);
1889 foundClosure = true;
1890 }
1891 }
1892 }
1893 // As we do not think about closures as classes, yet, we have to make sure
1894 // their superclasses are available for reflection manually.
1895 if (foundClosure) {
1896 reflectableMembers.add(closureClass);
1897 }
1898 // It would be nice to have a better means to select
1899 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers;
1900 if (closurizedMembers.any(reflectableMembers.contains)) {
1901 reflectableMembers.add(boundClosureClass);
1902 }
1903 // Register all symbols of reflectable elements
1904 for (Element element in reflectableMembers) {
1905 symbolsUsed.add(element.name);
1906 }
1907 _membersNeededForReflection = reflectableMembers;
1908 }
1909
1755 jsAst.Call generateIsJsIndexableCall(jsAst.Expression use1, 1910 jsAst.Call generateIsJsIndexableCall(jsAst.Expression use1,
1756 jsAst.Expression use2) { 1911 jsAst.Expression use2) {
1757 String dispatchPropertyName = 'init.dispatchPropertyName'; 1912 String dispatchPropertyName = 'init.dispatchPropertyName';
1758 1913
1759 // We pass the dispatch property record to the isJsIndexable 1914 // We pass the dispatch property record to the isJsIndexable
1760 // helper rather than reading it inside the helper to increase the 1915 // helper rather than reading it inside the helper to increase the
1761 // chance of making the dispatch record access monomorphic. 1916 // chance of making the dispatch record access monomorphic.
1762 jsAst.PropertyAccess record = new jsAst.PropertyAccess( 1917 jsAst.PropertyAccess record = new jsAst.PropertyAccess(
1763 use2, js(dispatchPropertyName)); 1918 use2, js(dispatchPropertyName));
1764 1919
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 if (target.isField) { 1962 if (target.isField) {
1808 staticFields.add(target); 1963 staticFields.add(target);
1809 } else if (target.isLibrary || target.isClass) { 1964 } else if (target.isLibrary || target.isClass) {
1810 addFieldsInContainer(target); 1965 addFieldsInContainer(target);
1811 } 1966 }
1812 } 1967 }
1813 return staticFields; 1968 return staticFields;
1814 } 1969 }
1815 1970
1816 /// Called when [enqueuer] is empty, but before it is closed. 1971 /// Called when [enqueuer] is empty, but before it is closed.
1817 void onQueueEmpty(Enqueuer enqueuer) { 1972 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) {
1818 // Add elements referenced only via custom elements. Return early if any 1973 // Add elements referenced only via custom elements. Return early if any
1819 // elements are added to avoid counting the elements as due to mirrors. 1974 // elements are added to avoid counting the elements as due to mirrors.
1820 customElementsAnalysis.onQueueEmpty(enqueuer); 1975 customElementsAnalysis.onQueueEmpty(enqueuer);
1821 if (!enqueuer.queueIsEmpty) return; 1976 if (!enqueuer.queueIsEmpty) return false;
1822 1977
1823 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { 1978 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) {
1824 preMirrorsMethodCount = generatedCode.length; 1979 preMirrorsMethodCount = generatedCode.length;
1825 } 1980 }
1826 1981
1827 if (isTreeShakingDisabled) { 1982 if (isTreeShakingDisabled) {
1828 enqueuer.enqueueEverything(); 1983 enqueuer.enqueueReflectiveElements(recentClasses);
1829 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { 1984 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) {
1830 // Add all static elements (not classes) that have been requested for 1985 // Add all static elements (not classes) that have been requested for
1831 // reflection. If there is no mirror-usage these are probably not 1986 // reflection. If there is no mirror-usage these are probably not
1832 // necessary, but the backend relies on them being resolved. 1987 // necessary, but the backend relies on them being resolved.
1833 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); 1988 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets());
1834 } 1989 }
1835 1990
1836 if (mustPreserveNames) compiler.log('Preserving names.'); 1991 if (mustPreserveNames) compiler.log('Preserving names.');
1837 1992
1838 if (mustRetainMetadata) { 1993 if (mustRetainMetadata) {
1839 compiler.log('Retaining metadata.'); 1994 compiler.log('Retaining metadata.');
1840 1995
1841 compiler.libraryLoader.libraries.forEach(retainMetadataOf); 1996 compiler.libraryLoader.libraries.forEach(retainMetadataOf);
1842 for (Dependency dependency in metadataConstants) { 1997 for (Dependency dependency in metadataConstants) {
1843 registerCompileTimeConstant( 1998 registerCompileTimeConstant(
1844 dependency.constant, dependency.registry); 1999 dependency.constant, dependency.registry);
1845 } 2000 }
1846 metadataConstants.clear(); 2001 metadataConstants.clear();
1847 } 2002 }
2003 return true;
1848 } 2004 }
1849 2005
1850 void onElementResolved(Element element, TreeElements elements) { 2006 void onElementResolved(Element element, TreeElements elements) {
1851 LibraryElement library = element.library; 2007 LibraryElement library = element.library;
1852 if (!library.isPlatformLibrary && !library.canUseNative) return; 2008 if (!library.isPlatformLibrary && !library.canUseNative) return;
1853 bool hasNoInline = false; 2009 bool hasNoInline = false;
1854 bool hasNoThrows = false; 2010 bool hasNoThrows = false;
1855 bool hasNoSideEffects = false; 2011 bool hasNoSideEffects = false;
1856 for (MetadataAnnotation metadata in element.metadata) { 2012 for (MetadataAnnotation metadata in element.metadata) {
1857 metadata.ensureResolved(compiler); 2013 metadata.ensureResolved(compiler);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 } 2260 }
2105 2261
2106 /// Records that [constant] is used by the element behind [registry]. 2262 /// Records that [constant] is used by the element behind [registry].
2107 class Dependency { 2263 class Dependency {
2108 final Constant constant; 2264 final Constant constant;
2109 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. 2265 // TODO(johnniwinther): Change to [Element] when dependency nodes are added.
2110 final Registry registry; 2266 final Registry registry;
2111 2267
2112 const Dependency(this.constant, this.registry); 2268 const Dependency(this.constant, this.registry);
2113 } 2269 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698