| 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 |