| 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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 // computed, meaning that it can't appear to be a pointer. If the low bit is | 560 // computed, meaning that it can't appear to be a pointer. If the low bit is |
| 561 // 0, then hash is computed, but the 0 bit prevents the field from appearing | 561 // 0, then hash is computed, but the 0 bit prevents the field from appearing |
| 562 // to be a pointer. | 562 // to be a pointer. |
| 563 STATIC_ASSERT(WeakCell::kSize >= kPointerSize); | 563 STATIC_ASSERT(WeakCell::kSize >= kPointerSize); |
| 564 STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == | 564 STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == |
| 565 WeakCell::kValueOffset && | 565 WeakCell::kValueOffset && |
| 566 WeakCell::kValueOffset == Symbol::kHashFieldSlot); | 566 WeakCell::kValueOffset == Symbol::kHashFieldSlot); |
| 567 | 567 |
| 568 Variable return_value(this, MachineRepresentation::kTagged); | 568 Variable return_value(this, MachineRepresentation::kTagged); |
| 569 Label handle_monomorphic(this), extra_checks(this), end(this), call(this), | 569 Label handle_monomorphic(this), extra_checks(this), end(this), call(this), |
| 570 call_function(this), call_without_feedback(this); | 570 call_function(this); |
| 571 | |
| 572 // Slot id of 0 is used to indicate no typefeedback is available. Call using | |
| 573 // call builtin. | |
| 574 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); | |
| 575 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); | |
| 576 GotoIf(is_feedback_unavailable, &call_without_feedback); | |
| 577 | 571 |
| 578 // The checks. First, does function match the recorded monomorphic target? | 572 // The checks. First, does function match the recorded monomorphic target? |
| 579 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); | 573 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); |
| 580 Node* feedback_value = LoadWeakCellValue(feedback_element); | 574 Node* feedback_value = LoadWeakCellValue(feedback_element); |
| 581 Node* is_monomorphic = WordEqual(function, feedback_value); | 575 Node* is_monomorphic = WordEqual(function, feedback_value); |
| 582 BranchIf(is_monomorphic, &handle_monomorphic, &extra_checks); | 576 BranchIf(is_monomorphic, &handle_monomorphic, &extra_checks); |
| 583 | 577 |
| 584 Bind(&handle_monomorphic); | 578 Bind(&handle_monomorphic); |
| 585 { | 579 { |
| 586 // The compare above could have been a SMI/SMI comparison. Guard against | 580 // The compare above could have been a SMI/SMI comparison. Guard against |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 // Call using call builtin. | 720 // Call using call builtin. |
| 727 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( | 721 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( |
| 728 isolate(), tail_call_mode, CallableType::kAny); | 722 isolate(), tail_call_mode, CallableType::kAny); |
| 729 Node* code_target_call = HeapConstant(callable_call.code()); | 723 Node* code_target_call = HeapConstant(callable_call.code()); |
| 730 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, | 724 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, |
| 731 context, arg_count, first_arg, function); | 725 context, arg_count, first_arg, function); |
| 732 return_value.Bind(ret_value); | 726 return_value.Bind(ret_value); |
| 733 Goto(&end); | 727 Goto(&end); |
| 734 } | 728 } |
| 735 | 729 |
| 736 Bind(&call_without_feedback); | |
| 737 { | |
| 738 // Call using call builtin. | |
| 739 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( | |
| 740 isolate(), tail_call_mode, CallableType::kAny); | |
| 741 Node* code_target_call = HeapConstant(callable_call.code()); | |
| 742 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, | |
| 743 context, arg_count, first_arg, function); | |
| 744 return_value.Bind(ret_value); | |
| 745 Goto(&end); | |
| 746 } | |
| 747 | |
| 748 Bind(&end); | 730 Bind(&end); |
| 749 return return_value.value(); | 731 return return_value.value(); |
| 750 } | 732 } |
| 751 | 733 |
| 752 Node* InterpreterAssembler::CallJS(Node* function, Node* context, | 734 Node* InterpreterAssembler::CallJS(Node* function, Node* context, |
| 753 Node* first_arg, Node* arg_count, | 735 Node* first_arg, Node* arg_count, |
| 754 TailCallMode tail_call_mode) { | 736 TailCallMode tail_call_mode) { |
| 755 Callable callable = CodeFactory::InterpreterPushArgsAndCall( | 737 Callable callable = CodeFactory::InterpreterPushArgsAndCall( |
| 756 isolate(), tail_call_mode, CallableType::kAny); | 738 isolate(), tail_call_mode, CallableType::kAny); |
| 757 Node* code_target = HeapConstant(callable.code()); | 739 Node* code_target = HeapConstant(callable.code()); |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 Goto(&loop); | 1353 Goto(&loop); |
| 1372 } | 1354 } |
| 1373 Bind(&done_loop); | 1355 Bind(&done_loop); |
| 1374 | 1356 |
| 1375 return array; | 1357 return array; |
| 1376 } | 1358 } |
| 1377 | 1359 |
| 1378 } // namespace interpreter | 1360 } // namespace interpreter |
| 1379 } // namespace internal | 1361 } // namespace internal |
| 1380 } // namespace v8 | 1362 } // namespace v8 |
| OLD | NEW |