| 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 2022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2033 } | 2033 } |
| 2034 | 2034 |
| 2035 | 2035 |
| 2036 HValue* HGraphBuilder::BuildCreateIterResultObject(HValue* value, | 2036 HValue* HGraphBuilder::BuildCreateIterResultObject(HValue* value, |
| 2037 HValue* done) { | 2037 HValue* done) { |
| 2038 NoObservableSideEffectsScope scope(this); | 2038 NoObservableSideEffectsScope scope(this); |
| 2039 | 2039 |
| 2040 // Allocate the JSIteratorResult object. | 2040 // Allocate the JSIteratorResult object. |
| 2041 HValue* result = | 2041 HValue* result = |
| 2042 Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(), | 2042 Add<HAllocate>(Add<HConstant>(JSIteratorResult::kSize), HType::JSObject(), |
| 2043 NOT_TENURED, JS_OBJECT_TYPE); | 2043 NOT_TENURED, JS_OBJECT_TYPE, graph()->GetConstant0()); |
| 2044 | 2044 |
| 2045 // Initialize the JSIteratorResult object. | 2045 // Initialize the JSIteratorResult object. |
| 2046 HValue* native_context = BuildGetNativeContext(); | 2046 HValue* native_context = BuildGetNativeContext(); |
| 2047 HValue* map = Add<HLoadNamedField>( | 2047 HValue* map = Add<HLoadNamedField>( |
| 2048 native_context, nullptr, | 2048 native_context, nullptr, |
| 2049 HObjectAccess::ForContextSlot(Context::ITERATOR_RESULT_MAP_INDEX)); | 2049 HObjectAccess::ForContextSlot(Context::ITERATOR_RESULT_MAP_INDEX)); |
| 2050 Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); | 2050 Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); |
| 2051 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); | 2051 HValue* empty_fixed_array = Add<HLoadRoot>(Heap::kEmptyFixedArrayRootIndex); |
| 2052 Add<HStoreNamedField>(result, HObjectAccess::ForPropertiesPointer(), | 2052 Add<HStoreNamedField>(result, HObjectAccess::ForPropertiesPointer(), |
| 2053 empty_fixed_array); | 2053 empty_fixed_array); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2070 NoObservableSideEffectsScope scope(this); | 2070 NoObservableSideEffectsScope scope(this); |
| 2071 HConstant* max_length = Add<HConstant>(JSArray::kInitialMaxFastElementArray); | 2071 HConstant* max_length = Add<HConstant>(JSArray::kInitialMaxFastElementArray); |
| 2072 Add<HBoundsCheck>(length, max_length); | 2072 Add<HBoundsCheck>(length, max_length); |
| 2073 | 2073 |
| 2074 // Generate size calculation code here in order to make it dominate | 2074 // Generate size calculation code here in order to make it dominate |
| 2075 // the JSRegExpResult allocation. | 2075 // the JSRegExpResult allocation. |
| 2076 ElementsKind elements_kind = FAST_ELEMENTS; | 2076 ElementsKind elements_kind = FAST_ELEMENTS; |
| 2077 HValue* size = BuildCalculateElementsSize(elements_kind, length); | 2077 HValue* size = BuildCalculateElementsSize(elements_kind, length); |
| 2078 | 2078 |
| 2079 // Allocate the JSRegExpResult and the FixedArray in one step. | 2079 // Allocate the JSRegExpResult and the FixedArray in one step. |
| 2080 HValue* result = Add<HAllocate>( | 2080 HValue* result = |
| 2081 Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), | 2081 Add<HAllocate>(Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), |
| 2082 NOT_TENURED, JS_ARRAY_TYPE); | 2082 NOT_TENURED, JS_ARRAY_TYPE, graph()->GetConstant0()); |
| 2083 | 2083 |
| 2084 // Initialize the JSRegExpResult header. | 2084 // Initialize the JSRegExpResult header. |
| 2085 HValue* native_context = Add<HLoadNamedField>( | 2085 HValue* native_context = Add<HLoadNamedField>( |
| 2086 context(), nullptr, | 2086 context(), nullptr, |
| 2087 HObjectAccess::ForContextSlot(Context::NATIVE_CONTEXT_INDEX)); | 2087 HObjectAccess::ForContextSlot(Context::NATIVE_CONTEXT_INDEX)); |
| 2088 Add<HStoreNamedField>( | 2088 Add<HStoreNamedField>( |
| 2089 result, HObjectAccess::ForMap(), | 2089 result, HObjectAccess::ForMap(), |
| 2090 Add<HLoadNamedField>( | 2090 Add<HLoadNamedField>( |
| 2091 native_context, nullptr, | 2091 native_context, nullptr, |
| 2092 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); | 2092 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2106 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), | 2106 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), |
| 2107 index); | 2107 index); |
| 2108 Add<HStoreNamedField>( | 2108 Add<HStoreNamedField>( |
| 2109 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), | 2109 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), |
| 2110 input); | 2110 input); |
| 2111 | 2111 |
| 2112 // Allocate and initialize the elements header. | 2112 // Allocate and initialize the elements header. |
| 2113 HAllocate* elements = BuildAllocateElements(elements_kind, size); | 2113 HAllocate* elements = BuildAllocateElements(elements_kind, size); |
| 2114 BuildInitializeElementsHeader(elements, elements_kind, length); | 2114 BuildInitializeElementsHeader(elements, elements_kind, length); |
| 2115 | 2115 |
| 2116 if (!elements->has_size_upper_bound()) { | |
| 2117 HConstant* size_in_bytes_upper_bound = EstablishElementsAllocationSize( | |
| 2118 elements_kind, max_length->Integer32Value()); | |
| 2119 elements->set_size_upper_bound(size_in_bytes_upper_bound); | |
| 2120 } | |
| 2121 | |
| 2122 Add<HStoreNamedField>( | 2116 Add<HStoreNamedField>( |
| 2123 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), | 2117 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), |
| 2124 elements); | 2118 elements); |
| 2125 | 2119 |
| 2126 // Initialize the elements contents with undefined. | 2120 // Initialize the elements contents with undefined. |
| 2127 BuildFillElementsWithValue( | 2121 BuildFillElementsWithValue( |
| 2128 elements, elements_kind, graph()->GetConstant0(), length, | 2122 elements, elements_kind, graph()->GetConstant0(), length, |
| 2129 graph()->GetConstantUndefined()); | 2123 graph()->GetConstantUndefined()); |
| 2130 | 2124 |
| 2131 return result; | 2125 return result; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2387 HAllocationMode allocation_mode) { | 2381 HAllocationMode allocation_mode) { |
| 2388 // Compute the effective allocation size. | 2382 // Compute the effective allocation size. |
| 2389 HValue* size = object_size; | 2383 HValue* size = object_size; |
| 2390 if (allocation_mode.CreateAllocationMementos()) { | 2384 if (allocation_mode.CreateAllocationMementos()) { |
| 2391 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); | 2385 size = AddUncasted<HAdd>(size, Add<HConstant>(AllocationMemento::kSize)); |
| 2392 size->ClearFlag(HValue::kCanOverflow); | 2386 size->ClearFlag(HValue::kCanOverflow); |
| 2393 } | 2387 } |
| 2394 | 2388 |
| 2395 // Perform the actual allocation. | 2389 // Perform the actual allocation. |
| 2396 HAllocate* object = Add<HAllocate>( | 2390 HAllocate* object = Add<HAllocate>( |
| 2397 size, type, allocation_mode.GetPretenureMode(), | 2391 size, type, allocation_mode.GetPretenureMode(), instance_type, |
| 2398 instance_type, allocation_mode.feedback_site()); | 2392 graph()->GetConstant0(), allocation_mode.feedback_site()); |
| 2399 | 2393 |
| 2400 // Setup the allocation memento. | 2394 // Setup the allocation memento. |
| 2401 if (allocation_mode.CreateAllocationMementos()) { | 2395 if (allocation_mode.CreateAllocationMementos()) { |
| 2402 BuildCreateAllocationMemento( | 2396 BuildCreateAllocationMemento( |
| 2403 object, object_size, allocation_mode.current_site()); | 2397 object, object_size, allocation_mode.current_site()); |
| 2404 } | 2398 } |
| 2405 | 2399 |
| 2406 return object; | 2400 return object; |
| 2407 } | 2401 } |
| 2408 | 2402 |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2883 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2877 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2884 JSArrayBuilder* array_builder, | 2878 JSArrayBuilder* array_builder, |
| 2885 HValue* length_argument) { | 2879 HValue* length_argument) { |
| 2886 if (length_argument->IsConstant() && | 2880 if (length_argument->IsConstant() && |
| 2887 HConstant::cast(length_argument)->HasSmiValue()) { | 2881 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2888 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2882 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| 2889 if (array_length == 0) { | 2883 if (array_length == 0) { |
| 2890 return array_builder->AllocateEmptyArray(); | 2884 return array_builder->AllocateEmptyArray(); |
| 2891 } else { | 2885 } else { |
| 2892 return array_builder->AllocateArray(length_argument, | 2886 return array_builder->AllocateArray(length_argument, |
| 2893 array_length, | |
| 2894 length_argument); | 2887 length_argument); |
| 2895 } | 2888 } |
| 2896 } | 2889 } |
| 2897 | 2890 |
| 2898 HValue* constant_zero = graph()->GetConstant0(); | 2891 HValue* constant_zero = graph()->GetConstant0(); |
| 2899 HConstant* max_alloc_length = | 2892 HConstant* max_alloc_length = |
| 2900 Add<HConstant>(JSArray::kInitialMaxFastElementArray); | 2893 Add<HConstant>(JSArray::kInitialMaxFastElementArray); |
| 2901 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, | 2894 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, |
| 2902 max_alloc_length); | 2895 max_alloc_length); |
| 2903 IfBuilder if_builder(this); | 2896 IfBuilder if_builder(this); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2916 Deoptimizer::kHoleyArrayDespitePackedElements_kindFeedback); | 2909 Deoptimizer::kHoleyArrayDespitePackedElements_kindFeedback); |
| 2917 } else { | 2910 } else { |
| 2918 Push(checked_length); // capacity | 2911 Push(checked_length); // capacity |
| 2919 Push(checked_length); // length | 2912 Push(checked_length); // length |
| 2920 } | 2913 } |
| 2921 if_builder.End(); | 2914 if_builder.End(); |
| 2922 | 2915 |
| 2923 // Figure out total size | 2916 // Figure out total size |
| 2924 HValue* length = Pop(); | 2917 HValue* length = Pop(); |
| 2925 HValue* capacity = Pop(); | 2918 HValue* capacity = Pop(); |
| 2926 return array_builder->AllocateArray(capacity, max_alloc_length, length); | 2919 return array_builder->AllocateArray(capacity, length); |
| 2927 } | 2920 } |
| 2928 | 2921 |
| 2929 | 2922 |
| 2930 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, | 2923 HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind, |
| 2931 HValue* capacity) { | 2924 HValue* capacity) { |
| 2932 int elements_size = IsFastDoubleElementsKind(kind) | 2925 int elements_size = IsFastDoubleElementsKind(kind) |
| 2933 ? kDoubleSize | 2926 ? kDoubleSize |
| 2934 : kPointerSize; | 2927 : kPointerSize; |
| 2935 | 2928 |
| 2936 HConstant* elements_size_value = Add<HConstant>(elements_size); | 2929 HConstant* elements_size_value = Add<HConstant>(elements_size); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2948 return total_size; | 2941 return total_size; |
| 2949 } | 2942 } |
| 2950 | 2943 |
| 2951 | 2944 |
| 2952 HAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) { | 2945 HAllocate* HGraphBuilder::AllocateJSArrayObject(AllocationSiteMode mode) { |
| 2953 int base_size = JSArray::kSize; | 2946 int base_size = JSArray::kSize; |
| 2954 if (mode == TRACK_ALLOCATION_SITE) { | 2947 if (mode == TRACK_ALLOCATION_SITE) { |
| 2955 base_size += AllocationMemento::kSize; | 2948 base_size += AllocationMemento::kSize; |
| 2956 } | 2949 } |
| 2957 HConstant* size_in_bytes = Add<HConstant>(base_size); | 2950 HConstant* size_in_bytes = Add<HConstant>(base_size); |
| 2958 return Add<HAllocate>( | 2951 return Add<HAllocate>(size_in_bytes, HType::JSArray(), NOT_TENURED, |
| 2959 size_in_bytes, HType::JSArray(), NOT_TENURED, JS_OBJECT_TYPE); | 2952 JS_OBJECT_TYPE, graph()->GetConstant0()); |
| 2960 } | 2953 } |
| 2961 | 2954 |
| 2962 | 2955 |
| 2963 HConstant* HGraphBuilder::EstablishElementsAllocationSize( | 2956 HConstant* HGraphBuilder::EstablishElementsAllocationSize( |
| 2964 ElementsKind kind, | 2957 ElementsKind kind, |
| 2965 int capacity) { | 2958 int capacity) { |
| 2966 int base_size = IsFastDoubleElementsKind(kind) | 2959 int base_size = IsFastDoubleElementsKind(kind) |
| 2967 ? FixedDoubleArray::SizeFor(capacity) | 2960 ? FixedDoubleArray::SizeFor(capacity) |
| 2968 : FixedArray::SizeFor(capacity); | 2961 : FixedArray::SizeFor(capacity); |
| 2969 | 2962 |
| 2970 return Add<HConstant>(base_size); | 2963 return Add<HConstant>(base_size); |
| 2971 } | 2964 } |
| 2972 | 2965 |
| 2973 | 2966 |
| 2974 HAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 2967 HAllocate* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
| 2975 HValue* size_in_bytes) { | 2968 HValue* size_in_bytes) { |
| 2976 InstanceType instance_type = IsFastDoubleElementsKind(kind) | 2969 InstanceType instance_type = IsFastDoubleElementsKind(kind) |
| 2977 ? FIXED_DOUBLE_ARRAY_TYPE | 2970 ? FIXED_DOUBLE_ARRAY_TYPE |
| 2978 : FIXED_ARRAY_TYPE; | 2971 : FIXED_ARRAY_TYPE; |
| 2979 | 2972 |
| 2980 return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED, | 2973 return Add<HAllocate>(size_in_bytes, HType::HeapObject(), NOT_TENURED, |
| 2981 instance_type); | 2974 instance_type, graph()->GetConstant0()); |
| 2982 } | 2975 } |
| 2983 | 2976 |
| 2984 | 2977 |
| 2985 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 2978 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
| 2986 ElementsKind kind, | 2979 ElementsKind kind, |
| 2987 HValue* capacity) { | 2980 HValue* capacity) { |
| 2988 Factory* factory = isolate()->factory(); | 2981 Factory* factory = isolate()->factory(); |
| 2989 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2982 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 2990 ? factory->fixed_double_array_map() | 2983 ? factory->fixed_double_array_map() |
| 2991 : factory->fixed_array_map(); | 2984 : factory->fixed_array_map(); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3359 | 3352 |
| 3360 // Create empty JSArray object for now, store elimination should remove | 3353 // Create empty JSArray object for now, store elimination should remove |
| 3361 // redundant initialization of elements and length fields and at the same | 3354 // redundant initialization of elements and length fields and at the same |
| 3362 // time the object will be fully prepared for GC if it happens during | 3355 // time the object will be fully prepared for GC if it happens during |
| 3363 // elements allocation. | 3356 // elements allocation. |
| 3364 HValue* result = BuildCloneShallowArrayEmpty( | 3357 HValue* result = BuildCloneShallowArrayEmpty( |
| 3365 boilerplate, allocation_site, mode); | 3358 boilerplate, allocation_site, mode); |
| 3366 | 3359 |
| 3367 HAllocate* elements = BuildAllocateElements(kind, elements_size); | 3360 HAllocate* elements = BuildAllocateElements(kind, elements_size); |
| 3368 | 3361 |
| 3369 // This function implicitly relies on the fact that the | |
| 3370 // FastCloneShallowArrayStub is called only for literals shorter than | |
| 3371 // JSArray::kInitialMaxFastElementArray. | |
| 3372 // Can't add HBoundsCheck here because otherwise the stub will eager a frame. | |
| 3373 HConstant* size_upper_bound = EstablishElementsAllocationSize( | |
| 3374 kind, JSArray::kInitialMaxFastElementArray); | |
| 3375 elements->set_size_upper_bound(size_upper_bound); | |
| 3376 | |
| 3377 Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements); | 3362 Add<HStoreNamedField>(result, HObjectAccess::ForElementsPointer(), elements); |
| 3378 | 3363 |
| 3379 // The allocation for the cloned array above causes register pressure on | 3364 // The allocation for the cloned array above causes register pressure on |
| 3380 // machines with low register counts. Force a reload of the boilerplate | 3365 // machines with low register counts. Force a reload of the boilerplate |
| 3381 // elements here to free up a register for the allocation to avoid unnecessary | 3366 // elements here to free up a register for the allocation to avoid unnecessary |
| 3382 // spillage. | 3367 // spillage. |
| 3383 boilerplate_elements = AddLoadElements(boilerplate); | 3368 boilerplate_elements = AddLoadElements(boilerplate); |
| 3384 boilerplate_elements->SetFlag(HValue::kCantBeReplaced); | 3369 boilerplate_elements->SetFlag(HValue::kCantBeReplaced); |
| 3385 | 3370 |
| 3386 // Copy the elements array header. | 3371 // Copy the elements array header. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3606 // Find the map near the constructor function | 3591 // Find the map near the constructor function |
| 3607 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3592 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3608 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, | 3593 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, |
| 3609 access); | 3594 access); |
| 3610 } | 3595 } |
| 3611 | 3596 |
| 3612 | 3597 |
| 3613 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 3598 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 3614 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 3599 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
| 3615 return AllocateArray(capacity, | 3600 return AllocateArray(capacity, |
| 3616 capacity, | |
| 3617 builder()->graph()->GetConstant0()); | 3601 builder()->graph()->GetConstant0()); |
| 3618 } | 3602 } |
| 3619 | 3603 |
| 3620 | 3604 |
| 3621 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( | 3605 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
| 3622 HValue* capacity, | 3606 HValue* capacity, |
| 3623 HConstant* capacity_upper_bound, | |
| 3624 HValue* length_field, | |
| 3625 FillMode fill_mode) { | |
| 3626 return AllocateArray(capacity, | |
| 3627 capacity_upper_bound->GetInteger32Constant(), | |
| 3628 length_field, | |
| 3629 fill_mode); | |
| 3630 } | |
| 3631 | |
| 3632 | |
| 3633 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( | |
| 3634 HValue* capacity, | |
| 3635 int capacity_upper_bound, | |
| 3636 HValue* length_field, | |
| 3637 FillMode fill_mode) { | |
| 3638 HConstant* elememts_size_upper_bound = capacity->IsInteger32Constant() | |
| 3639 ? HConstant::cast(capacity) | |
| 3640 : builder()->EstablishElementsAllocationSize(kind_, capacity_upper_bound); | |
| 3641 | |
| 3642 HAllocate* array = AllocateArray(capacity, length_field, fill_mode); | |
| 3643 if (!elements_location_->has_size_upper_bound()) { | |
| 3644 elements_location_->set_size_upper_bound(elememts_size_upper_bound); | |
| 3645 } | |
| 3646 return array; | |
| 3647 } | |
| 3648 | |
| 3649 | |
| 3650 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( | |
| 3651 HValue* capacity, | |
| 3652 HValue* length_field, | 3607 HValue* length_field, |
| 3653 FillMode fill_mode) { | 3608 FillMode fill_mode) { |
| 3654 // These HForceRepresentations are because we store these as fields in the | 3609 // These HForceRepresentations are because we store these as fields in the |
| 3655 // objects we construct, and an int32-to-smi HChange could deopt. Accept | 3610 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
| 3656 // the deopt possibility now, before allocation occurs. | 3611 // the deopt possibility now, before allocation occurs. |
| 3657 capacity = | 3612 capacity = |
| 3658 builder()->AddUncasted<HForceRepresentation>(capacity, | 3613 builder()->AddUncasted<HForceRepresentation>(capacity, |
| 3659 Representation::Smi()); | 3614 Representation::Smi()); |
| 3660 length_field = | 3615 length_field = |
| 3661 builder()->AddUncasted<HForceRepresentation>(length_field, | 3616 builder()->AddUncasted<HForceRepresentation>(length_field, |
| (...skipping 2700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6362 if (field_access.representation().IsDouble() && | 6317 if (field_access.representation().IsDouble() && |
| 6363 (!FLAG_unbox_double_fields || !field_access.IsInobject())) { | 6318 (!FLAG_unbox_double_fields || !field_access.IsInobject())) { |
| 6364 HObjectAccess heap_number_access = | 6319 HObjectAccess heap_number_access = |
| 6365 field_access.WithRepresentation(Representation::Tagged()); | 6320 field_access.WithRepresentation(Representation::Tagged()); |
| 6366 if (transition_to_field) { | 6321 if (transition_to_field) { |
| 6367 // The store requires a mutable HeapNumber to be allocated. | 6322 // The store requires a mutable HeapNumber to be allocated. |
| 6368 NoObservableSideEffectsScope no_side_effects(this); | 6323 NoObservableSideEffectsScope no_side_effects(this); |
| 6369 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 6324 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
| 6370 | 6325 |
| 6371 // TODO(hpayer): Allocation site pretenuring support. | 6326 // TODO(hpayer): Allocation site pretenuring support. |
| 6372 HInstruction* heap_number = Add<HAllocate>(heap_number_size, | 6327 HInstruction* heap_number = |
| 6373 HType::HeapObject(), | 6328 Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED, |
| 6374 NOT_TENURED, | 6329 MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0()); |
| 6375 MUTABLE_HEAP_NUMBER_TYPE); | |
| 6376 AddStoreMapConstant( | 6330 AddStoreMapConstant( |
| 6377 heap_number, isolate()->factory()->mutable_heap_number_map()); | 6331 heap_number, isolate()->factory()->mutable_heap_number_map()); |
| 6378 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 6332 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
| 6379 value); | 6333 value); |
| 6380 instr = New<HStoreNamedField>(checked_object->ActualValue(), | 6334 instr = New<HStoreNamedField>(checked_object->ActualValue(), |
| 6381 heap_number_access, | 6335 heap_number_access, |
| 6382 heap_number); | 6336 heap_number); |
| 6383 } else { | 6337 } else { |
| 6384 // Already holds a HeapNumber; load the box and write its value field. | 6338 // Already holds a HeapNumber; load the box and write its value field. |
| 6385 HInstruction* heap_number = | 6339 HInstruction* heap_number = |
| (...skipping 4004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10390 bool is_zero_byte_offset, | 10344 bool is_zero_byte_offset, |
| 10391 HValue* buffer, HValue* byte_offset, HValue* length) { | 10345 HValue* buffer, HValue* byte_offset, HValue* length) { |
| 10392 Handle<Map> external_array_map( | 10346 Handle<Map> external_array_map( |
| 10393 isolate()->heap()->MapForFixedTypedArray(array_type)); | 10347 isolate()->heap()->MapForFixedTypedArray(array_type)); |
| 10394 | 10348 |
| 10395 // The HForceRepresentation is to prevent possible deopt on int-smi | 10349 // The HForceRepresentation is to prevent possible deopt on int-smi |
| 10396 // conversion after allocation but before the new object fields are set. | 10350 // conversion after allocation but before the new object fields are set. |
| 10397 length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); | 10351 length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); |
| 10398 HValue* elements = Add<HAllocate>( | 10352 HValue* elements = Add<HAllocate>( |
| 10399 Add<HConstant>(FixedTypedArrayBase::kHeaderSize), HType::HeapObject(), | 10353 Add<HConstant>(FixedTypedArrayBase::kHeaderSize), HType::HeapObject(), |
| 10400 NOT_TENURED, external_array_map->instance_type()); | 10354 NOT_TENURED, external_array_map->instance_type(), |
| 10355 graph()->GetConstant0()); |
| 10401 | 10356 |
| 10402 AddStoreMapConstant(elements, external_array_map); | 10357 AddStoreMapConstant(elements, external_array_map); |
| 10403 Add<HStoreNamedField>(elements, | 10358 Add<HStoreNamedField>(elements, |
| 10404 HObjectAccess::ForFixedArrayLength(), length); | 10359 HObjectAccess::ForFixedArrayLength(), length); |
| 10405 | 10360 |
| 10406 HValue* backing_store = Add<HLoadNamedField>( | 10361 HValue* backing_store = Add<HLoadNamedField>( |
| 10407 buffer, nullptr, HObjectAccess::ForJSArrayBufferBackingStore()); | 10362 buffer, nullptr, HObjectAccess::ForJSArrayBufferBackingStore()); |
| 10408 | 10363 |
| 10409 HValue* typed_array_start; | 10364 HValue* typed_array_start; |
| 10410 if (is_zero_byte_offset) { | 10365 if (is_zero_byte_offset) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10446 total_size = AddUncasted<HAdd>(byte_length, | 10401 total_size = AddUncasted<HAdd>(byte_length, |
| 10447 Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); | 10402 Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); |
| 10448 total_size->ClearFlag(HValue::kCanOverflow); | 10403 total_size->ClearFlag(HValue::kCanOverflow); |
| 10449 } | 10404 } |
| 10450 | 10405 |
| 10451 // The HForceRepresentation is to prevent possible deopt on int-smi | 10406 // The HForceRepresentation is to prevent possible deopt on int-smi |
| 10452 // conversion after allocation but before the new object fields are set. | 10407 // conversion after allocation but before the new object fields are set. |
| 10453 length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); | 10408 length = AddUncasted<HForceRepresentation>(length, Representation::Smi()); |
| 10454 Handle<Map> fixed_typed_array_map( | 10409 Handle<Map> fixed_typed_array_map( |
| 10455 isolate()->heap()->MapForFixedTypedArray(array_type)); | 10410 isolate()->heap()->MapForFixedTypedArray(array_type)); |
| 10456 HAllocate* elements = | 10411 HAllocate* elements = Add<HAllocate>( |
| 10457 Add<HAllocate>(total_size, HType::HeapObject(), NOT_TENURED, | 10412 total_size, HType::HeapObject(), NOT_TENURED, |
| 10458 fixed_typed_array_map->instance_type()); | 10413 fixed_typed_array_map->instance_type(), graph()->GetConstant0()); |
| 10459 | 10414 |
| 10460 #ifndef V8_HOST_ARCH_64_BIT | 10415 #ifndef V8_HOST_ARCH_64_BIT |
| 10461 if (array_type == kExternalFloat64Array) { | 10416 if (array_type == kExternalFloat64Array) { |
| 10462 elements->MakeDoubleAligned(); | 10417 elements->MakeDoubleAligned(); |
| 10463 } | 10418 } |
| 10464 #endif | 10419 #endif |
| 10465 | 10420 |
| 10466 AddStoreMapConstant(elements, fixed_typed_array_map); | 10421 AddStoreMapConstant(elements, fixed_typed_array_map); |
| 10467 | 10422 |
| 10468 Add<HStoreNamedField>(elements, | 10423 Add<HStoreNamedField>(elements, |
| (...skipping 1556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12025 pretenure_flag = top_site->GetPretenureMode(); | 11980 pretenure_flag = top_site->GetPretenureMode(); |
| 12026 } | 11981 } |
| 12027 | 11982 |
| 12028 Handle<AllocationSite> current_site(*site_context->current(), isolate()); | 11983 Handle<AllocationSite> current_site(*site_context->current(), isolate()); |
| 12029 if (*top_site == *current_site) { | 11984 if (*top_site == *current_site) { |
| 12030 // We install a dependency for pretenuring only on the outermost literal. | 11985 // We install a dependency for pretenuring only on the outermost literal. |
| 12031 top_info()->dependencies()->AssumeTenuringDecision(top_site); | 11986 top_info()->dependencies()->AssumeTenuringDecision(top_site); |
| 12032 } | 11987 } |
| 12033 top_info()->dependencies()->AssumeTransitionStable(current_site); | 11988 top_info()->dependencies()->AssumeTransitionStable(current_site); |
| 12034 | 11989 |
| 12035 HInstruction* object = Add<HAllocate>( | 11990 HInstruction* object = |
| 12036 object_size_constant, type, pretenure_flag, instance_type, top_site); | 11991 Add<HAllocate>(object_size_constant, type, pretenure_flag, instance_type, |
| 11992 graph()->GetConstant0(), top_site); |
| 12037 | 11993 |
| 12038 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the | 11994 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the |
| 12039 // elements array may not get folded into the object. Hence, we set the | 11995 // elements array may not get folded into the object. Hence, we set the |
| 12040 // elements pointer to empty fixed array and let store elimination remove | 11996 // elements pointer to empty fixed array and let store elimination remove |
| 12041 // this store in the folding case. | 11997 // this store in the folding case. |
| 12042 HConstant* empty_fixed_array = Add<HConstant>( | 11998 HConstant* empty_fixed_array = Add<HConstant>( |
| 12043 isolate()->factory()->empty_fixed_array()); | 11999 isolate()->factory()->empty_fixed_array()); |
| 12044 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 12000 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 12045 empty_fixed_array); | 12001 empty_fixed_array); |
| 12046 | 12002 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 12067 Handle<FixedArray>::cast(elements))); | 12023 Handle<FixedArray>::cast(elements))); |
| 12068 boilerplate_object->set_elements(*elements); | 12024 boilerplate_object->set_elements(*elements); |
| 12069 } | 12025 } |
| 12070 | 12026 |
| 12071 HInstruction* object_elements = NULL; | 12027 HInstruction* object_elements = NULL; |
| 12072 if (elements_size > 0) { | 12028 if (elements_size > 0) { |
| 12073 HValue* object_elements_size = Add<HConstant>(elements_size); | 12029 HValue* object_elements_size = Add<HConstant>(elements_size); |
| 12074 InstanceType instance_type = boilerplate_object->HasFastDoubleElements() | 12030 InstanceType instance_type = boilerplate_object->HasFastDoubleElements() |
| 12075 ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; | 12031 ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; |
| 12076 object_elements = Add<HAllocate>(object_elements_size, HType::HeapObject(), | 12032 object_elements = Add<HAllocate>(object_elements_size, HType::HeapObject(), |
| 12077 pretenure_flag, instance_type, top_site); | 12033 pretenure_flag, instance_type, |
| 12034 graph()->GetConstant0(), top_site); |
| 12078 BuildEmitElements(boilerplate_object, elements, object_elements, | 12035 BuildEmitElements(boilerplate_object, elements, object_elements, |
| 12079 site_context); | 12036 site_context); |
| 12080 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 12037 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 12081 object_elements); | 12038 object_elements); |
| 12082 } else { | 12039 } else { |
| 12083 Handle<Object> elements_field = | 12040 Handle<Object> elements_field = |
| 12084 Handle<Object>(boilerplate_object->elements(), isolate()); | 12041 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 12085 HInstruction* object_elements_cow = Add<HConstant>(elements_field); | 12042 HInstruction* object_elements_cow = Add<HConstant>(elements_field); |
| 12086 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 12043 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 12087 object_elements_cow); | 12044 object_elements_cow); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12168 BuildFastLiteral(value_object, site_context); | 12125 BuildFastLiteral(value_object, site_context); |
| 12169 site_context->ExitScope(current_site, value_object); | 12126 site_context->ExitScope(current_site, value_object); |
| 12170 Add<HStoreNamedField>(object, access, result); | 12127 Add<HStoreNamedField>(object, access, result); |
| 12171 } else { | 12128 } else { |
| 12172 Representation representation = details.representation(); | 12129 Representation representation = details.representation(); |
| 12173 HInstruction* value_instruction; | 12130 HInstruction* value_instruction; |
| 12174 | 12131 |
| 12175 if (representation.IsDouble()) { | 12132 if (representation.IsDouble()) { |
| 12176 // Allocate a HeapNumber box and store the value into it. | 12133 // Allocate a HeapNumber box and store the value into it. |
| 12177 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); | 12134 HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize); |
| 12178 HInstruction* double_box = | 12135 HInstruction* double_box = Add<HAllocate>( |
| 12179 Add<HAllocate>(heap_number_constant, HType::HeapObject(), | 12136 heap_number_constant, HType::HeapObject(), pretenure_flag, |
| 12180 pretenure_flag, MUTABLE_HEAP_NUMBER_TYPE); | 12137 MUTABLE_HEAP_NUMBER_TYPE, graph()->GetConstant0()); |
| 12181 AddStoreMapConstant(double_box, | 12138 AddStoreMapConstant(double_box, |
| 12182 isolate()->factory()->mutable_heap_number_map()); | 12139 isolate()->factory()->mutable_heap_number_map()); |
| 12183 // Unwrap the mutable heap number from the boilerplate. | 12140 // Unwrap the mutable heap number from the boilerplate. |
| 12184 HValue* double_value = | 12141 HValue* double_value = |
| 12185 Add<HConstant>(Handle<HeapNumber>::cast(value)->value()); | 12142 Add<HConstant>(Handle<HeapNumber>::cast(value)->value()); |
| 12186 Add<HStoreNamedField>( | 12143 Add<HStoreNamedField>( |
| 12187 double_box, HObjectAccess::ForHeapNumberValue(), double_value); | 12144 double_box, HObjectAccess::ForHeapNumberValue(), double_value); |
| 12188 value_instruction = double_box; | 12145 value_instruction = double_box; |
| 12189 } else if (representation.IsSmi()) { | 12146 } else if (representation.IsSmi()) { |
| 12190 value_instruction = value->IsUninitialized() | 12147 value_instruction = value->IsUninitialized() |
| (...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12984 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; | 12941 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; |
| 12985 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + | 12942 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + |
| 12986 kBucketCount + | 12943 kBucketCount + |
| 12987 (kCapacity * CollectionType::kEntrySize); | 12944 (kCapacity * CollectionType::kEntrySize); |
| 12988 static const int kSizeInBytes = | 12945 static const int kSizeInBytes = |
| 12989 FixedArray::kHeaderSize + (kFixedArrayLength * kPointerSize); | 12946 FixedArray::kHeaderSize + (kFixedArrayLength * kPointerSize); |
| 12990 | 12947 |
| 12991 // Allocate the table and add the proper map. | 12948 // Allocate the table and add the proper map. |
| 12992 HValue* table = | 12949 HValue* table = |
| 12993 Add<HAllocate>(Add<HConstant>(kSizeInBytes), HType::HeapObject(), | 12950 Add<HAllocate>(Add<HConstant>(kSizeInBytes), HType::HeapObject(), |
| 12994 NOT_TENURED, FIXED_ARRAY_TYPE); | 12951 NOT_TENURED, FIXED_ARRAY_TYPE, graph()->GetConstant0()); |
| 12995 AddStoreMapConstant(table, isolate()->factory()->ordered_hash_table_map()); | 12952 AddStoreMapConstant(table, isolate()->factory()->ordered_hash_table_map()); |
| 12996 | 12953 |
| 12997 // Initialize the FixedArray... | 12954 // Initialize the FixedArray... |
| 12998 HValue* length = Add<HConstant>(kFixedArrayLength); | 12955 HValue* length = Add<HConstant>(kFixedArrayLength); |
| 12999 Add<HStoreNamedField>(table, HObjectAccess::ForFixedArrayLength(), length); | 12956 Add<HStoreNamedField>(table, HObjectAccess::ForFixedArrayLength(), length); |
| 13000 | 12957 |
| 13001 // ...and the OrderedHashTable fields. | 12958 // ...and the OrderedHashTable fields. |
| 13002 Add<HStoreNamedField>( | 12959 Add<HStoreNamedField>( |
| 13003 table, | 12960 table, |
| 13004 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>(), | 12961 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>(), |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13784 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13741 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13785 } | 13742 } |
| 13786 | 13743 |
| 13787 #ifdef DEBUG | 13744 #ifdef DEBUG |
| 13788 graph_->Verify(false); // No full verify. | 13745 graph_->Verify(false); // No full verify. |
| 13789 #endif | 13746 #endif |
| 13790 } | 13747 } |
| 13791 | 13748 |
| 13792 } // namespace internal | 13749 } // namespace internal |
| 13793 } // namespace v8 | 13750 } // namespace v8 |
| OLD | NEW |