OLD | NEW |
---|---|
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 import '../common/codegen.dart' show CodegenWorkItem; | 5 import '../common/codegen.dart' show CodegenWorkItem; |
6 import '../common/tasks.dart' show CompilerTask; | 6 import '../common/tasks.dart' show CompilerTask; |
7 import '../compiler.dart' show Compiler; | 7 import '../compiler.dart' show Compiler; |
8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
9 import '../constants/values.dart'; | 9 import '../constants/values.dart'; |
10 import '../core_types.dart' show CoreClasses; | 10 import '../core_types.dart' show CoreClasses; |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1030 return graph.addConstant( | 1030 return graph.addConstant( |
1031 constantSystem.createString(primitive.toDartString()), compiler); | 1031 constantSystem.createString(primitive.toDartString()), compiler); |
1032 } | 1032 } |
1033 return node; | 1033 return node; |
1034 } | 1034 } |
1035 | 1035 |
1036 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { | 1036 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { |
1037 return handleInterceptedCall(node); | 1037 return handleInterceptedCall(node); |
1038 } | 1038 } |
1039 | 1039 |
1040 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { | |
1041 ClassWorld classWorld = compiler.world; | |
1042 if (classWorld.isUsedAsMixin(cls)) return true; | |
1043 | |
1044 return classWorld.anyStrictSubclassOf(cls, (ClassElement subclass) { | |
1045 return !backend.rti.isTrivialSubstitution(subclass, cls); | |
1046 }); | |
1047 } | |
1048 | |
1049 HInstruction visitTypeInfoExpression(HTypeInfoExpression node) { | |
1050 // Identify the case where the type info expression would be of the form: | |
1051 // | |
1052 // [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)] | |
1053 // | |
1054 // and k is the number of type arguments of 'this'. We can simply copy the | |
1055 // list from 'this'. | |
1056 HInstruction tryCopyInfo() { | |
1057 if (node.kind != TypeInfoExpressionKind.INSTANCE) return null; | |
1058 | |
1059 HInstruction source; | |
1060 int expectedIndex = 0; | |
1061 | |
1062 for (HInstruction argument in node.inputs) { | |
1063 if (argument is HTypeInfoReadVariable) { | |
1064 HInstruction nextSource = argument.object; | |
1065 if (nextSource is HThis) { | |
1066 // TODO(sra): Handle non-this cases (i.e. inlined code). Some | |
1067 // non-this cases will have a TypeMask that does not need | |
1068 // substitution, even though the general case does, e.g. inlining a | |
1069 // method on an exact class. | |
1070 if (source == null) { | |
1071 source = nextSource; | |
1072 ClassElement contextClass = | |
1073 nextSource.sourceElement.enclosingClass; | |
1074 if (node.inputs.length != contextClass.typeVariables.length) { | |
1075 return null; | |
1076 } | |
1077 if (needsSubstitutionForTypeVariableAccess(contextClass)) { | |
1078 return null; | |
1079 } | |
1080 } | |
1081 if (nextSource != source) return null; | |
1082 // Check that the index is the one we expect. | |
1083 int index = argument.variable.element.index; | |
1084 if (index != expectedIndex++) return null; | |
1085 continue; | |
1086 } | |
1087 } | |
1088 // Fall-through for unrecognized argument. | |
Siggi Cherem (dart-lang)
2016/09/02 18:02:29
nit: I might prefer to remove the "continue" above
sra1
2016/09/02 18:23:14
Done.
| |
1089 return null; | |
1090 } | |
1091 | |
1092 if (source == null) return null; | |
1093 return new HTypeInfoReadRaw(source, backend.dynamicType); | |
1094 } | |
1095 | |
1096 // TODO(sra): Consider fusing type expression trees with no type variables, | |
1097 // as these could be represented like constants. | |
1098 | |
1099 return tryCopyInfo() ?? node; | |
1100 } | |
1101 | |
1040 HInstruction visitTypeInfoReadVariable(HTypeInfoReadVariable node) { | 1102 HInstruction visitTypeInfoReadVariable(HTypeInfoReadVariable node) { |
1041 TypeVariableType variable = node.variable; | 1103 TypeVariableType variable = node.variable; |
1042 HInstruction object = node.object; | 1104 HInstruction object = node.object; |
1043 | 1105 |
1044 HInstruction finishGroundType(InterfaceType groundType) { | 1106 HInstruction finishGroundType(InterfaceType groundType) { |
1045 InterfaceType typeAtVariable = | 1107 InterfaceType typeAtVariable = |
1046 groundType.asInstanceOf(variable.element.enclosingClass); | 1108 groundType.asInstanceOf(variable.element.enclosingClass); |
1047 if (typeAtVariable != null) { | 1109 if (typeAtVariable != null) { |
1048 int index = variable.element.index; | 1110 int index = variable.element.index; |
1049 DartType typeArgument = typeAtVariable.typeArguments[index]; | 1111 DartType typeArgument = typeAtVariable.typeArguments[index]; |
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2525 | 2587 |
2526 keyedValues.forEach((receiver, values) { | 2588 keyedValues.forEach((receiver, values) { |
2527 result.keyedValues[receiver] = | 2589 result.keyedValues[receiver] = |
2528 new Map<HInstruction, HInstruction>.from(values); | 2590 new Map<HInstruction, HInstruction>.from(values); |
2529 }); | 2591 }); |
2530 | 2592 |
2531 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2593 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
2532 return result; | 2594 return result; |
2533 } | 2595 } |
2534 } | 2596 } |
OLD | NEW |