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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2438553003: [ic] Support data handlers that represent simple field stores. (Closed)
Patch Set: One more fix for GC stress issues Created 4 years, 2 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
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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 #include "src/ic/handler-configuration.h" 8 #include "src/ic/handler-configuration.h"
9 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
10 10
(...skipping 5686 matching lines...) Expand 10 before | Expand all | Expand 10 after
5697 Bind(&slow); 5697 Bind(&slow);
5698 { 5698 {
5699 Comment("KeyedLoadGeneric_slow"); 5699 Comment("KeyedLoadGeneric_slow");
5700 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); 5700 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1);
5701 // TODO(jkummerow): Should we use the GetProperty TF stub instead? 5701 // TODO(jkummerow): Should we use the GetProperty TF stub instead?
5702 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, 5702 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver,
5703 p->name); 5703 p->name);
5704 } 5704 }
5705 } 5705 }
5706 5706
5707 void CodeStubAssembler::HandleStoreFieldAndReturn(
5708 Node* handler_word, Node* holder, Representation representation,
5709 Node* value, bool transition_to_field, Label* miss) {
5710 Node* prepared_value = PrepareValueForWrite(value, representation, miss);
5711
5712 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word);
5713 Label if_inobject(this), if_out_of_object(this);
5714 Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject,
5715 &if_out_of_object);
5716
5717 Bind(&if_inobject);
5718 {
5719 StoreNamedField(holder, offset, true, representation, prepared_value,
5720 transition_to_field);
5721 Return(value);
5722 }
5723
5724 Bind(&if_out_of_object);
5725 {
5726 StoreNamedField(holder, offset, false, representation, prepared_value,
5727 transition_to_field);
5728 Return(value);
5729 }
5730 }
5731
5732 void CodeStubAssembler::HandleStoreICSmiHandlerCase(Node* handler_word,
5733 Node* holder, Node* value,
5734 bool transition_to_field,
5735 Label* miss) {
5736 Comment(transition_to_field ? "transitioning field store" : "field store");
5737
5738 Node* field_representation =
5739 DecodeWord<StoreHandler::FieldRepresentationBits>(handler_word);
5740
5741 Label if_smi_field(this), if_double_field(this), if_heap_object_field(this),
5742 if_tagged_field(this);
5743
5744 GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kTagged)),
5745 &if_tagged_field);
5746 GotoIf(WordEqual(field_representation,
5747 IntPtrConstant(StoreHandler::kHeapObject)),
5748 &if_heap_object_field);
5749 GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kDouble)),
5750 &if_double_field);
5751 CSA_ASSERT(
5752 WordEqual(field_representation, IntPtrConstant(StoreHandler::kSmi)));
5753 Goto(&if_smi_field);
5754
5755 Bind(&if_tagged_field);
5756 {
5757 Comment("store tagged field");
5758 HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
5759 value, transition_to_field, miss);
5760 }
5761
5762 Bind(&if_double_field);
5763 {
5764 Comment("store double field");
5765 HandleStoreFieldAndReturn(handler_word, holder, Representation::Double(),
5766 value, transition_to_field, miss);
5767 }
5768
5769 Bind(&if_heap_object_field);
5770 {
5771 Comment("store heap object field");
5772 // Generate full field type check here and then store value as Tagged.
5773 Node* prepared_value =
5774 PrepareValueForWrite(value, Representation::HeapObject(), miss);
5775 Node* value_index_in_descriptor =
5776 DecodeWord<StoreHandler::DescriptorValueIndexBits>(handler_word);
5777 Node* descriptors = LoadMapDescriptors(LoadMap(holder));
5778 Node* maybe_field_type = LoadFixedArrayElement(
5779 descriptors, value_index_in_descriptor, 0, INTPTR_PARAMETERS);
5780 Label do_store(this);
5781 GotoIf(TaggedIsSmi(maybe_field_type), &do_store);
5782 // Check that value type matches the field type.
5783 {
5784 Node* field_type = LoadWeakCellValue(maybe_field_type, miss);
5785 Branch(WordEqual(LoadMap(prepared_value), field_type), &do_store, miss);
5786 }
5787 Bind(&do_store);
5788 HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(),
5789 prepared_value, transition_to_field, miss);
5790 }
5791
5792 Bind(&if_smi_field);
5793 {
5794 Comment("store smi field");
5795 HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(),
5796 value, transition_to_field, miss);
5797 }
5798 }
5799
5800 void CodeStubAssembler::HandleStoreICHandlerCase(const StoreICParameters* p,
5801 Node* handler, Label* miss) {
5802 Label if_smi_handler(this), call_handler(this);
5803
5804 Branch(TaggedIsSmi(handler), &if_smi_handler, &call_handler);
5805
5806 // |handler| is a Smi, encoding what to do. See SmiHandler methods
5807 // for the encoding format.
5808 Bind(&if_smi_handler);
5809 {
5810 Node* holder = p->receiver;
5811 Node* handler_word = SmiUntag(handler);
5812
5813 // Handle non-transitioning stores.
5814 HandleStoreICSmiHandlerCase(handler_word, holder, p->value, false, miss);
5815 }
5816
5817 // |handler| is a heap object. Must be code, call it.
5818 Bind(&call_handler);
5819 {
5820 StoreWithVectorDescriptor descriptor(isolate());
5821 TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
5822 p->value, p->slot, p->vector);
5823 }
5824 }
5825
5707 void CodeStubAssembler::StoreIC(const StoreICParameters* p) { 5826 void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
5708 Variable var_handler(this, MachineRepresentation::kTagged); 5827 Variable var_handler(this, MachineRepresentation::kTagged);
5709 // TODO(ishell): defer blocks when it works. 5828 // TODO(ishell): defer blocks when it works.
5710 Label if_handler(this, &var_handler), try_polymorphic(this), 5829 Label if_handler(this, &var_handler), try_polymorphic(this),
5711 try_megamorphic(this /*, Label::kDeferred*/), 5830 try_megamorphic(this /*, Label::kDeferred*/),
5712 miss(this /*, Label::kDeferred*/); 5831 miss(this /*, Label::kDeferred*/);
5713 5832
5714 Node* receiver_map = LoadReceiverMap(p->receiver); 5833 Node* receiver_map = LoadReceiverMap(p->receiver);
5715 5834
5716 // Check monomorphic case. 5835 // Check monomorphic case.
5717 Node* feedback = 5836 Node* feedback =
5718 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 5837 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
5719 &var_handler, &try_polymorphic); 5838 &var_handler, &try_polymorphic);
5720 Bind(&if_handler); 5839 Bind(&if_handler);
5721 { 5840 {
5722 Comment("StoreIC_if_handler"); 5841 Comment("StoreIC_if_handler");
5723 StoreWithVectorDescriptor descriptor(isolate()); 5842 HandleStoreICHandlerCase(p, var_handler.value(), &miss);
5724 TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
5725 p->name, p->value, p->slot, p->vector);
5726 } 5843 }
5727 5844
5728 Bind(&try_polymorphic); 5845 Bind(&try_polymorphic);
5729 { 5846 {
5730 // Check polymorphic case. 5847 // Check polymorphic case.
5731 Comment("StoreIC_try_polymorphic"); 5848 Comment("StoreIC_try_polymorphic");
5732 GotoUnless( 5849 GotoUnless(
5733 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), 5850 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
5734 &try_megamorphic); 5851 &try_megamorphic);
5735 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler, 5852 HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
(...skipping 13 matching lines...) Expand all
5749 Bind(&miss); 5866 Bind(&miss);
5750 { 5867 {
5751 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot, 5868 TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot,
5752 p->vector, p->receiver, p->name); 5869 p->vector, p->receiver, p->name);
5753 } 5870 }
5754 } 5871 }
5755 5872
5756 void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p, 5873 void CodeStubAssembler::KeyedStoreIC(const StoreICParameters* p,
5757 LanguageMode language_mode) { 5874 LanguageMode language_mode) {
5758 Variable var_handler(this, MachineRepresentation::kTagged); 5875 Variable var_handler(this, MachineRepresentation::kTagged);
5876 // This is to make |miss| label see the var_handler bound on all paths.
5877 var_handler.Bind(IntPtrConstant(0));
5878
5759 // TODO(ishell): defer blocks when it works. 5879 // TODO(ishell): defer blocks when it works.
5760 Label if_handler(this, &var_handler), try_polymorphic(this), 5880 Label if_handler(this, &var_handler), try_polymorphic(this),
5761 try_megamorphic(this /*, Label::kDeferred*/), 5881 try_megamorphic(this /*, Label::kDeferred*/),
5762 try_polymorphic_name(this /*, Label::kDeferred*/), 5882 try_polymorphic_name(this /*, Label::kDeferred*/),
5763 miss(this /*, Label::kDeferred*/); 5883 miss(this /*, Label::kDeferred*/);
5764 5884
5765 Node* receiver_map = LoadReceiverMap(p->receiver); 5885 Node* receiver_map = LoadReceiverMap(p->receiver);
5766 5886
5767 // Check monomorphic case. 5887 // Check monomorphic case.
5768 Node* feedback = 5888 Node* feedback =
5769 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler, 5889 TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
5770 &var_handler, &try_polymorphic); 5890 &var_handler, &try_polymorphic);
5771 Bind(&if_handler); 5891 Bind(&if_handler);
5772 { 5892 {
5773 Comment("KeyedStoreIC_if_handler"); 5893 Comment("KeyedStoreIC_if_handler");
5774 StoreWithVectorDescriptor descriptor(isolate()); 5894 HandleStoreICHandlerCase(p, var_handler.value(), &miss);
5775 TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
5776 p->name, p->value, p->slot, p->vector);
5777 } 5895 }
5778 5896
5779 Bind(&try_polymorphic); 5897 Bind(&try_polymorphic);
5780 { 5898 {
5781 // CheckPolymorphic case. 5899 // CheckPolymorphic case.
5782 Comment("KeyedStoreIC_try_polymorphic"); 5900 Comment("KeyedStoreIC_try_polymorphic");
5783 GotoUnless( 5901 GotoUnless(
5784 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), 5902 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
5785 &try_megamorphic); 5903 &try_megamorphic);
5786 Label if_transition_handler(this); 5904 Label if_transition_handler(this);
(...skipping 2546 matching lines...) Expand 10 before | Expand all | Expand 10 after
8333 Node* buffer_bit_field = LoadObjectField( 8451 Node* buffer_bit_field = LoadObjectField(
8334 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); 8452 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
8335 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); 8453 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask);
8336 8454
8337 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), 8455 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask),
8338 Int32Constant(0)); 8456 Int32Constant(0));
8339 } 8457 }
8340 8458
8341 } // namespace internal 8459 } // namespace internal
8342 } // namespace v8 8460 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/counters.h » ('j') | src/ic/ic.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698