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

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

Issue 2330063002: [stubs] Port StoreFastElementsStub to TurboFan. (Closed)
Patch Set: Retain removed, a comment added Created 4 years, 3 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.h ('k') | src/code-stubs.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/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 3517 matching lines...) Expand 10 before | Expand all | Expand 10 after
3528 Goto(&return_result); 3528 Goto(&return_result);
3529 3529
3530 Bind(&return_result); 3530 Bind(&return_result);
3531 return var_result.value(); 3531 return var_result.value();
3532 } 3532 }
3533 3533
3534 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, 3534 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
3535 ElementsKind kind, 3535 ElementsKind kind,
3536 ParameterMode mode, 3536 ParameterMode mode,
3537 int base_size) { 3537 int base_size) {
3538 bool is_double = IsFastDoubleElementsKind(kind); 3538 int element_size_shift = ElementsKindToShiftSize(kind);
3539 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2;
3540 int element_size = 1 << element_size_shift; 3539 int element_size = 1 << element_size_shift;
3541 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; 3540 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
3542 intptr_t index = 0; 3541 intptr_t index = 0;
3543 bool constant_index = false; 3542 bool constant_index = false;
3544 if (mode == SMI_PARAMETERS) { 3543 if (mode == SMI_PARAMETERS) {
3545 element_size_shift -= kSmiShiftBits; 3544 element_size_shift -= kSmiShiftBits;
3546 constant_index = ToIntPtrConstant(index_node, index); 3545 constant_index = ToIntPtrConstant(index_node, index);
3547 index = index >> kSmiShiftBits; 3546 index = index >> kSmiShiftBits;
3548 } else if (mode == INTEGER_PARAMETERS) { 3547 } else if (mode == INTEGER_PARAMETERS) {
3549 int32_t temp = 0; 3548 int32_t temp = 0;
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
4630 Node* native_context = LoadNativeContext(context); 4629 Node* native_context = LoadNativeContext(context);
4631 Node* script_context_table = 4630 Node* script_context_table =
4632 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX); 4631 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
4633 4632
4634 int offset = 4633 int offset =
4635 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag; 4634 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
4636 return Load(MachineType::AnyTagged(), script_context_table, 4635 return Load(MachineType::AnyTagged(), script_context_table,
4637 IntPtrConstant(offset)); 4636 IntPtrConstant(offset));
4638 } 4637 }
4639 4638
4639 Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) {
4640 Label done(this);
4641 Node* int32_zero = Int32Constant(0);
4642 Node* int32_255 = Int32Constant(255);
4643 Variable var_value(this, MachineRepresentation::kWord32);
4644 var_value.Bind(int32_value);
4645 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
4646 var_value.Bind(int32_zero);
4647 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
4648 var_value.Bind(int32_255);
4649 Goto(&done);
4650 Bind(&done);
4651 return var_value.value();
4652 }
4653
4654 namespace {
4655
4656 // Converts typed array elements kind to a machine representations.
4657 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) {
4658 switch (kind) {
4659 case UINT8_CLAMPED_ELEMENTS:
4660 case UINT8_ELEMENTS:
4661 case INT8_ELEMENTS:
4662 return MachineRepresentation::kWord8;
4663 case UINT16_ELEMENTS:
4664 case INT16_ELEMENTS:
4665 return MachineRepresentation::kWord16;
4666 case UINT32_ELEMENTS:
4667 case INT32_ELEMENTS:
4668 return MachineRepresentation::kWord32;
4669 case FLOAT32_ELEMENTS:
4670 return MachineRepresentation::kFloat32;
4671 case FLOAT64_ELEMENTS:
4672 return MachineRepresentation::kFloat64;
4673 default:
4674 UNREACHABLE();
4675 return MachineRepresentation::kNone;
4676 }
4677 }
4678
4679 } // namespace
4680
4681 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
4682 Node* index, Node* value,
4683 ParameterMode mode) {
4684 if (IsFixedTypedArrayElementsKind(kind)) {
4685 if (kind == UINT8_CLAMPED_ELEMENTS) {
4686 value = ClampedToUint8(value);
4687 }
4688 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
4689 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
4690 StoreNoWriteBarrier(rep, elements, offset, value);
4691 return;
4692 }
4693
4694 WriteBarrierMode barrier_mode =
4695 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
4696 if (IsFastDoubleElementsKind(kind)) {
4697 // Make sure we do not store signalling NaNs into double arrays.
4698 value = Float64SilenceNaN(value);
4699 StoreFixedDoubleArrayElement(elements, index, value, mode);
4700 } else {
4701 StoreFixedArrayElement(elements, index, value, barrier_mode, mode);
4702 }
4703 }
4704
4705 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
4706 bool is_jsarray,
4707 ElementsKind elements_kind,
4708 KeyedAccessStoreMode store_mode,
4709 Label* bailout) {
4710 Node* elements = LoadElements(object);
4711 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
4712 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
4713 // Bailout in case of COW elements.
4714 GotoIf(WordNotEqual(LoadMap(elements),
4715 LoadRoot(Heap::kFixedArrayMapRootIndex)),
4716 bailout);
4717 }
4718 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
4719 ParameterMode parameter_mode = INTPTR_PARAMETERS;
4720 key = TryToIntptr(key, bailout);
4721
4722 if (IsFixedTypedArrayElementsKind(elements_kind)) {
4723 Label done(this);
4724 // TODO(ishell): call ToNumber() on value and don't bailout but be careful
4725 // to call it only once if we decide to bailout because of bounds checks.
4726
4727 if (IsFixedFloatElementsKind(elements_kind)) {
4728 // TODO(ishell): move float32 truncation into PrepareValueForWrite.
4729 value = PrepareValueForWrite(value, Representation::Double(), bailout);
4730 if (elements_kind == FLOAT32_ELEMENTS) {
4731 value = TruncateFloat64ToFloat32(value);
4732 }
4733 } else {
4734 // TODO(ishell): It's fine for word8/16/32 to truncate the result.
4735 value = TryToIntptr(value, bailout);
4736 }
4737
4738 // There must be no allocations between the buffer load and
4739 // and the actual store to backing store, because GC may decide that
4740 // the buffer is not alive or move the elements.
4741 // TODO(ishell): introduce DisallowHeapAllocationCode scope here.
4742
4743 // Check if buffer has been neutered.
4744 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
4745 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
4746 MachineType::Uint32());
4747 Node* neutered_bit =
4748 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask));
4749 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), bailout);
4750
4751 // Bounds check.
4752 Node* length = UntagParameter(
4753 LoadObjectField(object, JSTypedArray::kLengthOffset), parameter_mode);
4754
4755 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
4756 // Skip the store if we write beyond the length.
4757 GotoUnless(IntPtrLessThan(key, length), &done);
4758 // ... but bailout if the key is negative.
4759 } else {
4760 DCHECK_EQ(STANDARD_STORE, store_mode);
4761 }
4762 GotoUnless(UintPtrLessThan(key, length), bailout);
4763
4764 // Backing store = external_pointer + base_pointer.
4765 Node* external_pointer =
4766 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
4767 MachineType::Pointer());
4768 Node* base_pointer =
4769 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
4770 Node* backing_store = IntPtrAdd(external_pointer, base_pointer);
4771 StoreElement(backing_store, elements_kind, key, value, parameter_mode);
4772 Goto(&done);
4773
4774 Bind(&done);
4775 return;
4776 }
4777 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
4778 IsFastDoubleElementsKind(elements_kind));
4779
4780 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset)
4781 : LoadFixedArrayBaseLength(elements);
4782 length = UntagParameter(length, parameter_mode);
4783
4784 // In case value is stored into a fast smi array, assure that the value is
4785 // a smi before manipulating the backing store. Otherwise the backing store
4786 // may be left in an invalid state.
4787 if (IsFastSmiElementsKind(elements_kind)) {
4788 GotoUnless(WordIsSmi(value), bailout);
4789 } else if (IsFastDoubleElementsKind(elements_kind)) {
4790 value = PrepareValueForWrite(value, Representation::Double(), bailout);
4791 }
4792
4793 if (IsGrowStoreMode(store_mode)) {
4794 elements = CheckForCapacityGrow(object, elements, elements_kind, length,
4795 key, parameter_mode, is_jsarray, bailout);
4796 } else {
4797 GotoUnless(UintPtrLessThan(key, length), bailout);
4798
4799 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) &&
4800 IsFastSmiOrObjectElementsKind(elements_kind)) {
4801 elements = CopyElementsOnWrite(object, elements, elements_kind, length,
4802 parameter_mode, bailout);
4803 }
4804 }
4805 StoreElement(elements, elements_kind, key, value, parameter_mode);
4806 }
4807
4808 Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
4809 ElementsKind kind, Node* length,
4810 Node* key, ParameterMode mode,
4811 bool is_js_array,
4812 Label* bailout) {
4813 Variable checked_elements(this, MachineRepresentation::kTagged);
4814 Label grow_case(this), no_grow_case(this), done(this);
4815
4816 Node* condition;
4817 if (IsHoleyElementsKind(kind)) {
4818 condition = UintPtrGreaterThanOrEqual(key, length);
4819 } else {
4820 condition = WordEqual(key, length);
4821 }
4822 Branch(condition, &grow_case, &no_grow_case);
4823
4824 Bind(&grow_case);
4825 {
4826 Node* current_capacity =
4827 UntagParameter(LoadFixedArrayBaseLength(elements), mode);
4828
4829 checked_elements.Bind(elements);
4830
4831 Label fits_capacity(this);
4832 GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity);
4833 {
4834 Node* new_elements = TryGrowElementsCapacity(
4835 object, elements, kind, key, current_capacity, mode, bailout);
4836
4837 checked_elements.Bind(new_elements);
4838 Goto(&fits_capacity);
4839 }
4840 Bind(&fits_capacity);
4841
4842 if (is_js_array) {
4843 Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode));
4844 StoreObjectFieldNoWriteBarrier(object, JSArray::kLengthOffset,
4845 TagParameter(new_length, mode));
4846 }
4847 Goto(&done);
4848 }
4849
4850 Bind(&no_grow_case);
4851 {
4852 GotoUnless(UintPtrLessThan(key, length), bailout);
4853 checked_elements.Bind(elements);
4854 Goto(&done);
4855 }
4856
4857 Bind(&done);
4858 return checked_elements.value();
4859 }
4860
4861 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements,
4862 ElementsKind kind, Node* length,
4863 ParameterMode mode,
4864 Label* bailout) {
4865 Variable new_elements_var(this, MachineRepresentation::kTagged);
4866 Label done(this);
4867
4868 new_elements_var.Bind(elements);
4869 GotoUnless(
4870 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)),
4871 &done);
4872 {
4873 Node* capacity = UntagParameter(LoadFixedArrayBaseLength(elements), mode);
4874 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind,
4875 length, capacity, mode, bailout);
4876
4877 new_elements_var.Bind(new_elements);
4878 Goto(&done);
4879 }
4880
4881 Bind(&done);
4882 return new_elements_var.value();
4883 }
4884
4640 Node* CodeStubAssembler::EnumLength(Node* map) { 4885 Node* CodeStubAssembler::EnumLength(Node* map) {
4641 Node* bitfield_3 = LoadMapBitField3(map); 4886 Node* bitfield_3 = LoadMapBitField3(map);
4642 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); 4887 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3);
4643 return SmiTag(enum_length); 4888 return SmiTag(enum_length);
4644 } 4889 }
4645 4890
4646 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, 4891 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
4647 Label* use_runtime) { 4892 Label* use_runtime) {
4648 Variable current_js_object(this, MachineRepresentation::kTagged); 4893 Variable current_js_object(this, MachineRepresentation::kTagged);
4649 current_js_object.Bind(receiver); 4894 current_js_object.Bind(receiver);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4717 Heap::kTheHoleValueRootIndex); 4962 Heap::kTheHoleValueRootIndex);
4718 4963
4719 // Store the WeakCell in the feedback vector. 4964 // Store the WeakCell in the feedback vector.
4720 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4965 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4721 CodeStubAssembler::SMI_PARAMETERS); 4966 CodeStubAssembler::SMI_PARAMETERS);
4722 return cell; 4967 return cell;
4723 } 4968 }
4724 4969
4725 } // namespace internal 4970 } // namespace internal
4726 } // namespace v8 4971 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698