OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 2608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2619 Handle<Map> map = IsFastDoubleElementsKind(kind) |
2620 ? factory->fixed_double_array_map() | 2620 ? factory->fixed_double_array_map() |
2621 : factory->fixed_array_map(); | 2621 : factory->fixed_array_map(); |
2622 | 2622 |
2623 Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); | 2623 Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); |
2624 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), | 2624 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
2625 capacity); | 2625 capacity); |
2626 } | 2626 } |
2627 | 2627 |
2628 | 2628 |
2629 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 2629 HValue* HGraphBuilder::BuildAllocateAndInitializeArray(ElementsKind kind, |
2630 ElementsKind kind, | 2630 HValue* capacity) { |
2631 HValue* capacity) { | |
2632 // The HForceRepresentation is to prevent possible deopt on int-smi | 2631 // The HForceRepresentation is to prevent possible deopt on int-smi |
2633 // conversion after allocation but before the new object fields are set. | 2632 // conversion after allocation but before the new object fields are set. |
2634 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); | 2633 capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi()); |
2635 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); | 2634 HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity); |
2636 HValue* new_elements = BuildAllocateElements(kind, size_in_bytes); | 2635 HValue* new_array = BuildAllocateElements(kind, size_in_bytes); |
2637 BuildInitializeElementsHeader(new_elements, kind, capacity); | 2636 BuildInitializeElementsHeader(new_array, kind, capacity); |
2638 return new_elements; | 2637 return new_array; |
2639 } | 2638 } |
2640 | 2639 |
2641 | 2640 |
2642 void HGraphBuilder::BuildJSArrayHeader(HValue* array, | 2641 void HGraphBuilder::BuildJSArrayHeader(HValue* array, |
2643 HValue* array_map, | 2642 HValue* array_map, |
2644 HValue* elements, | 2643 HValue* elements, |
2645 AllocationSiteMode mode, | 2644 AllocationSiteMode mode, |
2646 ElementsKind elements_kind, | 2645 ElementsKind elements_kind, |
2647 HValue* allocation_site_payload, | 2646 HValue* allocation_site_payload, |
2648 HValue* length_field) { | 2647 HValue* length_field) { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2747 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 2746 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
2748 HValue* elements, | 2747 HValue* elements, |
2749 ElementsKind kind, | 2748 ElementsKind kind, |
2750 ElementsKind new_kind, | 2749 ElementsKind new_kind, |
2751 HValue* length, | 2750 HValue* length, |
2752 HValue* new_capacity) { | 2751 HValue* new_capacity) { |
2753 Add<HBoundsCheck>(new_capacity, Add<HConstant>( | 2752 Add<HBoundsCheck>(new_capacity, Add<HConstant>( |
2754 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> | 2753 (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >> |
2755 ElementsKindToShiftSize(new_kind))); | 2754 ElementsKindToShiftSize(new_kind))); |
2756 | 2755 |
2757 HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader( | 2756 HValue* new_elements = |
2758 new_kind, new_capacity); | 2757 BuildAllocateAndInitializeArray(new_kind, new_capacity); |
2759 | 2758 |
2760 BuildCopyElements(elements, kind, new_elements, | 2759 BuildCopyElements(elements, kind, new_elements, |
2761 new_kind, length, new_capacity); | 2760 new_kind, length, new_capacity); |
2762 | 2761 |
2763 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 2762 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
2764 new_elements); | 2763 new_elements); |
2765 | 2764 |
2766 return new_elements; | 2765 return new_elements; |
2767 } | 2766 } |
2768 | 2767 |
(...skipping 13 matching lines...) Expand all Loading... |
2782 int initial_capacity = -1; | 2781 int initial_capacity = -1; |
2783 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { | 2782 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { |
2784 int constant_from = from->GetInteger32Constant(); | 2783 int constant_from = from->GetInteger32Constant(); |
2785 int constant_to = to->GetInteger32Constant(); | 2784 int constant_to = to->GetInteger32Constant(); |
2786 | 2785 |
2787 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { | 2786 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { |
2788 initial_capacity = constant_to; | 2787 initial_capacity = constant_to; |
2789 } | 2788 } |
2790 } | 2789 } |
2791 | 2790 |
2792 // Since we're about to store a hole value, the store instruction below must | |
2793 // assume an elements kind that supports heap object values. | |
2794 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | |
2795 elements_kind = FAST_HOLEY_ELEMENTS; | |
2796 } | |
2797 | |
2798 if (initial_capacity >= 0) { | 2791 if (initial_capacity >= 0) { |
2799 for (int i = 0; i < initial_capacity; i++) { | 2792 for (int i = 0; i < initial_capacity; i++) { |
2800 HInstruction* key = Add<HConstant>(i); | 2793 HInstruction* key = Add<HConstant>(i); |
2801 Add<HStoreKeyed>(elements, key, value, elements_kind); | 2794 Add<HStoreKeyed>(elements, key, value, elements_kind); |
2802 } | 2795 } |
2803 } else { | 2796 } else { |
2804 // Carefully loop backwards so that the "from" remains live through the loop | 2797 // Carefully loop backwards so that the "from" remains live through the loop |
2805 // rather than the to. This often corresponds to keeping length live rather | 2798 // rather than the to. This often corresponds to keeping length live rather |
2806 // then capacity, which helps register allocation, since length is used more | 2799 // then capacity, which helps register allocation, since length is used more |
2807 // other than capacity after filling with holes. | 2800 // other than capacity after filling with holes. |
(...skipping 17 matching lines...) Expand all Loading... |
2825 HValue* to) { | 2818 HValue* to) { |
2826 // Fast elements kinds need to be initialized in case statements below cause a | 2819 // Fast elements kinds need to be initialized in case statements below cause a |
2827 // garbage collection. | 2820 // garbage collection. |
2828 Factory* factory = isolate()->factory(); | 2821 Factory* factory = isolate()->factory(); |
2829 | 2822 |
2830 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 2823 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
2831 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) | 2824 HValue* hole = IsFastSmiOrObjectElementsKind(elements_kind) |
2832 ? Add<HConstant>(factory->the_hole_value()) | 2825 ? Add<HConstant>(factory->the_hole_value()) |
2833 : Add<HConstant>(nan_double); | 2826 : Add<HConstant>(nan_double); |
2834 | 2827 |
| 2828 // Since we're about to store a hole value, the store instruction below must |
| 2829 // assume an elements kind that supports heap object values. |
| 2830 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 2831 elements_kind = FAST_HOLEY_ELEMENTS; |
| 2832 } |
| 2833 |
2835 BuildFillElementsWithValue(elements, elements_kind, from, to, hole); | 2834 BuildFillElementsWithValue(elements, elements_kind, from, to, hole); |
2836 } | 2835 } |
2837 | 2836 |
2838 | 2837 |
| 2838 void HGraphBuilder::BuildCopyProperties(HValue* from_properties, |
| 2839 HValue* to_properties, HValue* length, |
| 2840 HValue* capacity) { |
| 2841 ElementsKind kind = FAST_ELEMENTS; |
| 2842 |
| 2843 BuildFillElementsWithValue(to_properties, kind, length, capacity, |
| 2844 graph()->GetConstantUndefined()); |
| 2845 |
| 2846 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2847 |
| 2848 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); |
| 2849 |
| 2850 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2851 key->ClearFlag(HValue::kCanOverflow); |
| 2852 |
| 2853 HValue* element = |
| 2854 Add<HLoadKeyed>(from_properties, key, static_cast<HValue*>(NULL), kind); |
| 2855 |
| 2856 Add<HStoreKeyed>(to_properties, key, element, kind); |
| 2857 |
| 2858 builder.EndBody(); |
| 2859 } |
| 2860 |
| 2861 |
2839 void HGraphBuilder::BuildCopyElements(HValue* from_elements, | 2862 void HGraphBuilder::BuildCopyElements(HValue* from_elements, |
2840 ElementsKind from_elements_kind, | 2863 ElementsKind from_elements_kind, |
2841 HValue* to_elements, | 2864 HValue* to_elements, |
2842 ElementsKind to_elements_kind, | 2865 ElementsKind to_elements_kind, |
2843 HValue* length, | 2866 HValue* length, |
2844 HValue* capacity) { | 2867 HValue* capacity) { |
2845 int constant_capacity = -1; | 2868 int constant_capacity = -1; |
2846 if (capacity != NULL && | 2869 if (capacity != NULL && |
2847 capacity->IsConstant() && | 2870 capacity->IsConstant() && |
2848 HConstant::cast(capacity)->HasInteger32Value()) { | 2871 HConstant::cast(capacity)->HasInteger32Value()) { |
(...skipping 9674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12523 if (ShouldProduceTraceOutput()) { | 12546 if (ShouldProduceTraceOutput()) { |
12524 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12547 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12525 } | 12548 } |
12526 | 12549 |
12527 #ifdef DEBUG | 12550 #ifdef DEBUG |
12528 graph_->Verify(false); // No full verify. | 12551 graph_->Verify(false); // No full verify. |
12529 #endif | 12552 #endif |
12530 } | 12553 } |
12531 | 12554 |
12532 } } // namespace v8::internal | 12555 } } // namespace v8::internal |
OLD | NEW |