| 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
| 8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
| 9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
| 10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 return validator.isValid; | 1060 return validator.isValid; |
| 1061 } | 1061 } |
| 1062 | 1062 |
| 1063 /** | 1063 /** |
| 1064 * The code for computing a bailout environment, and the code | 1064 * The code for computing a bailout environment, and the code |
| 1065 * generation must agree on what does not need to be captured, | 1065 * generation must agree on what does not need to be captured, |
| 1066 * so should always be generated at use site. | 1066 * so should always be generated at use site. |
| 1067 */ | 1067 */ |
| 1068 bool isCodeMotionInvariant() => false; | 1068 bool isCodeMotionInvariant() => false; |
| 1069 | 1069 |
| 1070 bool isStatement(HTypeMap types) => false; | 1070 bool isJsStatement(HTypeMap types) => false; |
| 1071 | 1071 |
| 1072 bool dominates(HInstruction other) { | 1072 bool dominates(HInstruction other) { |
| 1073 if (block != other.block) return block.dominates(other.block); | 1073 if (block != other.block) return block.dominates(other.block); |
| 1074 | 1074 |
| 1075 HInstruction current = this; | 1075 HInstruction current = this; |
| 1076 while (current !== null) { | 1076 while (current !== null) { |
| 1077 if (current === other) return true; | 1077 if (current === other) return true; |
| 1078 current = current.next; | 1078 current = current.next; |
| 1079 } | 1079 } |
| 1080 return false; | 1080 return false; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1099 /** | 1099 /** |
| 1100 * A [HCheck] instruction is an instruction that might do a dynamic | 1100 * A [HCheck] instruction is an instruction that might do a dynamic |
| 1101 * check at runtime on another instruction. To have proper instruction | 1101 * check at runtime on another instruction. To have proper instruction |
| 1102 * dependencies in the graph, instructions that depend on the check | 1102 * dependencies in the graph, instructions that depend on the check |
| 1103 * being done reference the [HCheck] instruction instead of the | 1103 * being done reference the [HCheck] instruction instead of the |
| 1104 * instruction itself. | 1104 * instruction itself. |
| 1105 */ | 1105 */ |
| 1106 abstract class HCheck extends HInstruction { | 1106 abstract class HCheck extends HInstruction { |
| 1107 HCheck(inputs) : super(inputs); | 1107 HCheck(inputs) : super(inputs); |
| 1108 HInstruction get checkedInput => inputs[0]; | 1108 HInstruction get checkedInput => inputs[0]; |
| 1109 bool isStatement(HTypeMap types) => true; | 1109 bool isJsStatement(HTypeMap types) => true; |
| 1110 void prepareGvn(HTypeMap types) { | 1110 void prepareGvn(HTypeMap types) { |
| 1111 assert(!hasSideEffects(types)); | 1111 assert(!hasSideEffects(types)); |
| 1112 setUseGvn(); | 1112 setUseGvn(); |
| 1113 } | 1113 } |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 class HBailoutTarget extends HInstruction { | 1116 class HBailoutTarget extends HInstruction { |
| 1117 final int state; | 1117 final int state; |
| 1118 bool isEnabled = false; | 1118 bool isEnabled = false; |
| 1119 HBailoutTarget(this.state) : super(<HInstruction>[]); | 1119 HBailoutTarget(this.state) : super(<HInstruction>[]); |
| 1120 void prepareGvn(HTypeMap types) { | 1120 void prepareGvn(HTypeMap types) { |
| 1121 assert(!hasSideEffects(types)); | 1121 assert(!hasSideEffects(types)); |
| 1122 setUseGvn(); | 1122 setUseGvn(); |
| 1123 } | 1123 } |
| 1124 | 1124 |
| 1125 bool isControlFlow() => true; | 1125 bool isControlFlow() => true; |
| 1126 bool isStatement(HTypeMap types) => isEnabled; | 1126 bool isJsStatement(HTypeMap types) => isEnabled; |
| 1127 | 1127 |
| 1128 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); | 1128 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); |
| 1129 int typeCode() => HInstruction.BAILOUT_TARGET_TYPECODE; | 1129 int typeCode() => HInstruction.BAILOUT_TARGET_TYPECODE; |
| 1130 bool typeEquals(other) => other is HBailoutTarget; | 1130 bool typeEquals(other) => other is HBailoutTarget; |
| 1131 bool dataEquals(HBailoutTarget other) => other.state == state; | 1131 bool dataEquals(HBailoutTarget other) => other.state == state; |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 class HTypeGuard extends HCheck { | 1134 class HTypeGuard extends HCheck { |
| 1135 final HType guardedType; | 1135 final HType guardedType; |
| 1136 bool isEnabled = false; | 1136 bool isEnabled = false; |
| 1137 | 1137 |
| 1138 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget) | 1138 HTypeGuard(this.guardedType, HInstruction guarded, HInstruction bailoutTarget) |
| 1139 : super(<HInstruction>[guarded, bailoutTarget]); | 1139 : super(<HInstruction>[guarded, bailoutTarget]); |
| 1140 | 1140 |
| 1141 HInstruction get guarded => inputs[0]; | 1141 HInstruction get guarded => inputs[0]; |
| 1142 HInstruction get checkedInput => guarded; | 1142 HInstruction get checkedInput => guarded; |
| 1143 HBailoutTarget get bailoutTarget => inputs[1]; | 1143 HBailoutTarget get bailoutTarget => inputs[1]; |
| 1144 int get state => bailoutTarget.state; | 1144 int get state => bailoutTarget.state; |
| 1145 | 1145 |
| 1146 HType computeTypeFromInputTypes(HTypeMap types) { | 1146 HType computeTypeFromInputTypes(HTypeMap types) { |
| 1147 return isEnabled ? guardedType : types[guarded]; | 1147 return isEnabled ? guardedType : types[guarded]; |
| 1148 } | 1148 } |
| 1149 | 1149 |
| 1150 HType get guaranteedType => isEnabled ? guardedType : HType.UNKNOWN; | 1150 HType get guaranteedType => isEnabled ? guardedType : HType.UNKNOWN; |
| 1151 | 1151 |
| 1152 bool isControlFlow() => true; | 1152 bool isControlFlow() => true; |
| 1153 | 1153 |
| 1154 bool isStatement(HTypeMap types) => isEnabled; | 1154 bool isJsStatement(HTypeMap types) => isEnabled; |
| 1155 | 1155 |
| 1156 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1156 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1157 int typeCode() => HInstruction.TYPE_GUARD_TYPECODE; | 1157 int typeCode() => HInstruction.TYPE_GUARD_TYPECODE; |
| 1158 bool typeEquals(other) => other is HTypeGuard; | 1158 bool typeEquals(other) => other is HTypeGuard; |
| 1159 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; | 1159 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType; |
| 1160 } | 1160 } |
| 1161 | 1161 |
| 1162 class HBoundsCheck extends HCheck { | 1162 class HBoundsCheck extends HCheck { |
| 1163 static const int ALWAYS_FALSE = 0; | 1163 static const int ALWAYS_FALSE = 0; |
| 1164 static const int FULL_CHECK = 1; | 1164 static const int FULL_CHECK = 1; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 abstract toString(); | 1216 abstract toString(); |
| 1217 } | 1217 } |
| 1218 | 1218 |
| 1219 class HControlFlow extends HInstruction { | 1219 class HControlFlow extends HInstruction { |
| 1220 HControlFlow(inputs) : super(inputs); | 1220 HControlFlow(inputs) : super(inputs); |
| 1221 abstract toString(); | 1221 abstract toString(); |
| 1222 void prepareGvn(HTypeMap types) { | 1222 void prepareGvn(HTypeMap types) { |
| 1223 // Control flow does not have side-effects. | 1223 // Control flow does not have side-effects. |
| 1224 } | 1224 } |
| 1225 bool isControlFlow() => true; | 1225 bool isControlFlow() => true; |
| 1226 bool isStatement(HTypeMap types) => true; | 1226 bool isJsStatement(HTypeMap types) => true; |
| 1227 } | 1227 } |
| 1228 | 1228 |
| 1229 class HInvoke extends HInstruction { | 1229 class HInvoke extends HInstruction { |
| 1230 /** | 1230 /** |
| 1231 * The first argument must be the target: either an [HStatic] node, or | 1231 * The first argument must be the target: either an [HStatic] node, or |
| 1232 * the receiver of a method-call. The remaining inputs are the arguments | 1232 * the receiver of a method-call. The remaining inputs are the arguments |
| 1233 * to the invocation. | 1233 * to the invocation. |
| 1234 */ | 1234 */ |
| 1235 HInvoke(List<HInstruction> inputs) : super(inputs); | 1235 HInvoke(List<HInstruction> inputs) : super(inputs); |
| 1236 static const int ARGUMENTS_OFFSET = 1; | 1236 static const int ARGUMENTS_OFFSET = 1; |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 | 1430 |
| 1431 HInstruction get receiver => inputs[0]; | 1431 HInstruction get receiver => inputs[0]; |
| 1432 HInstruction get value => inputs[1]; | 1432 HInstruction get value => inputs[1]; |
| 1433 accept(HVisitor visitor) => visitor.visitFieldSet(this); | 1433 accept(HVisitor visitor) => visitor.visitFieldSet(this); |
| 1434 | 1434 |
| 1435 void prepareGvn(HTypeMap types) { | 1435 void prepareGvn(HTypeMap types) { |
| 1436 // TODO(ngeoffray): implement more fine grained side effects. | 1436 // TODO(ngeoffray): implement more fine grained side effects. |
| 1437 setAllSideEffects(); | 1437 setAllSideEffects(); |
| 1438 } | 1438 } |
| 1439 | 1439 |
| 1440 bool isStatement(HTypeMap types) => true; | 1440 bool isJsStatement(HTypeMap types) => true; |
| 1441 String toString() => "FieldSet $element"; | 1441 String toString() => "FieldSet $element"; |
| 1442 } | 1442 } |
| 1443 | 1443 |
| 1444 class HLocalGet extends HFieldGet { | 1444 class HLocalGet extends HFieldGet { |
| 1445 HLocalGet(Element element, HLocalValue local) : super(element, local); | 1445 HLocalGet(Element element, HLocalValue local) : super(element, local); |
| 1446 | 1446 |
| 1447 accept(HVisitor visitor) => visitor.visitLocalGet(this); | 1447 accept(HVisitor visitor) => visitor.visitLocalGet(this); |
| 1448 | 1448 |
| 1449 HLocalValue get local => inputs[0]; | 1449 HLocalValue get local => inputs[0]; |
| 1450 | 1450 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN; | 1490 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN; |
| 1491 if (declaredType.slowToString() == 'int') return HType.INTEGER; | 1491 if (declaredType.slowToString() == 'int') return HType.INTEGER; |
| 1492 if (declaredType.slowToString() == 'double') return HType.DOUBLE; | 1492 if (declaredType.slowToString() == 'double') return HType.DOUBLE; |
| 1493 if (declaredType.slowToString() == 'num') return HType.NUMBER; | 1493 if (declaredType.slowToString() == 'num') return HType.NUMBER; |
| 1494 if (declaredType.slowToString() == 'String') return HType.STRING; | 1494 if (declaredType.slowToString() == 'String') return HType.STRING; |
| 1495 return HType.UNKNOWN; | 1495 return HType.UNKNOWN; |
| 1496 } | 1496 } |
| 1497 | 1497 |
| 1498 HType get guaranteedType => foreignType; | 1498 HType get guaranteedType => foreignType; |
| 1499 | 1499 |
| 1500 bool isStatement(HTypeMap types) => _isStatement; | 1500 bool isJsStatement(HTypeMap types) => _isStatement; |
| 1501 } | 1501 } |
| 1502 | 1502 |
| 1503 class HForeignNew extends HForeign { | 1503 class HForeignNew extends HForeign { |
| 1504 ClassElement element; | 1504 ClassElement element; |
| 1505 HForeignNew(this.element, List<HInstruction> inputs) | 1505 HForeignNew(this.element, List<HInstruction> inputs) |
| 1506 : super(const LiteralDartString("new"), | 1506 : super(const LiteralDartString("new"), |
| 1507 const LiteralDartString("Object"), inputs); | 1507 const LiteralDartString("Object"), inputs); |
| 1508 accept(HVisitor visitor) => visitor.visitForeignNew(this); | 1508 accept(HVisitor visitor) => visitor.visitForeignNew(this); |
| 1509 } | 1509 } |
| 1510 | 1510 |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2311 | 2311 |
| 2312 class HStaticStore extends HInstruction { | 2312 class HStaticStore extends HInstruction { |
| 2313 Element element; | 2313 Element element; |
| 2314 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]); | 2314 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]); |
| 2315 toString() => 'static store ${element.name}'; | 2315 toString() => 'static store ${element.name}'; |
| 2316 accept(HVisitor visitor) => visitor.visitStaticStore(this); | 2316 accept(HVisitor visitor) => visitor.visitStaticStore(this); |
| 2317 | 2317 |
| 2318 int typeCode() => HInstruction.STATIC_STORE_TYPECODE; | 2318 int typeCode() => HInstruction.STATIC_STORE_TYPECODE; |
| 2319 bool typeEquals(other) => other is HStaticStore; | 2319 bool typeEquals(other) => other is HStaticStore; |
| 2320 bool dataEquals(HStaticStore other) => element == other.element; | 2320 bool dataEquals(HStaticStore other) => element == other.element; |
| 2321 bool isStatement(HTypeMap types) => true; | 2321 bool isJsStatement(HTypeMap types) => true; |
| 2322 } | 2322 } |
| 2323 | 2323 |
| 2324 class HLiteralList extends HInstruction { | 2324 class HLiteralList extends HInstruction { |
| 2325 HLiteralList(inputs) : super(inputs); | 2325 HLiteralList(inputs) : super(inputs); |
| 2326 toString() => 'literal list'; | 2326 toString() => 'literal list'; |
| 2327 accept(HVisitor visitor) => visitor.visitLiteralList(this); | 2327 accept(HVisitor visitor) => visitor.visitLiteralList(this); |
| 2328 | 2328 |
| 2329 HType get guaranteedType => HType.EXTENDABLE_ARRAY; | 2329 HType get guaranteedType => HType.EXTENDABLE_ARRAY; |
| 2330 | 2330 |
| 2331 void prepareGvn(HTypeMap types) { | 2331 void prepareGvn(HTypeMap types) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2391 } | 2391 } |
| 2392 // The index should be an int when the receiver is a string or array. | 2392 // The index should be an int when the receiver is a string or array. |
| 2393 // However it turns out that inserting an integer check in the optimized | 2393 // However it turns out that inserting an integer check in the optimized |
| 2394 // version is cheaper than having another bailout case. This is true, | 2394 // version is cheaper than having another bailout case. This is true, |
| 2395 // because the integer check will simply throw if it fails. | 2395 // because the integer check will simply throw if it fails. |
| 2396 return HType.UNKNOWN; | 2396 return HType.UNKNOWN; |
| 2397 } | 2397 } |
| 2398 | 2398 |
| 2399 bool isBuiltin(HTypeMap types) | 2399 bool isBuiltin(HTypeMap types) |
| 2400 => receiver.isMutableArray(types) && index.isInteger(types); | 2400 => receiver.isMutableArray(types) && index.isInteger(types); |
| 2401 bool isStatement(HTypeMap types) => !isBuiltin(types); | 2401 bool isJsStatement(HTypeMap types) => !isBuiltin(types); |
| 2402 } | 2402 } |
| 2403 | 2403 |
| 2404 class HIs extends HInstruction { | 2404 class HIs extends HInstruction { |
| 2405 final Type typeExpression; | 2405 final Type typeExpression; |
| 2406 final bool nullOk; | 2406 final bool nullOk; |
| 2407 | 2407 |
| 2408 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression, | 2408 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression, |
| 2409 HInstruction typeInfo, [this.nullOk = false]) | 2409 HInstruction typeInfo, [this.nullOk = false]) |
| 2410 : super(<HInstruction>[expression, typeInfo]); | 2410 : super(<HInstruction>[expression, typeInfo]); |
| 2411 | 2411 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2448 | 2448 |
| 2449 bool get isChecked => kind != NO_CHECK; | 2449 bool get isChecked => kind != NO_CHECK; |
| 2450 bool get isCheckedModeCheck => kind == CHECKED_MODE_CHECK; | 2450 bool get isCheckedModeCheck => kind == CHECKED_MODE_CHECK; |
| 2451 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; | 2451 bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK; |
| 2452 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; | 2452 bool get isCastTypeCheck => kind == CAST_TYPE_CHECK; |
| 2453 | 2453 |
| 2454 HType get guaranteedType => type; | 2454 HType get guaranteedType => type; |
| 2455 | 2455 |
| 2456 accept(HVisitor visitor) => visitor.visitTypeConversion(this); | 2456 accept(HVisitor visitor) => visitor.visitTypeConversion(this); |
| 2457 | 2457 |
| 2458 bool isStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK; | 2458 bool isJsStatement(HTypeMap types) => kind == ARGUMENT_TYPE_CHECK; |
| 2459 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; | 2459 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; |
| 2460 | 2460 |
| 2461 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; | 2461 int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE; |
| 2462 bool typeEquals(HInstruction other) => other is HTypeConversion; | 2462 bool typeEquals(HInstruction other) => other is HTypeConversion; |
| 2463 bool dataEquals(HTypeConversion other) { | 2463 bool dataEquals(HTypeConversion other) { |
| 2464 return type == other.type && kind == other.kind; | 2464 return type == other.type && kind == other.kind; |
| 2465 } | 2465 } |
| 2466 } | 2466 } |
| 2467 | 2467 |
| 2468 class HStringConcat extends HInstruction { | 2468 class HStringConcat extends HInstruction { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2801 HBasicBlock get start => expression.start; | 2801 HBasicBlock get start => expression.start; |
| 2802 HBasicBlock get end { | 2802 HBasicBlock get end { |
| 2803 // We don't create a switch block if there are no cases. | 2803 // We don't create a switch block if there are no cases. |
| 2804 assert(!statements.isEmpty()); | 2804 assert(!statements.isEmpty()); |
| 2805 return statements.last().end; | 2805 return statements.last().end; |
| 2806 } | 2806 } |
| 2807 | 2807 |
| 2808 bool accept(HStatementInformationVisitor visitor) => | 2808 bool accept(HStatementInformationVisitor visitor) => |
| 2809 visitor.visitSwitchInfo(this); | 2809 visitor.visitSwitchInfo(this); |
| 2810 } | 2810 } |
| OLD | NEW |