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

Side by Side Diff: src/ic/accessor-assembler.cc

Issue 2619823005: [ic][stubs] Move more IC-related methods from CSA to AccessorAssembler. (Closed)
Patch Set: Code reshuffling Created 3 years, 11 months 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 | « src/code-stub-assembler.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/ic/accessor-assembler.h" 5 #include "src/ic/accessor-assembler.h"
6 #include "src/ic/accessor-assembler-impl.h" 6 #include "src/ic/accessor-assembler-impl.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/ic/handler-configuration.h" 10 #include "src/ic/handler-configuration.h"
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 Bind(&if_double_field); 663 Bind(&if_double_field);
664 { 664 {
665 Comment("store double field"); 665 Comment("store double field");
666 HandleStoreFieldAndReturn(handler_word, holder, Representation::Double(), 666 HandleStoreFieldAndReturn(handler_word, holder, Representation::Double(),
667 value, transition, miss); 667 value, transition, miss);
668 } 668 }
669 669
670 Bind(&if_heap_object_field); 670 Bind(&if_heap_object_field);
671 { 671 {
672 Comment("store heap object field"); 672 Comment("store heap object field");
673 // Generate full field type check here and then store value as Tagged. 673 HandleStoreFieldAndReturn(handler_word, holder,
674 Node* prepared_value = 674 Representation::HeapObject(), value, transition,
675 PrepareValueForWrite(value, Representation::HeapObject(), miss); 675 miss);
676 Node* value_index_in_descriptor =
677 DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
678 Node* descriptors =
679 LoadMapDescriptors(transition ? transition : LoadMap(holder));
680 Node* maybe_field_type =
681 LoadFixedArrayElement(descriptors, value_index_in_descriptor);
682 Label do_store(this);
683 GotoIf(TaggedIsSmi(maybe_field_type), &do_store);
684 // Check that value type matches the field type.
685 {
686 Node* field_type = LoadWeakCellValue(maybe_field_type, miss);
687 Branch(WordEqual(LoadMap(prepared_value), field_type), &do_store, miss);
688 }
689 Bind(&do_store);
690 HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
691 prepared_value, transition, miss);
692 } 676 }
693 677
694 Bind(&if_smi_field); 678 Bind(&if_smi_field);
695 { 679 {
696 Comment("store smi field"); 680 Comment("store smi field");
697 HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(), 681 HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(),
698 value, transition, miss); 682 value, transition, miss);
699 } 683 }
700 } 684 }
701 685
702 void AccessorAssemblerImpl::HandleStoreFieldAndReturn( 686 void AccessorAssemblerImpl::HandleStoreFieldAndReturn(
703 Node* handler_word, Node* holder, Representation representation, 687 Node* handler_word, Node* holder, Representation representation,
704 Node* value, Node* transition, Label* miss) { 688 Node* value, Node* transition, Label* miss) {
705 bool transition_to_field = transition != nullptr; 689 bool transition_to_field = transition != nullptr;
706 Node* prepared_value = PrepareValueForWrite(value, representation, miss); 690 Node* prepared_value = PrepareValueForStore(
707 691 handler_word, holder, representation, transition, value, miss);
708 if (transition_to_field) {
709 Label storage_extended(this);
710 GotoUnless(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word),
711 &storage_extended);
712 Comment("[ Extend storage");
713 ExtendPropertiesBackingStore(holder);
714 Comment("] Extend storage");
715 Goto(&storage_extended);
716
717 Bind(&storage_extended);
718 }
719 692
720 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word); 693 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word);
721 Label if_inobject(this), if_out_of_object(this); 694 Label if_inobject(this), if_out_of_object(this);
722 Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject, 695 Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject,
723 &if_out_of_object); 696 &if_out_of_object);
724 697
725 Bind(&if_inobject); 698 Bind(&if_inobject);
726 { 699 {
727 StoreNamedField(holder, offset, true, representation, prepared_value, 700 StoreNamedField(holder, offset, true, representation, prepared_value,
728 transition_to_field); 701 transition_to_field);
729 if (transition_to_field) { 702 if (transition_to_field) {
730 StoreMap(holder, transition); 703 StoreMap(holder, transition);
731 } 704 }
732 Return(value); 705 Return(value);
733 } 706 }
734 707
735 Bind(&if_out_of_object); 708 Bind(&if_out_of_object);
736 { 709 {
710 if (transition_to_field) {
711 Label storage_extended(this);
712 GotoUnless(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word),
713 &storage_extended);
714 Comment("[ Extend storage");
715 ExtendPropertiesBackingStore(holder);
716 Comment("] Extend storage");
717 Goto(&storage_extended);
718
719 Bind(&storage_extended);
720 }
721
737 StoreNamedField(holder, offset, false, representation, prepared_value, 722 StoreNamedField(holder, offset, false, representation, prepared_value,
738 transition_to_field); 723 transition_to_field);
739 if (transition_to_field) { 724 if (transition_to_field) {
740 StoreMap(holder, transition); 725 StoreMap(holder, transition);
741 } 726 }
742 Return(value); 727 Return(value);
743 } 728 }
744 } 729 }
745 730
731 Node* AccessorAssemblerImpl::PrepareValueForStore(Node* handler_word,
732 Node* holder,
733 Representation representation,
734 Node* transition, Node* value,
735 Label* bailout) {
736 if (representation.IsDouble()) {
737 value = TryTaggedToFloat64(value, bailout);
738
739 } else if (representation.IsHeapObject()) {
740 GotoIf(TaggedIsSmi(value), bailout);
741 Node* value_index_in_descriptor =
742 DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
743 Node* descriptors =
744 LoadMapDescriptors(transition ? transition : LoadMap(holder));
745 Node* maybe_field_type =
746 LoadFixedArrayElement(descriptors, value_index_in_descriptor);
747
748 Label done(this);
749 GotoIf(TaggedIsSmi(maybe_field_type), &done);
750 // Check that value type matches the field type.
751 {
752 Node* field_type = LoadWeakCellValue(maybe_field_type, bailout);
753 Branch(WordEqual(LoadMap(value), field_type), &done, bailout);
754 }
755 Bind(&done);
756
757 } else if (representation.IsSmi()) {
758 GotoUnless(TaggedIsSmi(value), bailout);
759
760 } else {
761 DCHECK(representation.IsTagged());
762 }
763 return value;
764 }
765
766 void AccessorAssemblerImpl::ExtendPropertiesBackingStore(Node* object) {
767 Node* properties = LoadProperties(object);
768 Node* length = LoadFixedArrayBaseLength(properties);
769
770 ParameterMode mode = OptimalParameterMode();
771 length = TaggedToParameter(length, mode);
772
773 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode);
774 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode);
775
776 // Grow properties array.
777 ElementsKind kind = FAST_ELEMENTS;
778 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded <
779 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind));
780 // The size of a new properties backing store is guaranteed to be small
781 // enough that the new backing store will be allocated in new space.
782 CSA_ASSERT(this,
783 UintPtrOrSmiLessThan(
784 new_capacity,
785 IntPtrOrSmiConstant(
786 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode),
787 mode));
788
789 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode);
790
791 FillFixedArrayWithValue(kind, new_properties, length, new_capacity,
792 Heap::kUndefinedValueRootIndex, mode);
793
794 // |new_properties| is guaranteed to be in new space, so we can skip
795 // the write barrier.
796 CopyFixedArrayElements(kind, properties, new_properties, length,
797 SKIP_WRITE_BARRIER, mode);
798
799 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties);
800 }
801
802 void AccessorAssemblerImpl::StoreNamedField(Node* object, Node* offset,
803 bool is_inobject,
804 Representation representation,
805 Node* value,
806 bool transition_to_field) {
807 bool store_value_as_double = representation.IsDouble();
808 Node* property_storage = object;
809 if (!is_inobject) {
810 property_storage = LoadProperties(object);
811 }
812
813 if (representation.IsDouble()) {
814 if (!FLAG_unbox_double_fields || !is_inobject) {
815 if (transition_to_field) {
816 Node* heap_number = AllocateHeapNumberWithValue(value, MUTABLE);
817 // Store the new mutable heap number into the object.
818 value = heap_number;
819 store_value_as_double = false;
820 } else {
821 // Load the heap number.
822 property_storage = LoadObjectField(property_storage, offset);
823 // Store the double value into it.
824 offset = IntPtrConstant(HeapNumber::kValueOffset);
825 }
826 }
827 }
828
829 if (store_value_as_double) {
830 StoreObjectFieldNoWriteBarrier(property_storage, offset, value,
831 MachineRepresentation::kFloat64);
832 } else if (representation.IsSmi()) {
833 StoreObjectFieldNoWriteBarrier(property_storage, offset, value);
834 } else {
835 StoreObjectField(property_storage, offset, value);
836 }
837 }
838
746 void AccessorAssemblerImpl::EmitFastElementsBoundsCheck( 839 void AccessorAssemblerImpl::EmitFastElementsBoundsCheck(
747 Node* object, Node* elements, Node* intptr_index, 840 Node* object, Node* elements, Node* intptr_index,
748 Node* is_jsarray_condition, Label* miss) { 841 Node* is_jsarray_condition, Label* miss) {
749 Variable var_length(this, MachineType::PointerRepresentation()); 842 Variable var_length(this, MachineType::PointerRepresentation());
750 Comment("Fast elements bounds check"); 843 Comment("Fast elements bounds check");
751 Label if_array(this), length_loaded(this, &var_length); 844 Label if_array(this), length_loaded(this, &var_length);
752 GotoIf(is_jsarray_condition, &if_array); 845 GotoIf(is_jsarray_condition, &if_array);
753 { 846 {
754 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); 847 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements)));
755 Goto(&length_loaded); 848 Goto(&length_loaded);
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
1827 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF( 1920 void AccessorAssembler::GenerateKeyedStoreICTrampolineTF(
1828 CodeAssemblerState* state, LanguageMode language_mode) { 1921 CodeAssemblerState* state, LanguageMode language_mode) {
1829 AccessorAssemblerImpl assembler(state); 1922 AccessorAssemblerImpl assembler(state);
1830 assembler.GenerateKeyedStoreICTrampolineTF(language_mode); 1923 assembler.GenerateKeyedStoreICTrampolineTF(language_mode);
1831 } 1924 }
1832 1925
1833 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE 1926 #undef ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE
1834 1927
1835 } // namespace internal 1928 } // namespace internal
1836 } // namespace v8 1929 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.cc ('k') | src/ic/accessor-assembler-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698