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

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2512023002: Add types for map literal construction with kernel code. (Closed)
Patch Set: . Created 4 years, 1 month 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/compiler/lib/src/ssa/kernel_ast_adapter.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
(...skipping 11 matching lines...) Expand all
22 import '../universe/selector.dart'; 22 import '../universe/selector.dart';
23 import '../universe/use.dart' show TypeUse; 23 import '../universe/use.dart' show TypeUse;
24 import 'graph_builder.dart'; 24 import 'graph_builder.dart';
25 import 'kernel_ast_adapter.dart'; 25 import 'kernel_ast_adapter.dart';
26 import 'kernel_string_builder.dart'; 26 import 'kernel_string_builder.dart';
27 import 'locals_handler.dart'; 27 import 'locals_handler.dart';
28 import 'loop_handler.dart'; 28 import 'loop_handler.dart';
29 import 'nodes.dart'; 29 import 'nodes.dart';
30 import 'ssa_branch_builder.dart'; 30 import 'ssa_branch_builder.dart';
31 import 'type_builder.dart'; 31 import 'type_builder.dart';
32 import 'types.dart' show TypeMaskFactory;
32 33
33 class SsaKernelBuilderTask extends CompilerTask { 34 class SsaKernelBuilderTask extends CompilerTask {
34 final JavaScriptBackend backend; 35 final JavaScriptBackend backend;
35 final SourceInformationStrategy sourceInformationFactory; 36 final SourceInformationStrategy sourceInformationFactory;
36 37
37 String get name => 'SSA kernel builder'; 38 String get name => 'SSA kernel builder';
38 39
39 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory) 40 SsaKernelBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
40 : backend = backend, 41 : backend = backend,
41 super(backend.compiler.measurer); 42 super(backend.compiler.measurer);
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 stack.add(graph.addConstant( 709 stack.add(graph.addConstant(
709 astAdapter.getConstantForSymbol(symbolLiteral), compiler)); 710 astAdapter.getConstantForSymbol(symbolLiteral), compiler));
710 registry?.registerConstSymbol(symbolLiteral.value); 711 registry?.registerConstSymbol(symbolLiteral.value);
711 } 712 }
712 713
713 @override 714 @override
714 void visitNullLiteral(ir.NullLiteral nullLiteral) { 715 void visitNullLiteral(ir.NullLiteral nullLiteral) {
715 stack.add(graph.addConstantNull(compiler)); 716 stack.add(graph.addConstantNull(compiler));
716 } 717 }
717 718
718 HInstruction setRtiIfNeeded(HInstruction object, ir.ListLiteral listLiteral) { 719 /// Set the runtime type information if necessary. Cases where this is needed
720 /// are for classes that are:
721 /// (1) used in a is check with type variables,
722 /// (2) dependencies of classes in (1),
723 /// (3) subclasses of (2) and (3).
sra1 2016/11/17 23:51:41 The code is now a little bit too general, since it
Emily Fortuna 2016/11/18 01:30:35 Done.
724 HInstruction setRuntimeTypeInfoIfNeeded(
725 HInstruction object, ir.ListLiteral listLiteral) {
719 InterfaceType type = localsHandler 726 InterfaceType type = localsHandler
720 .substInContext(elements.getType(astAdapter.getNode(listLiteral))); 727 .substInContext(elements.getType(astAdapter.getNode(listLiteral)));
721 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { 728 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) {
722 return object; 729 return object;
723 } 730 }
724 List<HInstruction> arguments = <HInstruction>[]; 731 List<HInstruction> arguments = <HInstruction>[];
725 for (DartType argument in type.typeArguments) { 732 for (DartType argument in type.typeArguments) {
726 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement)); 733 arguments.add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
727 } 734 }
728 // TODO(15489): Register at codegen. 735 // TODO(15489): Register at codegen.
729 registry?.registerInstantiation(type); 736 registry?.registerInstantiation(type);
730 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object); 737 return callSetRuntimeTypeInfoWithTypeArguments(type, arguments, object);
731 } 738 }
732 739
733 @override 740 @override
734 void visitListLiteral(ir.ListLiteral listLiteral) { 741 void visitListLiteral(ir.ListLiteral listLiteral) {
735 HInstruction listInstruction; 742 HInstruction listInstruction;
736 if (listLiteral.isConst) { 743 if (listLiteral.isConst) {
737 listInstruction = 744 listInstruction =
738 graph.addConstant(astAdapter.getConstantFor(listLiteral), compiler); 745 graph.addConstant(astAdapter.getConstantFor(listLiteral), compiler);
739 } else { 746 } else {
740 List<HInstruction> elements = <HInstruction>[]; 747 List<HInstruction> elements = <HInstruction>[];
741 for (ir.Expression element in listLiteral.expressions) { 748 for (ir.Expression element in listLiteral.expressions) {
742 element.accept(this); 749 element.accept(this);
743 elements.add(pop()); 750 elements.add(pop());
744 } 751 }
745 listInstruction = new HLiteralList(elements, backend.extendableArrayType); 752 listInstruction = new HLiteralList(elements, backend.extendableArrayType);
746 add(listInstruction); 753 add(listInstruction);
747 listInstruction = setRtiIfNeeded(listInstruction, listLiteral); 754 listInstruction =
755 setRuntimeTypeInfoIfNeeded(listInstruction, listLiteral);
748 } 756 }
749 757
750 TypeMask type = astAdapter.typeOfNewList(targetElement, listLiteral); 758 TypeMask type = astAdapter.typeOfNewList(targetElement, listLiteral);
751 if (!type.containsAll(compiler.closedWorld)) { 759 if (!type.containsAll(compiler.closedWorld)) {
752 listInstruction.instructionType = type; 760 listInstruction.instructionType = type;
753 } 761 }
754 stack.add(listInstruction); 762 stack.add(listInstruction);
755 } 763 }
756 764
757 @override 765 @override
(...skipping 18 matching lines...) Expand all
776 if (constructorArgs.isEmpty) { 784 if (constructorArgs.isEmpty) {
777 constructor = astAdapter.mapLiteralConstructorEmpty; 785 constructor = astAdapter.mapLiteralConstructorEmpty;
778 } else { 786 } else {
779 constructor = astAdapter.mapLiteralConstructor; 787 constructor = astAdapter.mapLiteralConstructor;
780 HLiteralList argList = 788 HLiteralList argList =
781 new HLiteralList(constructorArgs, backend.extendableArrayType); 789 new HLiteralList(constructorArgs, backend.extendableArrayType);
782 add(argList); 790 add(argList);
783 inputs.add(argList); 791 inputs.add(argList);
784 } 792 }
785 793
786 // TODO(het): Add type information 794 assert(constructor.kind == ir.ProcedureKind.Factory);
787 _pushStaticInvocation(constructor, inputs, backend.dynamicType); 795
796 InterfaceType type = localsHandler
797 .substInContext(elements.getType(astAdapter.getNode(mapLiteral)));
798
799 ir.Class cls = constructor.enclosingClass;
800
801 if (backend.classNeedsRti(astAdapter.getElement(cls))) {
802 List<HInstruction> typeInputs = <HInstruction>[];
803 type.typeArguments.forEach((DartType argument) {
804 typeInputs
805 .add(typeBuilder.analyzeTypeArgument(argument, sourceElement));
806 });
807
808 // We lift this common call pattern into a helper function to save space
809 // in the output.
810 if (typeInputs.every((HInstruction input) => input.isNull())) {
811 if (constructorArgs.isEmpty) {
812 constructor = astAdapter.mapLiteralUntypedEmptyMaker;
813 } else {
814 constructor = astAdapter.mapLiteralUntypedMaker;
815 }
816 } else {
817 inputs.addAll(typeInputs);
818 }
819 }
820
821 // If runtime type information is needed and the map literal has no type
822 // parameters, 'constructor' is a static function that forwards the call to
823 // the factory constructor without type parameters.
824 assert(constructor.kind == ir.ProcedureKind.Factory);
825
826 // The instruction type will always be a subtype of the mapLiteralClass, but
827 // type inference might discover a more specific type, or find nothing (in
828 // dart2js unit tests).
829 TypeMask mapType = new TypeMask.nonNullSubtype(
830 astAdapter.getElement(astAdapter.mapLiteralClass),
831 compiler.closedWorld);
832 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
833 astAdapter.getElement(constructor), compiler);
834 TypeMask instructionType =
835 mapType.intersection(returnTypeMask, compiler.closedWorld);
836
837 // TODO(efortuna): Inlining.
Siggi Cherem (dart-lang) 2016/11/17 23:56:53 Let's change the TODO to explicitly say this is fo
Emily Fortuna 2016/11/18 01:30:35 hmmmm. I added them, but I'm not certain that this
Siggi Cherem (dart-lang) 2016/11/18 15:47:06 Stephen/Johnni - please confirm, but I believe we
838 _pushStaticInvocation(constructor, inputs, instructionType);
788 } 839 }
789 840
790 @override 841 @override
791 void visitMapEntry(ir.MapEntry mapEntry) { 842 void visitMapEntry(ir.MapEntry mapEntry) {
792 // Visit value before the key because each will push an expression to the 843 // Visit value before the key because each will push an expression to the
793 // stack, so when we pop them off, the key is popped first, then the value. 844 // stack, so when we pop them off, the key is popped first, then the value.
794 mapEntry.value.accept(this); 845 mapEntry.value.accept(this);
795 mapEntry.key.accept(this); 846 mapEntry.key.accept(this);
796 } 847 }
797 848
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 push(new HNot(popBoolified(), backend.boolType)); 1102 push(new HNot(popBoolified(), backend.boolType));
1052 } 1103 }
1053 1104
1054 @override 1105 @override
1055 void visitStringConcatenation(ir.StringConcatenation stringConcat) { 1106 void visitStringConcatenation(ir.StringConcatenation stringConcat) {
1056 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); 1107 KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
1057 stringConcat.accept(stringBuilder); 1108 stringConcat.accept(stringBuilder);
1058 stack.add(stringBuilder.result); 1109 stack.add(stringBuilder.result);
1059 } 1110 }
1060 } 1111 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698