Index: src/interpreter/interpreter.cc |
diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc |
index 9128ee984039c764d20e4c34ae3a762f0c143829..635844b6b3d6422753fd7f4f7db41416aa38d4d4 100644 |
--- a/src/interpreter/interpreter.cc |
+++ b/src/interpreter/interpreter.cc |
@@ -995,62 +995,91 @@ void Interpreter::DoCompareOpWithFeedback(Token::Value compare_op, |
// sometimes emit comparisons that shouldn't collect feedback (e.g. |
// try-finally blocks and generators), and we could get rid of this by |
// introducing Smi equality tests. |
- Label skip_feedback_update(assembler); |
- __ GotoIf(__ WordEqual(slot_index, __ IntPtrConstant(0)), |
- &skip_feedback_update); |
+ Label gather_type_feedback(assembler), do_compare(assembler); |
+ __ Branch(__ WordEqual(slot_index, __ IntPtrConstant(0)), &do_compare, |
+ &gather_type_feedback); |
- Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
- Label lhs_is_smi(assembler), lhs_is_not_smi(assembler), |
- gather_rhs_type(assembler), do_compare(assembler); |
- __ Branch(__ TaggedIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
- |
- __ Bind(&lhs_is_smi); |
- var_type_feedback.Bind( |
- __ Int32Constant(CompareOperationFeedback::kSignedSmall)); |
- __ Goto(&gather_rhs_type); |
- |
- __ Bind(&lhs_is_not_smi); |
+ __ Bind(&gather_type_feedback); |
{ |
- Label lhs_is_number(assembler), lhs_is_not_number(assembler); |
- Node* lhs_map = __ LoadMap(lhs); |
- __ Branch(__ WordEqual(lhs_map, __ HeapNumberMapConstant()), &lhs_is_number, |
- &lhs_is_not_number); |
+ Variable var_type_feedback(assembler, MachineRepresentation::kWord32); |
+ Label lhs_is_not_smi(assembler), lhs_is_not_number(assembler), |
+ lhs_is_not_string(assembler), gather_rhs_type(assembler), |
+ update_feedback(assembler); |
+ |
+ __ GotoUnless(__ TaggedIsSmi(lhs), &lhs_is_not_smi); |
- __ Bind(&lhs_is_number); |
- var_type_feedback.Bind(__ Int32Constant(CompareOperationFeedback::kNumber)); |
+ var_type_feedback.Bind( |
+ __ Int32Constant(CompareOperationFeedback::kSignedSmall)); |
__ Goto(&gather_rhs_type); |
- __ Bind(&lhs_is_not_number); |
- var_type_feedback.Bind(__ Int32Constant(CompareOperationFeedback::kAny)); |
- __ Goto(&do_compare); |
- } |
+ __ Bind(&lhs_is_not_smi); |
+ { |
+ Node* lhs_map = __ LoadMap(lhs); |
+ __ GotoUnless(__ WordEqual(lhs_map, __ HeapNumberMapConstant()), |
+ &lhs_is_not_number); |
+ |
+ var_type_feedback.Bind( |
+ __ Int32Constant(CompareOperationFeedback::kNumber)); |
+ __ Goto(&gather_rhs_type); |
+ |
+ __ Bind(&lhs_is_not_number); |
+ { |
+ Node* lhs_instance_type = __ LoadInstanceType(lhs); |
+ Node* lhs_type = |
+ __ Select(__ IsStringInstanceType(lhs_instance_type), |
+ __ Int32Constant(CompareOperationFeedback::kString), |
+ __ Int32Constant(CompareOperationFeedback::kAny)); |
+ |
+ var_type_feedback.Bind(lhs_type); |
+ __ Goto(&gather_rhs_type); |
+ } |
+ } |
- __ Bind(&gather_rhs_type); |
- { |
- Label rhs_is_smi(assembler); |
- __ GotoIf(__ TaggedIsSmi(rhs), &rhs_is_smi); |
- |
- Node* rhs_map = __ LoadMap(rhs); |
- Node* rhs_type = |
- __ Select(__ WordEqual(rhs_map, __ HeapNumberMapConstant()), |
- __ Int32Constant(CompareOperationFeedback::kNumber), |
- __ Int32Constant(CompareOperationFeedback::kAny)); |
- var_type_feedback.Bind(__ Word32Or(var_type_feedback.value(), rhs_type)); |
- __ Goto(&do_compare); |
- |
- __ Bind(&rhs_is_smi); |
- var_type_feedback.Bind( |
- __ Word32Or(var_type_feedback.value(), |
- __ Int32Constant(CompareOperationFeedback::kSignedSmall))); |
- __ Goto(&do_compare); |
+ __ Bind(&gather_rhs_type); |
+ { |
+ Label rhs_is_not_smi(assembler), rhs_is_not_number(assembler); |
+ |
+ __ GotoUnless(__ TaggedIsSmi(rhs), &rhs_is_not_smi); |
+ |
+ var_type_feedback.Bind(__ Word32Or( |
+ var_type_feedback.value(), |
+ __ Int32Constant(CompareOperationFeedback::kSignedSmall))); |
+ __ Goto(&update_feedback); |
+ |
+ __ Bind(&rhs_is_not_smi); |
+ { |
+ Node* rhs_map = __ LoadMap(rhs); |
+ __ GotoUnless(__ WordEqual(rhs_map, __ HeapNumberMapConstant()), |
+ &rhs_is_not_number); |
+ |
+ var_type_feedback.Bind( |
+ __ Word32Or(var_type_feedback.value(), |
+ __ Int32Constant(CompareOperationFeedback::kNumber))); |
+ __ Goto(&update_feedback); |
+ |
+ __ Bind(&rhs_is_not_number); |
+ { |
+ Node* rhs_instance_type = __ LoadInstanceType(rhs); |
+ Node* rhs_type = |
+ __ Select(__ IsStringInstanceType(rhs_instance_type), |
+ __ Int32Constant(CompareOperationFeedback::kString), |
+ __ Int32Constant(CompareOperationFeedback::kAny)); |
+ var_type_feedback.Bind( |
+ __ Word32Or(var_type_feedback.value(), rhs_type)); |
+ __ Goto(&update_feedback); |
+ } |
+ } |
+ } |
+ |
+ __ Bind(&update_feedback); |
+ { |
+ __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
+ slot_index); |
+ __ Goto(&do_compare); |
+ } |
} |
__ Bind(&do_compare); |
- __ UpdateFeedback(var_type_feedback.value(), type_feedback_vector, |
- slot_index); |
- __ Goto(&skip_feedback_update); |
- |
- __ Bind(&skip_feedback_update); |
Node* result; |
switch (compare_op) { |
case Token::EQ: |