OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
6 | 6 |
7 #include <fstream> | 7 #include <fstream> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 // TODO(interpreter): the only reason this check is here is because we | 1037 // TODO(interpreter): the only reason this check is here is because we |
1038 // sometimes emit comparisons that shouldn't collect feedback (e.g. | 1038 // sometimes emit comparisons that shouldn't collect feedback (e.g. |
1039 // try-finally blocks and generators), and we could get rid of this by | 1039 // try-finally blocks and generators), and we could get rid of this by |
1040 // introducing Smi equality tests. | 1040 // introducing Smi equality tests. |
1041 Label gather_type_feedback(assembler), do_compare(assembler); | 1041 Label gather_type_feedback(assembler), do_compare(assembler); |
1042 __ Branch(__ WordEqual(slot_index, __ IntPtrConstant(0)), &do_compare, | 1042 __ Branch(__ WordEqual(slot_index, __ IntPtrConstant(0)), &do_compare, |
1043 &gather_type_feedback); | 1043 &gather_type_feedback); |
1044 | 1044 |
1045 __ Bind(&gather_type_feedback); | 1045 __ Bind(&gather_type_feedback); |
1046 { | 1046 { |
1047 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); | 1047 Variable var_type_feedback(assembler, MachineRepresentation::kTaggedSigned); |
1048 Label lhs_is_not_smi(assembler), lhs_is_not_number(assembler), | 1048 Label lhs_is_not_smi(assembler), lhs_is_not_number(assembler), |
1049 lhs_is_not_string(assembler), gather_rhs_type(assembler), | 1049 lhs_is_not_string(assembler), gather_rhs_type(assembler), |
1050 update_feedback(assembler); | 1050 update_feedback(assembler); |
1051 | 1051 |
1052 __ GotoUnless(__ TaggedIsSmi(lhs), &lhs_is_not_smi); | 1052 __ GotoUnless(__ TaggedIsSmi(lhs), &lhs_is_not_smi); |
1053 | 1053 |
1054 var_type_feedback.Bind( | 1054 var_type_feedback.Bind( |
1055 __ Int32Constant(CompareOperationFeedback::kSignedSmall)); | 1055 __ SmiConstant(CompareOperationFeedback::kSignedSmall)); |
1056 __ Goto(&gather_rhs_type); | 1056 __ Goto(&gather_rhs_type); |
1057 | 1057 |
1058 __ Bind(&lhs_is_not_smi); | 1058 __ Bind(&lhs_is_not_smi); |
1059 { | 1059 { |
1060 Node* lhs_map = __ LoadMap(lhs); | 1060 Node* lhs_map = __ LoadMap(lhs); |
1061 __ GotoUnless(__ IsHeapNumberMap(lhs_map), &lhs_is_not_number); | 1061 __ GotoUnless(__ IsHeapNumberMap(lhs_map), &lhs_is_not_number); |
1062 | 1062 |
1063 var_type_feedback.Bind( | 1063 var_type_feedback.Bind(__ SmiConstant(CompareOperationFeedback::kNumber)); |
1064 __ Int32Constant(CompareOperationFeedback::kNumber)); | |
1065 __ Goto(&gather_rhs_type); | 1064 __ Goto(&gather_rhs_type); |
1066 | 1065 |
1067 __ Bind(&lhs_is_not_number); | 1066 __ Bind(&lhs_is_not_number); |
1068 { | 1067 { |
1069 Node* lhs_instance_type = __ LoadInstanceType(lhs); | 1068 Node* lhs_instance_type = __ LoadInstanceType(lhs); |
1070 if (Token::IsOrderedRelationalCompareOp(compare_op)) { | 1069 if (Token::IsOrderedRelationalCompareOp(compare_op)) { |
1071 Label lhs_is_not_oddball(assembler); | 1070 Label lhs_is_not_oddball(assembler); |
1072 __ GotoUnless( | 1071 __ GotoUnless( |
1073 __ Word32Equal(lhs_instance_type, __ Int32Constant(ODDBALL_TYPE)), | 1072 __ Word32Equal(lhs_instance_type, __ Int32Constant(ODDBALL_TYPE)), |
1074 &lhs_is_not_oddball); | 1073 &lhs_is_not_oddball); |
1075 | 1074 |
1076 var_type_feedback.Bind( | 1075 var_type_feedback.Bind( |
1077 __ Int32Constant(CompareOperationFeedback::kNumberOrOddball)); | 1076 __ SmiConstant(CompareOperationFeedback::kNumberOrOddball)); |
1078 __ Goto(&gather_rhs_type); | 1077 __ Goto(&gather_rhs_type); |
1079 | 1078 |
1080 __ Bind(&lhs_is_not_oddball); | 1079 __ Bind(&lhs_is_not_oddball); |
1081 } | 1080 } |
1082 | 1081 |
1083 Label lhs_is_not_string(assembler); | 1082 Label lhs_is_not_string(assembler); |
1084 __ GotoUnless(__ IsStringInstanceType(lhs_instance_type), | 1083 __ GotoUnless(__ IsStringInstanceType(lhs_instance_type), |
1085 &lhs_is_not_string); | 1084 &lhs_is_not_string); |
1086 | 1085 |
1087 if (Token::IsOrderedRelationalCompareOp(compare_op)) { | 1086 if (Token::IsOrderedRelationalCompareOp(compare_op)) { |
1088 var_type_feedback.Bind( | 1087 var_type_feedback.Bind( |
1089 __ Int32Constant(CompareOperationFeedback::kString)); | 1088 __ SmiConstant(CompareOperationFeedback::kString)); |
1090 } else { | 1089 } else { |
1091 var_type_feedback.Bind(__ SelectInt32Constant( | 1090 var_type_feedback.Bind(__ SelectSmiConstant( |
1092 __ Word32Equal( | 1091 __ Word32Equal( |
1093 __ Word32And(lhs_instance_type, | 1092 __ Word32And(lhs_instance_type, |
1094 __ Int32Constant(kIsNotInternalizedMask)), | 1093 __ Int32Constant(kIsNotInternalizedMask)), |
1095 __ Int32Constant(kInternalizedTag)), | 1094 __ Int32Constant(kInternalizedTag)), |
1096 CompareOperationFeedback::kInternalizedString, | 1095 CompareOperationFeedback::kInternalizedString, |
1097 CompareOperationFeedback::kString)); | 1096 CompareOperationFeedback::kString)); |
1098 } | 1097 } |
1099 __ Goto(&gather_rhs_type); | 1098 __ Goto(&gather_rhs_type); |
1100 | 1099 |
1101 __ Bind(&lhs_is_not_string); | 1100 __ Bind(&lhs_is_not_string); |
1102 var_type_feedback.Bind( | 1101 var_type_feedback.Bind(__ SmiConstant(CompareOperationFeedback::kAny)); |
1103 __ Int32Constant(CompareOperationFeedback::kAny)); | |
1104 __ Goto(&gather_rhs_type); | 1102 __ Goto(&gather_rhs_type); |
1105 } | 1103 } |
1106 } | 1104 } |
1107 | 1105 |
1108 __ Bind(&gather_rhs_type); | 1106 __ Bind(&gather_rhs_type); |
1109 { | 1107 { |
1110 Label rhs_is_not_smi(assembler), rhs_is_not_number(assembler); | 1108 Label rhs_is_not_smi(assembler), rhs_is_not_number(assembler); |
1111 | 1109 |
1112 __ GotoUnless(__ TaggedIsSmi(rhs), &rhs_is_not_smi); | 1110 __ GotoUnless(__ TaggedIsSmi(rhs), &rhs_is_not_smi); |
1113 | 1111 |
1114 var_type_feedback.Bind(__ Word32Or( | 1112 var_type_feedback.Bind( |
1115 var_type_feedback.value(), | 1113 __ SmiOr(var_type_feedback.value(), |
1116 __ Int32Constant(CompareOperationFeedback::kSignedSmall))); | 1114 __ SmiConstant(CompareOperationFeedback::kSignedSmall))); |
1117 __ Goto(&update_feedback); | 1115 __ Goto(&update_feedback); |
1118 | 1116 |
1119 __ Bind(&rhs_is_not_smi); | 1117 __ Bind(&rhs_is_not_smi); |
1120 { | 1118 { |
1121 Node* rhs_map = __ LoadMap(rhs); | 1119 Node* rhs_map = __ LoadMap(rhs); |
1122 __ GotoUnless(__ IsHeapNumberMap(rhs_map), &rhs_is_not_number); | 1120 __ GotoUnless(__ IsHeapNumberMap(rhs_map), &rhs_is_not_number); |
1123 | 1121 |
1124 var_type_feedback.Bind( | 1122 var_type_feedback.Bind( |
1125 __ Word32Or(var_type_feedback.value(), | 1123 __ SmiOr(var_type_feedback.value(), |
1126 __ Int32Constant(CompareOperationFeedback::kNumber))); | 1124 __ SmiConstant(CompareOperationFeedback::kNumber))); |
1127 __ Goto(&update_feedback); | 1125 __ Goto(&update_feedback); |
1128 | 1126 |
1129 __ Bind(&rhs_is_not_number); | 1127 __ Bind(&rhs_is_not_number); |
1130 { | 1128 { |
1131 Node* rhs_instance_type = __ LoadInstanceType(rhs); | 1129 Node* rhs_instance_type = __ LoadInstanceType(rhs); |
1132 if (Token::IsOrderedRelationalCompareOp(compare_op)) { | 1130 if (Token::IsOrderedRelationalCompareOp(compare_op)) { |
1133 Label rhs_is_not_oddball(assembler); | 1131 Label rhs_is_not_oddball(assembler); |
1134 __ GotoUnless(__ Word32Equal(rhs_instance_type, | 1132 __ GotoUnless(__ Word32Equal(rhs_instance_type, |
1135 __ Int32Constant(ODDBALL_TYPE)), | 1133 __ Int32Constant(ODDBALL_TYPE)), |
1136 &rhs_is_not_oddball); | 1134 &rhs_is_not_oddball); |
1137 | 1135 |
1138 var_type_feedback.Bind(__ Word32Or( | 1136 var_type_feedback.Bind(__ SmiOr( |
1139 var_type_feedback.value(), | 1137 var_type_feedback.value(), |
1140 __ Int32Constant(CompareOperationFeedback::kNumberOrOddball))); | 1138 __ SmiConstant(CompareOperationFeedback::kNumberOrOddball))); |
1141 __ Goto(&update_feedback); | 1139 __ Goto(&update_feedback); |
1142 | 1140 |
1143 __ Bind(&rhs_is_not_oddball); | 1141 __ Bind(&rhs_is_not_oddball); |
1144 } | 1142 } |
1145 | 1143 |
1146 Label rhs_is_not_string(assembler); | 1144 Label rhs_is_not_string(assembler); |
1147 __ GotoUnless(__ IsStringInstanceType(rhs_instance_type), | 1145 __ GotoUnless(__ IsStringInstanceType(rhs_instance_type), |
1148 &rhs_is_not_string); | 1146 &rhs_is_not_string); |
1149 | 1147 |
1150 if (Token::IsOrderedRelationalCompareOp(compare_op)) { | 1148 if (Token::IsOrderedRelationalCompareOp(compare_op)) { |
1151 var_type_feedback.Bind(__ Word32Or( | 1149 var_type_feedback.Bind( |
| 1150 __ SmiOr(var_type_feedback.value(), |
| 1151 __ SmiConstant(CompareOperationFeedback::kString))); |
| 1152 } else { |
| 1153 var_type_feedback.Bind(__ SmiOr( |
1152 var_type_feedback.value(), | 1154 var_type_feedback.value(), |
1153 __ Int32Constant(CompareOperationFeedback::kString))); | 1155 __ SelectSmiConstant( |
1154 } else { | |
1155 var_type_feedback.Bind(__ Word32Or( | |
1156 var_type_feedback.value(), | |
1157 __ SelectInt32Constant( | |
1158 __ Word32Equal( | 1156 __ Word32Equal( |
1159 __ Word32And(rhs_instance_type, | 1157 __ Word32And(rhs_instance_type, |
1160 __ Int32Constant(kIsNotInternalizedMask)), | 1158 __ Int32Constant(kIsNotInternalizedMask)), |
1161 __ Int32Constant(kInternalizedTag)), | 1159 __ Int32Constant(kInternalizedTag)), |
1162 CompareOperationFeedback::kInternalizedString, | 1160 CompareOperationFeedback::kInternalizedString, |
1163 CompareOperationFeedback::kString))); | 1161 CompareOperationFeedback::kString))); |
1164 } | 1162 } |
1165 __ Goto(&update_feedback); | 1163 __ Goto(&update_feedback); |
1166 | 1164 |
1167 __ Bind(&rhs_is_not_string); | 1165 __ Bind(&rhs_is_not_string); |
1168 var_type_feedback.Bind( | 1166 var_type_feedback.Bind( |
1169 __ Int32Constant(CompareOperationFeedback::kAny)); | 1167 __ SmiConstant(CompareOperationFeedback::kAny)); |
1170 __ Goto(&update_feedback); | 1168 __ Goto(&update_feedback); |
1171 } | 1169 } |
1172 } | 1170 } |
1173 } | 1171 } |
1174 | 1172 |
1175 __ Bind(&update_feedback); | 1173 __ Bind(&update_feedback); |
1176 { | 1174 { |
1177 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1175 __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1178 slot_index); | 1176 slot_index); |
1179 __ Goto(&do_compare); | 1177 __ Goto(&do_compare); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 | 1253 |
1256 void Interpreter::DoBitwiseBinaryOp(Token::Value bitwise_op, | 1254 void Interpreter::DoBitwiseBinaryOp(Token::Value bitwise_op, |
1257 InterpreterAssembler* assembler) { | 1255 InterpreterAssembler* assembler) { |
1258 Node* reg_index = __ BytecodeOperandReg(0); | 1256 Node* reg_index = __ BytecodeOperandReg(0); |
1259 Node* lhs = __ LoadRegister(reg_index); | 1257 Node* lhs = __ LoadRegister(reg_index); |
1260 Node* rhs = __ GetAccumulator(); | 1258 Node* rhs = __ GetAccumulator(); |
1261 Node* context = __ GetContext(); | 1259 Node* context = __ GetContext(); |
1262 Node* slot_index = __ BytecodeOperandIdx(1); | 1260 Node* slot_index = __ BytecodeOperandIdx(1); |
1263 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1261 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1264 | 1262 |
1265 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32), | 1263 Variable var_lhs_type_feedback(assembler, |
1266 var_rhs_type_feedback(assembler, MachineRepresentation::kWord32); | 1264 MachineRepresentation::kTaggedSigned), |
| 1265 var_rhs_type_feedback(assembler, MachineRepresentation::kTaggedSigned); |
1267 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( | 1266 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
1268 context, lhs, &var_lhs_type_feedback); | 1267 context, lhs, &var_lhs_type_feedback); |
1269 Node* rhs_value = __ TruncateTaggedToWord32WithFeedback( | 1268 Node* rhs_value = __ TruncateTaggedToWord32WithFeedback( |
1270 context, rhs, &var_rhs_type_feedback); | 1269 context, rhs, &var_rhs_type_feedback); |
1271 Node* result = nullptr; | 1270 Node* result = nullptr; |
1272 | 1271 |
1273 switch (bitwise_op) { | 1272 switch (bitwise_op) { |
1274 case Token::BIT_OR: { | 1273 case Token::BIT_OR: { |
1275 Node* value = __ Word32Or(lhs_value, rhs_value); | 1274 Node* value = __ Word32Or(lhs_value, rhs_value); |
1276 result = __ ChangeInt32ToTagged(value); | 1275 result = __ ChangeInt32ToTagged(value); |
(...skipping 18 matching lines...) Expand all Loading... |
1295 } break; | 1294 } break; |
1296 case Token::SAR: { | 1295 case Token::SAR: { |
1297 Node* value = __ Word32Sar( | 1296 Node* value = __ Word32Sar( |
1298 lhs_value, __ Word32And(rhs_value, __ Int32Constant(0x1f))); | 1297 lhs_value, __ Word32And(rhs_value, __ Int32Constant(0x1f))); |
1299 result = __ ChangeInt32ToTagged(value); | 1298 result = __ ChangeInt32ToTagged(value); |
1300 } break; | 1299 } break; |
1301 default: | 1300 default: |
1302 UNREACHABLE(); | 1301 UNREACHABLE(); |
1303 } | 1302 } |
1304 | 1303 |
1305 Node* result_type = __ SelectInt32Constant( | 1304 Node* result_type = __ SelectSmiConstant( |
1306 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, | 1305 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, |
1307 BinaryOperationFeedback::kNumber); | 1306 BinaryOperationFeedback::kNumber); |
1308 | 1307 |
1309 if (FLAG_debug_code) { | 1308 if (FLAG_debug_code) { |
1310 Label ok(assembler); | 1309 Label ok(assembler); |
1311 __ GotoIf(__ TaggedIsSmi(result), &ok); | 1310 __ GotoIf(__ TaggedIsSmi(result), &ok); |
1312 Node* result_map = __ LoadMap(result); | 1311 Node* result_map = __ LoadMap(result); |
1313 __ AbortIfWordNotEqual(result_map, __ HeapNumberMapConstant(), | 1312 __ AbortIfWordNotEqual(result_map, __ HeapNumberMapConstant(), |
1314 kExpectedHeapNumber); | 1313 kExpectedHeapNumber); |
1315 __ Goto(&ok); | 1314 __ Goto(&ok); |
1316 __ Bind(&ok); | 1315 __ Bind(&ok); |
1317 } | 1316 } |
1318 | 1317 |
1319 Node* input_feedback = | 1318 Node* input_feedback = |
1320 __ Word32Or(var_lhs_type_feedback.value(), var_rhs_type_feedback.value()); | 1319 __ SmiOr(var_lhs_type_feedback.value(), var_rhs_type_feedback.value()); |
1321 __ UpdateFeedback(__ Word32Or(result_type, input_feedback), | 1320 __ UpdateFeedback(__ SmiOr(result_type, input_feedback), type_feedback_vector, |
1322 type_feedback_vector, slot_index); | 1321 slot_index); |
1323 __ SetAccumulator(result); | 1322 __ SetAccumulator(result); |
1324 __ Dispatch(); | 1323 __ Dispatch(); |
1325 } | 1324 } |
1326 | 1325 |
1327 // BitwiseOr <src> | 1326 // BitwiseOr <src> |
1328 // | 1327 // |
1329 // BitwiseOr register <src> to accumulator. | 1328 // BitwiseOr register <src> to accumulator. |
1330 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { | 1329 void Interpreter::DoBitwiseOr(InterpreterAssembler* assembler) { |
1331 DoBitwiseBinaryOp(Token::BIT_OR, assembler); | 1330 DoBitwiseBinaryOp(Token::BIT_OR, assembler); |
1332 } | 1331 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 // Try fast Smi addition first. | 1397 // Try fast Smi addition first. |
1399 Node* pair = __ IntPtrAddWithOverflow(__ BitcastTaggedToWord(left), | 1398 Node* pair = __ IntPtrAddWithOverflow(__ BitcastTaggedToWord(left), |
1400 __ BitcastTaggedToWord(right)); | 1399 __ BitcastTaggedToWord(right)); |
1401 Node* overflow = __ Projection(1, pair); | 1400 Node* overflow = __ Projection(1, pair); |
1402 | 1401 |
1403 // Check if the Smi additon overflowed. | 1402 // Check if the Smi additon overflowed. |
1404 Label if_notoverflow(assembler); | 1403 Label if_notoverflow(assembler); |
1405 __ Branch(overflow, &slowpath, &if_notoverflow); | 1404 __ Branch(overflow, &slowpath, &if_notoverflow); |
1406 __ Bind(&if_notoverflow); | 1405 __ Bind(&if_notoverflow); |
1407 { | 1406 { |
1408 __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall), | 1407 __ UpdateFeedback(__ SmiConstant(BinaryOperationFeedback::kSignedSmall), |
1409 type_feedback_vector, slot_index); | 1408 type_feedback_vector, slot_index); |
1410 var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair))); | 1409 var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair))); |
1411 __ Goto(&end); | 1410 __ Goto(&end); |
1412 } | 1411 } |
1413 } | 1412 } |
1414 __ Bind(&slowpath); | 1413 __ Bind(&slowpath); |
1415 { | 1414 { |
1416 Node* context = __ GetContext(); | 1415 Node* context = __ GetContext(); |
1417 AddWithFeedbackStub stub(__ isolate()); | 1416 AddWithFeedbackStub stub(__ isolate()); |
1418 Callable callable = | 1417 Callable callable = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 // Try fast Smi subtraction first. | 1451 // Try fast Smi subtraction first. |
1453 Node* pair = __ IntPtrSubWithOverflow(__ BitcastTaggedToWord(left), | 1452 Node* pair = __ IntPtrSubWithOverflow(__ BitcastTaggedToWord(left), |
1454 __ BitcastTaggedToWord(right)); | 1453 __ BitcastTaggedToWord(right)); |
1455 Node* overflow = __ Projection(1, pair); | 1454 Node* overflow = __ Projection(1, pair); |
1456 | 1455 |
1457 // Check if the Smi subtraction overflowed. | 1456 // Check if the Smi subtraction overflowed. |
1458 Label if_notoverflow(assembler); | 1457 Label if_notoverflow(assembler); |
1459 __ Branch(overflow, &slowpath, &if_notoverflow); | 1458 __ Branch(overflow, &slowpath, &if_notoverflow); |
1460 __ Bind(&if_notoverflow); | 1459 __ Bind(&if_notoverflow); |
1461 { | 1460 { |
1462 __ UpdateFeedback(__ Int32Constant(BinaryOperationFeedback::kSignedSmall), | 1461 __ UpdateFeedback(__ SmiConstant(BinaryOperationFeedback::kSignedSmall), |
1463 type_feedback_vector, slot_index); | 1462 type_feedback_vector, slot_index); |
1464 var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair))); | 1463 var_result.Bind(__ BitcastWordToTaggedSigned(__ Projection(0, pair))); |
1465 __ Goto(&end); | 1464 __ Goto(&end); |
1466 } | 1465 } |
1467 } | 1466 } |
1468 __ Bind(&slowpath); | 1467 __ Bind(&slowpath); |
1469 { | 1468 { |
1470 Node* context = __ GetContext(); | 1469 Node* context = __ GetContext(); |
1471 SubtractWithFeedbackStub stub(__ isolate()); | 1470 SubtractWithFeedbackStub stub(__ isolate()); |
1472 Callable callable = Callable( | 1471 Callable callable = Callable( |
(...skipping 14 matching lines...) Expand all Loading... |
1487 // | 1486 // |
1488 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs | 1487 // BitwiseOr <reg> with <imm>. For this operation <reg> is the lhs |
1489 // operand and <imm> is the rhs operand. | 1488 // operand and <imm> is the rhs operand. |
1490 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) { | 1489 void Interpreter::DoBitwiseOrSmi(InterpreterAssembler* assembler) { |
1491 Node* reg_index = __ BytecodeOperandReg(1); | 1490 Node* reg_index = __ BytecodeOperandReg(1); |
1492 Node* left = __ LoadRegister(reg_index); | 1491 Node* left = __ LoadRegister(reg_index); |
1493 Node* right = __ BytecodeOperandImmSmi(0); | 1492 Node* right = __ BytecodeOperandImmSmi(0); |
1494 Node* context = __ GetContext(); | 1493 Node* context = __ GetContext(); |
1495 Node* slot_index = __ BytecodeOperandIdx(2); | 1494 Node* slot_index = __ BytecodeOperandIdx(2); |
1496 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1495 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1497 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32); | 1496 Variable var_lhs_type_feedback(assembler, |
| 1497 MachineRepresentation::kTaggedSigned); |
1498 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( | 1498 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
1499 context, left, &var_lhs_type_feedback); | 1499 context, left, &var_lhs_type_feedback); |
1500 Node* rhs_value = __ SmiToWord32(right); | 1500 Node* rhs_value = __ SmiToWord32(right); |
1501 Node* value = __ Word32Or(lhs_value, rhs_value); | 1501 Node* value = __ Word32Or(lhs_value, rhs_value); |
1502 Node* result = __ ChangeInt32ToTagged(value); | 1502 Node* result = __ ChangeInt32ToTagged(value); |
1503 Node* result_type = __ SelectInt32Constant( | 1503 Node* result_type = __ SelectSmiConstant( |
1504 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, | 1504 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, |
1505 BinaryOperationFeedback::kNumber); | 1505 BinaryOperationFeedback::kNumber); |
1506 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()), | 1506 __ UpdateFeedback(__ SmiOr(result_type, var_lhs_type_feedback.value()), |
1507 type_feedback_vector, slot_index); | 1507 type_feedback_vector, slot_index); |
1508 __ SetAccumulator(result); | 1508 __ SetAccumulator(result); |
1509 __ Dispatch(); | 1509 __ Dispatch(); |
1510 } | 1510 } |
1511 | 1511 |
1512 // BitwiseAnd <imm> <reg> | 1512 // BitwiseAnd <imm> <reg> |
1513 // | 1513 // |
1514 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs | 1514 // BitwiseAnd <reg> with <imm>. For this operation <reg> is the lhs |
1515 // operand and <imm> is the rhs operand. | 1515 // operand and <imm> is the rhs operand. |
1516 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) { | 1516 void Interpreter::DoBitwiseAndSmi(InterpreterAssembler* assembler) { |
1517 Node* reg_index = __ BytecodeOperandReg(1); | 1517 Node* reg_index = __ BytecodeOperandReg(1); |
1518 Node* left = __ LoadRegister(reg_index); | 1518 Node* left = __ LoadRegister(reg_index); |
1519 Node* right = __ BytecodeOperandImmSmi(0); | 1519 Node* right = __ BytecodeOperandImmSmi(0); |
1520 Node* context = __ GetContext(); | 1520 Node* context = __ GetContext(); |
1521 Node* slot_index = __ BytecodeOperandIdx(2); | 1521 Node* slot_index = __ BytecodeOperandIdx(2); |
1522 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1522 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1523 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32); | 1523 Variable var_lhs_type_feedback(assembler, |
| 1524 MachineRepresentation::kTaggedSigned); |
1524 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( | 1525 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
1525 context, left, &var_lhs_type_feedback); | 1526 context, left, &var_lhs_type_feedback); |
1526 Node* rhs_value = __ SmiToWord32(right); | 1527 Node* rhs_value = __ SmiToWord32(right); |
1527 Node* value = __ Word32And(lhs_value, rhs_value); | 1528 Node* value = __ Word32And(lhs_value, rhs_value); |
1528 Node* result = __ ChangeInt32ToTagged(value); | 1529 Node* result = __ ChangeInt32ToTagged(value); |
1529 Node* result_type = __ SelectInt32Constant( | 1530 Node* result_type = __ SelectSmiConstant( |
1530 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, | 1531 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, |
1531 BinaryOperationFeedback::kNumber); | 1532 BinaryOperationFeedback::kNumber); |
1532 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()), | 1533 __ UpdateFeedback(__ SmiOr(result_type, var_lhs_type_feedback.value()), |
1533 type_feedback_vector, slot_index); | 1534 type_feedback_vector, slot_index); |
1534 __ SetAccumulator(result); | 1535 __ SetAccumulator(result); |
1535 __ Dispatch(); | 1536 __ Dispatch(); |
1536 } | 1537 } |
1537 | 1538 |
1538 // ShiftLeftSmi <imm> <reg> | 1539 // ShiftLeftSmi <imm> <reg> |
1539 // | 1540 // |
1540 // Left shifts register <src> by the count specified in <imm>. | 1541 // Left shifts register <src> by the count specified in <imm>. |
1541 // Register <src> is converted to an int32 before the operation. The 5 | 1542 // Register <src> is converted to an int32 before the operation. The 5 |
1542 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). | 1543 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). |
1543 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) { | 1544 void Interpreter::DoShiftLeftSmi(InterpreterAssembler* assembler) { |
1544 Node* reg_index = __ BytecodeOperandReg(1); | 1545 Node* reg_index = __ BytecodeOperandReg(1); |
1545 Node* left = __ LoadRegister(reg_index); | 1546 Node* left = __ LoadRegister(reg_index); |
1546 Node* right = __ BytecodeOperandImmSmi(0); | 1547 Node* right = __ BytecodeOperandImmSmi(0); |
1547 Node* context = __ GetContext(); | 1548 Node* context = __ GetContext(); |
1548 Node* slot_index = __ BytecodeOperandIdx(2); | 1549 Node* slot_index = __ BytecodeOperandIdx(2); |
1549 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1550 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1550 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32); | 1551 Variable var_lhs_type_feedback(assembler, |
| 1552 MachineRepresentation::kTaggedSigned); |
1551 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( | 1553 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
1552 context, left, &var_lhs_type_feedback); | 1554 context, left, &var_lhs_type_feedback); |
1553 Node* rhs_value = __ SmiToWord32(right); | 1555 Node* rhs_value = __ SmiToWord32(right); |
1554 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); | 1556 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); |
1555 Node* value = __ Word32Shl(lhs_value, shift_count); | 1557 Node* value = __ Word32Shl(lhs_value, shift_count); |
1556 Node* result = __ ChangeInt32ToTagged(value); | 1558 Node* result = __ ChangeInt32ToTagged(value); |
1557 Node* result_type = __ SelectInt32Constant( | 1559 Node* result_type = __ SelectSmiConstant( |
1558 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, | 1560 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, |
1559 BinaryOperationFeedback::kNumber); | 1561 BinaryOperationFeedback::kNumber); |
1560 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()), | 1562 __ UpdateFeedback(__ SmiOr(result_type, var_lhs_type_feedback.value()), |
1561 type_feedback_vector, slot_index); | 1563 type_feedback_vector, slot_index); |
1562 __ SetAccumulator(result); | 1564 __ SetAccumulator(result); |
1563 __ Dispatch(); | 1565 __ Dispatch(); |
1564 } | 1566 } |
1565 | 1567 |
1566 // ShiftRightSmi <imm> <reg> | 1568 // ShiftRightSmi <imm> <reg> |
1567 // | 1569 // |
1568 // Right shifts register <src> by the count specified in <imm>. | 1570 // Right shifts register <src> by the count specified in <imm>. |
1569 // Register <src> is converted to an int32 before the operation. The 5 | 1571 // Register <src> is converted to an int32 before the operation. The 5 |
1570 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). | 1572 // lsb bits from <imm> are used as count i.e. <src> << (<imm> & 0x1F). |
1571 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) { | 1573 void Interpreter::DoShiftRightSmi(InterpreterAssembler* assembler) { |
1572 Node* reg_index = __ BytecodeOperandReg(1); | 1574 Node* reg_index = __ BytecodeOperandReg(1); |
1573 Node* left = __ LoadRegister(reg_index); | 1575 Node* left = __ LoadRegister(reg_index); |
1574 Node* right = __ BytecodeOperandImmSmi(0); | 1576 Node* right = __ BytecodeOperandImmSmi(0); |
1575 Node* context = __ GetContext(); | 1577 Node* context = __ GetContext(); |
1576 Node* slot_index = __ BytecodeOperandIdx(2); | 1578 Node* slot_index = __ BytecodeOperandIdx(2); |
1577 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1579 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1578 Variable var_lhs_type_feedback(assembler, MachineRepresentation::kWord32); | 1580 Variable var_lhs_type_feedback(assembler, |
| 1581 MachineRepresentation::kTaggedSigned); |
1579 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( | 1582 Node* lhs_value = __ TruncateTaggedToWord32WithFeedback( |
1580 context, left, &var_lhs_type_feedback); | 1583 context, left, &var_lhs_type_feedback); |
1581 Node* rhs_value = __ SmiToWord32(right); | 1584 Node* rhs_value = __ SmiToWord32(right); |
1582 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); | 1585 Node* shift_count = __ Word32And(rhs_value, __ Int32Constant(0x1f)); |
1583 Node* value = __ Word32Sar(lhs_value, shift_count); | 1586 Node* value = __ Word32Sar(lhs_value, shift_count); |
1584 Node* result = __ ChangeInt32ToTagged(value); | 1587 Node* result = __ ChangeInt32ToTagged(value); |
1585 Node* result_type = __ SelectInt32Constant( | 1588 Node* result_type = __ SelectSmiConstant( |
1586 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, | 1589 __ TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, |
1587 BinaryOperationFeedback::kNumber); | 1590 BinaryOperationFeedback::kNumber); |
1588 __ UpdateFeedback(__ Word32Or(result_type, var_lhs_type_feedback.value()), | 1591 __ UpdateFeedback(__ SmiOr(result_type, var_lhs_type_feedback.value()), |
1589 type_feedback_vector, slot_index); | 1592 type_feedback_vector, slot_index); |
1590 __ SetAccumulator(result); | 1593 __ SetAccumulator(result); |
1591 __ Dispatch(); | 1594 __ Dispatch(); |
1592 } | 1595 } |
1593 | 1596 |
1594 Node* Interpreter::BuildUnaryOp(Callable callable, | 1597 Node* Interpreter::BuildUnaryOp(Callable callable, |
1595 InterpreterAssembler* assembler) { | 1598 InterpreterAssembler* assembler) { |
1596 Node* target = __ HeapConstant(callable.code()); | 1599 Node* target = __ HeapConstant(callable.code()); |
1597 Node* accumulator = __ GetAccumulator(); | 1600 Node* accumulator = __ GetAccumulator(); |
1598 Node* context = __ GetContext(); | 1601 Node* context = __ GetContext(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1655 Node* slot_index = __ BytecodeOperandIdx(0); | 1658 Node* slot_index = __ BytecodeOperandIdx(0); |
1656 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1659 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1657 | 1660 |
1658 // Shared entry for floating point increment. | 1661 // Shared entry for floating point increment. |
1659 Label do_finc(assembler), end(assembler); | 1662 Label do_finc(assembler), end(assembler); |
1660 Variable var_finc_value(assembler, MachineRepresentation::kFloat64); | 1663 Variable var_finc_value(assembler, MachineRepresentation::kFloat64); |
1661 | 1664 |
1662 // We might need to try again due to ToNumber conversion. | 1665 // We might need to try again due to ToNumber conversion. |
1663 Variable value_var(assembler, MachineRepresentation::kTagged); | 1666 Variable value_var(assembler, MachineRepresentation::kTagged); |
1664 Variable result_var(assembler, MachineRepresentation::kTagged); | 1667 Variable result_var(assembler, MachineRepresentation::kTagged); |
1665 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); | 1668 Variable var_type_feedback(assembler, MachineRepresentation::kTaggedSigned); |
1666 Variable* loop_vars[] = {&value_var, &var_type_feedback}; | 1669 Variable* loop_vars[] = {&value_var, &var_type_feedback}; |
1667 Label start(assembler, 2, loop_vars); | 1670 Label start(assembler, 2, loop_vars); |
1668 value_var.Bind(value); | 1671 value_var.Bind(value); |
1669 var_type_feedback.Bind( | 1672 var_type_feedback.Bind( |
1670 assembler->Int32Constant(BinaryOperationFeedback::kNone)); | 1673 assembler->SmiConstant(BinaryOperationFeedback::kNone)); |
1671 assembler->Goto(&start); | 1674 assembler->Goto(&start); |
1672 assembler->Bind(&start); | 1675 assembler->Bind(&start); |
1673 { | 1676 { |
1674 value = value_var.value(); | 1677 value = value_var.value(); |
1675 | 1678 |
1676 Label if_issmi(assembler), if_isnotsmi(assembler); | 1679 Label if_issmi(assembler), if_isnotsmi(assembler); |
1677 assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi); | 1680 assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi); |
1678 | 1681 |
1679 assembler->Bind(&if_issmi); | 1682 assembler->Bind(&if_issmi); |
1680 { | 1683 { |
1681 // Try fast Smi addition first. | 1684 // Try fast Smi addition first. |
1682 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 1685 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
1683 Node* pair = assembler->IntPtrAddWithOverflow( | 1686 Node* pair = assembler->IntPtrAddWithOverflow( |
1684 assembler->BitcastTaggedToWord(value), | 1687 assembler->BitcastTaggedToWord(value), |
1685 assembler->BitcastTaggedToWord(one)); | 1688 assembler->BitcastTaggedToWord(one)); |
1686 Node* overflow = assembler->Projection(1, pair); | 1689 Node* overflow = assembler->Projection(1, pair); |
1687 | 1690 |
1688 // Check if the Smi addition overflowed. | 1691 // Check if the Smi addition overflowed. |
1689 Label if_overflow(assembler), if_notoverflow(assembler); | 1692 Label if_overflow(assembler), if_notoverflow(assembler); |
1690 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 1693 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
1691 | 1694 |
1692 assembler->Bind(&if_notoverflow); | 1695 assembler->Bind(&if_notoverflow); |
1693 var_type_feedback.Bind(assembler->Word32Or( | 1696 var_type_feedback.Bind(assembler->SmiOr( |
1694 var_type_feedback.value(), | 1697 var_type_feedback.value(), |
1695 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall))); | 1698 assembler->SmiConstant(BinaryOperationFeedback::kSignedSmall))); |
1696 result_var.Bind( | 1699 result_var.Bind( |
1697 assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair))); | 1700 assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair))); |
1698 assembler->Goto(&end); | 1701 assembler->Goto(&end); |
1699 | 1702 |
1700 assembler->Bind(&if_overflow); | 1703 assembler->Bind(&if_overflow); |
1701 { | 1704 { |
1702 var_finc_value.Bind(assembler->SmiToFloat64(value)); | 1705 var_finc_value.Bind(assembler->SmiToFloat64(value)); |
1703 assembler->Goto(&do_finc); | 1706 assembler->Goto(&do_finc); |
1704 } | 1707 } |
1705 } | 1708 } |
(...skipping 13 matching lines...) Expand all Loading... |
1719 var_finc_value.Bind(assembler->LoadHeapNumberValue(value)); | 1722 var_finc_value.Bind(assembler->LoadHeapNumberValue(value)); |
1720 assembler->Goto(&do_finc); | 1723 assembler->Goto(&do_finc); |
1721 } | 1724 } |
1722 | 1725 |
1723 assembler->Bind(&if_valuenotnumber); | 1726 assembler->Bind(&if_valuenotnumber); |
1724 { | 1727 { |
1725 // We do not require an Or with earlier feedback here because once we | 1728 // We do not require an Or with earlier feedback here because once we |
1726 // convert the value to a number, we cannot reach this path. We can | 1729 // convert the value to a number, we cannot reach this path. We can |
1727 // only reach this path on the first pass when the feedback is kNone. | 1730 // only reach this path on the first pass when the feedback is kNone. |
1728 CSA_ASSERT(assembler, | 1731 CSA_ASSERT(assembler, |
1729 assembler->Word32Equal(var_type_feedback.value(), | 1732 assembler->SmiEqual( |
1730 assembler->Int32Constant( | 1733 var_type_feedback.value(), |
1731 BinaryOperationFeedback::kNone))); | 1734 assembler->SmiConstant(BinaryOperationFeedback::kNone))); |
1732 | 1735 |
1733 Label if_valueisoddball(assembler), if_valuenotoddball(assembler); | 1736 Label if_valueisoddball(assembler), if_valuenotoddball(assembler); |
1734 Node* instance_type = assembler->LoadMapInstanceType(value_map); | 1737 Node* instance_type = assembler->LoadMapInstanceType(value_map); |
1735 Node* is_oddball = assembler->Word32Equal( | 1738 Node* is_oddball = assembler->Word32Equal( |
1736 instance_type, assembler->Int32Constant(ODDBALL_TYPE)); | 1739 instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
1737 assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball); | 1740 assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball); |
1738 | 1741 |
1739 assembler->Bind(&if_valueisoddball); | 1742 assembler->Bind(&if_valueisoddball); |
1740 { | 1743 { |
1741 // Convert Oddball to Number and check again. | 1744 // Convert Oddball to Number and check again. |
1742 value_var.Bind( | 1745 value_var.Bind( |
1743 assembler->LoadObjectField(value, Oddball::kToNumberOffset)); | 1746 assembler->LoadObjectField(value, Oddball::kToNumberOffset)); |
1744 var_type_feedback.Bind(assembler->Int32Constant( | 1747 var_type_feedback.Bind(assembler->SmiConstant( |
1745 BinaryOperationFeedback::kNumberOrOddball)); | 1748 BinaryOperationFeedback::kNumberOrOddball)); |
1746 assembler->Goto(&start); | 1749 assembler->Goto(&start); |
1747 } | 1750 } |
1748 | 1751 |
1749 assembler->Bind(&if_valuenotoddball); | 1752 assembler->Bind(&if_valuenotoddball); |
1750 { | 1753 { |
1751 // Convert to a Number first and try again. | 1754 // Convert to a Number first and try again. |
1752 Callable callable = | 1755 Callable callable = |
1753 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1756 CodeFactory::NonNumberToNumber(assembler->isolate()); |
1754 var_type_feedback.Bind( | 1757 var_type_feedback.Bind( |
1755 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | 1758 assembler->SmiConstant(BinaryOperationFeedback::kAny)); |
1756 value_var.Bind(assembler->CallStub(callable, context, value)); | 1759 value_var.Bind(assembler->CallStub(callable, context, value)); |
1757 assembler->Goto(&start); | 1760 assembler->Goto(&start); |
1758 } | 1761 } |
1759 } | 1762 } |
1760 } | 1763 } |
1761 } | 1764 } |
1762 | 1765 |
1763 assembler->Bind(&do_finc); | 1766 assembler->Bind(&do_finc); |
1764 { | 1767 { |
1765 Node* finc_value = var_finc_value.value(); | 1768 Node* finc_value = var_finc_value.value(); |
1766 Node* one = assembler->Float64Constant(1.0); | 1769 Node* one = assembler->Float64Constant(1.0); |
1767 Node* finc_result = assembler->Float64Add(finc_value, one); | 1770 Node* finc_result = assembler->Float64Add(finc_value, one); |
1768 var_type_feedback.Bind(assembler->Word32Or( | 1771 var_type_feedback.Bind(assembler->SmiOr( |
1769 var_type_feedback.value(), | 1772 var_type_feedback.value(), |
1770 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); | 1773 assembler->SmiConstant(BinaryOperationFeedback::kNumber))); |
1771 result_var.Bind(assembler->AllocateHeapNumberWithValue(finc_result)); | 1774 result_var.Bind(assembler->AllocateHeapNumberWithValue(finc_result)); |
1772 assembler->Goto(&end); | 1775 assembler->Goto(&end); |
1773 } | 1776 } |
1774 | 1777 |
1775 assembler->Bind(&end); | 1778 assembler->Bind(&end); |
1776 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1779 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1777 slot_index); | 1780 slot_index); |
1778 | 1781 |
1779 __ SetAccumulator(result_var.value()); | 1782 __ SetAccumulator(result_var.value()); |
1780 __ Dispatch(); | 1783 __ Dispatch(); |
(...skipping 12 matching lines...) Expand all Loading... |
1793 Node* slot_index = __ BytecodeOperandIdx(0); | 1796 Node* slot_index = __ BytecodeOperandIdx(0); |
1794 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); | 1797 Node* type_feedback_vector = __ LoadTypeFeedbackVector(); |
1795 | 1798 |
1796 // Shared entry for floating point decrement. | 1799 // Shared entry for floating point decrement. |
1797 Label do_fdec(assembler), end(assembler); | 1800 Label do_fdec(assembler), end(assembler); |
1798 Variable var_fdec_value(assembler, MachineRepresentation::kFloat64); | 1801 Variable var_fdec_value(assembler, MachineRepresentation::kFloat64); |
1799 | 1802 |
1800 // We might need to try again due to ToNumber conversion. | 1803 // We might need to try again due to ToNumber conversion. |
1801 Variable value_var(assembler, MachineRepresentation::kTagged); | 1804 Variable value_var(assembler, MachineRepresentation::kTagged); |
1802 Variable result_var(assembler, MachineRepresentation::kTagged); | 1805 Variable result_var(assembler, MachineRepresentation::kTagged); |
1803 Variable var_type_feedback(assembler, MachineRepresentation::kWord32); | 1806 Variable var_type_feedback(assembler, MachineRepresentation::kTaggedSigned); |
1804 Variable* loop_vars[] = {&value_var, &var_type_feedback}; | 1807 Variable* loop_vars[] = {&value_var, &var_type_feedback}; |
1805 Label start(assembler, 2, loop_vars); | 1808 Label start(assembler, 2, loop_vars); |
1806 var_type_feedback.Bind( | 1809 var_type_feedback.Bind( |
1807 assembler->Int32Constant(BinaryOperationFeedback::kNone)); | 1810 assembler->SmiConstant(BinaryOperationFeedback::kNone)); |
1808 value_var.Bind(value); | 1811 value_var.Bind(value); |
1809 assembler->Goto(&start); | 1812 assembler->Goto(&start); |
1810 assembler->Bind(&start); | 1813 assembler->Bind(&start); |
1811 { | 1814 { |
1812 value = value_var.value(); | 1815 value = value_var.value(); |
1813 | 1816 |
1814 Label if_issmi(assembler), if_isnotsmi(assembler); | 1817 Label if_issmi(assembler), if_isnotsmi(assembler); |
1815 assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi); | 1818 assembler->Branch(assembler->TaggedIsSmi(value), &if_issmi, &if_isnotsmi); |
1816 | 1819 |
1817 assembler->Bind(&if_issmi); | 1820 assembler->Bind(&if_issmi); |
1818 { | 1821 { |
1819 // Try fast Smi subtraction first. | 1822 // Try fast Smi subtraction first. |
1820 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 1823 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
1821 Node* pair = assembler->IntPtrSubWithOverflow( | 1824 Node* pair = assembler->IntPtrSubWithOverflow( |
1822 assembler->BitcastTaggedToWord(value), | 1825 assembler->BitcastTaggedToWord(value), |
1823 assembler->BitcastTaggedToWord(one)); | 1826 assembler->BitcastTaggedToWord(one)); |
1824 Node* overflow = assembler->Projection(1, pair); | 1827 Node* overflow = assembler->Projection(1, pair); |
1825 | 1828 |
1826 // Check if the Smi subtraction overflowed. | 1829 // Check if the Smi subtraction overflowed. |
1827 Label if_overflow(assembler), if_notoverflow(assembler); | 1830 Label if_overflow(assembler), if_notoverflow(assembler); |
1828 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 1831 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
1829 | 1832 |
1830 assembler->Bind(&if_notoverflow); | 1833 assembler->Bind(&if_notoverflow); |
1831 var_type_feedback.Bind(assembler->Word32Or( | 1834 var_type_feedback.Bind(assembler->SmiOr( |
1832 var_type_feedback.value(), | 1835 var_type_feedback.value(), |
1833 assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall))); | 1836 assembler->SmiConstant(BinaryOperationFeedback::kSignedSmall))); |
1834 result_var.Bind( | 1837 result_var.Bind( |
1835 assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair))); | 1838 assembler->BitcastWordToTaggedSigned(assembler->Projection(0, pair))); |
1836 assembler->Goto(&end); | 1839 assembler->Goto(&end); |
1837 | 1840 |
1838 assembler->Bind(&if_overflow); | 1841 assembler->Bind(&if_overflow); |
1839 { | 1842 { |
1840 var_fdec_value.Bind(assembler->SmiToFloat64(value)); | 1843 var_fdec_value.Bind(assembler->SmiToFloat64(value)); |
1841 assembler->Goto(&do_fdec); | 1844 assembler->Goto(&do_fdec); |
1842 } | 1845 } |
1843 } | 1846 } |
(...skipping 13 matching lines...) Expand all Loading... |
1857 var_fdec_value.Bind(assembler->LoadHeapNumberValue(value)); | 1860 var_fdec_value.Bind(assembler->LoadHeapNumberValue(value)); |
1858 assembler->Goto(&do_fdec); | 1861 assembler->Goto(&do_fdec); |
1859 } | 1862 } |
1860 | 1863 |
1861 assembler->Bind(&if_valuenotnumber); | 1864 assembler->Bind(&if_valuenotnumber); |
1862 { | 1865 { |
1863 // We do not require an Or with earlier feedback here because once we | 1866 // We do not require an Or with earlier feedback here because once we |
1864 // convert the value to a number, we cannot reach this path. We can | 1867 // convert the value to a number, we cannot reach this path. We can |
1865 // only reach this path on the first pass when the feedback is kNone. | 1868 // only reach this path on the first pass when the feedback is kNone. |
1866 CSA_ASSERT(assembler, | 1869 CSA_ASSERT(assembler, |
1867 assembler->Word32Equal(var_type_feedback.value(), | 1870 assembler->SmiEqual( |
1868 assembler->Int32Constant( | 1871 var_type_feedback.value(), |
1869 BinaryOperationFeedback::kNone))); | 1872 assembler->SmiConstant(BinaryOperationFeedback::kNone))); |
1870 | 1873 |
1871 Label if_valueisoddball(assembler), if_valuenotoddball(assembler); | 1874 Label if_valueisoddball(assembler), if_valuenotoddball(assembler); |
1872 Node* instance_type = assembler->LoadMapInstanceType(value_map); | 1875 Node* instance_type = assembler->LoadMapInstanceType(value_map); |
1873 Node* is_oddball = assembler->Word32Equal( | 1876 Node* is_oddball = assembler->Word32Equal( |
1874 instance_type, assembler->Int32Constant(ODDBALL_TYPE)); | 1877 instance_type, assembler->Int32Constant(ODDBALL_TYPE)); |
1875 assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball); | 1878 assembler->Branch(is_oddball, &if_valueisoddball, &if_valuenotoddball); |
1876 | 1879 |
1877 assembler->Bind(&if_valueisoddball); | 1880 assembler->Bind(&if_valueisoddball); |
1878 { | 1881 { |
1879 // Convert Oddball to Number and check again. | 1882 // Convert Oddball to Number and check again. |
1880 value_var.Bind( | 1883 value_var.Bind( |
1881 assembler->LoadObjectField(value, Oddball::kToNumberOffset)); | 1884 assembler->LoadObjectField(value, Oddball::kToNumberOffset)); |
1882 var_type_feedback.Bind(assembler->Int32Constant( | 1885 var_type_feedback.Bind(assembler->SmiConstant( |
1883 BinaryOperationFeedback::kNumberOrOddball)); | 1886 BinaryOperationFeedback::kNumberOrOddball)); |
1884 assembler->Goto(&start); | 1887 assembler->Goto(&start); |
1885 } | 1888 } |
1886 | 1889 |
1887 assembler->Bind(&if_valuenotoddball); | 1890 assembler->Bind(&if_valuenotoddball); |
1888 { | 1891 { |
1889 // Convert to a Number first and try again. | 1892 // Convert to a Number first and try again. |
1890 Callable callable = | 1893 Callable callable = |
1891 CodeFactory::NonNumberToNumber(assembler->isolate()); | 1894 CodeFactory::NonNumberToNumber(assembler->isolate()); |
1892 var_type_feedback.Bind( | 1895 var_type_feedback.Bind( |
1893 assembler->Int32Constant(BinaryOperationFeedback::kAny)); | 1896 assembler->SmiConstant(BinaryOperationFeedback::kAny)); |
1894 value_var.Bind(assembler->CallStub(callable, context, value)); | 1897 value_var.Bind(assembler->CallStub(callable, context, value)); |
1895 assembler->Goto(&start); | 1898 assembler->Goto(&start); |
1896 } | 1899 } |
1897 } | 1900 } |
1898 } | 1901 } |
1899 } | 1902 } |
1900 | 1903 |
1901 assembler->Bind(&do_fdec); | 1904 assembler->Bind(&do_fdec); |
1902 { | 1905 { |
1903 Node* fdec_value = var_fdec_value.value(); | 1906 Node* fdec_value = var_fdec_value.value(); |
1904 Node* one = assembler->Float64Constant(1.0); | 1907 Node* one = assembler->Float64Constant(1.0); |
1905 Node* fdec_result = assembler->Float64Sub(fdec_value, one); | 1908 Node* fdec_result = assembler->Float64Sub(fdec_value, one); |
1906 var_type_feedback.Bind(assembler->Word32Or( | 1909 var_type_feedback.Bind(assembler->SmiOr( |
1907 var_type_feedback.value(), | 1910 var_type_feedback.value(), |
1908 assembler->Int32Constant(BinaryOperationFeedback::kNumber))); | 1911 assembler->SmiConstant(BinaryOperationFeedback::kNumber))); |
1909 result_var.Bind(assembler->AllocateHeapNumberWithValue(fdec_result)); | 1912 result_var.Bind(assembler->AllocateHeapNumberWithValue(fdec_result)); |
1910 assembler->Goto(&end); | 1913 assembler->Goto(&end); |
1911 } | 1914 } |
1912 | 1915 |
1913 assembler->Bind(&end); | 1916 assembler->Bind(&end); |
1914 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, | 1917 assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
1915 slot_index); | 1918 slot_index); |
1916 | 1919 |
1917 __ SetAccumulator(result_var.value()); | 1920 __ SetAccumulator(result_var.value()); |
1918 __ Dispatch(); | 1921 __ Dispatch(); |
(...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3251 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 3254 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
3252 __ SmiTag(new_state)); | 3255 __ SmiTag(new_state)); |
3253 __ SetAccumulator(old_state); | 3256 __ SetAccumulator(old_state); |
3254 | 3257 |
3255 __ Dispatch(); | 3258 __ Dispatch(); |
3256 } | 3259 } |
3257 | 3260 |
3258 } // namespace interpreter | 3261 } // namespace interpreter |
3259 } // namespace internal | 3262 } // namespace internal |
3260 } // namespace v8 | 3263 } // namespace v8 |
OLD | NEW |