Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(920)

Side by Side Diff: src/interpreter/interpreter-assembler.cc

Issue 2487573005: [Interpreter] Optimize for monomorphic case in Call and New bytecode handlers. (Closed)
Patch Set: Fixed comments. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not 539 // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not
540 // computed, meaning that it can't appear to be a pointer. If the low bit is 540 // computed, meaning that it can't appear to be a pointer. If the low bit is
541 // 0, then hash is computed, but the 0 bit prevents the field from appearing 541 // 0, then hash is computed, but the 0 bit prevents the field from appearing
542 // to be a pointer. 542 // to be a pointer.
543 STATIC_ASSERT(WeakCell::kSize >= kPointerSize); 543 STATIC_ASSERT(WeakCell::kSize >= kPointerSize);
544 STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == 544 STATIC_ASSERT(AllocationSite::kTransitionInfoOffset ==
545 WeakCell::kValueOffset && 545 WeakCell::kValueOffset &&
546 WeakCell::kValueOffset == Symbol::kHashFieldSlot); 546 WeakCell::kValueOffset == Symbol::kHashFieldSlot);
547 547
548 Variable return_value(this, MachineRepresentation::kTagged); 548 Variable return_value(this, MachineRepresentation::kTagged);
549 Label handle_monomorphic(this), extra_checks(this), end(this), call(this), 549 Label call_function(this), extra_checks(this, Label::kDeferred), call(this),
550 call_function(this); 550 end(this);
551 551
552 // The checks. First, does function match the recorded monomorphic target? 552 // The checks. First, does function match the recorded monomorphic target?
553 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id); 553 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id);
554 Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element); 554 Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element);
555 Node* is_monomorphic = WordEqual(function, feedback_value); 555 Node* is_monomorphic = WordEqual(function, feedback_value);
556 Branch(is_monomorphic, &handle_monomorphic, &extra_checks); 556 GotoUnless(is_monomorphic, &extra_checks);
557 557
558 Bind(&handle_monomorphic); 558 // The compare above could have been a SMI/SMI comparison. Guard against
559 // this convincing us that we have a monomorphic JSFunction.
560 Node* is_smi = TaggedIsSmi(function);
561 Branch(is_smi, &extra_checks, &call_function);
562
563 Bind(&call_function);
559 { 564 {
560 // The compare above could have been a SMI/SMI comparison. Guard against
561 // this convincing us that we have a monomorphic JSFunction.
562 Node* is_smi = TaggedIsSmi(function);
563 GotoIf(is_smi, &extra_checks);
564
565 // Increment the call count. 565 // Increment the call count.
566 IncrementCallCount(type_feedback_vector, slot_id); 566 IncrementCallCount(type_feedback_vector, slot_id);
567 567
568 // Call using call function builtin. 568 // Call using call function builtin.
569 Callable callable = CodeFactory::InterpreterPushArgsAndCall( 569 Callable callable = CodeFactory::InterpreterPushArgsAndCall(
570 isolate(), tail_call_mode, CallableType::kJSFunction); 570 isolate(), tail_call_mode, CallableType::kJSFunction);
571 Node* code_target = HeapConstant(callable.code()); 571 Node* code_target = HeapConstant(callable.code());
572 Node* ret_value = CallStub(callable.descriptor(), code_target, context, 572 Node* ret_value = CallStub(callable.descriptor(), code_target, context,
573 arg_count, first_arg, function); 573 arg_count, first_arg, function);
574 return_value.Bind(ret_value); 574 return_value.Bind(ret_value);
575 Goto(&end); 575 Goto(&end);
576 } 576 }
577 577
578 Bind(&extra_checks); 578 Bind(&extra_checks);
579 { 579 {
580 Label check_initialized(this, Label::kDeferred), mark_megamorphic(this), 580 Label check_initialized(this), mark_megamorphic(this),
581 check_allocation_site(this), 581 create_allocation_site(this);
582 create_allocation_site(this, Label::kDeferred); 582
583 // Check if it is a megamorphic target 583 Comment("check if megamorphic");
584 // Check if it is a megamorphic target.
584 Node* is_megamorphic = WordEqual( 585 Node* is_megamorphic = WordEqual(
585 feedback_element, 586 feedback_element,
586 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 587 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())));
587 Branch(is_megamorphic, &call, &check_allocation_site); 588 GotoIf(is_megamorphic, &call);
588 589
589 Bind(&check_allocation_site); 590 Comment("check if it is an allocation site");
590 { 591 Node* is_allocation_site = WordEqual(
591 Node* is_allocation_site = 592 LoadMap(feedback_element), LoadRoot(Heap::kAllocationSiteMapRootIndex));
592 WordEqual(LoadMap(feedback_element), 593 GotoUnless(is_allocation_site, &check_initialized);
593 LoadRoot(Heap::kAllocationSiteMapRootIndex));
594 GotoUnless(is_allocation_site, &check_initialized);
595 594
596 // If it is not the Array() function, mark megamorphic. 595 // If it is not the Array() function, mark megamorphic.
597 Node* context_slot = 596 Node* context_slot =
598 LoadFixedArrayElement(LoadNativeContext(context), 597 LoadFixedArrayElement(LoadNativeContext(context),
599 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); 598 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
600 Node* is_array_function = WordEqual(context_slot, function); 599 Node* is_array_function = WordEqual(context_slot, function);
601 GotoUnless(is_array_function, &mark_megamorphic); 600 GotoUnless(is_array_function, &mark_megamorphic);
602 601
603 // It is a monomorphic Array function. Increment the call count. 602 // It is a monomorphic Array function. Increment the call count.
604 IncrementCallCount(type_feedback_vector, slot_id); 603 IncrementCallCount(type_feedback_vector, slot_id);
605 604
606 // Call ArrayConstructorStub. 605 // Call ArrayConstructorStub.
607 Callable callable_call = 606 Callable callable_call =
608 CodeFactory::InterpreterPushArgsAndConstructArray(isolate()); 607 CodeFactory::InterpreterPushArgsAndConstructArray(isolate());
609 Node* code_target_call = HeapConstant(callable_call.code()); 608 Node* code_target_call = HeapConstant(callable_call.code());
610 Node* ret_value = 609 Node* ret_value =
611 CallStub(callable_call.descriptor(), code_target_call, context, 610 CallStub(callable_call.descriptor(), code_target_call, context,
612 arg_count, function, feedback_element, first_arg); 611 arg_count, function, feedback_element, first_arg);
613 return_value.Bind(ret_value); 612 return_value.Bind(ret_value);
614 Goto(&end); 613 Goto(&end);
615 }
616 614
617 Bind(&check_initialized); 615 Bind(&check_initialized);
618 { 616 {
619 Label possibly_monomorphic(this); 617 Comment("check if uninitialized");
620 // Check if it is uninitialized. 618 // Check if it is uninitialized target first.
621 Node* is_uninitialized = WordEqual( 619 Node* is_uninitialized = WordEqual(
622 feedback_element, 620 feedback_element,
623 HeapConstant(TypeFeedbackVector::UninitializedSentinel(isolate()))); 621 HeapConstant(TypeFeedbackVector::UninitializedSentinel(isolate())));
624 GotoUnless(is_uninitialized, &mark_megamorphic); 622 GotoUnless(is_uninitialized, &mark_megamorphic);
625 623
624 Comment("handle_unitinitialized");
625 // If it is not a JSFunction mark it as megamorphic.
626 Node* is_smi = TaggedIsSmi(function); 626 Node* is_smi = TaggedIsSmi(function);
627 GotoIf(is_smi, &mark_megamorphic); 627 GotoIf(is_smi, &mark_megamorphic);
628 628
629 // Check if function is an object of JSFunction type 629 // Check if function is an object of JSFunction type.
630 Node* instance_type = LoadInstanceType(function); 630 Node* instance_type = LoadInstanceType(function);
631 Node* is_js_function = 631 Node* is_js_function =
632 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); 632 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE));
633 GotoUnless(is_js_function, &mark_megamorphic); 633 GotoUnless(is_js_function, &mark_megamorphic);
634 634
635 // Check if it is the Array() function. 635 // Check if it is the Array() function.
636 Node* context_slot = 636 Node* context_slot =
637 LoadFixedArrayElement(LoadNativeContext(context), 637 LoadFixedArrayElement(LoadNativeContext(context),
638 Int32Constant(Context::ARRAY_FUNCTION_INDEX)); 638 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
639 Node* is_array_function = WordEqual(context_slot, function); 639 Node* is_array_function = WordEqual(context_slot, function);
640 GotoIf(is_array_function, &create_allocation_site); 640 GotoIf(is_array_function, &create_allocation_site);
641 641
642 // Check if the function belongs to the same native context 642 // Check if the function belongs to the same native context.
643 Node* native_context = LoadNativeContext( 643 Node* native_context = LoadNativeContext(
644 LoadObjectField(function, JSFunction::kContextOffset)); 644 LoadObjectField(function, JSFunction::kContextOffset));
645 Node* is_same_native_context = 645 Node* is_same_native_context =
646 WordEqual(native_context, LoadNativeContext(context)); 646 WordEqual(native_context, LoadNativeContext(context));
647 GotoUnless(is_same_native_context, &mark_megamorphic); 647 GotoUnless(is_same_native_context, &mark_megamorphic);
648 648
649 CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id), 649 CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id),
650 function); 650 function);
651 651
652 // Call using call function builtin. 652 // Call using call function builtin.
(...skipping 18 matching lines...) Expand all
671 // and will not move during a GC. So it is safe to skip write barrier. 671 // and will not move during a GC. So it is safe to skip write barrier.
672 DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex)); 672 DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex));
673 StoreFixedArrayElement( 673 StoreFixedArrayElement(
674 type_feedback_vector, slot_id, 674 type_feedback_vector, slot_id,
675 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())), 675 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())),
676 SKIP_WRITE_BARRIER); 676 SKIP_WRITE_BARRIER);
677 Goto(&call); 677 Goto(&call);
678 } 678 }
679 } 679 }
680 680
681 Bind(&call_function);
682 {
683 // Increment the call count.
684 IncrementCallCount(type_feedback_vector, slot_id);
685
686 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall(
687 isolate(), tail_call_mode, CallableType::kJSFunction);
688 Node* code_target_call = HeapConstant(callable_call.code());
689 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call,
690 context, arg_count, first_arg, function);
691 return_value.Bind(ret_value);
692 Goto(&end);
693 }
694
695 Bind(&call); 681 Bind(&call);
696 { 682 {
683 Comment("Increment call count and call using Call builtin");
697 // Increment the call count. 684 // Increment the call count.
698 IncrementCallCount(type_feedback_vector, slot_id); 685 IncrementCallCount(type_feedback_vector, slot_id);
699 686
700 // Call using call builtin. 687 // Call using call builtin.
701 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall( 688 Callable callable_call = CodeFactory::InterpreterPushArgsAndCall(
702 isolate(), tail_call_mode, CallableType::kAny); 689 isolate(), tail_call_mode, CallableType::kAny);
703 Node* code_target_call = HeapConstant(callable_call.code()); 690 Node* code_target_call = HeapConstant(callable_call.code());
704 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call, 691 Node* ret_value = CallStub(callable_call.descriptor(), code_target_call,
705 context, arg_count, first_arg, function); 692 context, arg_count, first_arg, function);
706 return_value.Bind(ret_value); 693 return_value.Bind(ret_value);
(...skipping 11 matching lines...) Expand all
718 isolate(), tail_call_mode, CallableType::kAny); 705 isolate(), tail_call_mode, CallableType::kAny);
719 Node* code_target = HeapConstant(callable.code()); 706 Node* code_target = HeapConstant(callable.code());
720 return CallStub(callable.descriptor(), code_target, context, arg_count, 707 return CallStub(callable.descriptor(), code_target, context, arg_count,
721 first_arg, function); 708 first_arg, function);
722 } 709 }
723 710
724 Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context, 711 Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
725 Node* new_target, Node* first_arg, 712 Node* new_target, Node* first_arg,
726 Node* arg_count, Node* slot_id, 713 Node* arg_count, Node* slot_id,
727 Node* type_feedback_vector) { 714 Node* type_feedback_vector) {
728 Label call_construct(this), js_function(this), end(this);
729 Variable return_value(this, MachineRepresentation::kTagged); 715 Variable return_value(this, MachineRepresentation::kTagged);
730 Variable allocation_feedback(this, MachineRepresentation::kTagged); 716 Variable allocation_feedback(this, MachineRepresentation::kTagged);
731 allocation_feedback.Bind(UndefinedConstant()); 717 Label call_construct_function(this, &allocation_feedback),
718 extra_checks(this, Label::kDeferred), call_construct(this), end(this);
732 719
733 // Slot id of 0 is used to indicate no type feedback is available. 720 // Slot id of 0 is used to indicate no type feedback is available.
734 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0); 721 STATIC_ASSERT(TypeFeedbackVector::kReservedIndexCount > 0);
735 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0)); 722 Node* is_feedback_unavailable = Word32Equal(slot_id, Int32Constant(0));
736 GotoIf(is_feedback_unavailable, &call_construct); 723 GotoIf(is_feedback_unavailable, &call_construct);
737 724
738 // Check that the constructor is not a smi. 725 // Check that the constructor is not a smi.
739 Node* is_smi = TaggedIsSmi(constructor); 726 Node* is_smi = TaggedIsSmi(constructor);
740 GotoIf(is_smi, &call_construct); 727 GotoIf(is_smi, &call_construct);
741 728
742 // Check that constructor is a JSFunction. 729 // Check that constructor is a JSFunction.
743 Node* instance_type = LoadInstanceType(constructor); 730 Node* instance_type = LoadInstanceType(constructor);
744 Node* is_js_function = 731 Node* is_js_function =
745 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)); 732 WordEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE));
746 Branch(is_js_function, &js_function, &call_construct); 733 GotoUnless(is_js_function, &call_construct);
747 734
748 Bind(&js_function); 735 // Check if it is a monomorphic constructor.
736 Node* feedback_element = LoadFixedArrayElement(type_feedback_vector, slot_id);
737 Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element);
738 Node* is_monomorphic = WordEqual(constructor, feedback_value);
739 allocation_feedback.Bind(UndefinedConstant());
740 Branch(is_monomorphic, &call_construct_function, &extra_checks);
741
742 Bind(&call_construct_function);
749 { 743 {
750 // Cache the called function in a feedback vector slot. Cache states 744 Comment("call using callConstructFunction");
751 // are uninitialized, monomorphic (indicated by a JSFunction), and 745 IncrementCallCount(type_feedback_vector, slot_id);
752 // megamorphic. 746 Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct(
753 // TODO(mythria/v8:5210): Check if it is better to mark extra_checks as a 747 isolate(), CallableType::kJSFunction);
754 // deferred block so that call_construct_function will be scheduled. 748 return_value.Bind(CallStub(callable_function.descriptor(),
755 Label extra_checks(this), call_construct_function(this); 749 HeapConstant(callable_function.code()), context,
750 arg_count, new_target, constructor,
751 allocation_feedback.value(), first_arg));
752 Goto(&end);
753 }
756 754
757 Node* feedback_element = 755 Bind(&extra_checks);
758 LoadFixedArrayElement(type_feedback_vector, slot_id); 756 {
759 Node* feedback_value = LoadWeakCellValueUnchecked(feedback_element); 757 Label check_allocation_site(this), check_initialized(this),
760 Node* is_monomorphic = WordEqual(constructor, feedback_value); 758 initialize(this), mark_megamorphic(this);
761 Branch(is_monomorphic, &call_construct_function, &extra_checks);
762 759
763 Bind(&extra_checks); 760 // Check if it is a megamorphic target.
761 Comment("check if megamorphic");
762 Node* is_megamorphic = WordEqual(
763 feedback_element,
764 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())));
765 GotoIf(is_megamorphic, &call_construct_function);
766
767 Comment("check if weak cell");
768 Node* is_weak_cell = WordEqual(LoadMap(feedback_element),
769 LoadRoot(Heap::kWeakCellMapRootIndex));
770 GotoUnless(is_weak_cell, &check_allocation_site);
771
772 // If the weak cell is cleared, we have a new chance to become
773 // monomorphic.
774 Comment("check if weak cell is cleared");
775 Node* is_smi = TaggedIsSmi(feedback_value);
776 Branch(is_smi, &initialize, &mark_megamorphic);
777
778 Bind(&check_allocation_site);
764 { 779 {
765 Label mark_megamorphic(this), initialize(this), 780 Comment("check if it is an allocation site");
766 check_allocation_site(this), check_initialized(this), 781 Node* is_allocation_site =
767 set_alloc_feedback_and_call(this); 782 WordEqual(LoadObjectField(feedback_element, 0),
783 LoadRoot(Heap::kAllocationSiteMapRootIndex));
784 GotoUnless(is_allocation_site, &check_initialized);
785
786 // Make sure the function is the Array() function.
787 Node* context_slot =
788 LoadFixedArrayElement(LoadNativeContext(context),
789 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
790 Node* is_array_function = WordEqual(context_slot, constructor);
791 GotoUnless(is_array_function, &mark_megamorphic);
792
793 allocation_feedback.Bind(feedback_element);
794 Goto(&call_construct_function);
795 }
796
797 Bind(&check_initialized);
798 {
799 // Check if it is uninitialized.
800 Comment("check if uninitialized");
801 Node* is_uninitialized = WordEqual(
802 feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex));
803 Branch(is_uninitialized, &initialize, &mark_megamorphic);
804 }
805
806 Bind(&initialize);
807 {
808 Label create_allocation_site(this), create_weak_cell(this);
809 Comment("initialize the feedback element");
810 // Create an allocation site if the function is an array function,
811 // otherwise create a weak cell.
812 Node* context_slot =
813 LoadFixedArrayElement(LoadNativeContext(context),
814 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
815 Node* is_array_function = WordEqual(context_slot, constructor);
816 Branch(is_array_function, &create_allocation_site, &create_weak_cell);
817
818 Bind(&create_allocation_site);
768 { 819 {
769 // Check if it is a megamorphic target 820 Node* site = CreateAllocationSiteInFeedbackVector(type_feedback_vector,
770 Comment("check if megamorphic"); 821 SmiTag(slot_id));
771 Node* is_megamorphic = WordEqual( 822 allocation_feedback.Bind(site);
772 feedback_element,
773 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())));
774 GotoIf(is_megamorphic, &call_construct_function);
775
776 Comment("check if weak cell");
777 Node* is_weak_cell = WordEqual(LoadMap(feedback_element),
778 LoadRoot(Heap::kWeakCellMapRootIndex));
779 GotoUnless(is_weak_cell, &check_allocation_site);
780 // If the weak cell is cleared, we have a new chance to become
781 // monomorphic.
782 Comment("check if weak cell is cleared");
783 Node* is_smi = TaggedIsSmi(feedback_value);
784 Branch(is_smi, &initialize, &mark_megamorphic);
785 }
786
787 Bind(&check_allocation_site);
788 {
789 Comment("check if it is an allocation site");
790 Node* is_allocation_site =
791 WordEqual(LoadObjectField(feedback_element, 0),
792 LoadRoot(Heap::kAllocationSiteMapRootIndex));
793 GotoUnless(is_allocation_site, &check_initialized);
794
795 // Make sure the function is the Array() function
796 Node* context_slot =
797 LoadFixedArrayElement(LoadNativeContext(context),
798 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
799 Node* is_array_function = WordEqual(context_slot, constructor);
800 Branch(is_array_function, &set_alloc_feedback_and_call,
801 &mark_megamorphic);
802 }
803
804 Bind(&set_alloc_feedback_and_call);
805 {
806 allocation_feedback.Bind(feedback_element);
807 Goto(&call_construct_function); 823 Goto(&call_construct_function);
808 } 824 }
809 825
810 Bind(&check_initialized); 826 Bind(&create_weak_cell);
811 { 827 {
812 // Check if it is uninitialized. 828 CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id),
813 Comment("check if uninitialized"); 829 constructor);
814 Node* is_uninitialized = WordEqual(
815 feedback_element, LoadRoot(Heap::kuninitialized_symbolRootIndex));
816 Branch(is_uninitialized, &initialize, &mark_megamorphic);
817 }
818
819 Bind(&initialize);
820 {
821 Label create_weak_cell(this), create_allocation_site(this);
822 Comment("initialize the feedback element");
823 // Check that it is the Array() function.
824 Node* context_slot =
825 LoadFixedArrayElement(LoadNativeContext(context),
826 Int32Constant(Context::ARRAY_FUNCTION_INDEX));
827 Node* is_array_function = WordEqual(context_slot, constructor);
828 Branch(is_array_function, &create_allocation_site, &create_weak_cell);
829
830 Bind(&create_allocation_site);
831 {
832 Node* site = CreateAllocationSiteInFeedbackVector(
833 type_feedback_vector, SmiTag(slot_id));
834 allocation_feedback.Bind(site);
835 Goto(&call_construct_function);
836 }
837
838 Bind(&create_weak_cell);
839 {
840 CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id),
841 constructor);
842 Goto(&call_construct_function);
843 }
844 }
845
846 Bind(&mark_megamorphic);
847 {
848 // MegamorphicSentinel is an immortal immovable object so
849 // write-barrier is not needed.
850 Comment("transition to megamorphic");
851 DCHECK(
852 Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex));
853 StoreFixedArrayElement(
854 type_feedback_vector, slot_id,
855 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())),
856 SKIP_WRITE_BARRIER);
857 Goto(&call_construct_function); 830 Goto(&call_construct_function);
858 } 831 }
859 } 832 }
860 833
861 Bind(&call_construct_function); 834 Bind(&mark_megamorphic);
862 { 835 {
863 Comment("call using callConstructFunction"); 836 // MegamorphicSentinel is an immortal immovable object so
864 IncrementCallCount(type_feedback_vector, slot_id); 837 // write-barrier is not needed.
865 Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct( 838 Comment("transition to megamorphic");
866 isolate(), CallableType::kJSFunction); 839 DCHECK(Heap::RootIsImmortalImmovable(Heap::kmegamorphic_symbolRootIndex));
867 return_value.Bind(CallStub(callable_function.descriptor(), 840 StoreFixedArrayElement(
868 HeapConstant(callable_function.code()), 841 type_feedback_vector, slot_id,
869 context, arg_count, new_target, constructor, 842 HeapConstant(TypeFeedbackVector::MegamorphicSentinel(isolate())),
870 allocation_feedback.value(), first_arg)); 843 SKIP_WRITE_BARRIER);
871 Goto(&end); 844 Goto(&call_construct_function);
872 } 845 }
873 } 846 }
874 847
875 Bind(&call_construct); 848 Bind(&call_construct);
876 { 849 {
877 Comment("call using callConstruct builtin"); 850 Comment("call using callConstruct builtin");
878 Callable callable = CodeFactory::InterpreterPushArgsAndConstruct( 851 Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(
879 isolate(), CallableType::kAny); 852 isolate(), CallableType::kAny);
880 Node* code_target = HeapConstant(callable.code()); 853 Node* code_target = HeapConstant(callable.code());
881 return_value.Bind(CallStub(callable.descriptor(), code_target, context, 854 return_value.Bind(CallStub(callable.descriptor(), code_target, context,
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 Goto(&loop); 1331 Goto(&loop);
1359 } 1332 }
1360 Bind(&done_loop); 1333 Bind(&done_loop);
1361 1334
1362 return array; 1335 return array;
1363 } 1336 }
1364 1337
1365 } // namespace interpreter 1338 } // namespace interpreter
1366 } // namespace internal 1339 } // namespace internal
1367 } // namespace v8 1340 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698