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

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

Issue 2551903002: Merged: [ic] Prevent KeyedStoreIC from being generic when storing doubles to integer typed arrays. (Closed)
Patch Set: Created 4 years 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/compiler/code-assembler.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 #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 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 265 }
266 266
267 Bind(&return_minus_x); 267 Bind(&return_minus_x);
268 var_x.Bind(Float64Neg(var_x.value())); 268 var_x.Bind(Float64Neg(var_x.value()));
269 Goto(&return_x); 269 Goto(&return_x);
270 270
271 Bind(&return_x); 271 Bind(&return_x);
272 return var_x.value(); 272 return var_x.value();
273 } 273 }
274 274
275 Node* CodeStubAssembler::Float64RoundToEven(Node* x) {
276 if (IsFloat64RoundTiesEvenSupported()) {
277 return Float64RoundTiesEven(x);
278 }
279 // See ES#sec-touint8clamp for details.
280 Node* f = Float64Floor(x);
281 Node* f_and_half = Float64Add(f, Float64Constant(0.5));
282
283 Variable var_result(this, MachineRepresentation::kFloat64);
284 Label return_f(this), return_f_plus_one(this), done(this);
285
286 GotoIf(Float64LessThan(f_and_half, x), &return_f_plus_one);
287 GotoIf(Float64LessThan(x, f_and_half), &return_f);
288 {
289 Node* f_mod_2 = Float64Mod(f, Float64Constant(2.0));
290 Branch(Float64Equal(f_mod_2, Float64Constant(0.0)), &return_f,
291 &return_f_plus_one);
292 }
293
294 Bind(&return_f);
295 var_result.Bind(f);
296 Goto(&done);
297
298 Bind(&return_f_plus_one);
299 var_result.Bind(Float64Add(f, Float64Constant(1.0)));
300 Goto(&done);
301
302 Bind(&done);
303 return var_result.value();
304 }
305
275 Node* CodeStubAssembler::Float64Trunc(Node* x) { 306 Node* CodeStubAssembler::Float64Trunc(Node* x) {
276 if (IsFloat64RoundTruncateSupported()) { 307 if (IsFloat64RoundTruncateSupported()) {
277 return Float64RoundTruncate(x); 308 return Float64RoundTruncate(x);
278 } 309 }
279 310
280 Node* one = Float64Constant(1.0); 311 Node* one = Float64Constant(1.0);
281 Node* zero = Float64Constant(0.0); 312 Node* zero = Float64Constant(0.0);
282 Node* two_52 = Float64Constant(4503599627370496.0E0); 313 Node* two_52 = Float64Constant(4503599627370496.0E0);
283 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); 314 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
284 315
(...skipping 6468 matching lines...) Expand 10 before | Expand all | Expand 10 after
6753 Node* native_context = LoadNativeContext(context); 6784 Node* native_context = LoadNativeContext(context);
6754 Node* script_context_table = 6785 Node* script_context_table =
6755 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX); 6786 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
6756 6787
6757 int offset = 6788 int offset =
6758 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag; 6789 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
6759 return Load(MachineType::AnyTagged(), script_context_table, 6790 return Load(MachineType::AnyTagged(), script_context_table,
6760 IntPtrConstant(offset)); 6791 IntPtrConstant(offset));
6761 } 6792 }
6762 6793
6763 Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) {
6764 Label done(this);
6765 Node* int32_zero = Int32Constant(0);
6766 Node* int32_255 = Int32Constant(255);
6767 Variable var_value(this, MachineRepresentation::kWord32);
6768 var_value.Bind(int32_value);
6769 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
6770 var_value.Bind(int32_zero);
6771 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
6772 var_value.Bind(int32_255);
6773 Goto(&done);
6774 Bind(&done);
6775 return var_value.value();
6776 }
6777
6778 namespace { 6794 namespace {
6779 6795
6780 // Converts typed array elements kind to a machine representations. 6796 // Converts typed array elements kind to a machine representations.
6781 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) { 6797 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) {
6782 switch (kind) { 6798 switch (kind) {
6783 case UINT8_CLAMPED_ELEMENTS: 6799 case UINT8_CLAMPED_ELEMENTS:
6784 case UINT8_ELEMENTS: 6800 case UINT8_ELEMENTS:
6785 case INT8_ELEMENTS: 6801 case INT8_ELEMENTS:
6786 return MachineRepresentation::kWord8; 6802 return MachineRepresentation::kWord8;
6787 case UINT16_ELEMENTS: 6803 case UINT16_ELEMENTS:
(...skipping 12 matching lines...) Expand all
6800 } 6816 }
6801 } 6817 }
6802 6818
6803 } // namespace 6819 } // namespace
6804 6820
6805 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, 6821 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
6806 Node* index, Node* value, 6822 Node* index, Node* value,
6807 ParameterMode mode) { 6823 ParameterMode mode) {
6808 if (IsFixedTypedArrayElementsKind(kind)) { 6824 if (IsFixedTypedArrayElementsKind(kind)) {
6809 if (kind == UINT8_CLAMPED_ELEMENTS) { 6825 if (kind == UINT8_CLAMPED_ELEMENTS) {
6810 value = ClampedToUint8(value); 6826 CSA_ASSERT(this,
6827 Word32Equal(value, Word32And(Int32Constant(0xff), value)));
6811 } 6828 }
6812 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0); 6829 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
6813 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind); 6830 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
6814 StoreNoWriteBarrier(rep, elements, offset, value); 6831 StoreNoWriteBarrier(rep, elements, offset, value);
6815 return; 6832 return;
6816 } 6833 }
6817 6834
6818 WriteBarrierMode barrier_mode = 6835 WriteBarrierMode barrier_mode =
6819 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 6836 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
6820 if (IsFastDoubleElementsKind(kind)) { 6837 if (IsFastDoubleElementsKind(kind)) {
6821 // Make sure we do not store signalling NaNs into double arrays. 6838 // Make sure we do not store signalling NaNs into double arrays.
6822 value = Float64SilenceNaN(value); 6839 value = Float64SilenceNaN(value);
6823 StoreFixedDoubleArrayElement(elements, index, value, mode); 6840 StoreFixedDoubleArrayElement(elements, index, value, mode);
6824 } else { 6841 } else {
6825 StoreFixedArrayElement(elements, index, value, barrier_mode, mode); 6842 StoreFixedArrayElement(elements, index, value, barrier_mode, mode);
6826 } 6843 }
6827 } 6844 }
6828 6845
6846 Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) {
6847 Label done(this);
6848 Node* int32_zero = Int32Constant(0);
6849 Node* int32_255 = Int32Constant(255);
6850 Variable var_value(this, MachineRepresentation::kWord32);
6851 var_value.Bind(int32_value);
6852 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
6853 var_value.Bind(int32_zero);
6854 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
6855 var_value.Bind(int32_255);
6856 Goto(&done);
6857 Bind(&done);
6858 return var_value.value();
6859 }
6860
6861 Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) {
6862 Label done(this);
6863 Variable var_value(this, MachineRepresentation::kWord32);
6864 var_value.Bind(Int32Constant(0));
6865 GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done);
6866 var_value.Bind(Int32Constant(255));
6867 GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done);
6868 {
6869 Node* rounded_value = Float64RoundToEven(float64_value);
6870 var_value.Bind(TruncateFloat64ToWord32(rounded_value));
6871 Goto(&done);
6872 }
6873 Bind(&done);
6874 return var_value.value();
6875 }
6876
6877 Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
6878 Node* input, ElementsKind elements_kind, Label* bailout) {
6879 DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
6880
6881 MachineRepresentation rep;
6882 switch (elements_kind) {
6883 case UINT8_ELEMENTS:
6884 case INT8_ELEMENTS:
6885 case UINT16_ELEMENTS:
6886 case INT16_ELEMENTS:
6887 case UINT32_ELEMENTS:
6888 case INT32_ELEMENTS:
6889 case UINT8_CLAMPED_ELEMENTS:
6890 rep = MachineRepresentation::kWord32;
6891 break;
6892 case FLOAT32_ELEMENTS:
6893 rep = MachineRepresentation::kFloat32;
6894 break;
6895 case FLOAT64_ELEMENTS:
6896 rep = MachineRepresentation::kFloat64;
6897 break;
6898 default:
6899 UNREACHABLE();
6900 return nullptr;
6901 }
6902
6903 Variable var_result(this, rep);
6904 Label done(this, &var_result), if_smi(this);
6905 GotoIf(TaggedIsSmi(input), &if_smi);
6906 // Try to convert a heap number to a Smi.
6907 GotoUnless(IsHeapNumberMap(LoadMap(input)), bailout);
6908 {
6909 Node* value = LoadHeapNumberValue(input);
6910 if (rep == MachineRepresentation::kWord32) {
6911 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
6912 value = Float64ToUint8Clamped(value);
6913 } else {
6914 value = TruncateFloat64ToWord32(value);
6915 }
6916 } else if (rep == MachineRepresentation::kFloat32) {
6917 value = TruncateFloat64ToFloat32(value);
6918 } else {
6919 DCHECK_EQ(MachineRepresentation::kFloat64, rep);
6920 }
6921 var_result.Bind(value);
6922 Goto(&done);
6923 }
6924
6925 Bind(&if_smi);
6926 {
6927 Node* value = SmiToWord32(input);
6928 if (rep == MachineRepresentation::kFloat32) {
6929 value = RoundInt32ToFloat32(value);
6930 } else if (rep == MachineRepresentation::kFloat64) {
6931 value = ChangeInt32ToFloat64(value);
6932 } else {
6933 DCHECK_EQ(MachineRepresentation::kWord32, rep);
6934 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
6935 value = Int32ToUint8Clamped(value);
6936 }
6937 }
6938 var_result.Bind(value);
6939 Goto(&done);
6940 }
6941
6942 Bind(&done);
6943 return var_result.value();
6944 }
6945
6829 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, 6946 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
6830 bool is_jsarray, 6947 bool is_jsarray,
6831 ElementsKind elements_kind, 6948 ElementsKind elements_kind,
6832 KeyedAccessStoreMode store_mode, 6949 KeyedAccessStoreMode store_mode,
6833 Label* bailout) { 6950 Label* bailout) {
6834 Node* elements = LoadElements(object); 6951 Node* elements = LoadElements(object);
6835 if (IsFastSmiOrObjectElementsKind(elements_kind) && 6952 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
6836 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 6953 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
6837 // Bailout in case of COW elements. 6954 // Bailout in case of COW elements.
6838 GotoIf(WordNotEqual(LoadMap(elements), 6955 GotoIf(WordNotEqual(LoadMap(elements),
6839 LoadRoot(Heap::kFixedArrayMapRootIndex)), 6956 LoadRoot(Heap::kFixedArrayMapRootIndex)),
6840 bailout); 6957 bailout);
6841 } 6958 }
6842 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode(). 6959 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
6843 ParameterMode parameter_mode = INTPTR_PARAMETERS; 6960 ParameterMode parameter_mode = INTPTR_PARAMETERS;
6844 key = TryToIntptr(key, bailout); 6961 key = TryToIntptr(key, bailout);
6845 6962
6846 if (IsFixedTypedArrayElementsKind(elements_kind)) { 6963 if (IsFixedTypedArrayElementsKind(elements_kind)) {
6847 Label done(this); 6964 Label done(this);
6848 // TODO(ishell): call ToNumber() on value and don't bailout but be careful 6965 // TODO(ishell): call ToNumber() on value and don't bailout but be careful
6849 // to call it only once if we decide to bailout because of bounds checks. 6966 // to call it only once if we decide to bailout because of bounds checks.
6850 6967
6851 if (IsFixedFloatElementsKind(elements_kind)) { 6968 value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout);
6852 // TODO(ishell): move float32 truncation into PrepareValueForWrite.
6853 value = PrepareValueForWrite(value, Representation::Double(), bailout);
6854 if (elements_kind == FLOAT32_ELEMENTS) {
6855 value = TruncateFloat64ToFloat32(value);
6856 }
6857 } else {
6858 // TODO(ishell): It's fine for word8/16/32 to truncate the result.
6859 value = TryToIntptr(value, bailout);
6860 }
6861 6969
6862 // There must be no allocations between the buffer load and 6970 // There must be no allocations between the buffer load and
6863 // and the actual store to backing store, because GC may decide that 6971 // and the actual store to backing store, because GC may decide that
6864 // the buffer is not alive or move the elements. 6972 // the buffer is not alive or move the elements.
6865 // TODO(ishell): introduce DisallowHeapAllocationCode scope here. 6973 // TODO(ishell): introduce DisallowHeapAllocationCode scope here.
6866 6974
6867 // Check if buffer has been neutered. 6975 // Check if buffer has been neutered.
6868 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 6976 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
6869 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, 6977 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
6870 MachineType::Uint32()); 6978 MachineType::Uint32());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6904 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) 7012 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset)
6905 : LoadFixedArrayBaseLength(elements); 7013 : LoadFixedArrayBaseLength(elements);
6906 length = UntagParameter(length, parameter_mode); 7014 length = UntagParameter(length, parameter_mode);
6907 7015
6908 // In case value is stored into a fast smi array, assure that the value is 7016 // In case value is stored into a fast smi array, assure that the value is
6909 // a smi before manipulating the backing store. Otherwise the backing store 7017 // a smi before manipulating the backing store. Otherwise the backing store
6910 // may be left in an invalid state. 7018 // may be left in an invalid state.
6911 if (IsFastSmiElementsKind(elements_kind)) { 7019 if (IsFastSmiElementsKind(elements_kind)) {
6912 GotoUnless(TaggedIsSmi(value), bailout); 7020 GotoUnless(TaggedIsSmi(value), bailout);
6913 } else if (IsFastDoubleElementsKind(elements_kind)) { 7021 } else if (IsFastDoubleElementsKind(elements_kind)) {
6914 value = PrepareValueForWrite(value, Representation::Double(), bailout); 7022 value = TryTaggedToFloat64(value, bailout);
6915 } 7023 }
6916 7024
6917 if (IsGrowStoreMode(store_mode)) { 7025 if (IsGrowStoreMode(store_mode)) {
6918 elements = CheckForCapacityGrow(object, elements, elements_kind, length, 7026 elements = CheckForCapacityGrow(object, elements, elements_kind, length,
6919 key, parameter_mode, is_jsarray, bailout); 7027 key, parameter_mode, is_jsarray, bailout);
6920 } else { 7028 } else {
6921 GotoUnless(UintPtrLessThan(key, length), bailout); 7029 GotoUnless(UintPtrLessThan(key, length), bailout);
6922 7030
6923 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) && 7031 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) &&
6924 IsFastSmiOrObjectElementsKind(elements_kind)) { 7032 IsFastSmiOrObjectElementsKind(elements_kind)) {
(...skipping 2301 matching lines...) Expand 10 before | Expand all | Expand 10 after
9226 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); 9334 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
9227 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); 9335 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
9228 9336
9229 // Check prototype chain if receiver does not have packed elements. 9337 // Check prototype chain if receiver does not have packed elements.
9230 Node* holey_elements = Word32And(elements_kind, Int32Constant(1)); 9338 Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
9231 return Word32Equal(holey_elements, Int32Constant(1)); 9339 return Word32Equal(holey_elements, Int32Constant(1));
9232 } 9340 }
9233 9341
9234 } // namespace internal 9342 } // namespace internal
9235 } // namespace v8 9343 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698