Chromium Code Reviews| Index: src/code-stubs.cc |
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
| index 14e98beb675af2440b02b66d1ecd5181818bdade..08d8a7233ca591ed1eb98aaa25b6dd8e14aa351f 100644 |
| --- a/src/code-stubs.cc |
| +++ b/src/code-stubs.cc |
| @@ -910,31 +910,42 @@ compiler::Node* AddStub::Generate(CodeStubAssembler* assembler, |
| compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| compiler::Node* left, |
| compiler::Node* right, |
| - compiler::Node* context) { |
| + compiler::Node* context, |
| + compiler::Node* type_feedback_vector, |
| + compiler::Node* slot_id) { |
| typedef CodeStubAssembler::Label Label; |
| typedef compiler::Node Node; |
| typedef CodeStubAssembler::Variable Variable; |
| + bool collect_type_feedback = (type_feedback_vector != NULL); |
| + |
| // Shared entry for floating point subtraction. |
| Label do_fsub(assembler), end(assembler); |
| Variable var_fsub_lhs(assembler, MachineRepresentation::kFloat64), |
| var_fsub_rhs(assembler, MachineRepresentation::kFloat64); |
| + Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
|
Benedikt Meurer
2016/08/08 04:56:13
I'm not sure if this will scale, because
(a) it'l
mythria
2016/08/08 07:17:36
Thanks Benedikt, I add a subtract stub that deals
|
| // We might need to loop several times due to ToPrimitive and/or ToNumber |
| // conversions. |
| Variable var_lhs(assembler, MachineRepresentation::kTagged), |
| var_rhs(assembler, MachineRepresentation::kTagged), |
| var_result(assembler, MachineRepresentation::kTagged); |
| - Variable* loop_vars[2] = {&var_lhs, &var_rhs}; |
| - Label loop(assembler, 2, loop_vars); |
| + Variable* loop_vars[3] = {&var_lhs, &var_rhs, &var_type_feedback}; |
| + Label loop(assembler, 3, loop_vars); |
| var_lhs.Bind(left); |
| var_rhs.Bind(right); |
| + // Start with Smi and keep growing up the lattice. This would avoid |
| + // incorrectly collecting Smi type after the ToNumber conversion. |
| + var_type_feedback.Bind( |
| + assembler->Int32Constant(BinaryOpTypeFeedback::SmiType::encode(1))); |
| assembler->Goto(&loop); |
| + |
| assembler->Bind(&loop); |
| { |
| // Load the current {lhs} and {rhs} values. |
| Node* lhs = var_lhs.value(); |
| Node* rhs = var_rhs.value(); |
| + Node* type_feedback = var_type_feedback.value(); |
| // Check if the {lhs} is a Smi or a HeapObject. |
| Label if_lhsissmi(assembler), if_lhsisnotsmi(assembler); |
| @@ -959,13 +970,23 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_overflow); |
| { |
| + // lhs, rhs - smi and result - number. combined - number. |
| // The result doesn't fit into Smi range. |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::NumberType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); |
| var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
| assembler->Goto(&do_fsub); |
| } |
| assembler->Bind(&if_notoverflow); |
| + // lhs, rhs, result smi. combined - smi. |
| + Node* smi_feedback = |
| + assembler->Int32Constant(BinaryOpTypeFeedback::SmiType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, smi_feedback)); |
| var_result.Bind(assembler->Projection(0, pair)); |
| assembler->Goto(&end); |
| } |
| @@ -984,6 +1005,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_rhsisnumber); |
| { |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::NumberType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Perform a floating point subtraction. |
| var_fsub_lhs.Bind(assembler->SmiToFloat64(lhs)); |
| var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
| @@ -992,6 +1017,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_rhsisnotnumber); |
| { |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::AnyType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Convert the {rhs} to a Number first. |
| Callable callable = |
| CodeFactory::NonNumberToNumber(assembler->isolate()); |
| @@ -1022,6 +1051,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_rhsissmi); |
| { |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::NumberType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Perform a floating point subtraction. |
| var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
| var_fsub_rhs.Bind(assembler->SmiToFloat64(rhs)); |
| @@ -1041,6 +1074,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_rhsisnumber); |
| { |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::NumberType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Perform a floating point subtraction. |
| var_fsub_lhs.Bind(assembler->LoadHeapNumberValue(lhs)); |
| var_fsub_rhs.Bind(assembler->LoadHeapNumberValue(rhs)); |
| @@ -1049,6 +1086,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_rhsisnotnumber); |
| { |
| + Node* current_feedback = assembler->Int32Constant( |
| + BinaryOpTypeFeedback::AnyType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Convert the {rhs} to a Number first. |
| Callable callable = |
| CodeFactory::NonNumberToNumber(assembler->isolate()); |
| @@ -1060,6 +1101,10 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| assembler->Bind(&if_lhsisnotnumber); |
| { |
| + Node* current_feedback = |
| + assembler->Int32Constant(BinaryOpTypeFeedback::AnyType::encode(1)); |
| + var_type_feedback.Bind( |
| + assembler->Word32Or(type_feedback, current_feedback)); |
| // Convert the {lhs} to a Number first. |
| Callable callable = |
| CodeFactory::NonNumberToNumber(assembler->isolate()); |
| @@ -1077,7 +1122,22 @@ compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
| var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
| assembler->Goto(&end); |
| } |
| + |
| assembler->Bind(&end); |
| + if (collect_type_feedback) { |
| + // Combine the current type with previous feedback and store it into the |
| + // feedback slot. |
| + Node* previous_feedback_smi = |
| + assembler->LoadFixedArrayElement(type_feedback_vector, slot_id); |
| + // TODO(mythria): Add a DCHECK to verify the loaded value is an Smi. |
| + // ASSERT (WordIsSmi(previous_feedback)); |
| + Node* previous_feedback = assembler->SmiUntag(previous_feedback_smi); |
| + Node* combined_feedback = |
| + assembler->Word32Or(previous_feedback, var_type_feedback.value()); |
| + assembler->StoreFixedArrayElement(type_feedback_vector, slot_id, |
| + assembler->SmiTag(combined_feedback), |
| + SKIP_WRITE_BARRIER); |
| + } |
| return var_result.value(); |
| } |