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

Side by Side Diff: lib/compiler/implementation/js_backend/backend.dart

Issue 10908068: Better tracking of provided types at call sites (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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 | Annotate | Revision Log
OLDNEW
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 typedef void Recompile(Element element); 5 typedef void Recompile(Element element);
6 6
7 class ReturnInfo { 7 class ReturnInfo {
8 HType returnType; 8 HType returnType;
9 List<Element> compiledFunctions; 9 List<Element> compiledFunctions;
10 10
(...skipping 17 matching lines...) Expand all
28 compiledFunctions.forEach(recompile); 28 compiledFunctions.forEach(recompile);
29 } 29 }
30 compiledFunctions.clear(); 30 compiledFunctions.clear();
31 } 31 }
32 } 32 }
33 33
34 addCompiledFunction(FunctionElement function) => 34 addCompiledFunction(FunctionElement function) =>
35 compiledFunctions.add(function); 35 compiledFunctions.add(function);
36 } 36 }
37 37
38 class OptionalParameterTypes {
39 final List<SourceString> names;
40 final List<HType> types;
41
42 OptionalParameterTypes(int optionalArgumentsCount)
43 : names = new List<SourceString>(optionalArgumentsCount),
44 types = new List<HType>(optionalArgumentsCount);
45
46 int get length => names.length;
47 SourceString name(int index) => names[index];
48 HType type(int index) => types[index];
49
50 void insert(int index, SourceString name, HType type) {
kasperl 2012/09/04 09:18:45 Insert makes it sound like you're growing the list
Søren Gjesse 2012/09/04 14:55:07 Done.
51 names[index] = name;
52 types[index] = type;
53 }
54
55 String toString() => "OptionalParameterTypes($names, $types)";
56 }
57
38 class HTypeList { 58 class HTypeList {
39 final List<HType> types; 59 final List<HType> types;
60 final List<SourceString> namedArguments;
40 61
41 HTypeList(int length) : types = new List<HType>(length); 62 HTypeList(int length)
42 const HTypeList.allUnknown() : types = null; 63 : types = new List<HType>(length),
64 namedArguments = null;
65 HTypeList.withNamedArguments(int length, this.namedArguments)
66 : types = new List<HType>(length);
67 const HTypeList.allUnknown()
68 : types = null,
69 namedArguments = null;
43 70
44 factory HTypeList.fromInvocation(HInvoke node, HTypeMap types) { 71 factory HTypeList.fromStaticInvocation(HInvokeStatic node, HTypeMap types) {
45 bool allUnknown = true; 72 bool allUnknown = true;
46 for (int i = 1; i < node.inputs.length; i++) { 73 for (int i = 1; i < node.inputs.length; i++) {
47 if (types[node.inputs[i]] != HType.UNKNOWN) { 74 if (types[node.inputs[i]] != HType.UNKNOWN) {
48 allUnknown = false; 75 allUnknown = false;
49 break; 76 break;
50 } 77 }
51 } 78 }
52 if (allUnknown) return HTypeList.ALL_UNKNOWN; 79 if (allUnknown) return HTypeList.ALL_UNKNOWN;
53 80
54 HTypeList result = new HTypeList(node.inputs.length - 1); 81 HTypeList result = new HTypeList(node.inputs.length - 1);
55 for (int i = 0; i < result.types.length; i++) { 82 for (int i = 0; i < result.types.length; i++) {
56 result.types[i] = types[node.inputs[i + 1]]; 83 result.types[i] = types[node.inputs[i + 1]];
57 } 84 }
58 return result; 85 return result;
59 } 86 }
60 87
88 factory HTypeList.fromDynamicInvocation(HInvokeDynamic node,
89 Selector selector,
90 HTypeMap types) {
91 HTypeList result;
92 if (selector.namedArgumentCount > 0) {
93 result =
94 new HTypeList.withNamedArguments(
95 node.inputs.length - 1, selector.namedArguments);
kasperl 2012/09/04 09:18:45 Maybe cache node.inputs.length - 1 in a local to m
Søren Gjesse 2012/09/04 14:55:07 Done.
96 } else {
97 result = new HTypeList(node.inputs.length - 1);
98 }
99 for (int i = 0; i < result.types.length; i++) {
100 result.types[i] = types[node.inputs[i + 1]];
101 }
102 return result;
103 }
104
61 static const HTypeList ALL_UNKNOWN = const HTypeList.allUnknown(); 105 static const HTypeList ALL_UNKNOWN = const HTypeList.allUnknown();
62 106
63 bool get allUnknown => types === null; 107 bool get allUnknown => types === null;
108 bool get hasNamedArguments => namedArguments != null;
64 int get length => types.length; 109 int get length => types.length;
65 HType operator[](int index) => types[index]; 110 HType operator[](int index) => types[index];
66 111
67 HTypeList union(HTypeList other) { 112 HTypeList union(HTypeList other) {
68 if (allUnknown) return this; 113 if (allUnknown) return this;
69 if (other.allUnknown) return other; 114 if (other.allUnknown) return other;
70 if (length != other.length) return HTypeList.ALL_UNKNOWN; 115 if (length != other.length) return HTypeList.ALL_UNKNOWN;
71 bool onlyUnknown = true; 116 bool onlyUnknown = true;
72 HTypeList result = this; 117 HTypeList result = this;
73 for (int i = 0; i < length; i++) { 118 for (int i = 0; i < length; i++) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 result.types.setRange(0, i, this.types); 155 result.types.setRange(0, i, this.types);
111 } 156 }
112 if (result != this) { 157 if (result != this) {
113 result.types[i] = newType; 158 result.types[i] = newType;
114 } 159 }
115 if (result[i] != HType.UNKNOWN) onlyUnknown = false; 160 if (result[i] != HType.UNKNOWN) onlyUnknown = false;
116 } 161 }
117 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result; 162 return onlyUnknown ? HTypeList.ALL_UNKNOWN : result;
118 } 163 }
119 164
165 HTypeList unionWithOptionalParameters(
kasperl 2012/09/04 09:18:45 This is fairly complicated. Can you add unit tests
Søren Gjesse 2012/09/04 14:55:07 I tried to do it in tests/compiler/dart2js/backend
166 Selector selector,
167 FunctionSignature signature,
168 OptionalParameterTypes defaultValueTypes) {
169 assert(allUnknown || selector.argumentCount == this.length);
170 // Create a new HTypeList for holding types for all parameters.
171 HTypeList result = new HTypeList(signature.parameterCount);
172
173 // First fill in the type of the positional arguments.
174 int nextTypeIndex = -1;
175 if (allUnknown) {
176 for (int i = 0; i < selector.positionalArgumentCount; i++) {
177 result.types[i] = HType.UNKNOWN;
178 }
179 } else {
180 result.types.setRange(0, selector.positionalArgumentCount, this.types);
181 nextTypeIndex = selector.positionalArgumentCount;
182 }
183 int next = selector.positionalArgumentCount; // Next parameter of interest.
184 int index = signature.requiredParameterCount; // Current parameter.
185 signature.forEachOptionalParameter((Element element) {
186 // If some optional parameters where passed positional these have
kasperl 2012/09/04 09:18:45 positional -> positionally
kasperl 2012/09/04 09:18:45 where -> were
Søren Gjesse 2012/09/04 14:55:07 Done.
Søren Gjesse 2012/09/04 14:55:07 Done.
187 // already been filled.
188 int positionalArgumentCount = selector.positionalArgumentCount;
kasperl 2012/09/04 09:18:45 This local isn't used.
Søren Gjesse 2012/09/04 14:55:07 Removed.
189 if (index == next) {
190 assert(result.types[index] === null);
191 HType type = null;
192 if (selector.namedArgumentCount > 0 && hasNamedArguments) {
193 for (int i = 0; i < namedArguments.length; i++) {
kasperl 2012/09/04 09:18:45 Could you use namedArguments.indexOf here? Maybe y
Søren Gjesse 2012/09/04 14:55:07 Nice simplification. Done.
194 if (namedArguments[i] == element.name) {
195 type = types[nextTypeIndex++];
196 break;
197 }
198 }
199 }
200 if (type === null) {
201 for (int i = 0; i < defaultValueTypes.length; i++) {
kasperl 2012/09/04 09:18:45 Maybe add indexOf to OptionalParameterTypes?
Søren Gjesse 2012/09/04 14:55:07 Added typeFor(SourceString name) instead.
202 if (defaultValueTypes.name(i) == element.name) {
203 type = defaultValueTypes.type(i);
kasperl 2012/09/04 09:18:45 If you end up not going for indexOf, you should pr
Søren Gjesse 2012/09/04 14:55:07 See above.
204 }
205 }
206 }
207 result.types[index] = type;
208 next++;
209 }
210 index++;
211 });
212 return result;
213 }
214
120 String toString() => 215 String toString() =>
121 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; 216 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types";
122 } 217 }
123 218
124 class ArgumentTypesRegistry { 219 class ArgumentTypesRegistry {
125 final JavaScriptBackend backend; 220 final JavaScriptBackend backend;
126 final Map<Element, HTypeList> staticTypeMap; 221 final Map<Element, HTypeList> staticTypeMap;
127 final Set<Element> optimizedStaticFunctions; 222 final Set<Element> optimizedStaticFunctions;
128 final SelectorMap<HTypeList> selectorTypeMap; 223 final SelectorMap<HTypeList> selectorTypeMap;
129 final FunctionSet optimizedFunctions; 224 final FunctionSet optimizedFunctions;
130 final Map<Element, HTypeList> optimizedTypes; 225 final Map<Element, HTypeList> optimizedTypes;
226 final Map<Element, OptionalParameterTypes> optimizedDefaultValueTypes;
131 227
132 ArgumentTypesRegistry(JavaScriptBackend backend) 228 ArgumentTypesRegistry(JavaScriptBackend backend)
133 : staticTypeMap = new Map<Element, HTypeList>(), 229 : staticTypeMap = new Map<Element, HTypeList>(),
134 optimizedStaticFunctions = new Set<Element>(), 230 optimizedStaticFunctions = new Set<Element>(),
135 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler), 231 selectorTypeMap = new SelectorMap<HTypeList>(backend.compiler),
136 optimizedFunctions = new FunctionSet(backend.compiler), 232 optimizedFunctions = new FunctionSet(backend.compiler),
137 optimizedTypes = new Map<Element, HTypeList>(), 233 optimizedTypes = new Map<Element, HTypeList>(),
234 optimizedDefaultValueTypes =
235 new Map<Element, OptionalParameterTypes>(),
138 this.backend = backend; 236 this.backend = backend;
139 237
140 Compiler get compiler => backend.compiler; 238 Compiler get compiler => backend.compiler;
141 239
142 // Gather the type information provided. If the types contains no
143 // useful information there is no need to actually store them.
144 HTypeList computeProvidedTypes(HInvoke node, HTypeMap types) {
145 return new HTypeList.fromInvocation(node, types);
146 }
147
148 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) { 240 void registerStaticInvocation(HInvokeStatic node, HTypeMap types) {
149 Element element = node.element; 241 Element element = node.element;
150 HTypeList oldTypes = staticTypeMap[element]; 242 HTypeList oldTypes = staticTypeMap[element];
151 if (oldTypes == null) { 243 if (oldTypes == null) {
152 staticTypeMap[element] = computeProvidedTypes(node, types); 244 staticTypeMap[element] = new HTypeList.fromStaticInvocation(node, types);
153 } else { 245 } else {
154 if (oldTypes.allUnknown) return; 246 if (oldTypes.allUnknown) return;
155 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); 247 HTypeList newTypes = oldTypes.unionWithInvoke(node, types);
156 if (newTypes === oldTypes) return; 248 if (newTypes === oldTypes) return;
157 staticTypeMap[element] = newTypes; 249 staticTypeMap[element] = newTypes;
158 if (optimizedStaticFunctions.contains(element)) { 250 if (optimizedStaticFunctions.contains(element)) {
159 backend.scheduleForRecompilation(element); 251 backend.scheduleForRecompilation(element);
160 } 252 }
161 } 253 }
162 } 254 }
(...skipping 17 matching lines...) Expand all
180 // TODO(sgjesse): These checks should use the codegenWorld and keep track 272 // TODO(sgjesse): These checks should use the codegenWorld and keep track
181 // of changes to this information. 273 // of changes to this information.
182 Element element = node.element; 274 Element element = node.element;
183 Universe resolverWorld = compiler.resolverWorld; 275 Universe resolverWorld = compiler.resolverWorld;
184 if (element != null && 276 if (element != null &&
185 (resolverWorld.hasFieldGetter(element, compiler) || 277 (resolverWorld.hasFieldGetter(element, compiler) ||
186 resolverWorld.hasInvokedGetter(element, compiler))) { 278 resolverWorld.hasInvokedGetter(element, compiler))) {
187 return; 279 return;
188 } 280 }
189 281
190 // TODO(kasperl): For now, we're only dealing with non-named arguments. 282 HTypeList providedTypes =
191 // We should generalize this. 283 new HTypeList.fromDynamicInvocation(node, selector, types);
192 HTypeList providedTypes = selector.namedArguments.isEmpty()
193 ? computeProvidedTypes(node, types)
194 : HTypeList.ALL_UNKNOWN;
195 if (!selectorTypeMap.containsKey(selector)) { 284 if (!selectorTypeMap.containsKey(selector)) {
196 selectorTypeMap[selector] = providedTypes; 285 selectorTypeMap[selector] = providedTypes;
197 } else { 286 } else {
198 HTypeList oldTypes = selectorTypeMap[selector]; 287 HTypeList oldTypes = selectorTypeMap[selector];
199 HTypeList newTypes = oldTypes.unionWithInvoke(node, types); 288 HTypeList newTypes = oldTypes.unionWithInvoke(node, types);
200 if (newTypes === oldTypes) return; 289 if (newTypes === oldTypes) return;
201 selectorTypeMap[selector] = newTypes; 290 selectorTypeMap[selector] = newTypes;
202 } 291 }
203 292
204 // If we're not compiling, we don't have to do anything. 293 // If we're not compiling, we don't have to do anything.
205 if (compiler.phase != Compiler.PHASE_COMPILING) return; 294 if (compiler.phase != Compiler.PHASE_COMPILING) return;
206 295
207 // Run through all optimized functions and figure out if they need 296 // Run through all optimized functions and figure out if they need
208 // to be recompiled because of this new invocation. 297 // to be recompiled because of this new invocation.
209 optimizedFunctions.filterBySelector(selector).forEach((Element element) { 298 optimizedFunctions.filterBySelector(selector).forEach((Element element) {
210 // TODO(kasperl): Maybe check if the element is already marked for 299 // TODO(kasperl): Maybe check if the element is already marked for
211 // recompilation? Could be pretty cheap compared to computing 300 // recompilation? Could be pretty cheap compared to computing
212 // union types. 301 // union types.
213 HTypeList newTypes = parameterTypes(element); 302 HTypeList newTypes =
303 parameterTypes(element, optimizedDefaultValueTypes[element]);
214 bool recompile = false; 304 bool recompile = false;
215 if (newTypes.allUnknown) { 305 if (newTypes.allUnknown) {
216 recompile = true; 306 recompile = true;
217 } else { 307 } else {
218 HTypeList oldTypes = optimizedTypes[element]; 308 HTypeList oldTypes = optimizedTypes[element];
219 if (newTypes.length != oldTypes.length) { 309 assert(newTypes.length == oldTypes.length);
kasperl 2012/09/04 09:18:45 This is great!
Søren Gjesse 2012/09/04 14:55:07 Thanks.
220 // TODO(kasperl): This can be improved. If the newTypes aren't in 310 for (int i = 0; i < oldTypes.length; i++) {
221 // conflict we can avoid the recompilation.
222 recompile = true;
223 } else for (int i = 0; i < oldTypes.length; i++) {
224 if (newTypes[i] != oldTypes[i]) { 311 if (newTypes[i] != oldTypes[i]) {
225 recompile = true; 312 recompile = true;
226 break; 313 break;
227 } 314 }
228 } 315 }
229 } 316 }
230 if (recompile) backend.scheduleForRecompilation(element); 317 if (recompile) backend.scheduleForRecompilation(element);
231 }); 318 });
232 } 319 }
233 320
234 HTypeList parameterTypes(element) { 321 HTypeList parameterTypes(FunctionElement element,
322 OptionalParameterTypes defaultValueTypes) {
235 // Handle static functions separately. 323 // Handle static functions separately.
236 if (Elements.isStaticOrTopLevelFunction(element)) { 324 if (Elements.isStaticOrTopLevelFunction(element)) {
237 HTypeList types = staticTypeMap[element]; 325 HTypeList types = staticTypeMap[element];
238 if (types !== null) { 326 if (types !== null) {
239 if (!optimizedStaticFunctions.contains(element)) { 327 if (!optimizedStaticFunctions.contains(element)) {
240 optimizedStaticFunctions.add(element); 328 optimizedStaticFunctions.add(element);
241 } 329 }
242 return types; 330 return types;
243 } else { 331 } else {
244 return HTypeList.ALL_UNKNOWN; 332 return HTypeList.ALL_UNKNOWN;
245 } 333 }
246 } 334 }
247 335
336
248 // TODO(kasperl): What kind of non-members do we get here? 337 // TODO(kasperl): What kind of non-members do we get here?
249 if (!element.isMember()) return HTypeList.ALL_UNKNOWN; 338 if (!element.isMember()) return HTypeList.ALL_UNKNOWN;
339 if (element.isGetter()) return HTypeList.ALL_UNKNOWN;
kasperl 2012/09/04 09:18:45 Add a comment that explains why getters should lea
Søren Gjesse 2012/09/04 14:55:07 Done.
250 340
251 FunctionSignature signature = element.computeSignature(compiler); 341 FunctionSignature signature = element.computeSignature(compiler);
252 HTypeList found = null; 342 HTypeList found = null;
253 selectorTypeMap.visitMatching(element, 343 selectorTypeMap.visitMatching(element,
254 (Selector selector, HTypeList types) { 344 (Selector selector, HTypeList types) {
255 if (selector.argumentCount != signature.parameterCount) { 345 if (selector.argumentCount != signature.parameterCount ||
256 found = HTypeList.ALL_UNKNOWN; 346 selector.namedArgumentCount > 0) {
257 return false; 347 types = types.unionWithOptionalParameters(selector,
258 } else if (found === null) { 348 signature,
kasperl 2012/09/04 09:18:45 Indentation is slightly off.
Søren Gjesse 2012/09/04 14:55:07 Done.
Søren Gjesse 2012/09/04 14:55:07 Done.
349 defaultValueTypes);
350 }
351 assert(types.allUnknown || types.length == signature.parameterCount);
352 if (found === null) {
259 found = types; 353 found = types;
260 return true; 354 return !found.allUnknown;
kasperl 2012/09/04 09:18:45 This should be shareable now. Something like:
Søren Gjesse 2012/09/04 14:55:07 Done.
261 } else { 355 } else {
262 found = found.union(types); 356 found = found.union(types);
263 return !found.allUnknown; 357 return !found.allUnknown;
264 } 358 }
265 }); 359 });
266 return found !== null ? found : HTypeList.ALL_UNKNOWN; 360 return found !== null ? found : HTypeList.ALL_UNKNOWN;
267 } 361 }
268 362
269 void registerOptimization(Element element, HTypeList parameterTypes) { 363 void registerOptimization(Element element,
364 HTypeList parameterTypes,
365 OptionalParameterTypes defaultValueTypes) {
270 if (Elements.isStaticOrTopLevelFunction(element)) { 366 if (Elements.isStaticOrTopLevelFunction(element)) {
271 if (parameterTypes.allUnknown) { 367 if (parameterTypes.allUnknown) {
272 optimizedStaticFunctions.remove(element); 368 optimizedStaticFunctions.remove(element);
273 } else { 369 } else {
274 optimizedStaticFunctions.add(element); 370 optimizedStaticFunctions.add(element);
275 } 371 }
276 } 372 }
277 373
278 // TODO(kasperl): What kind of non-members do we get here? 374 // TODO(kasperl): What kind of non-members do we get here?
279 if (!element.isMember()) return; 375 if (!element.isMember()) return;
280 376
281 if (parameterTypes.allUnknown) { 377 if (parameterTypes.allUnknown) {
282 optimizedFunctions.remove(element); 378 optimizedFunctions.remove(element);
283 optimizedTypes.remove(element); 379 optimizedTypes.remove(element);
380 optimizedDefaultValueTypes.remove(element);
284 } else { 381 } else {
285 optimizedFunctions.add(element); 382 optimizedFunctions.add(element);
286 optimizedTypes[element] = parameterTypes; 383 optimizedTypes[element] = parameterTypes;
384 optimizedDefaultValueTypes[element] = defaultValueTypes;
287 } 385 }
288 } 386 }
289 } 387 }
290 388
291 class JavaScriptItemCompilationContext extends ItemCompilationContext { 389 class JavaScriptItemCompilationContext extends ItemCompilationContext {
292 final HTypeMap types; 390 final HTypeMap types;
293 391
294 JavaScriptItemCompilationContext() : types = new HTypeMap(); 392 JavaScriptItemCompilationContext() : types = new HTypeMap();
295 } 393 }
296 394
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 */ 596 */
499 void registerNonCallStaticUse(HStatic node) { 597 void registerNonCallStaticUse(HStatic node) {
500 argumentTypes.registerNonCallStaticUse(node); 598 argumentTypes.registerNonCallStaticUse(node);
501 } 599 }
502 600
503 /** 601 /**
504 * Retrieve the types of the parameters used for calling the [element] 602 * Retrieve the types of the parameters used for calling the [element]
505 * function. The types are optimistic in the sense as they are based on the 603 * function. The types are optimistic in the sense as they are based on the
506 * possible invocations of the function seen so far. 604 * possible invocations of the function seen so far.
507 */ 605 */
508 HTypeList optimisticParameterTypes(FunctionElement element) { 606 HTypeList optimisticParameterTypes(
509 return argumentTypes.parameterTypes(element); 607 FunctionElement element,
608 OptionalParameterTypes defaultValueTypes) {
609 return argumentTypes.parameterTypes(element, defaultValueTypes);
510 } 610 }
511 611
512 /** 612 /**
513 * Register that the function [element] has been optimized under the 613 * Register that the function [element] has been optimized under the
514 * assumptions that the types [parameterType] will be used for calling it. 614 * assumptions that the types [parameterType] will be used for calling it.
515 * If this assumption fail the function will be scheduled for recompilation. 615 * The passed [defaultValueTypes] holds the types of default values for
616 * the optional parameters. If this assumption fail the function will be
617 * scheduled for recompilation.
516 */ 618 */
517 registerParameterTypesOptimization( 619 registerParameterTypesOptimization(
518 FunctionElement element, HTypeList parameterTypes) { 620 FunctionElement element,
519 argumentTypes.registerOptimization(element, parameterTypes); 621 HTypeList parameterTypes,
kasperl 2012/09/04 09:18:45 I wonder if we should have an abstraction over all
Søren Gjesse 2012/09/04 14:55:07 That might be - I will look at that as a separate
622 OptionalParameterTypes defaultValueTypes) {
623 argumentTypes.registerOptimization(
624 element, parameterTypes, defaultValueTypes);
520 } 625 }
521 626
522 void registerReturnType(FunctionElement element, HType returnType) { 627 void registerReturnType(FunctionElement element, HType returnType) {
523 ReturnInfo info = returnInfo[element]; 628 ReturnInfo info = returnInfo[element];
524 if (info != null) { 629 if (info != null) {
525 info.update(returnType, scheduleForRecompilation); 630 info.update(returnType, scheduleForRecompilation);
526 } else { 631 } else {
527 returnInfo[element] = new ReturnInfo(returnType); 632 returnInfo[element] = new ReturnInfo(returnType);
528 } 633 }
529 } 634 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 return const SourceString('listSuperTypeCheck'); 682 return const SourceString('listSuperTypeCheck');
578 } 683 }
579 } else if (nativeCheck) { 684 } else if (nativeCheck) {
580 return const SourceString('callTypeCheck'); 685 return const SourceString('callTypeCheck');
581 } else { 686 } else {
582 return const SourceString('propertyTypeCheck'); 687 return const SourceString('propertyTypeCheck');
583 } 688 }
584 } 689 }
585 } 690 }
586 } 691 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698