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 library dart2js.enqueue; | 5 library dart2js.enqueue; |
6 | 6 |
7 import 'dart:collection' show | 7 import 'dart:collection' show |
8 Queue; | 8 Queue; |
9 | 9 |
10 import 'common.dart'; | 10 import 'common.dart'; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 TypedElement, | 45 TypedElement, |
46 TypedefElement; | 46 TypedefElement; |
47 import 'js/js.dart' as js; | 47 import 'js/js.dart' as js; |
48 import 'native/native.dart' as native; | 48 import 'native/native.dart' as native; |
49 import 'types/types.dart' show | 49 import 'types/types.dart' show |
50 TypeMaskStrategy; | 50 TypeMaskStrategy; |
51 import 'universe/selector.dart' show | 51 import 'universe/selector.dart' show |
52 Selector; | 52 Selector; |
53 import 'universe/universe.dart'; | 53 import 'universe/universe.dart'; |
54 import 'universe/use.dart' show | 54 import 'universe/use.dart' show |
| 55 DynamicUse, |
55 StaticUse, | 56 StaticUse, |
56 StaticUseKind; | 57 StaticUseKind; |
57 import 'universe/world_impact.dart' show | 58 import 'universe/world_impact.dart' show |
58 WorldImpact; | 59 WorldImpact; |
59 import 'util/util.dart' show | 60 import 'util/util.dart' show |
60 Link, | 61 Link, |
61 Setlet; | 62 Setlet; |
62 | 63 |
63 typedef ItemCompilationContext ItemCompilationContextCreator(); | 64 typedef ItemCompilationContext ItemCompilationContextCreator(); |
64 | 65 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 superclass, this, compiler.globalDependencies); | 339 superclass, this, compiler.globalDependencies); |
339 } | 340 } |
340 | 341 |
341 while (cls != null) { | 342 while (cls != null) { |
342 processClass(cls); | 343 processClass(cls); |
343 cls = cls.superclass; | 344 cls = cls.superclass; |
344 } | 345 } |
345 }); | 346 }); |
346 } | 347 } |
347 | 348 |
348 void registerDynamicUse(UniverseSelector selector) { | 349 void registerDynamicUse(DynamicUse dynamicUse) { |
349 task.measure(() { | 350 task.measure(() { |
350 if (universe.registerDynamicUse(selector)) { | 351 if (universe.registerDynamicUse(dynamicUse)) { |
351 handleUnseenSelector(selector); | 352 handleUnseenSelector(dynamicUse); |
352 } | 353 } |
353 }); | 354 }); |
354 } | 355 } |
355 | 356 |
356 /** | 357 /** |
357 * Decides whether an element should be included to satisfy requirements | 358 * Decides whether an element should be included to satisfy requirements |
358 * of the mirror system. [includedEnclosing] provides a hint whether the | 359 * of the mirror system. [includedEnclosing] provides a hint whether the |
359 * enclosing element was included. | 360 * enclosing element was included. |
360 * | 361 * |
361 * The actual implementation depends on the current compiler phase. | 362 * The actual implementation depends on the current compiler phase. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 if (element.isTypedef) { | 400 if (element.isTypedef) { |
400 TypedefElement typedef = element; | 401 TypedefElement typedef = element; |
401 typedef.ensureResolved(resolution); | 402 typedef.ensureResolved(resolution); |
402 compiler.world.allTypedefs.add(element); | 403 compiler.world.allTypedefs.add(element); |
403 } else if (Elements.isStaticOrTopLevel(element)) { | 404 } else if (Elements.isStaticOrTopLevel(element)) { |
404 registerStaticUse(new StaticUse.foreignUse(element.declaration)); | 405 registerStaticUse(new StaticUse.foreignUse(element.declaration)); |
405 } else if (element.isInstanceMember) { | 406 } else if (element.isInstanceMember) { |
406 // We need to enqueue all members matching this one in subclasses, as | 407 // We need to enqueue all members matching this one in subclasses, as |
407 // well. | 408 // well. |
408 // TODO(herhut): Use TypedSelector.subtype for enqueueing | 409 // TODO(herhut): Use TypedSelector.subtype for enqueueing |
409 UniverseSelector selector = new UniverseSelector( | 410 DynamicUse dynamicUse = new DynamicUse( |
410 new Selector.fromElement(element), null); | 411 new Selector.fromElement(element), null); |
411 registerDynamicUse(selector); | 412 registerDynamicUse(dynamicUse); |
412 if (element.isField) { | 413 if (element.isField) { |
413 UniverseSelector selector = new UniverseSelector( | 414 DynamicUse dynamicUse = new DynamicUse( |
414 new Selector.setter(new Name( | 415 new Selector.setter(new Name( |
415 element.name, element.library, isSetter: true)), null); | 416 element.name, element.library, isSetter: true)), null); |
416 registerDynamicUse(selector); | 417 registerDynamicUse(dynamicUse); |
417 } | 418 } |
418 } | 419 } |
419 } | 420 } |
420 } | 421 } |
421 | 422 |
422 /// Enqeue the member [element] if it is required for reflection. | 423 /// Enqeue the member [element] if it is required for reflection. |
423 /// | 424 /// |
424 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 425 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
425 /// needed for reflection. | 426 /// needed for reflection. |
426 void enqueueReflectiveElementsInClass(ClassElement cls, | 427 void enqueueReflectiveElementsInClass(ClassElement cls, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 } | 552 } |
552 | 553 |
553 processInstanceMembers(String n, bool f(Element e)) { | 554 processInstanceMembers(String n, bool f(Element e)) { |
554 processSet(instanceMembersByName, n, f); | 555 processSet(instanceMembersByName, n, f); |
555 } | 556 } |
556 | 557 |
557 processInstanceFunctions(String n, bool f(Element e)) { | 558 processInstanceFunctions(String n, bool f(Element e)) { |
558 processSet(instanceFunctionsByName, n, f); | 559 processSet(instanceFunctionsByName, n, f); |
559 } | 560 } |
560 | 561 |
561 void handleUnseenSelector(UniverseSelector universeSelector) { | 562 void handleUnseenSelector(DynamicUse universeSelector) { |
562 strategy.processDynamicUse(this, universeSelector); | 563 strategy.processDynamicUse(this, universeSelector); |
563 } | 564 } |
564 | 565 |
565 void handleUnseenSelectorInternal(UniverseSelector universeSelector) { | 566 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { |
566 Selector selector = universeSelector.selector; | 567 Selector selector = dynamicUse.selector; |
567 String methodName = selector.name; | 568 String methodName = selector.name; |
568 processInstanceMembers(methodName, (Element member) { | 569 processInstanceMembers(methodName, (Element member) { |
569 if (universeSelector.appliesUnnamed(member, compiler.world)) { | 570 if (dynamicUse.appliesUnnamed(member, compiler.world)) { |
570 if (member.isFunction && selector.isGetter) { | 571 if (member.isFunction && selector.isGetter) { |
571 registerClosurizedMember(member); | 572 registerClosurizedMember(member); |
572 } | 573 } |
573 if (member.isField && compiler.backend.isNative(member.enclosingClass))
{ | 574 if (member.isField && compiler.backend.isNative(member.enclosingClass))
{ |
574 if (selector.isGetter || selector.isCall) { | 575 if (selector.isGetter || selector.isCall) { |
575 nativeEnqueuer.registerFieldLoad(member); | 576 nativeEnqueuer.registerFieldLoad(member); |
576 // We have to also handle storing to the field because we only get | 577 // We have to also handle storing to the field because we only get |
577 // one look at each member and there might be a store we have not | 578 // one look at each member and there might be a store we have not |
578 // seen yet. | 579 // seen yet. |
579 // TODO(sra): Process fields for storing separately. | 580 // TODO(sra): Process fields for storing separately. |
580 nativeEnqueuer.registerFieldStore(member); | 581 nativeEnqueuer.registerFieldStore(member); |
581 } else { | 582 } else { |
582 assert(selector.isSetter); | 583 assert(selector.isSetter); |
583 nativeEnqueuer.registerFieldStore(member); | 584 nativeEnqueuer.registerFieldStore(member); |
584 // We have to also handle loading from the field because we only get | 585 // We have to also handle loading from the field because we only get |
585 // one look at each member and there might be a load we have not | 586 // one look at each member and there might be a load we have not |
586 // seen yet. | 587 // seen yet. |
587 // TODO(sra): Process fields for storing separately. | 588 // TODO(sra): Process fields for storing separately. |
588 nativeEnqueuer.registerFieldLoad(member); | 589 nativeEnqueuer.registerFieldLoad(member); |
589 } | 590 } |
590 } | 591 } |
591 addToWorkList(member); | 592 addToWorkList(member); |
592 return true; | 593 return true; |
593 } | 594 } |
594 return false; | 595 return false; |
595 }); | 596 }); |
596 if (selector.isGetter) { | 597 if (selector.isGetter) { |
597 processInstanceFunctions(methodName, (Element member) { | 598 processInstanceFunctions(methodName, (Element member) { |
598 if (universeSelector.appliesUnnamed(member, compiler.world)) { | 599 if (dynamicUse.appliesUnnamed(member, compiler.world)) { |
599 registerClosurizedMember(member); | 600 registerClosurizedMember(member); |
600 return true; | 601 return true; |
601 } | 602 } |
602 return false; | 603 return false; |
603 }); | 604 }); |
604 } | 605 } |
605 } | 606 } |
606 | 607 |
607 /** | 608 /** |
608 * Documentation wanted -- johnniwinther | 609 * Documentation wanted -- johnniwinther |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
864 } | 865 } |
865 | 866 |
866 /// [Enqueuer] which is specific to code generation. | 867 /// [Enqueuer] which is specific to code generation. |
867 class CodegenEnqueuer extends Enqueuer { | 868 class CodegenEnqueuer extends Enqueuer { |
868 final Queue<CodegenWorkItem> queue; | 869 final Queue<CodegenWorkItem> queue; |
869 final Map<Element, js.Expression> generatedCode = | 870 final Map<Element, js.Expression> generatedCode = |
870 new Map<Element, js.Expression>(); | 871 new Map<Element, js.Expression>(); |
871 | 872 |
872 final Set<Element> newlyEnqueuedElements; | 873 final Set<Element> newlyEnqueuedElements; |
873 | 874 |
874 final Set<UniverseSelector> newlySeenSelectors; | 875 final Set<DynamicUse> newlySeenSelectors; |
875 | 876 |
876 bool enabledNoSuchMethod = false; | 877 bool enabledNoSuchMethod = false; |
877 | 878 |
878 CodegenEnqueuer(Compiler compiler, | 879 CodegenEnqueuer(Compiler compiler, |
879 ItemCompilationContext itemCompilationContextCreator(), | 880 ItemCompilationContext itemCompilationContextCreator(), |
880 EnqueuerStrategy strategy) | 881 EnqueuerStrategy strategy) |
881 : queue = new Queue<CodegenWorkItem>(), | 882 : queue = new Queue<CodegenWorkItem>(), |
882 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), | 883 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), |
883 newlySeenSelectors = compiler.cacheStrategy.newSet(), | 884 newlySeenSelectors = compiler.cacheStrategy.newSet(), |
884 super('codegen enqueuer', compiler, itemCompilationContextCreator, | 885 super('codegen enqueuer', compiler, itemCompilationContextCreator, |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 generatedCode.remove(element); | 943 generatedCode.remove(element); |
943 if (element is MemberElement) { | 944 if (element is MemberElement) { |
944 for (Element closure in element.nestedClosures) { | 945 for (Element closure in element.nestedClosures) { |
945 generatedCode.remove(closure); | 946 generatedCode.remove(closure); |
946 removeFromSet(instanceMembersByName, closure); | 947 removeFromSet(instanceMembersByName, closure); |
947 removeFromSet(instanceFunctionsByName, closure); | 948 removeFromSet(instanceFunctionsByName, closure); |
948 } | 949 } |
949 } | 950 } |
950 } | 951 } |
951 | 952 |
952 void handleUnseenSelector(UniverseSelector selector) { | 953 void handleUnseenSelector(DynamicUse dynamicUse) { |
953 if (compiler.hasIncrementalSupport) { | 954 if (compiler.hasIncrementalSupport) { |
954 newlySeenSelectors.add(selector); | 955 newlySeenSelectors.add(dynamicUse); |
955 } | 956 } |
956 super.handleUnseenSelector(selector); | 957 super.handleUnseenSelector(dynamicUse); |
957 } | 958 } |
958 } | 959 } |
959 | 960 |
960 /// Parameterizes filtering of which work items are enqueued. | 961 /// Parameterizes filtering of which work items are enqueued. |
961 class QueueFilter { | 962 class QueueFilter { |
962 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 963 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
963 enqueuer.task.measure(() { | 964 enqueuer.task.measure(() { |
964 // Run through the classes and see if we need to compile methods. | 965 // Run through the classes and see if we need to compile methods. |
965 for (ClassElement classElement in | 966 for (ClassElement classElement in |
966 enqueuer.universe.directlyInstantiatedClasses) { | 967 enqueuer.universe.directlyInstantiatedClasses) { |
(...skipping 22 matching lines...) Expand all Loading... |
989 // TODO(johnniwinther): Merge this interface with [QueueFilter]. | 990 // TODO(johnniwinther): Merge this interface with [QueueFilter]. |
990 class EnqueuerStrategy { | 991 class EnqueuerStrategy { |
991 const EnqueuerStrategy(); | 992 const EnqueuerStrategy(); |
992 | 993 |
993 /// Process a class instantiated in live code. | 994 /// Process a class instantiated in live code. |
994 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {} | 995 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {} |
995 | 996 |
996 /// Process a static use of and element in live code. | 997 /// Process a static use of and element in live code. |
997 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {} | 998 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {} |
998 | 999 |
999 /// Process a selector for a call site in live code. | 1000 /// Process a dynamic use for a call site in live code. |
1000 void processDynamicUse(Enqueuer enqueuer, UniverseSelector dynamicUse) {} | 1001 void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {} |
1001 } | 1002 } |
1002 | 1003 |
1003 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy { | 1004 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy { |
1004 const TreeShakingEnqueuerStrategy(); | 1005 const TreeShakingEnqueuerStrategy(); |
1005 | 1006 |
1006 @override | 1007 @override |
1007 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) { | 1008 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) { |
1008 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember); | 1009 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember); |
1009 } | 1010 } |
1010 | 1011 |
1011 @override | 1012 @override |
1012 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) { | 1013 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) { |
1013 enqueuer.registerStaticUseInternal(staticUse); | 1014 enqueuer.registerStaticUseInternal(staticUse); |
1014 } | 1015 } |
1015 | 1016 |
1016 @override | 1017 @override |
1017 void processDynamicUse(Enqueuer enqueuer, UniverseSelector dynamicUse) { | 1018 void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) { |
1018 enqueuer.handleUnseenSelectorInternal(dynamicUse); | 1019 enqueuer.handleUnseenSelectorInternal(dynamicUse); |
1019 } | 1020 } |
1020 } | 1021 } |
OLD | NEW |