| 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
| 7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 } | 327 } |
| 328 Node* new_stack = | 328 Node* new_stack = |
| 329 graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front()); | 329 graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front()); |
| 330 | 330 |
| 331 return graph()->NewNode(op, frame_state->InputAt(0), | 331 return graph()->NewNode(op, frame_state->InputAt(0), |
| 332 frame_state->InputAt(1), new_stack, | 332 frame_state->InputAt(1), new_stack, |
| 333 frame_state->InputAt(3), frame_state->InputAt(4)); | 333 frame_state->InputAt(3), frame_state->InputAt(4)); |
| 334 } | 334 } |
| 335 | 335 |
| 336 Node* ConvertPrimitiveToNumber(Node* node) { | 336 Node* ConvertPrimitiveToNumber(Node* node) { |
| 337 return lowering_->ConvertPrimitiveToNumber(node); | 337 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())); |
| 338 // Avoid inserting too many eager ToNumber() operations. |
| 339 Reduction const reduction = lowering_->ReduceJSToNumberInput(node); |
| 340 if (reduction.Changed()) return reduction.replacement(); |
| 341 return graph()->NewNode( |
| 342 javascript()->ToNumber(), node, jsgraph()->NoContextConstant(), |
| 343 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); |
| 338 } | 344 } |
| 339 | 345 |
| 340 Node* ConvertToNumber(Node* node, Node* frame_state) { | 346 Node* ConvertToNumber(Node* node, Node* frame_state) { |
| 341 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { | 347 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { |
| 342 return ConvertPrimitiveToNumber(node); | 348 return ConvertPrimitiveToNumber(node); |
| 343 } else { | 349 } else { |
| 344 Node* const n = | 350 Node* const n = |
| 345 graph()->NewNode(javascript()->ToNumber(), node, context(), | 351 graph()->NewNode(javascript()->ToNumber(), node, context(), |
| 346 frame_state, effect(), control()); | 352 frame_state, effect(), control()); |
| 347 update_effect(n); | 353 update_effect(n); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 } | 679 } |
| 674 if (input_type->Is(Type::Boolean())) { | 680 if (input_type->Is(Type::Boolean())) { |
| 675 // JSToNumber(x:boolean) => BooleanToNumber(x) | 681 // JSToNumber(x:boolean) => BooleanToNumber(x) |
| 676 return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input)); | 682 return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input)); |
| 677 } | 683 } |
| 678 // TODO(turbofan): js-typed-lowering of ToNumber(x:string) | 684 // TODO(turbofan): js-typed-lowering of ToNumber(x:string) |
| 679 return NoChange(); | 685 return NoChange(); |
| 680 } | 686 } |
| 681 | 687 |
| 682 | 688 |
| 689 namespace { |
| 690 |
| 691 bool CanCover(Node* user, Node* node) { |
| 692 for (auto edge : node->use_edges()) { |
| 693 if (NodeProperties::IsValueEdge(edge) && edge.from() != user) return false; |
| 694 } |
| 695 return true; |
| 696 } |
| 697 |
| 698 } // namespace |
| 699 |
| 700 |
| 701 // TODO(bmeurer): Move this into a dedicated conversion/truncation analysis, |
| 702 // which works bottom-up from the uses. |
| 703 Reduction JSTypedLowering::ReduceNumberToInt32(Node* node) { |
| 704 Node* const number = node->InputAt(0); |
| 705 if (number->opcode() == IrOpcode::kJSToNumber && CanCover(node, number)) { |
| 706 Node* const input = number->InputAt(0); |
| 707 if (input->opcode() == IrOpcode::kJSLoadProperty && |
| 708 CanCover(number, input)) { |
| 709 Node* key = NodeProperties::GetValueInput(input, 1); |
| 710 Node* base = NodeProperties::GetValueInput(input, 0); |
| 711 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 712 HeapObjectMatcher<Object> mbase(base); |
| 713 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { |
| 714 Handle<JSTypedArray> const array = |
| 715 Handle<JSTypedArray>::cast(mbase.Value().handle()); |
| 716 if (!array->GetBuffer()->was_neutered() && |
| 717 (array->type() != kExternalFloat32Array && |
| 718 array->type() != kExternalFloat64Array)) { |
| 719 array->GetBuffer()->set_is_neuterable(false); |
| 720 BufferAccess const access(array->type()); |
| 721 size_t const k = ElementSizeLog2Of(access.machine_type()); |
| 722 double const byte_length = array->byte_length()->Number(); |
| 723 CHECK_LT(k, arraysize(shifted_int32_ranges_)); |
| 724 if (IsExternalArrayElementsKind(array->map()->elements_kind()) && |
| 725 key_type->Is(shifted_int32_ranges_[k]) && |
| 726 byte_length <= kMaxInt) { |
| 727 // JSLoadProperty(typed-array, int32) |
| 728 Handle<ExternalArray> elements = |
| 729 Handle<ExternalArray>::cast(handle(array->elements())); |
| 730 Node* buffer = |
| 731 jsgraph()->PointerConstant(elements->external_pointer()); |
| 732 Node* length = jsgraph()->Constant(byte_length); |
| 733 Node* effect = NodeProperties::GetEffectInput(input); |
| 734 Node* control = NodeProperties::GetControlInput(input); |
| 735 // Compute byte offset. |
| 736 Node* offset = Word32Shl(key, static_cast<int>(k)); |
| 737 Node* load = |
| 738 graph()->NewNode(simplified()->LoadBuffer(access), buffer, |
| 739 offset, length, effect, control); |
| 740 NodeProperties::ReplaceWithValue(input, load, load); |
| 741 NodeProperties::ReplaceWithValue(number, load); |
| 742 number->Kill(); |
| 743 input->Kill(); |
| 744 return Replace(load); |
| 745 } |
| 746 } |
| 747 } |
| 748 } |
| 749 } |
| 750 return NoChange(); |
| 751 } |
| 752 |
| 753 |
| 754 // TODO(bmeurer): Move this into a dedicated conversion/truncation analysis, |
| 755 // which works bottom-up from the uses. |
| 756 Reduction JSTypedLowering::ReduceNumberToUint32(Node* node) { |
| 757 Node* const number = node->InputAt(0); |
| 758 if (number->opcode() == IrOpcode::kJSToNumber && CanCover(node, number)) { |
| 759 Node* const input = number->InputAt(0); |
| 760 if (input->opcode() == IrOpcode::kJSLoadProperty && |
| 761 CanCover(number, input)) { |
| 762 Node* key = NodeProperties::GetValueInput(input, 1); |
| 763 Node* base = NodeProperties::GetValueInput(input, 0); |
| 764 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 765 HeapObjectMatcher<Object> mbase(base); |
| 766 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { |
| 767 Handle<JSTypedArray> const array = |
| 768 Handle<JSTypedArray>::cast(mbase.Value().handle()); |
| 769 if (!array->GetBuffer()->was_neutered() && |
| 770 (array->type() != kExternalFloat32Array && |
| 771 array->type() != kExternalFloat64Array)) { |
| 772 array->GetBuffer()->set_is_neuterable(false); |
| 773 BufferAccess const access(array->type()); |
| 774 size_t const k = ElementSizeLog2Of(access.machine_type()); |
| 775 double const byte_length = array->byte_length()->Number(); |
| 776 CHECK_LT(k, arraysize(shifted_int32_ranges_)); |
| 777 if (IsExternalArrayElementsKind(array->map()->elements_kind()) && |
| 778 key_type->Is(shifted_int32_ranges_[k]) && |
| 779 byte_length <= kMaxInt) { |
| 780 // JSLoadProperty(typed-array, int32) |
| 781 Handle<ExternalArray> elements = |
| 782 Handle<ExternalArray>::cast(handle(array->elements())); |
| 783 Node* buffer = |
| 784 jsgraph()->PointerConstant(elements->external_pointer()); |
| 785 Node* length = jsgraph()->Constant(byte_length); |
| 786 Node* effect = NodeProperties::GetEffectInput(input); |
| 787 Node* control = NodeProperties::GetControlInput(input); |
| 788 // Compute byte offset. |
| 789 Node* offset = Word32Shl(key, static_cast<int>(k)); |
| 790 Node* load = |
| 791 graph()->NewNode(simplified()->LoadBuffer(access), buffer, |
| 792 offset, length, effect, control); |
| 793 NodeProperties::ReplaceWithValue(input, load, load); |
| 794 NodeProperties::ReplaceWithValue(number, load); |
| 795 number->Kill(); |
| 796 input->Kill(); |
| 797 return Replace(load); |
| 798 } |
| 799 } |
| 800 } |
| 801 } |
| 802 } |
| 803 return NoChange(); |
| 804 } |
| 805 |
| 806 |
| 683 Reduction JSTypedLowering::ReduceJSToNumber(Node* node) { | 807 Reduction JSTypedLowering::ReduceJSToNumber(Node* node) { |
| 684 // Try to reduce the input first. | 808 // Try to reduce the input first. |
| 685 Node* const input = node->InputAt(0); | 809 Node* const input = node->InputAt(0); |
| 686 Reduction reduction = ReduceJSToNumberInput(input); | 810 Reduction reduction = ReduceJSToNumberInput(input); |
| 687 if (reduction.Changed()) { | 811 if (reduction.Changed()) { |
| 688 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | 812 NodeProperties::ReplaceWithValue(node, reduction.replacement()); |
| 689 return reduction; | 813 return reduction; |
| 690 } | 814 } |
| 815 // TODO(bmeurer): Move this into a dedicated conversion/truncation analysis, |
| 816 // which works bottom-up from the uses. |
| 817 if (input->opcode() == IrOpcode::kJSLoadProperty && CanCover(node, input)) { |
| 818 Node* key = NodeProperties::GetValueInput(input, 1); |
| 819 Node* base = NodeProperties::GetValueInput(input, 0); |
| 820 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 821 HeapObjectMatcher<Object> mbase(base); |
| 822 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { |
| 823 Handle<JSTypedArray> const array = |
| 824 Handle<JSTypedArray>::cast(mbase.Value().handle()); |
| 825 if (!array->GetBuffer()->was_neutered() && |
| 826 (array->type() == kExternalFloat32Array || |
| 827 array->type() == kExternalFloat64Array)) { |
| 828 array->GetBuffer()->set_is_neuterable(false); |
| 829 BufferAccess const access(array->type()); |
| 830 size_t const k = ElementSizeLog2Of(access.machine_type()); |
| 831 double const byte_length = array->byte_length()->Number(); |
| 832 CHECK_LT(k, arraysize(shifted_int32_ranges_)); |
| 833 if (IsExternalArrayElementsKind(array->map()->elements_kind()) && |
| 834 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { |
| 835 // JSLoadProperty(typed-array, int32) |
| 836 Handle<ExternalArray> elements = |
| 837 Handle<ExternalArray>::cast(handle(array->elements())); |
| 838 Node* buffer = |
| 839 jsgraph()->PointerConstant(elements->external_pointer()); |
| 840 Node* length = jsgraph()->Constant(byte_length); |
| 841 Node* effect = NodeProperties::GetEffectInput(input); |
| 842 Node* control = NodeProperties::GetControlInput(input); |
| 843 // Compute byte offset. |
| 844 Node* offset = Word32Shl(key, static_cast<int>(k)); |
| 845 Node* load = |
| 846 graph()->NewNode(simplified()->LoadBuffer(access), buffer, offset, |
| 847 length, effect, control); |
| 848 NodeProperties::ReplaceWithValue(input, load, load); |
| 849 NodeProperties::ReplaceWithValue(node, load); |
| 850 input->Kill(); |
| 851 return Changed(load); |
| 852 } |
| 853 } |
| 854 } |
| 855 } |
| 691 Type* const input_type = NodeProperties::GetBounds(input).upper; | 856 Type* const input_type = NodeProperties::GetBounds(input).upper; |
| 692 if (input_type->Is(Type::PlainPrimitive())) { | 857 if (input_type->Is(Type::PlainPrimitive())) { |
| 693 if (NodeProperties::GetContextInput(node) != | 858 if (NodeProperties::GetContextInput(node) != |
| 694 jsgraph()->NoContextConstant() || | 859 jsgraph()->NoContextConstant() || |
| 695 NodeProperties::GetEffectInput(node) != graph()->start() || | 860 NodeProperties::GetEffectInput(node) != graph()->start() || |
| 696 NodeProperties::GetControlInput(node) != graph()->start()) { | 861 NodeProperties::GetControlInput(node) != graph()->start()) { |
| 697 // JSToNumber(x:plain-primitive,context,effect,control) | 862 // JSToNumber(x:plain-primitive,context,effect,control) |
| 698 // => JSToNumber(x,no-context,start,start) | 863 // => JSToNumber(x,no-context,start,start) |
| 699 RelaxEffectsAndControls(node); | 864 RelaxEffectsAndControls(node); |
| 700 NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant()); | 865 NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 Node* key = NodeProperties::GetValueInput(node, 1); | 931 Node* key = NodeProperties::GetValueInput(node, 1); |
| 767 Node* base = NodeProperties::GetValueInput(node, 0); | 932 Node* base = NodeProperties::GetValueInput(node, 0); |
| 768 Type* key_type = NodeProperties::GetBounds(key).upper; | 933 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 769 HeapObjectMatcher<Object> mbase(base); | 934 HeapObjectMatcher<Object> mbase(base); |
| 770 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { | 935 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { |
| 771 Handle<JSTypedArray> const array = | 936 Handle<JSTypedArray> const array = |
| 772 Handle<JSTypedArray>::cast(mbase.Value().handle()); | 937 Handle<JSTypedArray>::cast(mbase.Value().handle()); |
| 773 if (!array->GetBuffer()->was_neutered()) { | 938 if (!array->GetBuffer()->was_neutered()) { |
| 774 array->GetBuffer()->set_is_neuterable(false); | 939 array->GetBuffer()->set_is_neuterable(false); |
| 775 BufferAccess const access(array->type()); | 940 BufferAccess const access(array->type()); |
| 776 size_t const k = ElementSizeLog2Of(access.machine_type()); | 941 if (array->byte_length()->Number() <= kMaxInt && |
| 777 double const byte_length = array->byte_length()->Number(); | 942 key_type->Is(Type::Unsigned32()) && |
| 778 CHECK_LT(k, arraysize(shifted_int32_ranges_)); | 943 key_type->Max() < array->length()->Number()) { |
| 779 if (IsExternalArrayElementsKind(array->map()->elements_kind()) && | 944 // JSLoadProperty(typed-array, unsigned32) |
| 780 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { | |
| 781 // JSLoadProperty(typed-array, int32) | |
| 782 Handle<ExternalArray> elements = | 945 Handle<ExternalArray> elements = |
| 783 Handle<ExternalArray>::cast(handle(array->elements())); | 946 Handle<ExternalArray>::cast(handle(array->elements())); |
| 784 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); | 947 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); |
| 785 Node* length = jsgraph()->Constant(byte_length); | |
| 786 Node* effect = NodeProperties::GetEffectInput(node); | 948 Node* effect = NodeProperties::GetEffectInput(node); |
| 787 Node* control = NodeProperties::GetControlInput(node); | 949 Node* control = NodeProperties::GetControlInput(node); |
| 788 // Check if we can avoid the bounds check. | 950 Node* load = graph()->NewNode( |
| 789 if (key_type->Min() >= 0 && | 951 simplified()->LoadElement( |
| 790 key_type->Max() < array->length()->Number()) { | 952 AccessBuilder::ForTypedArrayElement(array->type(), true)), |
| 791 Node* load = graph()->NewNode( | 953 buffer, key, effect, control); |
| 792 simplified()->LoadElement( | |
| 793 AccessBuilder::ForTypedArrayElement(array->type(), true)), | |
| 794 buffer, key, effect, control); | |
| 795 return ReplaceEagerly(node, load); | |
| 796 } | |
| 797 // Compute byte offset. | |
| 798 Node* offset = Word32Shl(key, static_cast<int>(k)); | |
| 799 Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer, | |
| 800 offset, length, effect, control); | |
| 801 return ReplaceEagerly(node, load); | 954 return ReplaceEagerly(node, load); |
| 802 } | 955 } |
| 803 } | 956 } |
| 804 } | 957 } |
| 805 return NoChange(); | 958 return NoChange(); |
| 806 } | 959 } |
| 807 | 960 |
| 808 | 961 |
| 809 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { | 962 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { |
| 810 Node* key = NodeProperties::GetValueInput(node, 1); | 963 Node* key = NodeProperties::GetValueInput(node, 1); |
| 811 Node* base = NodeProperties::GetValueInput(node, 0); | 964 Node* base = NodeProperties::GetValueInput(node, 0); |
| 812 Node* value = NodeProperties::GetValueInput(node, 2); | 965 Node* value = NodeProperties::GetValueInput(node, 2); |
| 813 Type* key_type = NodeProperties::GetBounds(key).upper; | 966 Type* key_type = NodeProperties::GetBounds(key).upper; |
| 814 Type* value_type = NodeProperties::GetBounds(value).upper; | 967 Type* value_type = NodeProperties::GetBounds(value).upper; |
| 815 HeapObjectMatcher<Object> mbase(base); | 968 HeapObjectMatcher<Object> mbase(base); |
| 816 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { | 969 if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) { |
| 817 Handle<JSTypedArray> const array = | 970 Handle<JSTypedArray> const array = |
| 818 Handle<JSTypedArray>::cast(mbase.Value().handle()); | 971 Handle<JSTypedArray>::cast(mbase.Value().handle()); |
| 819 if (!array->GetBuffer()->was_neutered()) { | 972 if (!array->GetBuffer()->was_neutered()) { |
| 820 array->GetBuffer()->set_is_neuterable(false); | 973 array->GetBuffer()->set_is_neuterable(false); |
| 821 BufferAccess const access(array->type()); | 974 BufferAccess const access(array->type()); |
| 822 size_t const k = ElementSizeLog2Of(access.machine_type()); | 975 size_t const k = ElementSizeLog2Of(access.machine_type()); |
| 823 double const byte_length = array->byte_length()->Number(); | 976 double const byte_length = array->byte_length()->Number(); |
| 824 CHECK_LT(k, arraysize(shifted_int32_ranges_)); | 977 CHECK_LT(k, arraysize(shifted_int32_ranges_)); |
| 825 if (IsExternalArrayElementsKind(array->map()->elements_kind()) && | 978 if (access.external_array_type() != kExternalUint8ClampedArray && |
| 826 access.external_array_type() != kExternalUint8ClampedArray && | |
| 827 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { | 979 key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) { |
| 828 // JSLoadProperty(typed-array, int32) | 980 // JSLoadProperty(typed-array, int32) |
| 829 Handle<ExternalArray> elements = | 981 Handle<ExternalArray> elements = |
| 830 Handle<ExternalArray>::cast(handle(array->elements())); | 982 Handle<ExternalArray>::cast(handle(array->elements())); |
| 831 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); | 983 Node* buffer = jsgraph()->PointerConstant(elements->external_pointer()); |
| 832 Node* length = jsgraph()->Constant(byte_length); | 984 Node* length = jsgraph()->Constant(byte_length); |
| 833 Node* context = NodeProperties::GetContextInput(node); | 985 Node* context = NodeProperties::GetContextInput(node); |
| 834 Node* effect = NodeProperties::GetEffectInput(node); | 986 Node* effect = NodeProperties::GetEffectInput(node); |
| 835 Node* control = NodeProperties::GetControlInput(node); | 987 Node* control = NodeProperties::GetControlInput(node); |
| 836 // Convert to a number first. | 988 // Convert to a number first. |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 case IrOpcode::kJSCreateClosure: | 1327 case IrOpcode::kJSCreateClosure: |
| 1176 return ReduceJSCreateClosure(node); | 1328 return ReduceJSCreateClosure(node); |
| 1177 case IrOpcode::kJSCreateLiteralArray: | 1329 case IrOpcode::kJSCreateLiteralArray: |
| 1178 return ReduceJSCreateLiteralArray(node); | 1330 return ReduceJSCreateLiteralArray(node); |
| 1179 case IrOpcode::kJSCreateLiteralObject: | 1331 case IrOpcode::kJSCreateLiteralObject: |
| 1180 return ReduceJSCreateLiteralObject(node); | 1332 return ReduceJSCreateLiteralObject(node); |
| 1181 case IrOpcode::kJSCreateWithContext: | 1333 case IrOpcode::kJSCreateWithContext: |
| 1182 return ReduceJSCreateWithContext(node); | 1334 return ReduceJSCreateWithContext(node); |
| 1183 case IrOpcode::kJSCreateBlockContext: | 1335 case IrOpcode::kJSCreateBlockContext: |
| 1184 return ReduceJSCreateBlockContext(node); | 1336 return ReduceJSCreateBlockContext(node); |
| 1337 case IrOpcode::kNumberToInt32: |
| 1338 return ReduceNumberToInt32(node); |
| 1339 case IrOpcode::kNumberToUint32: |
| 1340 return ReduceNumberToUint32(node); |
| 1185 default: | 1341 default: |
| 1186 break; | 1342 break; |
| 1187 } | 1343 } |
| 1188 return NoChange(); | 1344 return NoChange(); |
| 1189 } | 1345 } |
| 1190 | 1346 |
| 1191 | 1347 |
| 1192 Node* JSTypedLowering::ConvertPrimitiveToNumber(Node* input) { | |
| 1193 DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive())); | |
| 1194 // Avoid inserting too many eager ToNumber() operations. | |
| 1195 Reduction const reduction = ReduceJSToNumberInput(input); | |
| 1196 if (reduction.Changed()) return reduction.replacement(); | |
| 1197 // TODO(jarin) Use PlainPrimitiveToNumber once we have it. | |
| 1198 return graph()->NewNode( | |
| 1199 javascript()->ToNumber(), input, jsgraph()->NoContextConstant(), | |
| 1200 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); | |
| 1201 } | |
| 1202 | |
| 1203 | |
| 1204 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { | 1348 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) { |
| 1205 if (rhs == 0) return lhs; | 1349 if (rhs == 0) return lhs; |
| 1206 return graph()->NewNode(machine()->Word32Shl(), lhs, | 1350 return graph()->NewNode(machine()->Word32Shl(), lhs, |
| 1207 jsgraph()->Int32Constant(rhs)); | 1351 jsgraph()->Int32Constant(rhs)); |
| 1208 } | 1352 } |
| 1209 | 1353 |
| 1210 | 1354 |
| 1211 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } | 1355 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } |
| 1212 | 1356 |
| 1213 | 1357 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1224 } | 1368 } |
| 1225 | 1369 |
| 1226 | 1370 |
| 1227 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1371 MachineOperatorBuilder* JSTypedLowering::machine() const { |
| 1228 return jsgraph()->machine(); | 1372 return jsgraph()->machine(); |
| 1229 } | 1373 } |
| 1230 | 1374 |
| 1231 } // namespace compiler | 1375 } // namespace compiler |
| 1232 } // namespace internal | 1376 } // namespace internal |
| 1233 } // namespace v8 | 1377 } // namespace v8 |
| OLD | NEW |