| 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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 // The checks. First, does function match the recorded monomorphic target? | 578 // The checks. First, does function match the recorded monomorphic target? |
| 579 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); | 579 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); |
| 580 Node* feedback_value = LoadWeakCellValue(feedback_element); | 580 Node* feedback_value = LoadWeakCellValue(feedback_element); |
| 581 Node* is_monomorphic = WordEqual(function, feedback_value); | 581 Node* is_monomorphic = WordEqual(function, feedback_value); |
| 582 BranchIf(is_monomorphic, &handle_monomorphic, &extra_checks); | 582 BranchIf(is_monomorphic, &handle_monomorphic, &extra_checks); |
| 583 | 583 |
| 584 Bind(&handle_monomorphic); | 584 Bind(&handle_monomorphic); |
| 585 { | 585 { |
| 586 // The compare above could have been a SMI/SMI comparison. Guard against | 586 // The compare above could have been a SMI/SMI comparison. Guard against |
| 587 // this convincing us that we have a monomorphic JSFunction. | 587 // this convincing us that we have a monomorphic JSFunction. |
| 588 Node* is_smi = WordIsSmi(function); | 588 Node* is_smi = TaggedIsSmi(function); |
| 589 GotoIf(is_smi, &extra_checks); | 589 GotoIf(is_smi, &extra_checks); |
| 590 | 590 |
| 591 // Increment the call count. | 591 // Increment the call count. |
| 592 IncrementCallCount(type_feedback_vector, slot_id); | 592 IncrementCallCount(type_feedback_vector, slot_id); |
| 593 | 593 |
| 594 // Call using call function builtin. | 594 // Call using call function builtin. |
| 595 Callable callable = CodeFactory::InterpreterPushArgsAndCall( | 595 Callable callable = CodeFactory::InterpreterPushArgsAndCall( |
| 596 isolate(), tail_call_mode, CallableType::kJSFunction); | 596 isolate(), tail_call_mode, CallableType::kJSFunction); |
| 597 Node* code_target = HeapConstant(callable.code()); | 597 Node* code_target = HeapConstant(callable.code()); |
| 598 Node* ret_value = CallStub(callable.descriptor(), code_target, context, | 598 Node* ret_value = CallStub(callable.descriptor(), code_target, context, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 | 642 |
| 643 Bind(&check_initialized); | 643 Bind(&check_initialized); |
| 644 { | 644 { |
| 645 Label possibly_monomorphic(this); | 645 Label possibly_monomorphic(this); |
| 646 // Check if it is uninitialized. | 646 // Check if it is uninitialized. |
| 647 Node* is_uninitialized = WordEqual( | 647 Node* is_uninitialized = WordEqual( |
| 648 feedback_element, | 648 feedback_element, |
| 649 HeapConstant(TypeFeedbackVector::UninitializedSentinel(isolate()))); | 649 HeapConstant(TypeFeedbackVector::UninitializedSentinel(isolate()))); |
| 650 GotoUnless(is_uninitialized, &mark_megamorphic); | 650 GotoUnless(is_uninitialized, &mark_megamorphic); |
| 651 | 651 |
| 652 Node* is_smi = WordIsSmi(function); | 652 Node* is_smi = TaggedIsSmi(function); |
| 653 GotoIf(is_smi, &mark_megamorphic); | 653 GotoIf(is_smi, &mark_megamorphic); |
| 654 | 654 |
| 655 // Check if function is an object of JSFunction type | 655 // Check if function is an object of JSFunction type |
| 656 Node* instance_type = LoadInstanceType(function); | 656 Node* instance_type = LoadInstanceType(function); |
| 657 Node* is_js_function = | 657 Node* is_js_function = |
| 658 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); | 658 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); |
| 659 GotoUnless(is_js_function, &mark_megamorphic); | 659 GotoUnless(is_js_function, &mark_megamorphic); |
| 660 | 660 |
| 661 // Check if it is the Array() function. | 661 // Check if it is the Array() function. |
| 662 Node* context_slot = | 662 Node* context_slot = |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 Variable return_value(this, MachineRepresentation::kTagged); | 767 Variable return_value(this, MachineRepresentation::kTagged); |
| 768 Variable allocation_feedback(this, MachineRepresentation::kTagged); | 768 Variable allocation_feedback(this, MachineRepresentation::kTagged); |
| 769 allocation_feedback.Bind(UndefinedConstant()); | 769 allocation_feedback.Bind(UndefinedConstant()); |
| 770 | 770 |
| 771 // Slot id of 0 is used to indicate no type feedback is available. | 771 // Slot id of 0 is used to indicate no type feedback is available. |
| 772 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); | 772 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); |
| 773 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); | 773 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); |
| 774 GotoIf(is_feedback_unavailable, &call_construct); | 774 GotoIf(is_feedback_unavailable, &call_construct); |
| 775 | 775 |
| 776 // Check that the constructor is not a smi. | 776 // Check that the constructor is not a smi. |
| 777 Node* is_smi = WordIsSmi(constructor); | 777 Node* is_smi = TaggedIsSmi(constructor); |
| 778 GotoIf(is_smi, &call_construct); | 778 GotoIf(is_smi, &call_construct); |
| 779 | 779 |
| 780 // Check that constructor is a JSFunction. | 780 // Check that constructor is a JSFunction. |
| 781 Node* instance_type = LoadInstanceType(constructor); | 781 Node* instance_type = LoadInstanceType(constructor); |
| 782 Node* is_js_function = | 782 Node* is_js_function = |
| 783 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); | 783 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); |
| 784 BranchIf(is_js_function, &js_function, &call_construct); | 784 BranchIf(is_js_function, &js_function, &call_construct); |
| 785 | 785 |
| 786 Bind(&js_function); | 786 Bind(&js_function); |
| 787 { | 787 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 811 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); | 811 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); |
| 812 GotoIf(is_megamorphic, &call_construct_function); | 812 GotoIf(is_megamorphic, &call_construct_function); |
| 813 | 813 |
| 814 Comment("check if weak cell"); | 814 Comment("check if weak cell"); |
| 815 Node* is_weak_cell = WordEqual(LoadMap(feedback_element), | 815 Node* is_weak_cell = WordEqual(LoadMap(feedback_element), |
| 816 LoadRoot(Heap::kWeakCellMapRootIndex)); | 816 LoadRoot(Heap::kWeakCellMapRootIndex)); |
| 817 GotoUnless(is_weak_cell, &check_allocation_site); | 817 GotoUnless(is_weak_cell, &check_allocation_site); |
| 818 // If the weak cell is cleared, we have a new chance to become | 818 // If the weak cell is cleared, we have a new chance to become |
| 819 // monomorphic. | 819 // monomorphic. |
| 820 Comment("check if weak cell is cleared"); | 820 Comment("check if weak cell is cleared"); |
| 821 Node* is_smi = WordIsSmi(feedback_value); | 821 Node* is_smi = TaggedIsSmi(feedback_value); |
| 822 BranchIf(is_smi, &initialize, &mark_megamorphic); | 822 BranchIf(is_smi, &initialize, &mark_megamorphic); |
| 823 } | 823 } |
| 824 | 824 |
| 825 Bind(&check_allocation_site); | 825 Bind(&check_allocation_site); |
| 826 { | 826 { |
| 827 Comment("check if it is an allocation site"); | 827 Comment("check if it is an allocation site"); |
| 828 Node* is_allocation_site = | 828 Node* is_allocation_site = |
| 829 WordEqual(LoadObjectField(feedback_element, 0), | 829 WordEqual(LoadObjectField(feedback_element, 0), |
| 830 LoadRoot(Heap::kAllocationSiteMapRootIndex)); | 830 LoadRoot(Heap::kAllocationSiteMapRootIndex)); |
| 831 GotoUnless(is_allocation_site, &check_initialized); | 831 GotoUnless(is_allocation_site, &check_initialized); |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 var_value.Bind(value); | 1154 var_value.Bind(value); |
| 1155 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kNone)); | 1155 var_type_feedback->Bind(Int32Constant(BinaryOperationFeedback::kNone)); |
| 1156 Goto(&loop); | 1156 Goto(&loop); |
| 1157 Bind(&loop); | 1157 Bind(&loop); |
| 1158 { | 1158 { |
| 1159 // Load the current {value}. | 1159 // Load the current {value}. |
| 1160 value = var_value.value(); | 1160 value = var_value.value(); |
| 1161 | 1161 |
| 1162 // Check if the {value} is a Smi or a HeapObject. | 1162 // Check if the {value} is a Smi or a HeapObject. |
| 1163 Label if_valueissmi(this), if_valueisnotsmi(this); | 1163 Label if_valueissmi(this), if_valueisnotsmi(this); |
| 1164 Branch(WordIsSmi(value), &if_valueissmi, &if_valueisnotsmi); | 1164 Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); |
| 1165 | 1165 |
| 1166 Bind(&if_valueissmi); | 1166 Bind(&if_valueissmi); |
| 1167 { | 1167 { |
| 1168 // Convert the Smi {value}. | 1168 // Convert the Smi {value}. |
| 1169 var_result.Bind(SmiToWord32(value)); | 1169 var_result.Bind(SmiToWord32(value)); |
| 1170 var_type_feedback->Bind( | 1170 var_type_feedback->Bind( |
| 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 } |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 Goto(&loop); | 1371 Goto(&loop); |
| 1372 } | 1372 } |
| 1373 Bind(&done_loop); | 1373 Bind(&done_loop); |
| 1374 | 1374 |
| 1375 return array; | 1375 return array; |
| 1376 } | 1376 } |
| 1377 | 1377 |
| 1378 } // namespace interpreter | 1378 } // namespace interpreter |
| 1379 } // namespace internal | 1379 } // namespace internal |
| 1380 } // namespace v8 | 1380 } // namespace v8 |
| OLD | NEW |