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

Side by Side Diff: pkg/fletchc/lib/src/dynamic_call_enqueuer.dart

Issue 1328793002: Don't rely on resolution for enqueuing (Closed) Base URL: git@github.com:dart-lang/fletch.git@master
Patch Set: Created 5 years, 3 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 | « no previous file | pkg/fletchc/lib/src/fletch_enqueuer.dart » ('j') | 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) 2015, the Fletch project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Fletch 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.md file. 3 // BSD-style license that can be found in the LICENSE.md file.
4 4
5 library fletchc.dynamic_call_enqueuer; 5 library fletchc.dynamic_call_enqueuer;
6 6
7 import 'dart:collection' show 7 import 'dart:collection' show
8 Queue; 8 Queue;
9 9
10 import 'package:compiler/src/dart2jslib.dart' show
11 EnqueueTask;
12
13 import 'package:compiler/src/universe/universe.dart' show 10 import 'package:compiler/src/universe/universe.dart' show
14 CallStructure, 11 CallStructure,
12 Selector,
15 UniverseSelector; 13 UniverseSelector;
16 14
17 import 'package:compiler/src/dart_types.dart' show 15 import 'package:compiler/src/dart_types.dart' show
18 InterfaceType; 16 InterfaceType;
19 17
20 import 'package:compiler/src/elements/elements.dart' show 18 import 'package:compiler/src/elements/elements.dart' show
21 ClassElement, 19 ClassElement,
22 Element, 20 Element,
21 FunctionElement,
23 Name; 22 Name;
24 23
25 import 'package:compiler/src/util/util.dart' show 24 import 'package:compiler/src/util/util.dart' show
26 Hashing; 25 Hashing;
27 26
28 import 'fletch_compiler_implementation.dart' show 27 import 'fletch_compiler_implementation.dart' show
29 FletchCompilerImplementation; 28 FletchCompilerImplementation;
30 29
30 typedef void ElementUsage(Element element, UniverseSelector selector);
31
31 /// Implements the dynamic part of the tree-shaking algorithm. 32 /// Implements the dynamic part of the tree-shaking algorithm.
32 /// 33 ///
33 /// By "dynamic" part we mean the part that is about matching instantiated 34 /// By "dynamic" part we mean the part that is about matching instantiated
34 /// classes with called instance methods. 35 /// classes with called instance methods.
35 class DynamicCallEnqueuer { 36 class DynamicCallEnqueuer {
36 final FletchCompilerImplementation compiler; 37 final FletchCompilerImplementation compiler;
37 38
38 final Set<ClassElement> instantiatedClasses = new Set<ClassElement>(); 39 final Set<ClassElement> instantiatedClasses = new Set<ClassElement>();
39 40
40 final Queue<ClassElement> pendingInstantiatedClasses = 41 final Queue<ClassElement> pendingInstantiatedClasses =
41 new Queue<ClassElement>(); 42 new Queue<ClassElement>();
42 43
43 final Set<UntypedSelector> enqueuedSelectors = new Set<UntypedSelector>(); 44 final Set<Selector> enqueuedSelectors = new Set<Selector>();
44 45
45 final Queue<UntypedSelector> pendingSelectors = 46 final Queue<Selector> pendingSelectors = new Queue<Selector>();
46 new Queue<UntypedSelector>();
47 47
48 final Set<UniverseSelector> newlySeenSelectors; 48 final Set<UniverseSelector> newlySeenSelectors;
49 49
50 EnqueueTask task;
51
52 DynamicCallEnqueuer(FletchCompilerImplementation compiler) 50 DynamicCallEnqueuer(FletchCompilerImplementation compiler)
53 : compiler = compiler, 51 : compiler = compiler,
54 newlySeenSelectors = compiler.cacheStrategy.newSet(); 52 newlySeenSelectors = compiler.cacheStrategy.newSet();
55 53
56 void registerInstantiatedType(InterfaceType type) { 54 void registerInstantiatedType(InterfaceType type) {
57 ClassElement cls = type.element.declaration; 55 ClassElement cls = type.element.declaration;
58 if (instantiatedClasses.add(cls)) { 56 if (instantiatedClasses.add(cls)) {
59 pendingInstantiatedClasses.addLast(cls); 57 pendingInstantiatedClasses.addLast(cls);
60 } 58 }
61 } 59 }
62 60
63 void enqueueApplicableMembers( 61 void enqueueApplicableMembers(
64 ClassElement cls, 62 ClassElement cls,
65 UntypedSelector selector, 63 Selector selector,
66 void enqueueElement(Element element)) { 64 ElementUsage enqueueElement) {
67 Element member = cls.lookupByName(selector.name); 65 Element member = cls.lookupByName(selector.memberName);
68 if (member != null && task.resolution.isProcessed(member)) { 66 if (member == null) return;
69 // TODO(ahe): Check if selector applies; Don't consult resolution. 67 if (!member.isInstanceMember) return;
70 enqueueElement(member); 68 if (selector.isGetter) {
69 if (member.isField || member.isGetter) {
70 enqueueElement(member, new UniverseSelector(selector, null));
71 } else {
72 // Tear-off.
73 compiler.reportVerboseInfo(
74 member, "enqueued as tear-off", forceVerbose: true);
75 enqueueElement(member, new UniverseSelector(selector, null));
76 }
77 } else if (selector.isSetter) {
78 if (member.isField || member.isSetter) {
79 enqueueElement(member, new UniverseSelector(selector, null));
80 }
81 } else if (member.isFunction && selector.signatureApplies(member)) {
82 enqueueElement(member, new UniverseSelector(selector, null));
71 } 83 }
72 } 84 }
73 85
74 void enqueueInstanceMethods(void enqueueElement(Element element)) { 86 void enqueueInstanceMethods(ElementUsage enqueueElement) {
75 while (!pendingInstantiatedClasses.isEmpty) { 87 while (!pendingInstantiatedClasses.isEmpty) {
76 ClassElement cls = pendingInstantiatedClasses.removeFirst(); 88 ClassElement cls = pendingInstantiatedClasses.removeFirst();
77 compiler.reportVerboseInfo(cls, "was instantiated", forceVerbose: true); 89 compiler.reportVerboseInfo(cls, "was instantiated", forceVerbose: true);
78 for (UntypedSelector selector in enqueuedSelectors) { 90 for (Selector selector in enqueuedSelectors) {
79 // TODO(ahe): As we iterate over enqueuedSelectors, we may end up 91 // TODO(ahe): As we iterate over enqueuedSelectors, we may end up
80 // processing calling _enqueueApplicableMembers twice for newly 92 // processing calling _enqueueApplicableMembers twice for newly
81 // instantiated classes. Once here, and then once more in the while 93 // instantiated classes. Once here, and then once more in the while
82 // loop below. 94 // loop below.
83 enqueueApplicableMembers(cls, selector, enqueueElement); 95 enqueueApplicableMembers(cls, selector, enqueueElement);
84 } 96 }
85 } 97 }
86 while (!pendingSelectors.isEmpty) { 98 while (!pendingSelectors.isEmpty) {
87 UntypedSelector selector = pendingSelectors.removeFirst(); 99 Selector selector = pendingSelectors.removeFirst();
88 compiler.reportVerboseInfo( 100 compiler.reportVerboseInfo(
89 null, "$selector was called", forceVerbose: true); 101 null, "$selector was called", forceVerbose: true);
90 for (ClassElement cls in instantiatedClasses) { 102 for (ClassElement cls in instantiatedClasses) {
91 enqueueApplicableMembers(cls, selector, enqueueElement); 103 enqueueApplicableMembers(cls, selector, enqueueElement);
92 } 104 }
93 } 105 }
94 } 106 }
95 107
96 void enqueueSelector(UniverseSelector universeSelector) { 108 void enqueueSelector(UniverseSelector universeSelector) {
97 UntypedSelector selector = 109 assert(universeSelector.mask == null);
98 new UntypedSelector.fromUniverseSelector(universeSelector); 110 Selector selector = universeSelector.selector;
99 if (enqueuedSelectors.add(selector)) { 111 if (enqueuedSelectors.add(selector)) {
100 pendingSelectors.add(selector); 112 pendingSelectors.add(selector);
101 newlySeenSelectors.add(universeSelector); 113 newlySeenSelectors.add(universeSelector);
102 } 114 }
103 } 115 }
104 116
105 void forgetElement(Element element) { 117 void forgetElement(Element element) {
106 // TODO(ahe): Make sure that the incremental compiler 118 // TODO(ahe): Make sure that the incremental compiler
107 // (library_updater.dart) registers classes with schema changes as having 119 // (library_updater.dart) registers classes with schema changes as having
108 // been instantiated. 120 // been instantiated.
109 instantiatedClasses.remove(element); 121 instantiatedClasses.remove(element);
110 } 122 }
111 } 123 }
112
113 /// Represents information about a call site.
114 ///
115 /// This class differ from [UniverseSelector] in two key areas:
116 ///
117 /// 1. Implements `operator ==` (and is thus suitable for use in a [Set])
ahe 2015/09/03 15:07:10 I had overlooked that Selector is canonicalized an
Johnni Winther 2015/09/03 16:21:17 They might actually not always be canonicalized bu
ahe 2015/09/03 16:24:09 That's good enough for me :-)
118 /// 2. Has no type mask
119 class UntypedSelector {
120 final Name name;
121
122 final bool isGetter;
123
124 final bool isSetter;
125
126 final CallStructure structure;
127
128 final int hashCode;
129
130 UntypedSelector(
131 this.name,
132 this.isGetter,
133 this.isSetter,
134 this.structure,
135 this.hashCode);
136
137 factory UntypedSelector.fromUniverseSelector(UniverseSelector selector) {
138 if (selector.mask != null) {
139 throw new ArgumentError("[selector] has non-null type mask");
140 }
141 Name name = selector.selector.memberName;
142 CallStructure structure = selector.selector.callStructure;
143 bool isGetter = selector.selector.isGetter;
144 bool isSetter = selector.selector.isSetter;
145 int hash = Hashing.mixHashCodeBits(name.hashCode, structure.hashCode);
146 hash = Hashing.mixHashCodeBits(hash, isSetter.hashCode);
147 hash = Hashing.mixHashCodeBits(hash, isGetter.hashCode);
148 return new UntypedSelector(name, isGetter, isSetter, structure, hash);
149 }
150
151 bool operator ==(other) {
152 if (other is UntypedSelector) {
153 return name == other.name &&
154 isGetter == other.isGetter && isSetter == other.isSetter &&
155 structure == other.structure;
156 } else {
157 return false;
158 }
159 }
160
161 String toString() {
162 return
163 'UntypedSelector($name, '
164 '${isGetter ? "getter, " : ""}'
165 '${isSetter ? "setter, " : ""}'
166 '$structure)';
167 }
168 }
OLDNEW
« no previous file with comments | « no previous file | pkg/fletchc/lib/src/fletch_enqueuer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698