Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: pkg/compiler/lib/src/universe/resolution_world_builder.dart

Issue 2729613004: Cleanup registration of closures (Closed)
Patch Set: Updated cf. comments. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/universe/codegen_world_builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 world_builder; 5 part of world_builder;
6 6
7 abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld { 7 abstract class ResolutionWorldBuilder implements WorldBuilder, OpenWorld {
8 /// Set of all local functions in the program. Used by the mirror tracking
9 /// system to find all live closure instances.
10 Iterable<LocalFunctionElement> get localFunctions;
11
8 /// Set of (live) local functions (closures) whose signatures reference type 12 /// Set of (live) local functions (closures) whose signatures reference type
9 /// variables. 13 /// variables.
10 /// 14 ///
11 /// A live function is one whose enclosing member function has been enqueued. 15 /// A live function is one whose enclosing member function has been enqueued.
12 Iterable<Element> get closuresWithFreeTypeVariables; 16 Iterable<LocalFunctionElement> get localFunctionsWithFreeTypeVariables;
13
14 /// Set of (live) `call` methods whose signatures reference type variables.
15 ///
16 /// A live `call` method is one whose enclosing class has been instantiated.
17 Iterable<Element> get callMethodsWithFreeTypeVariables;
18
19 /// Set of all closures in the program. Used by the mirror tracking system
20 /// to find all live closure instances.
21 Iterable<LocalFunctionElement> get allClosures;
22 17
23 /// Set of methods in instantiated classes that are potentially closurized. 18 /// Set of methods in instantiated classes that are potentially closurized.
24 Iterable<Element> get closurizedMembers; 19 Iterable<MethodElement> get closurizedMembers;
20
21 /// Set of live closurized members whose signatures reference type variables.
22 ///
23 /// A closurized method is considered live if the enclosing class has been
24 /// instantiated.
25 Iterable<MethodElement> get closurizedMembersWithFreeTypeVariables;
25 26
26 /// Returns `true` if [cls] is considered to be implemented by an 27 /// Returns `true` if [cls] is considered to be implemented by an
27 /// instantiated class, either directly, through subclasses or through 28 /// instantiated class, either directly, through subclasses or through
28 /// subtypes. The latter case only contains spurious information from 29 /// subtypes. The latter case only contains spurious information from
29 /// instantiations through factory constructors and mixins. 30 /// instantiations through factory constructors and mixins.
30 bool isImplemented(ClassElement cls); 31 bool isImplemented(ClassElement cls);
31 32
32 /// Set of all fields that are statically known to be written to. 33 /// Set of all fields that are statically known to be written to.
33 Iterable<Element> get fieldSetters; 34 Iterable<Element> get fieldSetters;
34 35
(...skipping 15 matching lines...) Expand all
50 /// This is only available after the world builder has been closed. 51 /// This is only available after the world builder has been closed.
51 ClosedWorld get closedWorldForTesting; 52 ClosedWorld get closedWorldForTesting;
52 } 53 }
53 54
54 /// Extended [ResolutionWorldBuilder] interface used by the 55 /// Extended [ResolutionWorldBuilder] interface used by the
55 /// [ResolutionEnqueuer]. 56 /// [ResolutionEnqueuer].
56 abstract class ResolutionEnqueuerWorldBuilder extends ResolutionWorldBuilder { 57 abstract class ResolutionEnqueuerWorldBuilder extends ResolutionWorldBuilder {
57 /// Returns the classes registered as directly or indirectly instantiated. 58 /// Returns the classes registered as directly or indirectly instantiated.
58 Iterable<ClassEntity> get processedClasses; 59 Iterable<ClassEntity> get processedClasses;
59 60
60 /// Registers that the generic [element] has been closurized.
61 void registerClosureWithFreeTypeVariables(MemberEntity element);
62
63 /// Registers that [element] has been closurized. 61 /// Registers that [element] has been closurized.
64 void registerClosurizedMember(MemberEntity element); 62 void registerClosurizedMember(MemberEntity element);
65 63
66 /// Register [type] as (directly) instantiated. 64 /// Register [type] as (directly) instantiated.
67 /// 65 ///
68 /// If [byMirrors] is `true`, the instantiation is through mirrors. 66 /// If [byMirrors] is `true`, the instantiation is through mirrors.
69 // TODO(johnniwinther): Fully enforce the separation between exact, through 67 // TODO(johnniwinther): Fully enforce the separation between exact, through
70 // subclass and through subtype instantiated types/classes. 68 // subclass and through subtype instantiated types/classes.
71 // TODO(johnniwinther): Support unknown type arguments for generic types. 69 // TODO(johnniwinther): Support unknown type arguments for generic types.
72 void registerTypeInstantiation( 70 void registerTypeInstantiation(
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 294
297 /// Map containing instance methods of live classes that are not yet 295 /// Map containing instance methods of live classes that are not yet
298 /// closurized. 296 /// closurized.
299 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName = 297 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName =
300 <String, Set<_MemberUsage>>{}; 298 <String, Set<_MemberUsage>>{};
301 299
302 /// Fields set. 300 /// Fields set.
303 final Set<Element> fieldSetters = new Set<Element>(); 301 final Set<Element> fieldSetters = new Set<Element>();
304 final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>(); 302 final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>();
305 303
306 /** 304 /// Set of all closures in the program. Used by the mirror tracking system
307 * Set of (live) [:call:] methods whose signatures reference type variables. 305 /// to find all live closure instances.
308 * 306 final Set<LocalFunctionElement> localFunctions =
309 * A live [:call:] method is one whose enclosing class has been instantiated. 307 new Set<LocalFunctionElement>();
310 */
311 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
312 308
313 /** 309 /// Set of live local functions (closures) whose signatures reference type
314 * Set of (live) local functions (closures) whose signatures reference type 310 /// variables.
315 * variables. 311 ///
316 * 312 /// A local function is considered live if the enclosing member function is
317 * A live function is one whose enclosing member function has been enqueued. 313 /// live.
318 */ 314 final Set<LocalFunctionElement> localFunctionsWithFreeTypeVariables =
319 final Set<Element> closuresWithFreeTypeVariables = new Set<Element>(); 315 new Set<LocalFunctionElement>();
320 316
321 /** 317 /// Set of methods in instantiated classes that are potentially closurized.
322 * Set of all closures in the program. Used by the mirror tracking system 318 final Set<MethodElement> closurizedMembers = new Set<MethodElement>();
323 * to find all live closure instances.
324 */
325 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
326 319
327 /** 320 /// Set of live closurized members whose signatures reference type variables.
328 * Set of methods in instantiated classes that are potentially 321 ///
329 * closurized. 322 /// A closurized method is considered live if the enclosing class has been
330 */ 323 /// instantiated.
331 final Set<Element> closurizedMembers = new Set<Element>(); 324 final Set<MethodElement> closurizedMembersWithFreeTypeVariables =
325 new Set<MethodElement>();
332 326
333 final SelectorConstraintsStrategy selectorConstraintsStrategy; 327 final SelectorConstraintsStrategy selectorConstraintsStrategy;
334 328
335 bool hasRuntimeTypeSupport = false; 329 bool hasRuntimeTypeSupport = false;
336 bool hasIsolateSupport = false; 330 bool hasIsolateSupport = false;
337 bool hasFunctionApplySupport = false; 331 bool hasFunctionApplySupport = false;
338 332
339 /// Used for testing the new more precise computation of instantiated types 333 /// Used for testing the new more precise computation of instantiated types
340 /// and classes. 334 /// and classes.
341 bool useInstantiationMap = false; 335 bool useInstantiationMap = false;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 406
413 /// Returns `true` if [cls] is considered to be implemented by an 407 /// Returns `true` if [cls] is considered to be implemented by an
414 /// instantiated class, either directly, through subclasses or through 408 /// instantiated class, either directly, through subclasses or through
415 /// subtypes. The latter case only contains spurious information from 409 /// subtypes. The latter case only contains spurious information from
416 /// instantiations through factory constructors and mixins. 410 /// instantiations through factory constructors and mixins.
417 // TODO(johnniwinther): Improve semantic precision. 411 // TODO(johnniwinther): Improve semantic precision.
418 bool isImplemented(ClassElement cls) { 412 bool isImplemented(ClassElement cls) {
419 return _implementedClasses.contains(cls.declaration); 413 return _implementedClasses.contains(cls.declaration);
420 } 414 }
421 415
422 void registerClosureWithFreeTypeVariables(MemberElement element) {
423 closuresWithFreeTypeVariables.add(element);
424 }
425
426 void registerClosurizedMember(MemberElement element) { 416 void registerClosurizedMember(MemberElement element) {
427 closurizedMembers.add(element); 417 closurizedMembers.add(element);
418 if (element.type.containsTypeVariables) {
419 closurizedMembersWithFreeTypeVariables.add(element);
420 }
428 } 421 }
429 422
430 /// Register [type] as (directly) instantiated. 423 /// Register [type] as (directly) instantiated.
431 /// 424 ///
432 /// If [byMirrors] is `true`, the instantiation is through mirrors. 425 /// If [byMirrors] is `true`, the instantiation is through mirrors.
433 // TODO(johnniwinther): Fully enforce the separation between exact, through 426 // TODO(johnniwinther): Fully enforce the separation between exact, through
434 // subclass and through subtype instantiated types/classes. 427 // subclass and through subtype instantiated types/classes.
435 // TODO(johnniwinther): Support unknown type arguments for generic types. 428 // TODO(johnniwinther): Support unknown type arguments for generic types.
436 void registerTypeInstantiation( 429 void registerTypeInstantiation(
437 ResolutionInterfaceType type, ClassUsedCallback classUsed, 430 ResolutionInterfaceType type, ClassUsedCallback classUsed,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. 626 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
634 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 627 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
635 // enqueue. 628 // enqueue.
636 switch (staticUse.kind) { 629 switch (staticUse.kind) {
637 case StaticUseKind.FIELD_GET: 630 case StaticUseKind.FIELD_GET:
638 break; 631 break;
639 case StaticUseKind.FIELD_SET: 632 case StaticUseKind.FIELD_SET:
640 fieldSetters.add(element); 633 fieldSetters.add(element);
641 break; 634 break;
642 case StaticUseKind.CLOSURE: 635 case StaticUseKind.CLOSURE:
643 LocalFunctionElement closure = staticUse.element; 636 LocalFunctionElement localFunction = staticUse.element;
644 if (closure.type.containsTypeVariables) { 637 if (localFunction.type.containsTypeVariables) {
645 closuresWithFreeTypeVariables.add(closure); 638 localFunctionsWithFreeTypeVariables.add(localFunction);
646 } 639 }
647 allClosures.add(element); 640 localFunctions.add(element);
648 break; 641 break;
649 case StaticUseKind.SUPER_TEAR_OFF: 642 case StaticUseKind.SUPER_TEAR_OFF:
650 useSet.addAll(usage.tearOff()); 643 useSet.addAll(usage.tearOff());
651 methodsNeedingSuperGetter.add(element); 644 methodsNeedingSuperGetter.add(element);
652 break; 645 break;
653 case StaticUseKind.SUPER_FIELD_SET: 646 case StaticUseKind.SUPER_FIELD_SET:
654 fieldSetters.add(element); 647 fieldSetters.add(element);
655 useSet.addAll(usage.normalUse()); 648 useSet.addAll(usage.normalUse());
656 break; 649 break;
657 case StaticUseKind.STATIC_TEAR_OFF: 650 case StaticUseKind.STATIC_TEAR_OFF:
658 useSet.addAll(usage.tearOff()); 651 useSet.addAll(usage.tearOff());
659 break; 652 break;
660 case StaticUseKind.GENERAL: 653 case StaticUseKind.GENERAL:
661 case StaticUseKind.DIRECT_USE: 654 case StaticUseKind.DIRECT_USE:
662 case StaticUseKind.CONSTRUCTOR_INVOKE: 655 case StaticUseKind.CONSTRUCTOR_INVOKE:
663 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 656 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
664 case StaticUseKind.REDIRECTION: 657 case StaticUseKind.REDIRECTION:
665 useSet.addAll(usage.normalUse()); 658 useSet.addAll(usage.normalUse());
666 break; 659 break;
667 case StaticUseKind.DIRECT_INVOKE: 660 case StaticUseKind.DIRECT_INVOKE:
668 invariant( 661 invariant(
669 element, 'Direct static use is not supported for resolution.'); 662 element, 'Direct static use is not supported for resolution.');
670 break; 663 break;
671 } 664 }
672 if (useSet.isNotEmpty) { 665 if (useSet.isNotEmpty) {
673 memberUsed(usage.entity, useSet); 666 memberUsed(usage.entity, useSet);
674 } 667 }
675 } 668 }
676 669
677 // TODO(ahe): Replace this method with something that is O(1), for example,
678 // by using a map.
679 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
680 // Return new list to guard against concurrent modifications.
681 return new List<LocalFunctionElement>.from(
682 allClosures.where((LocalFunctionElement closure) {
683 return closure.executableContext == element;
684 }));
685 }
686
687 /// Return the canonical [_ClassUsage] for [cls]. 670 /// Return the canonical [_ClassUsage] for [cls].
688 _ClassUsage _getClassUsage(ClassElement cls) { 671 _ClassUsage _getClassUsage(ClassElement cls) {
689 return _processedClasses.putIfAbsent(cls, () { 672 return _processedClasses.putIfAbsent(cls, () {
690 cls.ensureResolved(_resolution); 673 cls.ensureResolved(_resolution);
691 _ClassUsage usage = new _ClassUsage(cls); 674 _ClassUsage usage = new _ClassUsage(cls);
692 _resolution.ensureClassMembers(cls); 675 _resolution.ensureClassMembers(cls);
693 return usage; 676 return usage;
694 }); 677 });
695 } 678 }
696 679
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 bool isNative = _backend.nativeData.isNativeClass(cls); 740 bool isNative = _backend.nativeData.isNativeClass(cls);
758 _MemberUsage usage = new _MemberUsage(member, isNative: isNative); 741 _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
759 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); 742 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
760 useSet.addAll(usage.appliedUse); 743 useSet.addAll(usage.appliedUse);
761 if (member.isField && isNative) { 744 if (member.isField && isNative) {
762 registerUsedElement(member); 745 registerUsedElement(member);
763 } 746 }
764 if (member.isFunction && 747 if (member.isFunction &&
765 member.name == Identifiers.call && 748 member.name == Identifiers.call &&
766 !cls.typeVariables.isEmpty) { 749 !cls.typeVariables.isEmpty) {
767 callMethodsWithFreeTypeVariables.add(member); 750 closurizedMembersWithFreeTypeVariables.add(member);
768 } 751 }
769 752
770 if (_hasInvokedGetter(member)) { 753 if (_hasInvokedGetter(member)) {
771 useSet.addAll(usage.read()); 754 useSet.addAll(usage.read());
772 } 755 }
773 if (_hasInvocation(member)) { 756 if (_hasInvocation(member)) {
774 useSet.addAll(usage.invoke()); 757 useSet.addAll(usage.invoke());
775 } 758 }
776 if (hasInvokedSetter(member)) { 759 if (hasInvokedSetter(member)) {
777 useSet.addAll(usage.write()); 760 useSet.addAll(usage.write());
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 @override 942 @override
960 bool isMemberUsed(MemberEntity member) { 943 bool isMemberUsed(MemberEntity member) {
961 if (member.isInstanceMember) { 944 if (member.isInstanceMember) {
962 _MemberUsage usage = _instanceMemberUsage[member]; 945 _MemberUsage usage = _instanceMemberUsage[member];
963 if (usage != null && usage.hasUse) return true; 946 if (usage != null && usage.hasUse) return true;
964 } 947 }
965 _StaticMemberUsage usage = _staticMemberUsage[member]; 948 _StaticMemberUsage usage = _staticMemberUsage[member];
966 return usage != null && usage.hasUse; 949 return usage != null && usage.hasUse;
967 } 950 }
968 } 951 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/codegen_world_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698