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