OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-typed-lowering.h" | 7 #include "src/compiler/js-typed-lowering.h" |
8 #include "src/compiler/node-aux-data-inl.h" | 8 #include "src/compiler/node-aux-data-inl.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/types.h" | 10 #include "src/types.h" |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 | 551 |
552 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { | 552 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { |
553 Node* key = NodeProperties::GetValueInput(node, 1); | 553 Node* key = NodeProperties::GetValueInput(node, 1); |
554 Node* base = NodeProperties::GetValueInput(node, 0); | 554 Node* base = NodeProperties::GetValueInput(node, 0); |
555 Node* value = NodeProperties::GetValueInput(node, 2); | 555 Node* value = NodeProperties::GetValueInput(node, 2); |
556 Type* key_type = NodeProperties::GetBounds(key).upper; | 556 Type* key_type = NodeProperties::GetBounds(key).upper; |
557 Type* base_type = NodeProperties::GetBounds(base).upper; | 557 Type* base_type = NodeProperties::GetBounds(base).upper; |
558 // TODO(mstarzinger): This lowering is not correct if: | 558 // TODO(mstarzinger): This lowering is not correct if: |
559 // a) The typed array turns external (i.e. MaterializeArrayBuffer) | 559 // a) The typed array turns external (i.e. MaterializeArrayBuffer) |
560 // b) The typed array or it's buffer is neutered. | 560 // b) The typed array or it's buffer is neutered. |
561 // c) The index is out of bounds | |
562 if (key_type->Is(Type::Integral32()) && base_type->IsConstant() && | 561 if (key_type->Is(Type::Integral32()) && base_type->IsConstant() && |
563 base_type->AsConstant()->Value()->IsJSTypedArray()) { | 562 base_type->AsConstant()->Value()->IsJSTypedArray()) { |
564 // JSStoreProperty(typed-array, int32, value) | 563 // JSStoreProperty(typed-array, int32, value) |
565 JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value()); | 564 JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value()); |
566 ElementsKind elements_kind = array->map()->elements_kind(); | 565 ElementsKind elements_kind = array->map()->elements_kind(); |
567 ExternalArrayType type = array->type(); | 566 ExternalArrayType type = array->type(); |
| 567 uint32_t length; |
| 568 CHECK(array->length()->ToUint32(&length)); |
568 ElementAccess element_access; | 569 ElementAccess element_access; |
569 Node* elements = graph()->NewNode( | 570 Node* elements = graph()->NewNode( |
570 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), base, | 571 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), base, |
571 NodeProperties::GetEffectInput(node)); | 572 NodeProperties::GetEffectInput(node)); |
572 if (IsExternalArrayElementsKind(elements_kind)) { | 573 if (IsExternalArrayElementsKind(elements_kind)) { |
573 elements = graph()->NewNode( | 574 elements = graph()->NewNode( |
574 simplified()->LoadField(AccessBuilder::ForExternalArrayPointer()), | 575 simplified()->LoadField(AccessBuilder::ForExternalArrayPointer()), |
575 elements, NodeProperties::GetEffectInput(node)); | 576 elements, NodeProperties::GetEffectInput(node)); |
576 element_access = AccessBuilder::ForTypedArrayElement(type, true); | 577 element_access = AccessBuilder::ForTypedArrayElement(type, true); |
577 } else { | 578 } else { |
578 DCHECK(IsFixedTypedArrayElementsKind(elements_kind)); | 579 DCHECK(IsFixedTypedArrayElementsKind(elements_kind)); |
579 element_access = AccessBuilder::ForTypedArrayElement(type, false); | 580 element_access = AccessBuilder::ForTypedArrayElement(type, false); |
580 } | 581 } |
581 Node* store = | 582 |
582 graph()->NewNode(simplified()->StoreElement(element_access), elements, | 583 Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, |
583 key, value, NodeProperties::GetEffectInput(node), | 584 jsgraph()->Uint32Constant(length)); |
584 NodeProperties::GetControlInput(node)); | 585 Node* branch = graph()->NewNode(common()->Branch(), check, |
585 return ReplaceEagerly(node, store); | 586 NodeProperties::GetControlInput(node)); |
| 587 |
| 588 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 589 Node* store = graph()->NewNode( |
| 590 simplified()->StoreElement(element_access), elements, key, value, |
| 591 NodeProperties::GetEffectInput(node), if_true); |
| 592 |
| 593 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 594 |
| 595 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 596 Node* phi = graph()->NewNode(common()->EffectPhi(2), store, |
| 597 NodeProperties::GetEffectInput(node), merge); |
| 598 |
| 599 return ReplaceWith(phi); |
586 } | 600 } |
587 return NoChange(); | 601 return NoChange(); |
588 } | 602 } |
589 | 603 |
590 | 604 |
591 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { | 605 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { |
592 if (reduction.Changed()) { | 606 if (reduction.Changed()) { |
593 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | 607 NodeProperties::ReplaceWithValue(node, reduction.replacement()); |
594 return reduction; | 608 return reduction; |
595 } | 609 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 return ReduceJSStoreProperty(node); | 682 return ReduceJSStoreProperty(node); |
669 default: | 683 default: |
670 break; | 684 break; |
671 } | 685 } |
672 return NoChange(); | 686 return NoChange(); |
673 } | 687 } |
674 | 688 |
675 } // namespace compiler | 689 } // namespace compiler |
676 } // namespace internal | 690 } // namespace internal |
677 } // namespace v8 | 691 } // namespace v8 |
OLD | NEW |