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

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

Issue 2539013002: [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 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 5383 matching lines...) Expand 10 before | Expand all | Expand 10 after
5394 Node* native_context = LoadNativeContext(context); 5394 Node* native_context = LoadNativeContext(context);
5395 Node* script_context_table = 5395 Node* script_context_table =
5396 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX); 5396 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
5397 5397
5398 int offset = 5398 int offset =
5399 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag; 5399 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
5400 return Load(MachineType::AnyTagged(), script_context_table, 5400 return Load(MachineType::AnyTagged(), script_context_table,
5401 IntPtrConstant(offset)); 5401 IntPtrConstant(offset));
5402 } 5402 }
5403 5403
5404 Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) {
Igor Sheludko 2016/11/30 09:32:05 I renamed it and moved down.
5405 Label done(this);
5406 Node* int32_zero = Int32Constant(0);
5407 Node* int32_255 = Int32Constant(255);
5408 Variable var_value(this, MachineRepresentation::kWord32);
5409 var_value.Bind(int32_value);
5410 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
5411 var_value.Bind(int32_zero);
5412 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
5413 var_value.Bind(int32_255);
5414 Goto(&done);
5415 Bind(&done);
5416 return var_value.value();
5417 }
5418
5419 namespace { 5404 namespace {
5420 5405
5421 // Converts typed array elements kind to a machine representations. 5406 // Converts typed array elements kind to a machine representations.
5422 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) { 5407 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) {
5423 switch (kind) { 5408 switch (kind) {
5424 case UINT8_CLAMPED_ELEMENTS: 5409 case UINT8_CLAMPED_ELEMENTS:
5425 case UINT8_ELEMENTS: 5410 case UINT8_ELEMENTS:
5426 case INT8_ELEMENTS: 5411 case INT8_ELEMENTS:
5427 return MachineRepresentation::kWord8; 5412 return MachineRepresentation::kWord8;
5428 case UINT16_ELEMENTS: 5413 case UINT16_ELEMENTS:
(...skipping 12 matching lines...) Expand all
5441 } 5426 }
5442 } 5427 }
5443 5428
5444 } // namespace 5429 } // namespace
5445 5430
5446 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, 5431 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
5447 Node* index, Node* value, 5432 Node* index, Node* value,
5448 ParameterMode mode) { 5433 ParameterMode mode) {
5449 if (IsFixedTypedArrayElementsKind(kind)) { 5434 if (IsFixedTypedArrayElementsKind(kind)) {
5450 if (kind == UINT8_CLAMPED_ELEMENTS) { 5435 if (kind == UINT8_CLAMPED_ELEMENTS) {
5451 value = ClampedToUint8(value); 5436 CSA_ASSERT(this,
5437 Word32Equal(value, Word32And(Int32Constant(0xff), value)));
5452 } 5438 }
5453 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0); 5439 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
5454 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind); 5440 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
5455 StoreNoWriteBarrier(rep, elements, offset, value); 5441 StoreNoWriteBarrier(rep, elements, offset, value);
5456 return; 5442 return;
5457 } 5443 }
5458 5444
5459 WriteBarrierMode barrier_mode = 5445 WriteBarrierMode barrier_mode =
5460 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 5446 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
5461 if (IsFastDoubleElementsKind(kind)) { 5447 if (IsFastDoubleElementsKind(kind)) {
5462 // Make sure we do not store signalling NaNs into double arrays. 5448 // Make sure we do not store signalling NaNs into double arrays.
5463 value = Float64SilenceNaN(value); 5449 value = Float64SilenceNaN(value);
5464 StoreFixedDoubleArrayElement(elements, index, value, mode); 5450 StoreFixedDoubleArrayElement(elements, index, value, mode);
5465 } else { 5451 } else {
5466 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode); 5452 StoreFixedArrayElement(elements, index, value, barrier_mode, 0, mode);
5467 } 5453 }
5468 } 5454 }
5469 5455
5456 Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) {
5457 Label done(this);
5458 Node* int32_zero = Int32Constant(0);
5459 Node* int32_255 = Int32Constant(255);
5460 Variable var_value(this, MachineRepresentation::kWord32);
5461 var_value.Bind(int32_value);
5462 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
5463 var_value.Bind(int32_zero);
5464 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
5465 var_value.Bind(int32_255);
5466 Goto(&done);
5467 Bind(&done);
5468 return var_value.value();
5469 }
5470
5471 Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) {
5472 Label done(this);
5473 Variable var_value(this, MachineRepresentation::kWord32);
5474 var_value.Bind(Int32Constant(0));
5475 GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done);
5476 var_value.Bind(Int32Constant(255));
5477 GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done);
5478 {
5479 Node* rounded_value = Float64RoundTiesEven(float64_value);
5480 var_value.Bind(TruncateFloat64ToWord32(rounded_value));
5481 Goto(&done);
5482 }
5483 Bind(&done);
5484 return var_value.value();
5485 }
5486
5487 Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
5488 Node* input, ElementsKind elements_kind, Label* bailout) {
5489 DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
5490
5491 MachineRepresentation rep;
5492 switch (elements_kind) {
5493 case UINT8_ELEMENTS:
5494 case INT8_ELEMENTS:
5495 case UINT16_ELEMENTS:
5496 case INT16_ELEMENTS:
5497 case UINT32_ELEMENTS:
5498 case INT32_ELEMENTS:
5499 case UINT8_CLAMPED_ELEMENTS:
5500 rep = MachineRepresentation::kWord32;
5501 break;
5502 case FLOAT32_ELEMENTS:
5503 rep = MachineRepresentation::kFloat32;
5504 break;
5505 case FLOAT64_ELEMENTS:
5506 rep = MachineRepresentation::kFloat64;
5507 break;
5508 default:
5509 UNREACHABLE();
5510 return nullptr;
5511 }
5512
5513 Variable var_result(this, rep);
5514 Label done(this, &var_result), if_smi(this);
5515 GotoIf(TaggedIsSmi(input), &if_smi);
5516 // Try to convert a heap number to a Smi.
5517 GotoUnless(IsHeapNumberMap(LoadMap(input)), bailout);
5518 {
5519 Node* value = LoadHeapNumberValue(input);
5520 if (rep == MachineRepresentation::kWord32) {
5521 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
5522 value = Float64ToUint8Clamped(value);
5523 } else {
5524 value = TruncateFloat64ToWord32(value);
5525 }
5526 } else if (rep == MachineRepresentation::kFloat32) {
5527 value = TruncateFloat64ToFloat32(value);
5528 } else {
5529 DCHECK_EQ(MachineRepresentation::kFloat64, rep);
5530 }
5531 var_result.Bind(value);
5532 Goto(&done);
5533 }
5534
5535 Bind(&if_smi);
5536 {
5537 Node* value = SmiToWord32(input);
5538 if (rep == MachineRepresentation::kFloat32) {
5539 value = RoundInt32ToFloat32(value);
5540 } else if (rep == MachineRepresentation::kFloat64) {
5541 value = ChangeInt32ToFloat64(value);
5542 } else {
5543 DCHECK_EQ(MachineRepresentation::kWord32, rep);
5544 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
5545 value = Int32ToUint8Clamped(value);
5546 }
5547 }
5548 var_result.Bind(value);
5549 Goto(&done);
5550 }
5551
5552 Bind(&done);
5553 return var_result.value();
5554 }
5555
5470 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, 5556 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
5471 bool is_jsarray, 5557 bool is_jsarray,
5472 ElementsKind elements_kind, 5558 ElementsKind elements_kind,
5473 KeyedAccessStoreMode store_mode, 5559 KeyedAccessStoreMode store_mode,
5474 Label* bailout) { 5560 Label* bailout) {
5475 Node* elements = LoadElements(object); 5561 Node* elements = LoadElements(object);
5476 if (IsFastSmiOrObjectElementsKind(elements_kind) && 5562 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
5477 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 5563 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
5478 // Bailout in case of COW elements. 5564 // Bailout in case of COW elements.
5479 GotoIf(WordNotEqual(LoadMap(elements), 5565 GotoIf(WordNotEqual(LoadMap(elements),
5480 LoadRoot(Heap::kFixedArrayMapRootIndex)), 5566 LoadRoot(Heap::kFixedArrayMapRootIndex)),
5481 bailout); 5567 bailout);
5482 } 5568 }
5483 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode(). 5569 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
5484 ParameterMode parameter_mode = INTPTR_PARAMETERS; 5570 ParameterMode parameter_mode = INTPTR_PARAMETERS;
5485 key = TryToIntptr(key, bailout); 5571 key = TryToIntptr(key, bailout);
5486 5572
5487 if (IsFixedTypedArrayElementsKind(elements_kind)) { 5573 if (IsFixedTypedArrayElementsKind(elements_kind)) {
5488 Label done(this); 5574 Label done(this);
5489 // TODO(ishell): call ToNumber() on value and don't bailout but be careful 5575 // TODO(ishell): call ToNumber() on value and don't bailout but be careful
5490 // to call it only once if we decide to bailout because of bounds checks. 5576 // to call it only once if we decide to bailout because of bounds checks.
5491 5577
5492 if (IsFixedFloatElementsKind(elements_kind)) { 5578 value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout);
5493 // TODO(ishell): move float32 truncation into PrepareValueForWrite.
5494 value = PrepareValueForWrite(value, Representation::Double(), bailout);
5495 if (elements_kind == FLOAT32_ELEMENTS) {
5496 value = TruncateFloat64ToFloat32(value);
5497 }
5498 } else {
5499 // TODO(ishell): It's fine for word8/16/32 to truncate the result.
5500 value = TryToIntptr(value, bailout);
5501 }
5502 5579
5503 // There must be no allocations between the buffer load and 5580 // There must be no allocations between the buffer load and
5504 // and the actual store to backing store, because GC may decide that 5581 // and the actual store to backing store, because GC may decide that
5505 // the buffer is not alive or move the elements. 5582 // the buffer is not alive or move the elements.
5506 // TODO(ishell): introduce DisallowHeapAllocationCode scope here. 5583 // TODO(ishell): introduce DisallowHeapAllocationCode scope here.
5507 5584
5508 // Check if buffer has been neutered. 5585 // Check if buffer has been neutered.
5509 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 5586 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
5510 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, 5587 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
5511 MachineType::Uint32()); 5588 MachineType::Uint32());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5545 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset) 5622 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset)
5546 : LoadFixedArrayBaseLength(elements); 5623 : LoadFixedArrayBaseLength(elements);
5547 length = UntagParameter(length, parameter_mode); 5624 length = UntagParameter(length, parameter_mode);
5548 5625
5549 // In case value is stored into a fast smi array, assure that the value is 5626 // In case value is stored into a fast smi array, assure that the value is
5550 // a smi before manipulating the backing store. Otherwise the backing store 5627 // a smi before manipulating the backing store. Otherwise the backing store
5551 // may be left in an invalid state. 5628 // may be left in an invalid state.
5552 if (IsFastSmiElementsKind(elements_kind)) { 5629 if (IsFastSmiElementsKind(elements_kind)) {
5553 GotoUnless(TaggedIsSmi(value), bailout); 5630 GotoUnless(TaggedIsSmi(value), bailout);
5554 } else if (IsFastDoubleElementsKind(elements_kind)) { 5631 } else if (IsFastDoubleElementsKind(elements_kind)) {
5555 value = PrepareValueForWrite(value, Representation::Double(), bailout); 5632 value = TryTaggedToFloat64(value, bailout);
5556 } 5633 }
5557 5634
5558 if (IsGrowStoreMode(store_mode)) { 5635 if (IsGrowStoreMode(store_mode)) {
5559 elements = CheckForCapacityGrow(object, elements, elements_kind, length, 5636 elements = CheckForCapacityGrow(object, elements, elements_kind, length,
5560 key, parameter_mode, is_jsarray, bailout); 5637 key, parameter_mode, is_jsarray, bailout);
5561 } else { 5638 } else {
5562 GotoUnless(UintPtrLessThan(key, length), bailout); 5639 GotoUnless(UintPtrLessThan(key, length), bailout);
5563 5640
5564 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) && 5641 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) &&
5565 IsFastSmiOrObjectElementsKind(elements_kind)) { 5642 IsFastSmiOrObjectElementsKind(elements_kind)) {
(...skipping 2283 matching lines...) Expand 10 before | Expand all | Expand 10 after
7849 7926
7850 Node* CodeStubAssembler::IsDebugActive() { 7927 Node* CodeStubAssembler::IsDebugActive() {
7851 Node* is_debug_active = Load( 7928 Node* is_debug_active = Load(
7852 MachineType::Uint8(), 7929 MachineType::Uint8(),
7853 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); 7930 ExternalConstant(ExternalReference::debug_is_active_address(isolate())));
7854 return WordNotEqual(is_debug_active, Int32Constant(0)); 7931 return WordNotEqual(is_debug_active, Int32Constant(0));
7855 } 7932 }
7856 7933
7857 } // namespace internal 7934 } // namespace internal
7858 } // namespace v8 7935 } // 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