| 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 dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 typedef ItemCompilationContext ItemCompilationContextCreator(); | 7 typedef ItemCompilationContext ItemCompilationContextCreator(); |
| 8 | 8 |
| 9 class EnqueueTask extends CompilerTask { | 9 class EnqueueTask extends CompilerTask { |
| 10 final ResolutionEnqueuer resolution; | 10 final ResolutionEnqueuer resolution; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 void forgetElement(Element element) { | 29 void forgetElement(Element element) { |
| 30 resolution.forgetElement(element); | 30 resolution.forgetElement(element); |
| 31 codegen.forgetElement(element); | 31 codegen.forgetElement(element); |
| 32 } | 32 } |
| 33 } | 33 } |
| 34 | 34 |
| 35 class WorldImpact { | 35 class WorldImpact { |
| 36 const WorldImpact(); | 36 const WorldImpact(); |
| 37 | 37 |
| 38 Iterable<UniverseSelector> get dynamicInvocations => | 38 Iterable<Selector> get dynamicInvocations => const <Selector>[]; |
| 39 const <UniverseSelector>[]; | 39 Iterable<Selector> get dynamicGetters => const <Selector>[]; |
| 40 Iterable<UniverseSelector> get dynamicGetters => const <UniverseSelector>[]; | 40 Iterable<Selector> get dynamicSetters => const <Selector>[]; |
| 41 Iterable<UniverseSelector> get dynamicSetters => const <UniverseSelector>[]; | |
| 42 | 41 |
| 43 // TODO(johnniwinther): Split this into more precise subsets. | 42 // TODO(johnniwinther): Split this into more precise subsets. |
| 44 Iterable<Element> get staticUses => const <Element>[]; | 43 Iterable<Element> get staticUses => const <Element>[]; |
| 45 | 44 |
| 46 // TODO(johnniwinther): Replace this by called constructors with type | 45 // TODO(johnniwinther): Replace this by called constructors with type |
| 47 // arguments. | 46 // arguments. |
| 48 Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[]; | 47 Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[]; |
| 49 | 48 |
| 50 // TODO(johnniwinther): Collect checked types for checked mode separately to | 49 // TODO(johnniwinther): Collect checked types for checked mode separately to |
| 51 // support serialization. | 50 // support serialization. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 } | 136 } |
| 138 | 137 |
| 139 void processInstantiatedClassMembers(ClassElement cls) { | 138 void processInstantiatedClassMembers(ClassElement cls) { |
| 140 cls.implementation.forEachMember(processInstantiatedClassMember); | 139 cls.implementation.forEachMember(processInstantiatedClassMember); |
| 141 } | 140 } |
| 142 | 141 |
| 143 void processInstantiatedClassMember(ClassElement cls, Element member) { | 142 void processInstantiatedClassMember(ClassElement cls, Element member) { |
| 144 assert(invariant(member, member.isDeclaration)); | 143 assert(invariant(member, member.isDeclaration)); |
| 145 if (isProcessed(member)) return; | 144 if (isProcessed(member)) return; |
| 146 if (!member.isInstanceMember) return; | 145 if (!member.isInstanceMember) return; |
| 146 |
| 147 String memberName = member.name; | 147 String memberName = member.name; |
| 148 | 148 |
| 149 if (member.kind == ElementKind.FIELD) { | 149 if (member.kind == ElementKind.FIELD) { |
| 150 // The obvious thing to test here would be "member.isNative", | 150 // The obvious thing to test here would be "member.isNative", |
| 151 // however, that only works after metadata has been parsed/analyzed, | 151 // however, that only works after metadata has been parsed/analyzed, |
| 152 // and that may not have happened yet. | 152 // and that may not have happened yet. |
| 153 // So instead we use the enclosing class, which we know have had | 153 // So instead we use the enclosing class, which we know have had |
| 154 // its metadata parsed and analyzed. | 154 // its metadata parsed and analyzed. |
| 155 // Note: this assumes that there are no non-native fields on native | 155 // Note: this assumes that there are no non-native fields on native |
| 156 // classes, which may not be the case when a native class is subclassed. | 156 // classes, which may not be the case when a native class is subclassed. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 cls, this, compiler.globalDependencies); | 269 cls, this, compiler.globalDependencies); |
| 270 } | 270 } |
| 271 processClass(cls); | 271 processClass(cls); |
| 272 for (Link<DartType> supertypes = cls.allSupertypes; | 272 for (Link<DartType> supertypes = cls.allSupertypes; |
| 273 !supertypes.isEmpty; supertypes = supertypes.tail) { | 273 !supertypes.isEmpty; supertypes = supertypes.tail) { |
| 274 processClass(supertypes.head.element); | 274 processClass(supertypes.head.element); |
| 275 } | 275 } |
| 276 }); | 276 }); |
| 277 } | 277 } |
| 278 | 278 |
| 279 void registerInvocation(UniverseSelector selector) { | 279 void registerNewSelector(Selector selector, |
| 280 Map<String, Set<Selector>> selectorsMap) { |
| 281 String name = selector.name; |
| 282 Set<Selector> selectors = |
| 283 selectorsMap.putIfAbsent(name, () => new Setlet<Selector>()); |
| 284 if (!selectors.contains(selector)) { |
| 285 selectors.add(selector); |
| 286 handleUnseenSelector(name, selector); |
| 287 } |
| 288 } |
| 289 |
| 290 void registerInvocation(Selector selector) { |
| 280 task.measure(() { | 291 task.measure(() { |
| 281 if (universe.registerInvocation(selector)) { | 292 registerNewSelector(selector, universe.invokedNames); |
| 282 handleUnseenSelector(selector); | |
| 283 } | |
| 284 }); | 293 }); |
| 285 } | 294 } |
| 286 | 295 |
| 287 void registerInvokedGetter(UniverseSelector selector) { | 296 void registerInvokedGetter(Selector selector) { |
| 288 task.measure(() { | 297 task.measure(() { |
| 289 if (universe.registerInvokedGetter(selector)) { | 298 registerNewSelector(selector, universe.invokedGetters); |
| 290 handleUnseenSelector(selector); | |
| 291 } | |
| 292 }); | 299 }); |
| 293 } | 300 } |
| 294 | 301 |
| 295 void registerInvokedSetter(UniverseSelector selector) { | 302 void registerInvokedSetter(Selector selector) { |
| 296 task.measure(() { | 303 task.measure(() { |
| 297 if (universe.registerInvokedSetter(selector)) { | 304 registerNewSelector(selector, universe.invokedSetters); |
| 298 handleUnseenSelector(selector); | |
| 299 } | |
| 300 }); | 305 }); |
| 301 } | 306 } |
| 302 | 307 |
| 303 /** | 308 /** |
| 304 * Decides whether an element should be included to satisfy requirements | 309 * Decides whether an element should be included to satisfy requirements |
| 305 * of the mirror system. [includedEnclosing] provides a hint whether the | 310 * of the mirror system. [includedEnclosing] provides a hint whether the |
| 306 * enclosing element was included. | 311 * enclosing element was included. |
| 307 * | 312 * |
| 308 * The actual implementation depends on the current compiler phase. | 313 * The actual implementation depends on the current compiler phase. |
| 309 */ | 314 */ |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 if (element.isTypedef) { | 348 if (element.isTypedef) { |
| 344 TypedefElement typedef = element; | 349 TypedefElement typedef = element; |
| 345 typedef.ensureResolved(compiler); | 350 typedef.ensureResolved(compiler); |
| 346 compiler.world.allTypedefs.add(element); | 351 compiler.world.allTypedefs.add(element); |
| 347 } else if (Elements.isStaticOrTopLevel(element)) { | 352 } else if (Elements.isStaticOrTopLevel(element)) { |
| 348 registerStaticUse(element.declaration); | 353 registerStaticUse(element.declaration); |
| 349 } else if (element.isInstanceMember) { | 354 } else if (element.isInstanceMember) { |
| 350 // We need to enqueue all members matching this one in subclasses, as | 355 // We need to enqueue all members matching this one in subclasses, as |
| 351 // well. | 356 // well. |
| 352 // TODO(herhut): Use TypedSelector.subtype for enqueueing | 357 // TODO(herhut): Use TypedSelector.subtype for enqueueing |
| 353 UniverseSelector selector = new UniverseSelector( | 358 Selector selector = new Selector.fromElement(element); |
| 354 new Selector.fromElement(element), null); | |
| 355 registerSelectorUse(selector); | 359 registerSelectorUse(selector); |
| 356 if (element.isField) { | 360 if (element.isField) { |
| 357 UniverseSelector selector = new UniverseSelector( | 361 Selector selector = |
| 358 new Selector.setter(element.name, element.library), null); | 362 new Selector.setter(element.name, element.library); |
| 359 registerInvokedSetter(selector); | 363 registerInvokedSetter(selector); |
| 360 } | 364 } |
| 361 } | 365 } |
| 362 } | 366 } |
| 363 } | 367 } |
| 364 | 368 |
| 365 /// Enqeue the member [element] if it is required for reflection. | 369 /// Enqeue the member [element] if it is required for reflection. |
| 366 /// | 370 /// |
| 367 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 371 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
| 368 /// needed for reflection. | 372 /// needed for reflection. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 } | 492 } |
| 489 | 493 |
| 490 processInstanceMembers(String n, bool f(Element e)) { | 494 processInstanceMembers(String n, bool f(Element e)) { |
| 491 processSet(instanceMembersByName, n, f); | 495 processSet(instanceMembersByName, n, f); |
| 492 } | 496 } |
| 493 | 497 |
| 494 processInstanceFunctions(String n, bool f(Element e)) { | 498 processInstanceFunctions(String n, bool f(Element e)) { |
| 495 processSet(instanceFunctionsByName, n, f); | 499 processSet(instanceFunctionsByName, n, f); |
| 496 } | 500 } |
| 497 | 501 |
| 498 void handleUnseenSelector(UniverseSelector universeSelector) { | 502 void handleUnseenSelector(String methodName, Selector selector) { |
| 499 Selector selector = universeSelector.selector; | |
| 500 String methodName = selector.name; | |
| 501 processInstanceMembers(methodName, (Element member) { | 503 processInstanceMembers(methodName, (Element member) { |
| 502 if (universeSelector.appliesUnnamed(member, compiler.world)) { | 504 if (selector.appliesUnnamed(member, compiler.world)) { |
| 503 if (member.isFunction && selector.isGetter) { | 505 if (member.isFunction && selector.isGetter) { |
| 504 registerClosurizedMember(member, compiler.globalDependencies); | 506 registerClosurizedMember(member, compiler.globalDependencies); |
| 505 } | 507 } |
| 506 if (member.isField && member.enclosingClass.isNative) { | 508 if (member.isField && member.enclosingClass.isNative) { |
| 507 if (selector.isGetter || selector.isCall) { | 509 if (selector.isGetter || selector.isCall) { |
| 508 nativeEnqueuer.registerFieldLoad(member); | 510 nativeEnqueuer.registerFieldLoad(member); |
| 509 // We have to also handle storing to the field because we only get | 511 // We have to also handle storing to the field because we only get |
| 510 // one look at each member and there might be a store we have not | 512 // one look at each member and there might be a store we have not |
| 511 // seen yet. | 513 // seen yet. |
| 512 // TODO(sra): Process fields for storing separately. | 514 // TODO(sra): Process fields for storing separately. |
| 513 nativeEnqueuer.registerFieldStore(member); | 515 nativeEnqueuer.registerFieldStore(member); |
| 514 } else { | 516 } else { |
| 515 assert(selector.isSetter); | 517 assert(selector.isSetter); |
| 516 nativeEnqueuer.registerFieldStore(member); | 518 nativeEnqueuer.registerFieldStore(member); |
| 517 // We have to also handle loading from the field because we only get | 519 // We have to also handle loading from the field because we only get |
| 518 // one look at each member and there might be a load we have not | 520 // one look at each member and there might be a load we have not |
| 519 // seen yet. | 521 // seen yet. |
| 520 // TODO(sra): Process fields for storing separately. | 522 // TODO(sra): Process fields for storing separately. |
| 521 nativeEnqueuer.registerFieldLoad(member); | 523 nativeEnqueuer.registerFieldLoad(member); |
| 522 } | 524 } |
| 523 } | 525 } |
| 524 addToWorkList(member); | 526 addToWorkList(member); |
| 525 return true; | 527 return true; |
| 526 } | 528 } |
| 527 return false; | 529 return false; |
| 528 }); | 530 }); |
| 529 if (selector.isGetter) { | 531 if (selector.isGetter) { |
| 530 processInstanceFunctions(methodName, (Element member) { | 532 processInstanceFunctions(methodName, (Element member) { |
| 531 if (universeSelector.appliesUnnamed(member, compiler.world)) { | 533 if (selector.appliesUnnamed(member, compiler.world)) { |
| 532 registerClosurizedMember(member, compiler.globalDependencies); | 534 registerClosurizedMember(member, compiler.globalDependencies); |
| 533 return true; | 535 return true; |
| 534 } | 536 } |
| 535 return false; | 537 return false; |
| 536 }); | 538 }); |
| 537 } | 539 } |
| 538 } | 540 } |
| 539 | 541 |
| 540 /** | 542 /** |
| 541 * Documentation wanted -- johnniwinther | 543 * Documentation wanted -- johnniwinther |
| (...skipping 10 matching lines...) Expand all Loading... |
| 552 addToWorkList(element); | 554 addToWorkList(element); |
| 553 compiler.backend.registerStaticUse(element, this); | 555 compiler.backend.registerStaticUse(element, this); |
| 554 } | 556 } |
| 555 | 557 |
| 556 void registerGetOfStaticFunction(FunctionElement element) { | 558 void registerGetOfStaticFunction(FunctionElement element) { |
| 557 registerStaticUse(element); | 559 registerStaticUse(element); |
| 558 compiler.backend.registerGetOfStaticFunction(this); | 560 compiler.backend.registerGetOfStaticFunction(this); |
| 559 universe.staticFunctionsNeedingGetter.add(element); | 561 universe.staticFunctionsNeedingGetter.add(element); |
| 560 } | 562 } |
| 561 | 563 |
| 562 void registerDynamicInvocation(UniverseSelector selector) { | 564 void registerDynamicInvocation(Selector selector) { |
| 563 assert(selector != null); | 565 assert(selector != null); |
| 564 registerInvocation(selector); | 566 registerInvocation(selector); |
| 565 } | 567 } |
| 566 | 568 |
| 567 void registerSelectorUse(UniverseSelector universeSelector) { | 569 void registerSelectorUse(Selector selector) { |
| 568 if (universeSelector.selector.isGetter) { | 570 if (selector.isGetter) { |
| 569 registerInvokedGetter(universeSelector); | 571 registerInvokedGetter(selector); |
| 570 } else if (universeSelector.selector.isSetter) { | 572 } else if (selector.isSetter) { |
| 571 registerInvokedSetter(universeSelector); | 573 registerInvokedSetter(selector); |
| 572 } else { | 574 } else { |
| 573 registerInvocation(universeSelector); | 575 registerInvocation(selector); |
| 574 } | 576 } |
| 575 } | 577 } |
| 576 | 578 |
| 577 void registerDynamicGetter(UniverseSelector selector) { | 579 void registerDynamicGetter(Selector selector) { |
| 578 registerInvokedGetter(selector); | 580 registerInvokedGetter(selector); |
| 579 } | 581 } |
| 580 | 582 |
| 581 void registerDynamicSetter(UniverseSelector selector) { | 583 void registerDynamicSetter(Selector selector) { |
| 582 registerInvokedSetter(selector); | 584 registerInvokedSetter(selector); |
| 583 } | 585 } |
| 584 | 586 |
| 585 void registerGetterForSuperMethod(Element element) { | 587 void registerGetterForSuperMethod(Element element) { |
| 586 universe.methodsNeedingSuperGetter.add(element); | 588 universe.methodsNeedingSuperGetter.add(element); |
| 587 } | 589 } |
| 588 | 590 |
| 589 void registerFieldGetter(Element element) { | 591 void registerFieldGetter(Element element) { |
| 590 universe.fieldGetters.add(element); | 592 universe.fieldGetters.add(element); |
| 591 } | 593 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 } | 834 } |
| 833 | 835 |
| 834 /// [Enqueuer] which is specific to code generation. | 836 /// [Enqueuer] which is specific to code generation. |
| 835 class CodegenEnqueuer extends Enqueuer { | 837 class CodegenEnqueuer extends Enqueuer { |
| 836 final Queue<CodegenWorkItem> queue; | 838 final Queue<CodegenWorkItem> queue; |
| 837 final Map<Element, js.Expression> generatedCode = | 839 final Map<Element, js.Expression> generatedCode = |
| 838 new Map<Element, js.Expression>(); | 840 new Map<Element, js.Expression>(); |
| 839 | 841 |
| 840 final Set<Element> newlyEnqueuedElements; | 842 final Set<Element> newlyEnqueuedElements; |
| 841 | 843 |
| 842 final Set<UniverseSelector> newlySeenSelectors; | 844 final Set<Selector> newlySeenSelectors; |
| 843 | 845 |
| 844 bool enabledNoSuchMethod = false; | 846 bool enabledNoSuchMethod = false; |
| 845 | 847 |
| 846 CodegenEnqueuer(Compiler compiler, | 848 CodegenEnqueuer(Compiler compiler, |
| 847 ItemCompilationContext itemCompilationContextCreator()) | 849 ItemCompilationContext itemCompilationContextCreator()) |
| 848 : queue = new Queue<CodegenWorkItem>(), | 850 : queue = new Queue<CodegenWorkItem>(), |
| 849 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 851 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
| 850 newlySeenSelectors = compiler.cacheStrategy.newSet(), | 852 newlySeenSelectors = compiler.cacheStrategy.newSet(), |
| 851 super('codegen enqueuer', compiler, itemCompilationContextCreator); | 853 super('codegen enqueuer', compiler, itemCompilationContextCreator); |
| 852 | 854 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 generatedCode.remove(element); | 910 generatedCode.remove(element); |
| 909 if (element is MemberElement) { | 911 if (element is MemberElement) { |
| 910 for (Element closure in element.nestedClosures) { | 912 for (Element closure in element.nestedClosures) { |
| 911 generatedCode.remove(closure); | 913 generatedCode.remove(closure); |
| 912 removeFromSet(instanceMembersByName, closure); | 914 removeFromSet(instanceMembersByName, closure); |
| 913 removeFromSet(instanceFunctionsByName, closure); | 915 removeFromSet(instanceFunctionsByName, closure); |
| 914 } | 916 } |
| 915 } | 917 } |
| 916 } | 918 } |
| 917 | 919 |
| 918 void handleUnseenSelector(UniverseSelector selector) { | 920 void handleUnseenSelector(String methodName, Selector selector) { |
| 919 if (compiler.hasIncrementalSupport) { | 921 if (compiler.hasIncrementalSupport) { |
| 920 newlySeenSelectors.add(selector); | 922 newlySeenSelectors.add(selector); |
| 921 } | 923 } |
| 922 super.handleUnseenSelector(selector); | 924 super.handleUnseenSelector(methodName, selector); |
| 923 } | 925 } |
| 924 } | 926 } |
| 925 | 927 |
| 926 /// Parameterizes filtering of which work items are enqueued. | 928 /// Parameterizes filtering of which work items are enqueued. |
| 927 class QueueFilter { | 929 class QueueFilter { |
| 928 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 930 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
| 929 enqueuer.task.measure(() { | 931 enqueuer.task.measure(() { |
| 930 // Run through the classes and see if we need to compile methods. | 932 // Run through the classes and see if we need to compile methods. |
| 931 for (ClassElement classElement in | 933 for (ClassElement classElement in |
| 932 enqueuer.universe.directlyInstantiatedClasses) { | 934 enqueuer.universe.directlyInstantiatedClasses) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 943 void processWorkItem(void f(WorkItem work), WorkItem work) { | 945 void processWorkItem(void f(WorkItem work), WorkItem work) { |
| 944 f(work); | 946 f(work); |
| 945 } | 947 } |
| 946 } | 948 } |
| 947 | 949 |
| 948 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 950 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
| 949 Set<Element> set = map[element.name]; | 951 Set<Element> set = map[element.name]; |
| 950 if (set == null) return; | 952 if (set == null) return; |
| 951 set.remove(element); | 953 set.remove(element); |
| 952 } | 954 } |
| OLD | NEW |