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 |