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-assembler.h" | 5 #include "src/interpreter/interpreter-assembler.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <ostream> | 8 #include <ostream> |
9 | 9 |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 } | 1053 } |
1054 | 1054 |
1055 Node* InterpreterAssembler::TruncateTaggedToWord32WithFeedback( | 1055 Node* InterpreterAssembler::TruncateTaggedToWord32WithFeedback( |
1056 Node* context, Node* value, Variable* var_type_feedback) { | 1056 Node* context, Node* value, Variable* var_type_feedback) { |
1057 // We might need to loop once due to ToNumber conversion. | 1057 // We might need to loop once due to ToNumber conversion. |
1058 Variable var_value(this, MachineRepresentation::kTagged), | 1058 Variable var_value(this, MachineRepresentation::kTagged), |
1059 var_result(this, MachineRepresentation::kWord32); | 1059 var_result(this, MachineRepresentation::kWord32); |
1060 Variable* loop_vars[] = {&var_value, var_type_feedback}; | 1060 Variable* loop_vars[] = {&var_value, var_type_feedback}; |
1061 Label loop(this, 2, loop_vars), done_loop(this, &var_result); | 1061 Label loop(this, 2, loop_vars), done_loop(this, &var_result); |
1062 var_value.Bind(value); | 1062 var_value.Bind(value); |
1063 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kNone)); | 1063 var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNone)); |
1064 Goto(&loop); | 1064 Goto(&loop); |
1065 Bind(&loop); | 1065 Bind(&loop); |
1066 { | 1066 { |
1067 // Load the current {value}. | 1067 // Load the current {value}. |
1068 value = var_value.value(); | 1068 value = var_value.value(); |
1069 | 1069 |
1070 // Check if the {value} is a Smi or a HeapObject. | 1070 // Check if the {value} is a Smi or a HeapObject. |
1071 Label if_valueissmi(this), if_valueisnotsmi(this); | 1071 Label if_valueissmi(this), if_valueisnotsmi(this); |
1072 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 1072 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
1073 | 1073 |
1074 Bind(&if_valueissmi); | 1074 Bind(&if_valueissmi); |
1075 { | 1075 { |
1076 // Convert the Smi {value}. | 1076 // Convert the Smi {value}. |
1077 var_result.Bind(SmiToWord32(value)); | 1077 var_result.Bind(SmiToWord32(value)); |
1078 var_type_feedback->Bind( | 1078 var_type_feedback->Bind( |
1079 Word32Or(var_type_feedback->value(), | 1079 SmiOr(var_type_feedback->value(), |
1080 Int32Constant(BinaryOperationFeedback::kSignedSmall))); | 1080 SmiConstant(BinaryOperationFeedback::kSignedSmall))); |
1081 Goto(&done_loop); | 1081 Goto(&done_loop); |
1082 } | 1082 } |
1083 | 1083 |
1084 Bind(&if_valueisnotsmi); | 1084 Bind(&if_valueisnotsmi); |
1085 { | 1085 { |
1086 // Check if {value} is a HeapNumber. | 1086 // Check if {value} is a HeapNumber. |
1087 Label if_valueisheapnumber(this), | 1087 Label if_valueisheapnumber(this), |
1088 if_valueisnotheapnumber(this, Label::kDeferred); | 1088 if_valueisnotheapnumber(this, Label::kDeferred); |
1089 Node* value_map = LoadMap(value); | 1089 Node* value_map = LoadMap(value); |
1090 Branch(IsHeapNumberMap(value_map), &if_valueisheapnumber, | 1090 Branch(IsHeapNumberMap(value_map), &if_valueisheapnumber, |
1091 &if_valueisnotheapnumber); | 1091 &if_valueisnotheapnumber); |
1092 | 1092 |
1093 Bind(&if_valueisheapnumber); | 1093 Bind(&if_valueisheapnumber); |
1094 { | 1094 { |
1095 // Truncate the floating point value. | 1095 // Truncate the floating point value. |
1096 var_result.Bind(TruncateHeapNumberValueToWord32(value)); | 1096 var_result.Bind(TruncateHeapNumberValueToWord32(value)); |
1097 var_type_feedback->Bind( | 1097 var_type_feedback->Bind( |
1098 Word32Or(var_type_feedback->value(), | 1098 SmiOr(var_type_feedback->value(), |
1099 Int32Constant(BinaryOperationFeedback::kNumber))); | 1099 SmiConstant(BinaryOperationFeedback::kNumber))); |
1100 Goto(&done_loop); | 1100 Goto(&done_loop); |
1101 } | 1101 } |
1102 | 1102 |
1103 Bind(&if_valueisnotheapnumber); | 1103 Bind(&if_valueisnotheapnumber); |
1104 { | 1104 { |
1105 // We do not require an Or with earlier feedback here because once we | 1105 // We do not require an Or with earlier feedback here because once we |
1106 // convert the value to a number, we cannot reach this path. We can | 1106 // convert the value to a number, we cannot reach this path. We can |
1107 // only reach this path on the first pass when the feedback is kNone. | 1107 // only reach this path on the first pass when the feedback is kNone. |
1108 CSA_ASSERT(this, | 1108 CSA_ASSERT(this, SmiEqual(var_type_feedback->value(), |
1109 Word32Equal(var_type_feedback->value(), | 1109 SmiConstant(BinaryOperationFeedback::kNone))); |
1110 Int32Constant(BinaryOperationFeedback::kNone))); | |
1111 | 1110 |
1112 Label if_valueisoddball(this), | 1111 Label if_valueisoddball(this), |
1113 if_valueisnotoddball(this, Label::kDeferred); | 1112 if_valueisnotoddball(this, Label::kDeferred); |
1114 Node* is_oddball = Word32Equal(LoadMapInstanceType(value_map), | 1113 Node* is_oddball = Word32Equal(LoadMapInstanceType(value_map), |
1115 Int32Constant(ODDBALL_TYPE)); | 1114 Int32Constant(ODDBALL_TYPE)); |
1116 Branch(is_oddball, &if_valueisoddball, &if_valueisnotoddball); | 1115 Branch(is_oddball, &if_valueisoddball, &if_valueisnotoddball); |
1117 | 1116 |
1118 Bind(&if_valueisoddball); | 1117 Bind(&if_valueisoddball); |
1119 { | 1118 { |
1120 // Convert Oddball to a Number and perform checks again. | 1119 // Convert Oddball to a Number and perform checks again. |
1121 var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); | 1120 var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); |
1122 var_type_feedback->Bind( | 1121 var_type_feedback->Bind( |
1123 Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); | 1122 SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); |
1124 Goto(&loop); | 1123 Goto(&loop); |
1125 } | 1124 } |
1126 | 1125 |
1127 Bind(&if_valueisnotoddball); | 1126 Bind(&if_valueisnotoddball); |
1128 { | 1127 { |
1129 // Convert the {value} to a Number first. | 1128 // Convert the {value} to a Number first. |
1130 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | 1129 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
1131 var_value.Bind(CallStub(callable, context, value)); | 1130 var_value.Bind(CallStub(callable, context, value)); |
1132 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kAny)); | 1131 var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kAny)); |
1133 Goto(&loop); | 1132 Goto(&loop); |
1134 } | 1133 } |
1135 } | 1134 } |
1136 } | 1135 } |
1137 } | 1136 } |
1138 Bind(&done_loop); | 1137 Bind(&done_loop); |
1139 return var_result.value(); | 1138 return var_result.value(); |
1140 } | 1139 } |
1141 | 1140 |
1142 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { | 1141 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 Goto(&loop); | 1303 Goto(&loop); |
1305 } | 1304 } |
1306 Bind(&done_loop); | 1305 Bind(&done_loop); |
1307 | 1306 |
1308 return array; | 1307 return array; |
1309 } | 1308 } |
1310 | 1309 |
1311 } // namespace interpreter | 1310 } // namespace interpreter |
1312 } // namespace internal | 1311 } // namespace internal |
1313 } // namespace v8 | 1312 } // namespace v8 |
OLD | NEW |