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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 768543002: [WIP] TrapHandler 2014/11/27. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 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/compiler/js-typed-lowering.h ('k') | src/compiler/opcodes.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 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-builtin-reducer.h" 7 #include "src/compiler/js-builtin-reducer.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/node-aux-data-inl.h" 9 #include "src/compiler/node-aux-data-inl.h"
10 #include "src/compiler/node-matchers.h" // TODO(bmeurer): get rid of this?
10 #include "src/compiler/node-properties-inl.h" 11 #include "src/compiler/node-properties-inl.h"
11 #include "src/types.h" 12 #include "src/types.h"
12 13
13 namespace v8 { 14 namespace v8 {
14 namespace internal { 15 namespace internal {
15 namespace compiler { 16 namespace compiler {
16 17
17 // TODO(turbofan): js-typed-lowering improvements possible 18 // TODO(turbofan): js-typed-lowering improvements possible
18 // - immediately put in type bounds for all new nodes 19 // - immediately put in type bounds for all new nodes
19 // - relax effects from generic but not-side-effecting operations 20 // - relax effects from generic but not-side-effecting operations
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 } 666 }
666 return NoChange(); 667 return NoChange();
667 } 668 }
668 669
669 670
670 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) { 671 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
671 Node* key = NodeProperties::GetValueInput(node, 1); 672 Node* key = NodeProperties::GetValueInput(node, 1);
672 Node* base = NodeProperties::GetValueInput(node, 0); 673 Node* base = NodeProperties::GetValueInput(node, 0);
673 Type* key_type = NodeProperties::GetBounds(key).upper; 674 Type* key_type = NodeProperties::GetBounds(key).upper;
674 Type* base_type = NodeProperties::GetBounds(base).upper; 675 Type* base_type = NodeProperties::GetBounds(base).upper;
675 // TODO(mstarzinger): This lowering is not correct if:
676 // a) The typed array or it's buffer is neutered.
677 if (base_type->IsConstant() && key_type->Is(Type::Integral32()) && 676 if (base_type->IsConstant() && key_type->Is(Type::Integral32()) &&
678 base_type->AsConstant()->Value()->IsJSTypedArray()) { 677 base_type->AsConstant()->Value()->IsJSTypedArray()) {
679 // JSLoadProperty(typed-array, int32) 678 // JSLoadProperty(typed-array, int32)
680 Handle<JSTypedArray> array = 679 Handle<JSTypedArray> array =
681 Handle<JSTypedArray>::cast(base_type->AsConstant()->Value()); 680 Handle<JSTypedArray>::cast(base_type->AsConstant()->Value());
682 if (IsExternalArrayElementsKind(array->map()->elements_kind())) { 681 if (IsExternalArrayElementsKind(array->map()->elements_kind())) {
683 ExternalArrayType type = array->type(); 682 Handle<JSArrayBuffer> buffer =
684 double byte_length = array->byte_length()->Number(); 683 Handle<JSArrayBuffer>::cast(handle(array->buffer(), isolate()));
685 if (byte_length <= kMaxInt) { 684 size_t byte_length;
686 Handle<ExternalArray> elements = 685 size_t const page_size = base::OS::CommitPageSize();
687 Handle<ExternalArray>::cast(handle(array->elements())); 686 size_t const guard_size = buffer->is_guarded() ? page_size : 0;
687 if (array->byte_offset()->SameValue(Smi::FromInt(0)) &&
688 array->byte_length()->SameValue(buffer->byte_length()) &&
689 TryNumberToSize(isolate(), array->byte_length(), &byte_length) &&
690 byte_length <= 0x80000000u - guard_size) {
691 DCHECK((byte_length % array->element_size()) == 0);
692 BufferAccess const access(array->type(), guard_size);
688 Node* pointer = jsgraph()->IntPtrConstant( 693 Node* pointer = jsgraph()->IntPtrConstant(
689 bit_cast<intptr_t>(elements->external_pointer())); 694 bit_cast<intptr_t>(buffer->backing_store()));
690 Node* length = jsgraph()->Constant(array->length()->Number()); 695 Node* offset = key;
696 int const element_size_shift =
697 WhichPowerOf2(static_cast<int>(array->element_size()));
698 // TODO(bmeurer)
699 Factory* factory = zone()->isolate()->factory();
700 Handle<Object> min = factory->NewNumber(0);
701 Handle<Object> max =
702 factory->NewNumber((byte_length - 1) >> element_size_shift);
703 if (key_type->Is(Type::Range(min, max, zone()))) {
704 offset =
705 graph()->NewNode(machine()->Word32Shl(), key,
706 jsgraph()->Uint32Constant(element_size_shift));
707 } else if (element_size_shift != 0) {
708 if (offset->opcode() != IrOpcode::kWord32Sar) return NoChange();
709 NumberBinopMatcher moffset(offset);
710 if (!moffset.right().Is(element_size_shift)) return NoChange();
711 offset = moffset.left().node();
712 }
713 Node* length = jsgraph()->Constant(static_cast<double>(byte_length));
691 Node* effect = NodeProperties::GetEffectInput(node); 714 Node* effect = NodeProperties::GetEffectInput(node);
692 Node* load = graph()->NewNode( 715 Node* control = NodeProperties::GetControlInput(node);
693 simplified()->LoadElement( 716 Node* load = graph()->NewNode(simplified()->LoadBuffer(access), pointer,
694 AccessBuilder::ForTypedArrayElement(type, true)), 717 offset, length, effect, control);
695 pointer, key, length, effect);
696 return ReplaceEagerly(node, load); 718 return ReplaceEagerly(node, load);
697 } 719 }
698 } 720 }
699 } 721 }
700 return NoChange(); 722 return NoChange();
701 } 723 }
702 724
703 725
704 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { 726 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
705 Node* key = NodeProperties::GetValueInput(node, 1); 727 Node* key = NodeProperties::GetValueInput(node, 1);
706 Node* base = NodeProperties::GetValueInput(node, 0); 728 Node* base = NodeProperties::GetValueInput(node, 0);
707 Node* value = NodeProperties::GetValueInput(node, 2); 729 Node* value = NodeProperties::GetValueInput(node, 2);
708 Type* key_type = NodeProperties::GetBounds(key).upper; 730 Type* key_type = NodeProperties::GetBounds(key).upper;
709 Type* base_type = NodeProperties::GetBounds(base).upper; 731 Type* base_type = NodeProperties::GetBounds(base).upper;
710 // TODO(mstarzinger): This lowering is not correct if: 732 Type* value_type = NodeProperties::GetBounds(value).upper;
711 // a) The typed array or its buffer is neutered. 733 if (base_type->IsConstant() && key_type->Is(Type::Integral32()) &&
712 if (key_type->Is(Type::Integral32()) && base_type->IsConstant() &&
713 base_type->AsConstant()->Value()->IsJSTypedArray()) { 734 base_type->AsConstant()->Value()->IsJSTypedArray()) {
714 // JSStoreProperty(typed-array, int32, value) 735 // JSStoreProperty(typed-array, int32, value)
715 Handle<JSTypedArray> array = 736 Handle<JSTypedArray> array =
716 Handle<JSTypedArray>::cast(base_type->AsConstant()->Value()); 737 Handle<JSTypedArray>::cast(base_type->AsConstant()->Value());
717 if (IsExternalArrayElementsKind(array->map()->elements_kind())) { 738 if (IsExternalArrayElementsKind(array->map()->elements_kind())) {
718 ExternalArrayType type = array->type(); 739 Handle<JSArrayBuffer> buffer =
719 double byte_length = array->byte_length()->Number(); 740 Handle<JSArrayBuffer>::cast(handle(array->buffer(), isolate()));
720 if (byte_length <= kMaxInt) { 741 size_t byte_length;
721 Handle<ExternalArray> elements = 742 size_t const page_size = base::OS::CommitPageSize();
722 Handle<ExternalArray>::cast(handle(array->elements())); 743 size_t const guard_size = buffer->is_guarded() ? page_size : 0;
744 if (array->byte_offset()->SameValue(Smi::FromInt(0)) &&
745 array->byte_length()->SameValue(buffer->byte_length()) &&
746 TryNumberToSize(isolate(), array->byte_length(), &byte_length) &&
747 byte_length <= 0x80000000u - guard_size) {
748 DCHECK((byte_length % array->element_size()) == 0);
749 BufferAccess const access(array->type(), guard_size);
723 Node* pointer = jsgraph()->IntPtrConstant( 750 Node* pointer = jsgraph()->IntPtrConstant(
724 bit_cast<intptr_t>(elements->external_pointer())); 751 bit_cast<intptr_t>(buffer->backing_store()));
725 Node* length = jsgraph()->Constant(array->length()->Number()); 752 Node* offset = key;
753 int const element_size_shift =
754 WhichPowerOf2(static_cast<int>(array->element_size()));
755 // TODO(bmeurer)
756 Factory* factory = zone()->isolate()->factory();
757 Handle<Object> min = factory->NewNumber(0);
758 Handle<Object> max =
759 factory->NewNumber((byte_length - 1) >> element_size_shift);
760 if (key_type->Is(Type::Range(min, max, zone()))) {
761 offset =
762 graph()->NewNode(machine()->Word32Shl(), key,
763 jsgraph()->Uint32Constant(element_size_shift));
764 } else if (element_size_shift != 0) {
765 if (offset->opcode() != IrOpcode::kWord32Sar) return NoChange();
766 NumberBinopMatcher moffset(offset);
767 if (!moffset.right().Is(element_size_shift)) return NoChange();
768 offset = moffset.left().node();
769 }
770 Node* length = jsgraph()->Constant(static_cast<double>(byte_length));
726 Node* effect = NodeProperties::GetEffectInput(node); 771 Node* effect = NodeProperties::GetEffectInput(node);
727 Node* control = NodeProperties::GetControlInput(node); 772 Node* control = NodeProperties::GetControlInput(node);
728 773
729 ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
730 Type* value_type = NodeProperties::GetBounds(value).upper;
731 // If the value input does not have the required type, insert the 774 // If the value input does not have the required type, insert the
732 // appropriate conversion. 775 // appropriate conversion.
733 776
734 // Convert to a number first. 777 // Convert to a number first.
735 if (!value_type->Is(Type::Number())) { 778 if (!value_type->Is(Type::Number())) {
736 Reduction number_reduction = ReduceJSToNumberInput(value); 779 Reduction number_reduction = ReduceJSToNumberInput(value);
737 if (number_reduction.Changed()) { 780 if (number_reduction.Changed()) {
738 value = number_reduction.replacement(); 781 value = number_reduction.replacement();
739 } else { 782 } else {
740 Node* context = NodeProperties::GetContextInput(node); 783 Node* context = NodeProperties::GetContextInput(node);
741 value = graph()->NewNode(javascript()->ToNumber(), value, context, 784 value = graph()->NewNode(javascript()->ToNumber(), value, context,
742 effect, control); 785 effect, control);
743 effect = value; 786 effect = value;
744 } 787 }
745 } 788 }
746 // For integer-typed arrays, convert to the integer type. 789 // For integer-typed arrays, convert to the integer type.
747 if (access.type->Is(Type::Signed32()) && 790 if (TypeOf(access.machine_type()) == kTypeInt32 &&
748 !value_type->Is(Type::Signed32())) { 791 !value_type->Is(Type::Signed32())) {
749 value = graph()->NewNode(simplified()->NumberToInt32(), value); 792 value = graph()->NewNode(simplified()->NumberToInt32(), value);
750 } else if (access.type->Is(Type::Unsigned32()) && 793 } else if (TypeOf(access.machine_type()) == kTypeUint32 &&
751 !value_type->Is(Type::Unsigned32())) { 794 !value_type->Is(Type::Unsigned32())) {
752 value = graph()->NewNode(simplified()->NumberToUint32(), value); 795 value = graph()->NewNode(simplified()->NumberToUint32(), value);
753 } 796 }
754 797
755 Node* store = 798 Node* store =
756 graph()->NewNode(simplified()->StoreElement(access), pointer, key, 799 graph()->NewNode(simplified()->StoreBuffer(access), pointer, offset,
757 length, value, effect, control); 800 length, value, effect, control);
758 return ReplaceEagerly(node, store); 801 return ReplaceEagerly(node, store);
759 } 802 }
760 } 803 }
761 } 804 }
762 return NoChange(); 805 return NoChange();
763 } 806 }
764 807
765 808
766 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { 809 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 return JSBuiltinReducer(jsgraph()).Reduce(node); 896 return JSBuiltinReducer(jsgraph()).Reduce(node);
854 default: 897 default:
855 break; 898 break;
856 } 899 }
857 return NoChange(); 900 return NoChange();
858 } 901 }
859 902
860 } // namespace compiler 903 } // namespace compiler
861 } // namespace internal 904 } // namespace internal
862 } // namespace v8 905 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698