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 |