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 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 Word32Or(var_type_feedback->value(), | 1171 Word32Or(var_type_feedback->value(), |
1172 Int32Constant(BinaryOperationFeedback::kSignedSmall))); | 1172 Int32Constant(BinaryOperationFeedback::kSignedSmall))); |
1173 Goto(&done_loop); | 1173 Goto(&done_loop); |
1174 } | 1174 } |
1175 | 1175 |
1176 Bind(&if_valueisnotsmi); | 1176 Bind(&if_valueisnotsmi); |
1177 { | 1177 { |
1178 // Check if {value} is a HeapNumber. | 1178 // Check if {value} is a HeapNumber. |
1179 Label if_valueisheapnumber(this), | 1179 Label if_valueisheapnumber(this), |
1180 if_valueisnotheapnumber(this, Label::kDeferred); | 1180 if_valueisnotheapnumber(this, Label::kDeferred); |
1181 Branch(WordEqual(LoadMap(value), HeapNumberMapConstant()), | 1181 Node* value_map = LoadMap(value); |
| 1182 Branch(WordEqual(value_map, HeapNumberMapConstant()), |
1182 &if_valueisheapnumber, &if_valueisnotheapnumber); | 1183 &if_valueisheapnumber, &if_valueisnotheapnumber); |
1183 | 1184 |
1184 Bind(&if_valueisheapnumber); | 1185 Bind(&if_valueisheapnumber); |
1185 { | 1186 { |
1186 // Truncate the floating point value. | 1187 // Truncate the floating point value. |
1187 var_result.Bind(TruncateHeapNumberValueToWord32(value)); | 1188 var_result.Bind(TruncateHeapNumberValueToWord32(value)); |
1188 var_type_feedback->Bind( | 1189 var_type_feedback->Bind( |
1189 Word32Or(var_type_feedback->value(), | 1190 Word32Or(var_type_feedback->value(), |
1190 Int32Constant(BinaryOperationFeedback::kNumber))); | 1191 Int32Constant(BinaryOperationFeedback::kNumber))); |
1191 Goto(&done_loop); | 1192 Goto(&done_loop); |
1192 } | 1193 } |
1193 | 1194 |
1194 Bind(&if_valueisnotheapnumber); | 1195 Bind(&if_valueisnotheapnumber); |
1195 { | 1196 { |
1196 // Convert the {value} to a Number first. | 1197 Label if_valueisoddball(this), |
1197 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | 1198 if_valueisnotoddball(this, Label::kDeferred); |
1198 var_value.Bind(CallStub(callable, context, value)); | 1199 Node* is_oddball = Word32Equal(LoadMapInstanceType(value_map), |
1199 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kAny)); | 1200 Int32Constant(ODDBALL_TYPE)); |
1200 Goto(&loop); | 1201 Branch(is_oddball, &if_valueisoddball, &if_valueisnotoddball); |
| 1202 |
| 1203 Bind(&if_valueisoddball); |
| 1204 { |
| 1205 // Convert Oddball to a Number and perform checks again. |
| 1206 var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); |
| 1207 // We do not require an Or with earlier feedback here because once we |
| 1208 // convert the value to a number, we cannot reach this path. We can |
| 1209 // only reach this path on the first pass. |
| 1210 var_type_feedback->Bind( |
| 1211 Int32Constant(BinaryOperationFeedback::kNumberOrOddball)); |
| 1212 Goto(&loop); |
| 1213 } |
| 1214 |
| 1215 Bind(&if_valueisnotoddball); |
| 1216 { |
| 1217 // Convert the {value} to a Number first. |
| 1218 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
| 1219 var_value.Bind(CallStub(callable, context, value)); |
| 1220 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kAny)); |
| 1221 Goto(&loop); |
| 1222 } |
1201 } | 1223 } |
1202 } | 1224 } |
1203 } | 1225 } |
1204 Bind(&done_loop); | 1226 Bind(&done_loop); |
1205 return var_result.value(); | 1227 return var_result.value(); |
1206 } | 1228 } |
1207 | 1229 |
1208 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { | 1230 void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { |
1209 // TODO(rmcilroy): Investigate whether it is worth supporting self | 1231 // TODO(rmcilroy): Investigate whether it is worth supporting self |
1210 // optimization of primitive functions like FullCodegen. | 1232 // optimization of primitive functions like FullCodegen. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 Goto(&loop); | 1393 Goto(&loop); |
1372 } | 1394 } |
1373 Bind(&done_loop); | 1395 Bind(&done_loop); |
1374 | 1396 |
1375 return array; | 1397 return array; |
1376 } | 1398 } |
1377 | 1399 |
1378 } // namespace interpreter | 1400 } // namespace interpreter |
1379 } // namespace internal | 1401 } // namespace internal |
1380 } // namespace v8 | 1402 } // namespace v8 |
OLD | NEW |