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

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

Issue 10964016: Change the type inference for fields in dart2js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed more comments and added more tests Created 8 years, 2 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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 } 216 }
217 index++; 217 index++;
218 }); 218 });
219 return result; 219 return result;
220 } 220 }
221 221
222 String toString() => 222 String toString() =>
223 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types"; 223 allUnknown ? "HTypeList.ALL_UNKNOWN" : "HTypeList $types";
224 } 224 }
225 225
226 class FieldTypesRegistry {
227 final JavaScriptBackend backend;
228
229 /**
230 * For each class [constructors] holds the set of constructors. If there is
ngeoffray 2012/09/27 12:35:46 each class,
Søren Gjesse 2012/09/27 13:22:49 Done.
231 * more than one constructor for a class it is currently not possible to
232 * infer the field types from construction as the information collected does
ngeoffray 2012/09/27 12:35:46 from construction,
Søren Gjesse 2012/09/27 13:22:49 Done.
233 * not correlate the generative constructors and generative constructor
234 * body/bodies.
235 */
236 final Map<Element, Set<Element>> constructors;
ngeoffray 2012/09/27 12:35:46 Type the keys as ClassElement?
Søren Gjesse 2012/09/27 13:22:49 Done.
237
238 /**
239 * The collected type information is stored in three maps. One for types
240 * assigned in the initializer list(s) [fieldInitializerTypeMap], one for
241 * types assigned in the constructor(s) [fieldConstructorTypeMap] and one
ngeoffray 2012/09/27 12:35:46 , and
Søren Gjesse 2012/09/27 13:22:49 Done.
242 * for typesassigned in the rest of the code [fieldTypeMap].
ngeoffray 2012/09/27 12:35:46 typesassigned -> types assigned
ngeoffray 2012/09/27 12:35:46 rest of the code where the field can be resolved.
Søren Gjesse 2012/09/27 13:22:49 Done.
Søren Gjesse 2012/09/27 13:22:49 Done.
243 *
244 * If a field has a type both from constructors and from the initializer
245 * list(s) then the type from the constructor(s) will owerride the one from
ngeoffray 2012/09/27 12:35:46 , then
Søren Gjesse 2012/09/27 13:22:49 Done.
246 * the initializer list(s).
247 *
248 * As the order in which generative constructors, generative constructor
ngeoffray 2012/09/27 12:35:46 As -> Because ?
Søren Gjesse 2012/09/27 13:22:49 Done.
249 * bodies and normal methods/functions is undefined, and as they can all be
ngeoffray 2012/09/27 12:35:46 bodies,
ngeoffray 2012/09/27 12:35:46 as -> because ?
Søren Gjesse 2012/09/27 13:22:49 Done.
Søren Gjesse 2012/09/27 13:22:49 Done.
250 * recompiled it is not possible to combile this information into one map at
ngeoffray 2012/09/27 12:35:46 recompiled,
ngeoffray 2012/09/27 12:35:46 combile -> combine
Søren Gjesse 2012/09/27 13:22:49 Done.
Søren Gjesse 2012/09/27 13:22:49 Done.
251 * the moment.
252 */
253 final Map<Element, HType> fieldInitializerTypeMap;
254 final Map<Element, HType> fieldConstructorTypeMap;
255 final Map<Element, HType> fieldTypeMap;
256
257 /**
258 * The set of current names setter selectors used. If a named selector is
259 * used it is currently not possible to infer the type of the field.
260 */
261 final Set<SourceString> setterSelectorsUsed;
262
263 final Map<Element, Set<Element>> optimizedStaticFunctions;
264 final Map<Element, FunctionSet> optimizedFunctions;
265
266 FieldTypesRegistry(JavaScriptBackend backend)
267 : constructors = new Map<Element, Set<Element>>(),
268 fieldInitializerTypeMap = new Map<Element, HType>(),
269 fieldConstructorTypeMap = new Map<Element, HType>(),
270 fieldTypeMap = new Map<Element, HType>(),
271 setterSelectorsUsed = new Set<SourceString>(),
272 optimizedStaticFunctions = new Map<Element, Set<Element>>(),
273 optimizedFunctions = new Map<Element, FunctionSet>(),
274 this.backend = backend;
275
276 Compiler get compiler => backend.compiler;
277
278 void scheduleRecompilation(Element field) {
279 Set optimizedStatics = optimizedStaticFunctions[field];
280 if (optimizedStatics != null) {
281 optimizedStatics.forEach(backend.scheduleForRecompilation);
282 optimizedStaticFunctions.remove(field);
283 }
284 FunctionSet optimized = optimizedFunctions[field];
285 if (optimized != null) {
286 optimized.forEach(backend.scheduleForRecompilation);
287 optimizedFunctions.remove(field);
288 }
289 }
290
291 int constructorCount(Element element) {
292 assert(element.isClass());
293 Set<Element> ctors = constructors[element];
294 return ctors === null ? 0 : ctors.length;
295 }
296
297 void registerFieldType(Map<Element, HType> typeMap,
298 Element field,
299 HType type) {
300 assert(field.isField());
301 HType before = optimisticFieldType(field);
302
303 HType oldType = typeMap[field];
304 HType newType;
305
306 if (oldType != null) {
307 newType = oldType.union(type);
308 } else {
309 newType = type;
310 }
311 typeMap[field] = newType;
312 if (oldType != newType) {
313 scheduleRecompilation(field);
314 }
315 }
316
317 void registerConstructor(Element element) {
318 assert(element.isGenerativeConstructor());
319 Element cls = element.enclosingElement;
320 constructors.putIfAbsent(cls, () => new Set<Element>());
321 Set<Element> ctors = constructors[cls];
322 if (ctors.contains(element)) return;
323 ctors.add(element);
324 // We cannot infer field types for classes with more than one constructor.
325 // When the second constructor is seen recompile all functions relying on
ngeoffray 2012/09/27 12:35:46 seen,
Søren Gjesse 2012/09/27 13:22:49 Done.
326 // optimistic field types for that class.
327 // TODO(sgjesse): Handle field types for classes with more than one
328 // constructor.
329 if (ctors.length == 2) {
330 optimizedFunctions.forEach((Element field, _) {
331 if (field.enclosingElement === cls) {
332 scheduleRecompilation(field);
333 }
334 });
335 }
336 }
337
338 void registerFieldInitializer(Element field, HType type) {
339 registerFieldType(fieldInitializerTypeMap, field, type);
340 }
341
342 void registerFieldConstructor(Element field, HType type) {
343 registerFieldType(fieldConstructorTypeMap, field, type);
344 }
345
346 void registerFieldSetter(FunctionElement element, Element field, HType type) {
347 HType initializerType = fieldInitializerTypeMap[field];
348 HType constructorType = fieldConstructorTypeMap[field];
349 HType setterType = fieldTypeMap[field];
350 if (type == HType.UNKNOWN
351 && initializerType == null
352 && constructorType == null
353 && setterType == null) {
354 // Don't register UNKONWN if there is currently no type information
355 // present for the field. Instead register the function holding the
356 // setter for recompilation if better type information for the field
357 // becomes available.
358 registerOptimizedFunction(element, field, type);
359 return;
360 }
361 registerFieldType(fieldTypeMap, field, type);
362 }
363
364 void addedDynamicSetter(Selector setter, HType type) {
365 // Field type optimizations are disabled for all fields matching a
366 // setter selector.
367 assert(setter.isSetter());
368 // TODO(sgjesse): Take the type of the setter into account.
369 if (setterSelectorsUsed.contains(setter.name)) return;
370 setterSelectorsUsed.add(setter.name);
371 optimizedStaticFunctions.forEach((Element field, _) {
372 if (field.name == setter.name) {
373 scheduleRecompilation(field);
374 }
375 });
376 optimizedFunctions.forEach((Element field, _) {
377 if (field.name == setter.name) {
378 scheduleRecompilation(field);
379 }
380 });
381 }
382
383 HType optimisticFieldType(Element field) {
384 assert(field.isField());
385 if (constructorCount(field.enclosingElement) > 1) {
386 return HType.UNKNOWN;
387 }
388 if (setterSelectorsUsed.contains(field.name)) {
389 return HType.UNKNOWN;
390 }
391 HType initializerType = fieldInitializerTypeMap[field];
392 HType constructorType = fieldConstructorTypeMap[field];
393 if (initializerType === null && constructorType === null) {
394 return HType.UNKNOWN;
ngeoffray 2012/09/27 12:35:46 Why don't you also check fieldTypeMap here? Please
Søren Gjesse 2012/09/27 13:22:49 Done.
395 }
396 HType result = constructorType != null ? constructorType : initializerType;
ngeoffray 2012/09/27 12:35:46 Also add a comment here on why you're using constr
Søren Gjesse 2012/09/27 13:22:49 Done.
397 HType type = fieldTypeMap[field];
398 if (type !== null) result = result.union(type);
399 return result;
400 }
401
402 void registerOptimizedFunction(FunctionElement element,
403 Element field,
404 HType type) {
405 assert(field.isField());
406 if (Elements.isStaticOrTopLevel(element)) {
407 optimizedStaticFunctions.putIfAbsent(
408 field, () => new Set<Element>());
409 optimizedStaticFunctions[field].add(element);
410 } else {
411 optimizedFunctions.putIfAbsent(
412 field, () => new FunctionSet(backend.compiler));
413 optimizedFunctions[field].add(element);
414 }
415 }
416
417 void dump() {
418 Set<Element> allFields = new Set<Element>();
419 fieldInitializerTypeMap.getKeys().forEach(allFields.add);
420 fieldConstructorTypeMap.getKeys().forEach(allFields.add);
421 fieldTypeMap.getKeys().forEach(allFields.add);
422 allFields.forEach((Element field) {
423 print("Inferred $field has type ${optimisticFieldType(field)}");
424 });
425 }
426 }
427
226 class ArgumentTypesRegistry { 428 class ArgumentTypesRegistry {
227 final JavaScriptBackend backend; 429 final JavaScriptBackend backend;
228 430
229 /** 431 /**
230 * Documentation wanted -- johnniwinther 432 * Documentation wanted -- johnniwinther
231 * 433 *
232 * Invariant: Keys must be declaration elements. 434 * Invariant: Keys must be declaration elements.
233 */ 435 */
234 final Map<Element, HTypeList> staticTypeMap; 436 final Map<Element, HTypeList> staticTypeMap;
235 437
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 signature, 580 signature,
379 defaultValueTypes); 581 defaultValueTypes);
380 } 582 }
381 assert(types.allUnknown || types.length == signature.parameterCount); 583 assert(types.allUnknown || types.length == signature.parameterCount);
382 found = (found === null) ? types : found.union(types); 584 found = (found === null) ? types : found.union(types);
383 return !found.allUnknown; 585 return !found.allUnknown;
384 }); 586 });
385 return found !== null ? found : HTypeList.ALL_UNKNOWN; 587 return found !== null ? found : HTypeList.ALL_UNKNOWN;
386 } 588 }
387 589
388 void registerOptimization(Element element, 590 void registerOptimizedFunction(Element element,
389 HTypeList parameterTypes, 591 HTypeList parameterTypes,
390 OptionalParameterTypes defaultValueTypes) { 592 OptionalParameterTypes defaultValueTypes) {
391 assert(invariant(element, element.isDeclaration));
392 if (Elements.isStaticOrTopLevelFunction(element)) { 593 if (Elements.isStaticOrTopLevelFunction(element)) {
393 if (parameterTypes.allUnknown) { 594 if (parameterTypes.allUnknown) {
394 optimizedStaticFunctions.remove(element); 595 optimizedStaticFunctions.remove(element);
395 } else { 596 } else {
396 optimizedStaticFunctions.add(element); 597 optimizedStaticFunctions.add(element);
397 } 598 }
398 } 599 }
399 600
400 // TODO(kasperl): What kind of non-members do we get here? 601 // TODO(kasperl): What kind of non-members do we get here?
401 if (!element.isMember()) return; 602 if (!element.isMember()) return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 637
437 final Namer namer; 638 final Namer namer;
438 639
439 /** 640 /**
440 * Interface used to determine if an object has the JavaScript 641 * Interface used to determine if an object has the JavaScript
441 * indexing behavior. The interface is only visible to specific 642 * indexing behavior. The interface is only visible to specific
442 * libraries. 643 * libraries.
443 */ 644 */
444 ClassElement jsIndexingBehaviorInterface; 645 ClassElement jsIndexingBehaviorInterface;
445 646
446 final Map<Element, Map<Element, HType>> fieldInitializers;
447 final Map<Element, Map<Element, HType>> fieldConstructorSetters;
448 final Map<Element, Map<Element, HType>> fieldSettersType;
449
450 final Map<Element, ReturnInfo> returnInfo; 647 final Map<Element, ReturnInfo> returnInfo;
451 648
452 /** 649 /**
453 * Documentation wanted -- johnniwinther 650 * Documentation wanted -- johnniwinther
454 * 651 *
455 * Invariant: Elements must be declaration elements. 652 * Invariant: Elements must be declaration elements.
456 */ 653 */
457 final List<Element> invalidateAfterCodegen; 654 final List<Element> invalidateAfterCodegen;
458 ArgumentTypesRegistry argumentTypes; 655 ArgumentTypesRegistry argumentTypes;
656 FieldTypesRegistry fieldTypes;
459 657
460 List<CompilerTask> get tasks { 658 List<CompilerTask> get tasks {
461 return <CompilerTask>[builder, optimizer, generator, emitter]; 659 return <CompilerTask>[builder, optimizer, generator, emitter];
462 } 660 }
463 661
464 JavaScriptBackend(Compiler compiler, bool generateSourceMap) 662 JavaScriptBackend(Compiler compiler, bool generateSourceMap)
465 : fieldInitializers = new Map<Element, Map<Element, HType>>(), 663 : namer = new Namer(compiler),
466 fieldConstructorSetters = new Map<Element, Map<Element, HType>>(),
467 fieldSettersType = new Map<Element, Map<Element, HType>>(),
468 namer = new Namer(compiler),
469 returnInfo = new Map<Element, ReturnInfo>(), 664 returnInfo = new Map<Element, ReturnInfo>(),
470 invalidateAfterCodegen = new List<Element>(), 665 invalidateAfterCodegen = new List<Element>(),
471 super(compiler, constantSystem: JAVA_SCRIPT_CONSTANT_SYSTEM) { 666 super(compiler, constantSystem: JAVA_SCRIPT_CONSTANT_SYSTEM) {
472 emitter = new CodeEmitterTask(compiler, namer, generateSourceMap); 667 emitter = new CodeEmitterTask(compiler, namer, generateSourceMap);
473 builder = new SsaBuilderTask(this); 668 builder = new SsaBuilderTask(this);
474 optimizer = new SsaOptimizerTask(this); 669 optimizer = new SsaOptimizerTask(this);
475 generator = new SsaCodeGeneratorTask(this); 670 generator = new SsaCodeGeneratorTask(this);
476 argumentTypes = new ArgumentTypesRegistry(this); 671 argumentTypes = new ArgumentTypesRegistry(this);
672 fieldTypes = new FieldTypesRegistry(this);
477 } 673 }
478 674
479 Element get cyclicThrowHelper { 675 Element get cyclicThrowHelper {
480 return compiler.findHelper(const SourceString("throwCyclicInit")); 676 return compiler.findHelper(const SourceString("throwCyclicInit"));
481 } 677 }
482 678
483 JavaScriptItemCompilationContext createItemCompilationContext() { 679 JavaScriptItemCompilationContext createItemCompilationContext() {
484 return new JavaScriptItemCompilationContext(); 680 return new JavaScriptItemCompilationContext();
485 } 681 }
486 682
(...skipping 22 matching lines...) Expand all
509 } else { 705 } else {
510 // If the constant-handler was not able to produce a result we have to 706 // If the constant-handler was not able to produce a result we have to
511 // go through the builder (below) to generate the lazy initializer for 707 // go through the builder (below) to generate the lazy initializer for
512 // the static variable. 708 // the static variable.
513 // We also need to register the use of the cyclic-error helper. 709 // We also need to register the use of the cyclic-error helper.
514 compiler.enqueuer.codegen.registerStaticUse(cyclicThrowHelper); 710 compiler.enqueuer.codegen.registerStaticUse(cyclicThrowHelper);
515 } 711 }
516 } 712 }
517 713
518 HGraph graph = builder.build(work); 714 HGraph graph = builder.build(work);
519 optimizer.optimize(work, graph); 715 optimizer.optimize(work, graph, false);
520 if (work.allowSpeculativeOptimization 716 if (work.allowSpeculativeOptimization
521 && optimizer.trySpeculativeOptimizations(work, graph)) { 717 && optimizer.trySpeculativeOptimizations(work, graph)) {
522 CodeBuffer codeBuffer = generator.generateBailoutMethod(work, graph); 718 CodeBuffer codeBuffer = generator.generateBailoutMethod(work, graph);
523 compiler.codegenWorld.addBailoutCode(work, codeBuffer); 719 compiler.codegenWorld.addBailoutCode(work, codeBuffer);
524 optimizer.prepareForSpeculativeOptimizations(work, graph); 720 optimizer.prepareForSpeculativeOptimizations(work, graph);
525 optimizer.optimize(work, graph); 721 optimizer.optimize(work, graph, true);
526 } 722 }
527 CodeBuffer codeBuffer = generator.generateCode(work, graph); 723 CodeBuffer codeBuffer = generator.generateCode(work, graph);
528 compiler.codegenWorld.addGeneratedCode(work, codeBuffer); 724 compiler.codegenWorld.addGeneratedCode(work, codeBuffer);
529 invalidateAfterCodegen.forEach(compiler.enqueuer.codegen.eagerRecompile); 725 invalidateAfterCodegen.forEach(compiler.enqueuer.codegen.eagerRecompile);
530 invalidateAfterCodegen.clear(); 726 invalidateAfterCodegen.clear();
531 } 727 }
532 728
533 void processNativeClasses(Enqueuer world, 729 void processNativeClasses(Enqueuer world,
534 Collection<LibraryElement> libraries) { 730 Collection<LibraryElement> libraries) {
535 native.processNativeClasses(world, emitter, libraries); 731 native.processNativeClasses(world, emitter, libraries);
536 } 732 }
537 733
538 void assembleProgram() { 734 void assembleProgram() {
539 emitter.assembleProgram(); 735 emitter.assembleProgram();
540 } 736 }
541 737
542 void updateFieldInitializers(Element field, HType propagatedType) {
543 assert(field.isField());
544 assert(field.isMember());
545 Map<Element, HType> fields =
546 fieldInitializers.putIfAbsent(
547 field.getEnclosingClass(), () => new Map<Element, HType>());
548 if (!fields.containsKey(field)) {
549 fields[field] = propagatedType;
550 } else {
551 fields[field] = fields[field].union(propagatedType);
552 }
553 }
554
555 HType typeFromInitializersSoFar(Element field) {
556 assert(field.isField());
557 assert(field.isMember());
558 if (!fieldInitializers.containsKey(field.getEnclosingClass())) {
559 return HType.CONFLICTING;
560 }
561 Map<Element, HType> fields = fieldInitializers[field.getEnclosingClass()];
562 return fields[field];
563 }
564
565 void updateFieldConstructorSetters(Element field, HType type) {
566 assert(field.isField());
567 assert(field.isMember());
568 Map<Element, HType> fields =
569 fieldConstructorSetters.putIfAbsent(
570 field.getEnclosingClass(), () => new Map<Element, HType>());
571 if (!fields.containsKey(field)) {
572 fields[field] = type;
573 } else {
574 fields[field] = fields[field].union(type);
575 }
576 }
577
578 // Check if this field is set in the constructor body.
579 bool hasConstructorBodyFieldSetter(Element field) {
580 ClassElement enclosingClass = field.getEnclosingClass();
581 if (!fieldConstructorSetters.containsKey(enclosingClass)) {
582 return false;
583 }
584 return fieldConstructorSetters[enclosingClass][field] != null;
585 }
586
587 // Provide an optimistic estimate of the type of a field after construction.
588 // If the constructor body has setters for fields returns HType.UNKNOWN.
589 // This only takes the initializer lists and field assignments in the
590 // constructor body into account. The constructor body might have method calls
591 // that could alter the field.
592 HType optimisticFieldTypeAfterConstruction(Element field) {
593 assert(field.isField());
594 assert(field.isMember());
595
596 ClassElement classElement = field.getEnclosingClass();
597 if (hasConstructorBodyFieldSetter(field)) {
598 // If there are field setters but there is only constructor then the type
599 // of the field is determined by the assignments in the constructor
600 // body.
601 var constructors = classElement.constructors;
602 if (constructors.head !== null && constructors.tail.isEmpty()) {
603 return fieldConstructorSetters[classElement][field];
604 } else {
605 return HType.UNKNOWN;
606 }
607 } else if (fieldInitializers.containsKey(classElement)) {
608 HType type = fieldInitializers[classElement][field];
609 return type == null ? HType.CONFLICTING : type;
610 } else {
611 return HType.CONFLICTING;
612 }
613 }
614
615 void updateFieldSetters(Element field, HType type) {
616 assert(field.isField());
617 assert(field.isMember());
618 Map<Element, HType> fields =
619 fieldSettersType.putIfAbsent(
620 field.getEnclosingClass(), () => new Map<Element, HType>());
621 if (!fields.containsKey(field)) {
622 fields[field] = type;
623 } else {
624 fields[field] = fields[field].union(type);
625 }
626 }
627
628 // Returns the type that field setters are setting the field to based on what
629 // have been seen during compilation so far.
630 HType fieldSettersTypeSoFar(Element field) {
631 assert(field.isField());
632 assert(field.isMember());
633 ClassElement enclosingClass = field.getEnclosingClass();
634 if (!fieldSettersType.containsKey(enclosingClass)) {
635 return HType.CONFLICTING;
636 }
637 Map<Element, HType> fields = fieldSettersType[enclosingClass];
638 if (!fields.containsKey(field)) return HType.CONFLICTING;
639 return fields[field];
640 }
641
642 /** 738 /**
643 * Documentation wanted -- johnniwinther 739 * Documentation wanted -- johnniwinther
644 * 740 *
645 * Invariant: [element] must be a declaration element. 741 * Invariant: [element] must be a declaration element.
646 */ 742 */
647 void scheduleForRecompilation(Element element) { 743 void scheduleForRecompilation(Element element) {
648 assert(invariant(element, element.isDeclaration)); 744 assert(invariant(element, element.isDeclaration));
649 if (compiler.phase == Compiler.PHASE_COMPILING) { 745 if (compiler.phase == Compiler.PHASE_COMPILING) {
650 invalidateAfterCodegen.add(element); 746 invalidateAfterCodegen.add(element);
651 } 747 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 * scheduled for recompilation. 796 * scheduled for recompilation.
701 * 797 *
702 * Invariant: [element] must be a declaration element. 798 * Invariant: [element] must be a declaration element.
703 */ 799 */
704 registerParameterTypesOptimization( 800 registerParameterTypesOptimization(
705 FunctionElement element, 801 FunctionElement element,
706 HTypeList parameterTypes, 802 HTypeList parameterTypes,
707 OptionalParameterTypes defaultValueTypes) { 803 OptionalParameterTypes defaultValueTypes) {
708 assert(invariant(element, element.isDeclaration)); 804 assert(invariant(element, element.isDeclaration));
709 if (element.parameterCount(compiler) == 0) return; 805 if (element.parameterCount(compiler) == 0) return;
710 argumentTypes.registerOptimization( 806 argumentTypes.registerOptimizedFunction(
711 element, parameterTypes, defaultValueTypes); 807 element, parameterTypes, defaultValueTypes);
712 } 808 }
713 809
810 registerFieldTypesOptimization(FunctionElement element,
811 Element field,
812 HType type) {
813 fieldTypes.registerOptimizedFunction(element, field, type);
814 }
815
714 /** 816 /**
715 * Documentation wanted -- johnniwinther 817 * Documentation wanted -- johnniwinther
716 * 818 *
717 * Invariant: [element] must be a declaration element. 819 * Invariant: [element] must be a declaration element.
718 */ 820 */
719 void registerReturnType(FunctionElement element, HType returnType) { 821 void registerReturnType(FunctionElement element, HType returnType) {
720 assert(invariant(element, element.isDeclaration)); 822 assert(invariant(element, element.isDeclaration));
721 ReturnInfo info = returnInfo[element]; 823 ReturnInfo info = returnInfo[element];
722 if (info != null) { 824 if (info != null) {
723 info.update(returnType, scheduleForRecompilation); 825 info.update(returnType, scheduleForRecompilation);
(...skipping 24 matching lines...) Expand all
748 } 850 }
749 851
750 void dumpReturnTypes() { 852 void dumpReturnTypes() {
751 returnInfo.forEach((Element element, ReturnInfo info) { 853 returnInfo.forEach((Element element, ReturnInfo info) {
752 if (info.returnType != HType.UNKNOWN) { 854 if (info.returnType != HType.UNKNOWN) {
753 print("Inferred $element has return type ${info.returnType}"); 855 print("Inferred $element has return type ${info.returnType}");
754 } 856 }
755 }); 857 });
756 } 858 }
757 859
860 void registerConstructor(Element element) {
861 fieldTypes.registerConstructor(element);
862 }
863
864 void registerFieldInitializer(Element field, HType type) {
865 fieldTypes.registerFieldInitializer(field, type);
866 }
867
868 void registerFieldConstructor(Element field, HType type) {
869 fieldTypes.registerFieldConstructor(field, type);
870 }
871
872 void registerFieldSetter(FunctionElement element, Element field, HType type) {
873 fieldTypes.registerFieldSetter(element, field, type);
874 }
875
876 void addedDynamicSetter(Selector setter, HType type) {
877 fieldTypes.addedDynamicSetter(setter, type);
878 }
879
880 HType optimisticFieldType(Element element) {
881 return fieldTypes.optimisticFieldType(element);
882 }
883
758 SourceString getCheckedModeHelper(DartType type) { 884 SourceString getCheckedModeHelper(DartType type) {
759 Element element = type.element; 885 Element element = type.element;
760 bool nativeCheck = 886 bool nativeCheck =
761 emitter.nativeEmitter.requiresNativeIsCheck(element); 887 emitter.nativeEmitter.requiresNativeIsCheck(element);
762 if (element == compiler.stringClass) { 888 if (element == compiler.stringClass) {
763 return const SourceString('stringTypeCheck'); 889 return const SourceString('stringTypeCheck');
764 } else if (element == compiler.doubleClass) { 890 } else if (element == compiler.doubleClass) {
765 return const SourceString('doubleTypeCheck'); 891 return const SourceString('doubleTypeCheck');
766 } else if (element == compiler.numClass) { 892 } else if (element == compiler.numClass) {
767 return const SourceString('numTypeCheck'); 893 return const SourceString('numTypeCheck');
(...skipping 19 matching lines...) Expand all
787 ? const SourceString('listSuperNativeTypeCheck') 913 ? const SourceString('listSuperNativeTypeCheck')
788 : const SourceString('listSuperTypeCheck'); 914 : const SourceString('listSuperTypeCheck');
789 } else { 915 } else {
790 return nativeCheck 916 return nativeCheck
791 ? const SourceString('callTypeCheck') 917 ? const SourceString('callTypeCheck')
792 : const SourceString('propertyTypeCheck'); 918 : const SourceString('propertyTypeCheck');
793 } 919 }
794 } 920 }
795 } 921 }
796 } 922 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698