| 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 |