Index: src/interpreter/interpreter-assembler.cc |
diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc |
index b195d5860af5d172ee53888be0d443817a52c89d..e4d26937d9ecc02775485c40b6fcc16509e63687 100644 |
--- a/src/interpreter/interpreter-assembler.cc |
+++ b/src/interpreter/interpreter-assembler.cc |
@@ -845,6 +845,67 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { |
DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset); |
} |
+Node* InterpreterAssembler::TruncateTaggedToWord32WithFeedback( |
+ Node* context, Node* value, Variable* var_type_feedback) { |
+ // We might need to loop once due to ToNumber conversion. |
+ Variable var_value(this, MachineRepresentation::kTagged), |
+ var_result(this, MachineRepresentation::kWord32); |
+ Variable* loop_vars[] = {&var_value, var_type_feedback}; |
+ Label loop(this, 2, loop_vars), done_loop(this, &var_result); |
+ var_value.Bind(value); |
+ var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kNone)); |
+ Goto(&loop); |
+ Bind(&loop); |
+ { |
+ // Load the current {value}. |
+ value = var_value.value(); |
+ |
+ // Check if the {value} is a Smi or a HeapObject. |
+ Label if_valueissmi(this), if_valueisnotsmi(this); |
+ Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
+ |
+ Bind(&if_valueissmi); |
+ { |
+ // Convert the Smi {value}. |
+ var_result.Bind(SmiToWord32(value)); |
+ var_type_feedback->Bind( |
+ Word32And(var_type_feedback->value(), |
+ Int32Constant(BinaryOperationFeedback::kSignedSmall))); |
+ Goto(&done_loop); |
+ } |
+ |
+ Bind(&if_valueisnotsmi); |
+ { |
+ // Check if {value} is a HeapNumber. |
+ Label if_valueisheapnumber(this), |
+ if_valueisnotheapnumber(this, Label::kDeferred); |
+ Branch(WordEqual(LoadMap(value), HeapNumberMapConstant()), |
+ &if_valueisheapnumber, &if_valueisnotheapnumber); |
+ |
+ Bind(&if_valueisheapnumber); |
+ { |
+ // Truncate the floating point value. |
+ var_result.Bind(TruncateHeapNumberValueToWord32(value)); |
+ var_type_feedback->Bind( |
+ Word32Or(var_type_feedback->value(), |
+ Int32Constant(BinaryOperationFeedback::kNumber))); |
+ Goto(&done_loop); |
+ } |
+ |
+ Bind(&if_valueisnotheapnumber); |
+ { |
+ // Convert the {value} to a Number first. |
+ Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
+ var_value.Bind(CallStub(callable, context, value)); |
+ var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kAny)); |
+ Goto(&loop); |
+ } |
+ } |
+ } |
+ Bind(&done_loop); |
+ return var_result.value(); |
+} |
+ |
void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { |
// TODO(rmcilroy): Investigate whether it is worth supporting self |
// optimization of primitive functions like FullCodegen. |