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 '../closure.dart'; | 5 import '../closure.dart'; |
6 import '../common.dart'; | 6 import '../common.dart'; |
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 '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 R visitTruncatingDivide(HTruncatingDivide node); | 92 R visitTruncatingDivide(HTruncatingDivide node); |
93 R visitTry(HTry node); | 93 R visitTry(HTry node); |
94 R visitTypeConversion(HTypeConversion node); | 94 R visitTypeConversion(HTypeConversion node); |
95 R visitTypeKnown(HTypeKnown node); | 95 R visitTypeKnown(HTypeKnown node); |
96 R visitYield(HYield node); | 96 R visitYield(HYield node); |
97 R visitReadTypeVariable(HReadTypeVariable node); | 97 R visitReadTypeVariable(HReadTypeVariable node); |
98 R visitFunctionType(HFunctionType node); | 98 R visitFunctionType(HFunctionType node); |
99 R visitVoidType(HVoidType node); | 99 R visitVoidType(HVoidType node); |
100 R visitInterfaceType(HInterfaceType node); | 100 R visitInterfaceType(HInterfaceType node); |
101 R visitDynamicType(HDynamicType node); | 101 R visitDynamicType(HDynamicType node); |
102 | |
103 R visitTypeInfoReadRaw(HTypeInfoReadRaw node); | |
104 R visitTypeInfoReadVariable(HTypeInfoReadVariable node); | |
105 R visitTypeInfoExpression(HTypeInfoExpression node); | |
102 } | 106 } |
103 | 107 |
104 abstract class HGraphVisitor { | 108 abstract class HGraphVisitor { |
105 visitDominatorTree(HGraph graph) { | 109 visitDominatorTree(HGraph graph) { |
106 void visitBasicBlockAndSuccessors(HBasicBlock block) { | 110 void visitBasicBlockAndSuccessors(HBasicBlock block) { |
107 visitBasicBlock(block); | 111 visitBasicBlock(block); |
108 List dominated = block.dominatedBlocks; | 112 List dominated = block.dominatedBlocks; |
109 for (int i = 0; i < dominated.length; i++) { | 113 for (int i = 0; i < dominated.length; i++) { |
110 visitBasicBlockAndSuccessors(dominated[i]); | 114 visitBasicBlockAndSuccessors(dominated[i]); |
111 } | 115 } |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 visitIsViaInterceptor(HIsViaInterceptor node) => visitInstruction(node); | 391 visitIsViaInterceptor(HIsViaInterceptor node) => visitInstruction(node); |
388 visitTypeConversion(HTypeConversion node) => visitCheck(node); | 392 visitTypeConversion(HTypeConversion node) => visitCheck(node); |
389 visitTypeKnown(HTypeKnown node) => visitCheck(node); | 393 visitTypeKnown(HTypeKnown node) => visitCheck(node); |
390 visitReadTypeVariable(HReadTypeVariable node) => visitInstruction(node); | 394 visitReadTypeVariable(HReadTypeVariable node) => visitInstruction(node); |
391 visitFunctionType(HFunctionType node) => visitInstruction(node); | 395 visitFunctionType(HFunctionType node) => visitInstruction(node); |
392 visitVoidType(HVoidType node) => visitInstruction(node); | 396 visitVoidType(HVoidType node) => visitInstruction(node); |
393 visitInterfaceType(HInterfaceType node) => visitInstruction(node); | 397 visitInterfaceType(HInterfaceType node) => visitInstruction(node); |
394 visitDynamicType(HDynamicType node) => visitInstruction(node); | 398 visitDynamicType(HDynamicType node) => visitInstruction(node); |
395 visitAwait(HAwait node) => visitInstruction(node); | 399 visitAwait(HAwait node) => visitInstruction(node); |
396 visitYield(HYield node) => visitInstruction(node); | 400 visitYield(HYield node) => visitInstruction(node); |
401 | |
402 visitTypeInfoReadRaw(HTypeInfoReadRaw node) => visitInstruction(node); | |
403 visitTypeInfoReadVariable(HTypeInfoReadVariable node) => | |
404 visitInstruction(node); | |
405 visitTypeInfoExpression(HTypeInfoExpression node) => visitInstruction(node); | |
397 } | 406 } |
398 | 407 |
399 class SubGraph { | 408 class SubGraph { |
400 // The first and last block of the sub-graph. | 409 // The first and last block of the sub-graph. |
401 final HBasicBlock start; | 410 final HBasicBlock start; |
402 final HBasicBlock end; | 411 final HBasicBlock end; |
403 | 412 |
404 const SubGraph(this.start, this.end); | 413 const SubGraph(this.start, this.end); |
405 | 414 |
406 bool contains(HBasicBlock block) { | 415 bool contains(HBasicBlock block) { |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 static const int INVOKE_DYNAMIC_TYPECODE = 29; | 856 static const int INVOKE_DYNAMIC_TYPECODE = 29; |
848 static const int SHIFT_RIGHT_TYPECODE = 30; | 857 static const int SHIFT_RIGHT_TYPECODE = 30; |
849 static const int READ_TYPE_VARIABLE_TYPECODE = 31; | 858 static const int READ_TYPE_VARIABLE_TYPECODE = 31; |
850 static const int FUNCTION_TYPE_TYPECODE = 32; | 859 static const int FUNCTION_TYPE_TYPECODE = 32; |
851 static const int VOID_TYPE_TYPECODE = 33; | 860 static const int VOID_TYPE_TYPECODE = 33; |
852 static const int INTERFACE_TYPE_TYPECODE = 34; | 861 static const int INTERFACE_TYPE_TYPECODE = 34; |
853 static const int DYNAMIC_TYPE_TYPECODE = 35; | 862 static const int DYNAMIC_TYPE_TYPECODE = 35; |
854 static const int TRUNCATING_DIVIDE_TYPECODE = 36; | 863 static const int TRUNCATING_DIVIDE_TYPECODE = 36; |
855 static const int IS_VIA_INTERCEPTOR_TYPECODE = 37; | 864 static const int IS_VIA_INTERCEPTOR_TYPECODE = 37; |
856 | 865 |
866 static const int TYPE_INFO_READ_RAW_TYPECODE = 38; | |
867 static const int TYPE_INFO_READ_VARIABLE_TYPECODE = 39; | |
868 static const int TYPE_INFO_EXPRESSION_TYPECODE = 40; | |
869 | |
857 HInstruction(this.inputs, this.instructionType) | 870 HInstruction(this.inputs, this.instructionType) |
858 : id = idCounter++, | 871 : id = idCounter++, |
859 usedBy = <HInstruction>[] { | 872 usedBy = <HInstruction>[] { |
860 assert(inputs.every((e) => e != null)); | 873 assert(inputs.every((e) => e != null)); |
861 } | 874 } |
862 | 875 |
863 int get hashCode => id; | 876 int get hashCode => id; |
864 | 877 |
865 bool useGvn() => _useGvn; | 878 bool useGvn() => _useGvn; |
866 void setUseGvn() { | 879 void setUseGvn() { |
(...skipping 2308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3175 HBasicBlock get end { | 3188 HBasicBlock get end { |
3176 // We don't create a switch block if there are no cases. | 3189 // We don't create a switch block if there are no cases. |
3177 assert(!statements.isEmpty); | 3190 assert(!statements.isEmpty); |
3178 return statements.last.end; | 3191 return statements.last.end; |
3179 } | 3192 } |
3180 | 3193 |
3181 bool accept(HStatementInformationVisitor visitor) => | 3194 bool accept(HStatementInformationVisitor visitor) => |
3182 visitor.visitSwitchInfo(this); | 3195 visitor.visitSwitchInfo(this); |
3183 } | 3196 } |
3184 | 3197 |
3198 /// Reads raw reified type info from an object. | |
3199 class HTypeInfoReadRaw extends HInstruction { | |
3200 HTypeInfoReadRaw(HInstruction receiver, TypeMask instructionType) | |
3201 : super(<HInstruction>[receiver], instructionType) { | |
3202 setUseGvn(); | |
3203 } | |
3204 | |
3205 accept(HVisitor visitor) => visitor.visitTypeInfoReadRaw(this); | |
3206 | |
3207 bool canThrow() => false; | |
3208 | |
3209 int typeCode() => HInstruction.TYPE_INFO_READ_RAW_TYPECODE; | |
3210 bool typeEquals(HInstruction other) => other is HTypeInfoReadRaw; | |
3211 | |
3212 bool dataEquals(HTypeInfoReadRaw other) { | |
3213 return true; | |
3214 } | |
3215 } | |
3216 | |
3217 /// Reads a type variable from an object. The read may be a simple indexing of | |
3218 /// the type parameters or it may require 'substitution'. | |
3219 class HTypeInfoReadVariable extends HInstruction { | |
3220 /// The type variable being read. | |
3221 final TypeVariableType variable; | |
3222 | |
3223 HTypeInfoReadVariable( | |
3224 this.variable, HInstruction receiver, TypeMask instructionType) | |
3225 : super(<HInstruction>[receiver], instructionType) { | |
3226 setUseGvn(); | |
3227 } | |
3228 | |
3229 accept(HVisitor visitor) => visitor.visitTypeInfoReadVariable(this); | |
3230 | |
3231 bool canThrow() => false; | |
3232 | |
3233 int typeCode() => HInstruction.TYPE_INFO_READ_VARIABLE_TYPECODE; | |
3234 bool typeEquals(HInstruction other) => other is HTypeInfoReadVariable; | |
3235 | |
3236 bool dataEquals(HTypeInfoReadVariable other) { | |
3237 return variable.element == other.variable.element; | |
3238 } | |
3239 } | |
3240 | |
3241 enum TypeInfoExpressionKind { COMPLETE, INSTANCE } | |
3242 | |
3243 /// Constructs a representation of a closed or ground-term type (that is, a type | |
3244 /// without type variables). | |
3245 /// | |
3246 /// There are two forms: | |
3247 /// | |
3248 /// - COMPLETE: A complete form that is self contained, used for the values of | |
3249 /// type parameters and non-raw is-checks. | |
3250 /// | |
3251 /// - INSTANCE: A headless flat form for representing the sequence of values of | |
Siggi Cherem (dart-lang)
2016/08/19 18:21:46
I'm trying to understand the need for the distinct
sra1
2016/08/19 18:47:44
Correct.
This is just how it is currently done.
I
| |
3252 /// the type parameters of an instance of a generic type. | |
3253 /// | |
3254 /// The COMPLETE form value is constructed from [dartType] by replacing the type | |
3255 /// variables with consecutive values from [arguments], in the order generated | |
Siggi Cherem (dart-lang)
2016/08/19 18:21:46
[arguments] => [inputs]?
sra1
2016/08/19 18:47:43
Done.
| |
3256 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are | |
3257 /// treated as 'holes' in the term, which means that it must be ensured at | |
3258 /// construction, that duplicate occurences of a type variable in [dartType] are | |
3259 /// assigned the same value. | |
3260 /// | |
3261 /// The INSTANCE form is constructed as a list of [arguments]. This is the same | |
Siggi Cherem (dart-lang)
2016/08/19 18:21:46
ditto?
sra1
2016/08/19 18:47:43
Done.
| |
3262 /// as the COMPLETE form for the 'thisType', except the root term's type is | |
3263 /// missing; this is implicit as the raw type of instance. The [dartType] of | |
3264 /// the INSTANCE form must be the thisType of some class. | |
3265 /// | |
3266 /// We want to remove the constrains on the INSTANCE form. In the meantime we | |
3267 /// get by with a tree of TypeExpressions. Consider: | |
3268 /// | |
3269 /// class Foo<T> { | |
3270 /// ... new Set<List<T>>() | |
3271 /// } | |
3272 /// class Set<E1> { | |
3273 /// factory Set() => new _LinkedHashSet<E1>(); | |
3274 /// } | |
3275 /// class List<E2> { ... } | |
3276 /// class _LinkedHashSet<E3> { ... } | |
3277 /// | |
3278 /// After inlining the factory constructor for `Set<E1>`, the HForeignNew | |
3279 /// should have type `_LinkedHashSet<List<T>>` and the TypeExpression should be | |
3280 /// a tree: | |
3281 /// | |
3282 /// HForeignNew(dartType: _LinkedHashSet<List<T>>, | |
3283 /// [], // No arguments | |
3284 /// HTypeInfoExpression(INSTANCE, | |
3285 /// dartType: _LinkedHashSet<E3>, // _LinkedHashSet's thisType | |
3286 /// HTypeInfoExpression(COMPLETE, // E3 = List<T> | |
3287 /// dartType: List<E2>, | |
3288 /// HTypeInfoReadVariable(this, T)))) // E2 = T | |
3289 | |
3290 // TODO(sra): The INSTANCE form requires the actual instance for full | |
3291 // interpretation. If the COMPLETE form was used on instances, then we could | |
3292 // simplify HTypeInfoReadVariable without an object. | |
3293 | |
3294 class HTypeInfoExpression extends HInstruction { | |
3295 final TypeInfoExpressionKind kind; | |
3296 final DartType dartType; | |
3297 HTypeInfoExpression(this.kind, this.dartType, List<HInstruction> inputs, | |
3298 TypeMask instructionType) | |
3299 : super(inputs, instructionType) { | |
3300 setUseGvn(); | |
3301 } | |
3302 | |
3303 accept(HVisitor visitor) => visitor.visitTypeInfoExpression(this); | |
3304 | |
3305 bool canThrow() => false; | |
3306 | |
3307 int typeCode() => HInstruction.TYPE_INFO_EXPRESSION_TYPECODE; | |
3308 bool typeEquals(HInstruction other) => other is HTypeInfoExpression; | |
3309 | |
3310 bool dataEquals(HTypeInfoExpression other) { | |
3311 return kind == other.kind && dartType == other.dartType; | |
3312 } | |
3313 | |
3314 String toString() => 'HTypeInfoExpression $kindAsString $dartType'; | |
3315 | |
3316 String get kindAsString { | |
3317 switch (kind) { | |
3318 case TypeInfoExpressionKind.COMPLETE: return 'COMPLETE'; | |
3319 case TypeInfoExpressionKind.INSTANCE: return 'INSTANCE'; | |
3320 } | |
3321 } | |
3322 } | |
3323 | |
3324 | |
3185 class HReadTypeVariable extends HInstruction { | 3325 class HReadTypeVariable extends HInstruction { |
3186 /// The type variable being read. | 3326 /// The type variable being read. |
3187 final TypeVariableType dartType; | 3327 final TypeVariableType dartType; |
3188 | 3328 |
3189 final bool hasReceiver; | 3329 final bool hasReceiver; |
3190 | 3330 |
3191 HReadTypeVariable( | 3331 HReadTypeVariable( |
3192 this.dartType, HInstruction receiver, TypeMask instructionType) | 3332 this.dartType, HInstruction receiver, TypeMask instructionType) |
3193 : hasReceiver = true, | 3333 : hasReceiver = true, |
3194 super(<HInstruction>[receiver], instructionType) { | 3334 super(<HInstruction>[receiver], instructionType) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3277 class HDynamicType extends HRuntimeType { | 3417 class HDynamicType extends HRuntimeType { |
3278 HDynamicType(DynamicType dartType, TypeMask instructionType) | 3418 HDynamicType(DynamicType dartType, TypeMask instructionType) |
3279 : super(const <HInstruction>[], dartType, instructionType); | 3419 : super(const <HInstruction>[], dartType, instructionType); |
3280 | 3420 |
3281 accept(HVisitor visitor) => visitor.visitDynamicType(this); | 3421 accept(HVisitor visitor) => visitor.visitDynamicType(this); |
3282 | 3422 |
3283 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; | 3423 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; |
3284 | 3424 |
3285 bool typeEquals(HInstruction other) => other is HDynamicType; | 3425 bool typeEquals(HInstruction other) => other is HDynamicType; |
3286 } | 3426 } |
OLD | NEW |