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

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

Issue 2729613004: Cleanup registration of closures (Closed)
Patch Set: 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
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
Siggi Cherem (dart-lang) 2017/03/14 03:02:34 Just to be sure: this is only for RTI and so it in
Johnni Winther 2017/03/14 16:59:46 Yes
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 17
14 /// Set of (live) `call` methods whose signatures reference type variables. 18 /// Set of live local functions (closures) whose signatures reference type
15 /// 19 /// variables.
16 /// A live `call` method is one whose enclosing class has been instantiated. 20 /// A local function is considered live if the enclosing member function is
Siggi Cherem (dart-lang) 2017/03/14 03:02:34 nit: add extra line to divide the paragraph
Johnni Winther 2017/03/14 16:59:46 Duplicate paragraph, removed.
17 Iterable<Element> get callMethodsWithFreeTypeVariables; 21 /// live.
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 22
23 /// Set of methods in instantiated classes that are potentially closurized. 23 /// Set of methods in instantiated classes that are potentially closurized.
24 Iterable<Element> get closurizedMembers; 24 Iterable<MethodElement> get closurizedMembers;
25
26 /// Set of live closurized members whose signatures reference type variables.
27 ///
28 /// A `call` method is considered live if the enclosing class has been
Siggi Cherem (dart-lang) 2017/03/14 03:02:34 `call` method => closurized member
Johnni Winther 2017/03/14 16:59:46 Done.
29 /// instantiated.
30 Iterable<MethodElement> get closurizedMembersWithFreeTypeVariables;
25 31
26 /// Returns `true` if [cls] is considered to be implemented by an 32 /// Returns `true` if [cls] is considered to be implemented by an
27 /// instantiated class, either directly, through subclasses or through 33 /// instantiated class, either directly, through subclasses or through
28 /// subtypes. The latter case only contains spurious information from 34 /// subtypes. The latter case only contains spurious information from
29 /// instantiations through factory constructors and mixins. 35 /// instantiations through factory constructors and mixins.
30 bool isImplemented(ClassElement cls); 36 bool isImplemented(ClassElement cls);
31 37
32 /// Set of all fields that are statically known to be written to. 38 /// Set of all fields that are statically known to be written to.
33 Iterable<Element> get fieldSetters; 39 Iterable<Element> get fieldSetters;
34 40
(...skipping 15 matching lines...) Expand all
50 /// This is only available after the world builder has been closed. 56 /// This is only available after the world builder has been closed.
51 ClosedWorld get closedWorldForTesting; 57 ClosedWorld get closedWorldForTesting;
52 } 58 }
53 59
54 /// Extended [ResolutionWorldBuilder] interface used by the 60 /// Extended [ResolutionWorldBuilder] interface used by the
55 /// [ResolutionEnqueuer]. 61 /// [ResolutionEnqueuer].
56 abstract class ResolutionEnqueuerWorldBuilder extends ResolutionWorldBuilder { 62 abstract class ResolutionEnqueuerWorldBuilder extends ResolutionWorldBuilder {
57 /// Returns the classes registered as directly or indirectly instantiated. 63 /// Returns the classes registered as directly or indirectly instantiated.
58 Iterable<ClassEntity> get processedClasses; 64 Iterable<ClassEntity> get processedClasses;
59 65
60 /// Registers that the generic [element] has been closurized.
61 void registerClosureWithFreeTypeVariables(MemberEntity element);
62
63 /// Registers that [element] has been closurized. 66 /// Registers that [element] has been closurized.
64 void registerClosurizedMember(MemberEntity element); 67 void registerClosurizedMember(MemberEntity element);
65 68
66 /// Register [type] as (directly) instantiated. 69 /// Register [type] as (directly) instantiated.
67 /// 70 ///
68 /// If [byMirrors] is `true`, the instantiation is through mirrors. 71 /// If [byMirrors] is `true`, the instantiation is through mirrors.
69 // TODO(johnniwinther): Fully enforce the separation between exact, through 72 // TODO(johnniwinther): Fully enforce the separation between exact, through
70 // subclass and through subtype instantiated types/classes. 73 // subclass and through subtype instantiated types/classes.
71 // TODO(johnniwinther): Support unknown type arguments for generic types. 74 // TODO(johnniwinther): Support unknown type arguments for generic types.
72 void registerTypeInstantiation( 75 void registerTypeInstantiation(
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 299
297 /// Map containing instance methods of live classes that are not yet 300 /// Map containing instance methods of live classes that are not yet
298 /// closurized. 301 /// closurized.
299 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName = 302 final Map<String, Set<_MemberUsage>> _instanceFunctionsByName =
300 <String, Set<_MemberUsage>>{}; 303 <String, Set<_MemberUsage>>{};
301 304
302 /// Fields set. 305 /// Fields set.
303 final Set<Element> fieldSetters = new Set<Element>(); 306 final Set<Element> fieldSetters = new Set<Element>();
304 final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>(); 307 final Set<ResolutionDartType> isChecks = new Set<ResolutionDartType>();
305 308
306 /** 309 /// Set of all closures in the program. Used by the mirror tracking system
307 * Set of (live) [:call:] methods whose signatures reference type variables. 310 /// to find all live closure instances.
308 * 311 final Set<LocalFunctionElement> localFunctions =
309 * A live [:call:] method is one whose enclosing class has been instantiated. 312 new Set<LocalFunctionElement>();
310 */
311 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
312 313
313 /** 314 /// Set of live local functions (closures) whose signatures reference type
314 * Set of (live) local functions (closures) whose signatures reference type 315 /// variables.
315 * variables. 316 /// A local function is considered live if the enclosing member function is
Siggi Cherem (dart-lang) 2017/03/14 03:02:34 \n
Johnni Winther 2017/03/14 16:59:46 Done.
316 * 317 /// live.
317 * A live function is one whose enclosing member function has been enqueued. 318 final Set<LocalFunctionElement> localFunctionsWithFreeTypeVariables =
318 */ 319 new Set<LocalFunctionElement>();
319 final Set<Element> closuresWithFreeTypeVariables = new Set<Element>();
320 320
321 /** 321 /// Set of methods in instantiated classes that are potentially closurized.
322 * Set of all closures in the program. Used by the mirror tracking system 322 final Set<MethodElement> closurizedMembers = new Set<MethodElement>();
323 * to find all live closure instances.
324 */
325 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
326 323
327 /** 324 /// Set of live closurized members whose signatures reference type variables.
328 * Set of methods in instantiated classes that are potentially 325 ///
329 * closurized. 326 /// A `call` method is considered live if the enclosing class has been
Siggi Cherem (dart-lang) 2017/03/14 03:02:34 `call` method => closurized member
Johnni Winther 2017/03/14 16:59:46 Done.
330 */ 327 /// instantiated.
331 final Set<Element> closurizedMembers = new Set<Element>(); 328 final Set<MethodElement> closurizedMembersWithFreeTypeVariables =
329 new Set<MethodElement>();
332 330
333 final SelectorConstraintsStrategy selectorConstraintsStrategy; 331 final SelectorConstraintsStrategy selectorConstraintsStrategy;
334 332
335 bool hasRuntimeTypeSupport = false; 333 bool hasRuntimeTypeSupport = false;
336 bool hasIsolateSupport = false; 334 bool hasIsolateSupport = false;
337 bool hasFunctionApplySupport = false; 335 bool hasFunctionApplySupport = false;
338 336
339 /// Used for testing the new more precise computation of instantiated types 337 /// Used for testing the new more precise computation of instantiated types
340 /// and classes. 338 /// and classes.
341 bool useInstantiationMap = false; 339 bool useInstantiationMap = false;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 410
413 /// Returns `true` if [cls] is considered to be implemented by an 411 /// Returns `true` if [cls] is considered to be implemented by an
414 /// instantiated class, either directly, through subclasses or through 412 /// instantiated class, either directly, through subclasses or through
415 /// subtypes. The latter case only contains spurious information from 413 /// subtypes. The latter case only contains spurious information from
416 /// instantiations through factory constructors and mixins. 414 /// instantiations through factory constructors and mixins.
417 // TODO(johnniwinther): Improve semantic precision. 415 // TODO(johnniwinther): Improve semantic precision.
418 bool isImplemented(ClassElement cls) { 416 bool isImplemented(ClassElement cls) {
419 return _implementedClasses.contains(cls.declaration); 417 return _implementedClasses.contains(cls.declaration);
420 } 418 }
421 419
422 void registerClosureWithFreeTypeVariables(MemberElement element) {
423 closuresWithFreeTypeVariables.add(element);
424 }
425
426 void registerClosurizedMember(MemberElement element) { 420 void registerClosurizedMember(MemberElement element) {
427 closurizedMembers.add(element); 421 closurizedMembers.add(element);
422 if (element.type.containsTypeVariables) {
423 closurizedMembersWithFreeTypeVariables.add(element);
424 }
428 } 425 }
429 426
430 /// Register [type] as (directly) instantiated. 427 /// Register [type] as (directly) instantiated.
431 /// 428 ///
432 /// If [byMirrors] is `true`, the instantiation is through mirrors. 429 /// If [byMirrors] is `true`, the instantiation is through mirrors.
433 // TODO(johnniwinther): Fully enforce the separation between exact, through 430 // TODO(johnniwinther): Fully enforce the separation between exact, through
434 // subclass and through subtype instantiated types/classes. 431 // subclass and through subtype instantiated types/classes.
435 // TODO(johnniwinther): Support unknown type arguments for generic types. 432 // TODO(johnniwinther): Support unknown type arguments for generic types.
436 void registerTypeInstantiation( 433 void registerTypeInstantiation(
437 ResolutionInterfaceType type, ClassUsedCallback classUsed, 434 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. 630 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
634 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 631 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
635 // enqueue. 632 // enqueue.
636 switch (staticUse.kind) { 633 switch (staticUse.kind) {
637 case StaticUseKind.FIELD_GET: 634 case StaticUseKind.FIELD_GET:
638 break; 635 break;
639 case StaticUseKind.FIELD_SET: 636 case StaticUseKind.FIELD_SET:
640 fieldSetters.add(element); 637 fieldSetters.add(element);
641 break; 638 break;
642 case StaticUseKind.CLOSURE: 639 case StaticUseKind.CLOSURE:
643 LocalFunctionElement closure = staticUse.element; 640 LocalFunctionElement localFunction = staticUse.element;
644 if (closure.type.containsTypeVariables) { 641 if (localFunction.type.containsTypeVariables) {
645 closuresWithFreeTypeVariables.add(closure); 642 localFunctionsWithFreeTypeVariables.add(localFunction);
646 } 643 }
647 allClosures.add(element); 644 localFunctions.add(element);
648 break; 645 break;
649 case StaticUseKind.SUPER_TEAR_OFF: 646 case StaticUseKind.SUPER_TEAR_OFF:
650 useSet.addAll(usage.tearOff()); 647 useSet.addAll(usage.tearOff());
651 methodsNeedingSuperGetter.add(element); 648 methodsNeedingSuperGetter.add(element);
652 break; 649 break;
653 case StaticUseKind.SUPER_FIELD_SET: 650 case StaticUseKind.SUPER_FIELD_SET:
654 fieldSetters.add(element); 651 fieldSetters.add(element);
655 useSet.addAll(usage.normalUse()); 652 useSet.addAll(usage.normalUse());
656 break; 653 break;
657 case StaticUseKind.STATIC_TEAR_OFF: 654 case StaticUseKind.STATIC_TEAR_OFF:
658 useSet.addAll(usage.tearOff()); 655 useSet.addAll(usage.tearOff());
659 break; 656 break;
660 case StaticUseKind.GENERAL: 657 case StaticUseKind.GENERAL:
661 case StaticUseKind.DIRECT_USE: 658 case StaticUseKind.DIRECT_USE:
662 case StaticUseKind.CONSTRUCTOR_INVOKE: 659 case StaticUseKind.CONSTRUCTOR_INVOKE:
663 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 660 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
664 case StaticUseKind.REDIRECTION: 661 case StaticUseKind.REDIRECTION:
665 useSet.addAll(usage.normalUse()); 662 useSet.addAll(usage.normalUse());
666 break; 663 break;
667 case StaticUseKind.DIRECT_INVOKE: 664 case StaticUseKind.DIRECT_INVOKE:
668 invariant( 665 invariant(
669 element, 'Direct static use is not supported for resolution.'); 666 element, 'Direct static use is not supported for resolution.');
670 break; 667 break;
671 } 668 }
672 if (useSet.isNotEmpty) { 669 if (useSet.isNotEmpty) {
673 memberUsed(usage.entity, useSet); 670 memberUsed(usage.entity, useSet);
674 } 671 }
675 } 672 }
676 673
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]. 674 /// Return the canonical [_ClassUsage] for [cls].
688 _ClassUsage _getClassUsage(ClassElement cls) { 675 _ClassUsage _getClassUsage(ClassElement cls) {
689 return _processedClasses.putIfAbsent(cls, () { 676 return _processedClasses.putIfAbsent(cls, () {
690 cls.ensureResolved(_resolution); 677 cls.ensureResolved(_resolution);
691 _ClassUsage usage = new _ClassUsage(cls); 678 _ClassUsage usage = new _ClassUsage(cls);
692 _resolution.ensureClassMembers(cls); 679 _resolution.ensureClassMembers(cls);
693 return usage; 680 return usage;
694 }); 681 });
695 } 682 }
696 683
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 bool isNative = _backend.nativeData.isNativeClass(cls); 744 bool isNative = _backend.nativeData.isNativeClass(cls);
758 _MemberUsage usage = new _MemberUsage(member, isNative: isNative); 745 _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
759 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>(); 746 EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
760 useSet.addAll(usage.appliedUse); 747 useSet.addAll(usage.appliedUse);
761 if (member.isField && isNative) { 748 if (member.isField && isNative) {
762 registerUsedElement(member); 749 registerUsedElement(member);
763 } 750 }
764 if (member.isFunction && 751 if (member.isFunction &&
765 member.name == Identifiers.call && 752 member.name == Identifiers.call &&
766 !cls.typeVariables.isEmpty) { 753 !cls.typeVariables.isEmpty) {
767 callMethodsWithFreeTypeVariables.add(member); 754 closurizedMembersWithFreeTypeVariables.add(member);
768 } 755 }
769 756
770 if (_hasInvokedGetter(member)) { 757 if (_hasInvokedGetter(member)) {
771 useSet.addAll(usage.read()); 758 useSet.addAll(usage.read());
772 } 759 }
773 if (_hasInvocation(member)) { 760 if (_hasInvocation(member)) {
774 useSet.addAll(usage.invoke()); 761 useSet.addAll(usage.invoke());
775 } 762 }
776 if (hasInvokedSetter(member)) { 763 if (hasInvokedSetter(member)) {
777 useSet.addAll(usage.write()); 764 useSet.addAll(usage.write());
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 @override 946 @override
960 bool isMemberUsed(MemberEntity member) { 947 bool isMemberUsed(MemberEntity member) {
961 if (member.isInstanceMember) { 948 if (member.isInstanceMember) {
962 _MemberUsage usage = _instanceMemberUsage[member]; 949 _MemberUsage usage = _instanceMemberUsage[member];
963 if (usage != null && usage.hasUse) return true; 950 if (usage != null && usage.hasUse) return true;
964 } 951 }
965 _StaticMemberUsage usage = _staticMemberUsage[member]; 952 _StaticMemberUsage usage = _staticMemberUsage[member];
966 return usage != null && usage.hasUse; 953 return usage != null && usage.hasUse;
967 } 954 }
968 } 955 }
OLDNEW
« pkg/compiler/lib/src/enqueue.dart ('K') | « 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