| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index f7b310003e0c1140936a8c86d51638534acd824a..ac0a4b0c862e08622d5d8b604b57ce5580132d30 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -2136,7 +2136,6 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
|
| }
|
|
|
|
|
| -
|
| HValue* HGraphBuilder::BuildAllocateArrayFromLength(
|
| JSArrayBuilder* array_builder,
|
| HValue* length_argument) {
|
| @@ -2179,29 +2178,36 @@ HValue* HGraphBuilder::BuildAllocateArrayFromLength(
|
| return array_builder->AllocateArray(capacity, length);
|
| }
|
|
|
| -HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
|
| - HValue* capacity) {
|
| - int elements_size;
|
| - InstanceType instance_type;
|
| -
|
| - if (IsFastDoubleElementsKind(kind)) {
|
| - elements_size = kDoubleSize;
|
| - instance_type = FIXED_DOUBLE_ARRAY_TYPE;
|
| - } else {
|
| - elements_size = kPointerSize;
|
| - instance_type = FIXED_ARRAY_TYPE;
|
| - }
|
| +HValue* HGraphBuilder::BuildCalculateElementsSize(ElementsKind kind,
|
| + HValue* capacity) {
|
| + int elements_size = IsFastDoubleElementsKind(kind)
|
| + ? kDoubleSize
|
| + : kPointerSize;
|
|
|
| HConstant* elements_size_value = Add<HConstant>(elements_size);
|
| - HValue* mul = AddUncasted<HMul>(capacity, elements_size_value);
|
| + HInstruction* mul = HMul::NewImul(zone(), context(),
|
| + capacity->ActualValue(),
|
| + elements_size_value);
|
| + AddInstruction(mul);
|
| mul->ClearFlag(HValue::kCanOverflow);
|
|
|
| + STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
|
| +
|
| HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
|
| HValue* total_size = AddUncasted<HAdd>(mul, header_size);
|
| total_size->ClearFlag(HValue::kCanOverflow);
|
| + return total_size;
|
| +}
|
|
|
| - return Add<HAllocate>(total_size, HType::JSArray(),
|
| - isolate()->heap()->GetPretenureMode(), instance_type);
|
| +HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind,
|
| + HValue* size_in_bytes,
|
| + PretenureFlag pretenure) {
|
| + InstanceType instance_type = IsFastDoubleElementsKind(kind)
|
| + ? FIXED_DOUBLE_ARRAY_TYPE
|
| + : FIXED_ARRAY_TYPE;
|
| +
|
| + return Add<HAllocate>(size_in_bytes, HType::JSArray(),
|
| + pretenure, instance_type);
|
| }
|
|
|
|
|
| @@ -2225,43 +2231,39 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
|
| // The HForceRepresentation is to prevent possible deopt on int-smi
|
| // conversion after allocation but before the new object fields are set.
|
| capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
|
| - HValue* new_elements = BuildAllocateElements(kind, capacity);
|
| + HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
|
| + HValue* new_elements = BuildAllocateElements(
|
| + kind, size_in_bytes, isolate()->heap()->GetPretenureMode());
|
| BuildInitializeElementsHeader(new_elements, kind, capacity);
|
| return new_elements;
|
| }
|
|
|
|
|
| -HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
|
| - HValue* array_map,
|
| - AllocationSiteMode mode,
|
| - ElementsKind elements_kind,
|
| - HValue* allocation_site_payload,
|
| - HValue* length_field) {
|
| -
|
| +void HGraphBuilder::BuildJSArrayHeader(HValue* array,
|
| + HValue* array_map,
|
| + AllocationSiteMode mode,
|
| + ElementsKind elements_kind,
|
| + HValue* allocation_site_payload,
|
| + HValue* length_field) {
|
| Add<HStoreNamedField>(array, HObjectAccess::ForMap(), array_map);
|
|
|
| HConstant* empty_fixed_array =
|
| Add<HConstant>(isolate()->factory()->empty_fixed_array());
|
|
|
| - HObjectAccess access = HObjectAccess::ForPropertiesPointer();
|
| - Add<HStoreNamedField>(array, access, empty_fixed_array);
|
| - Add<HStoreNamedField>(array, HObjectAccess::ForArrayLength(elements_kind),
|
| - length_field);
|
| + Add<HStoreNamedField>(
|
| + array, HObjectAccess::ForPropertiesPointer(), empty_fixed_array);
|
| +
|
| + Add<HStoreNamedField>(
|
| + array, HObjectAccess::ForElementsPointer(), empty_fixed_array);
|
| +
|
| + Add<HStoreNamedField>(
|
| + array, HObjectAccess::ForArrayLength(elements_kind), length_field);
|
|
|
| if (mode == TRACK_ALLOCATION_SITE) {
|
| BuildCreateAllocationMemento(array,
|
| JSArray::kSize,
|
| allocation_site_payload);
|
| }
|
| -
|
| - int elements_location = JSArray::kSize;
|
| - if (mode == TRACK_ALLOCATION_SITE) {
|
| - elements_location += AllocationMemento::kSize;
|
| - }
|
| -
|
| - HValue* elements = Add<HInnerAllocatedObject>(array, elements_location);
|
| - Add<HStoreNamedField>(array, HObjectAccess::ForElementsPointer(), elements);
|
| - return static_cast<HInnerAllocatedObject*>(elements);
|
| }
|
|
|
|
|
| @@ -2679,51 +2681,18 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
|
| }
|
|
|
|
|
| -HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
|
| - HValue* length_node) {
|
| - ASSERT(length_node != NULL);
|
| -
|
| +HValue* HGraphBuilder::JSArrayBuilder::EstablishHeaderAllocationSize() {
|
| int base_size = JSArray::kSize;
|
| if (mode_ == TRACK_ALLOCATION_SITE) {
|
| base_size += AllocationMemento::kSize;
|
| }
|
| -
|
| - STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize);
|
| - base_size += FixedArray::kHeaderSize;
|
| -
|
| - HInstruction* elements_size_value =
|
| - builder()->Add<HConstant>(elements_size());
|
| - HInstruction* mul = HMul::NewImul(builder()->zone(), builder()->context(),
|
| - length_node, elements_size_value);
|
| - builder()->AddInstruction(mul);
|
| - HInstruction* base = builder()->Add<HConstant>(base_size);
|
| - HInstruction* total_size = HAdd::New(builder()->zone(), builder()->context(),
|
| - base, mul);
|
| - total_size->ClearFlag(HValue::kCanOverflow);
|
| - builder()->AddInstruction(total_size);
|
| - return total_size;
|
| -}
|
| -
|
| -
|
| -HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
|
| - int base_size = JSArray::kSize;
|
| - if (mode_ == TRACK_ALLOCATION_SITE) {
|
| - base_size += AllocationMemento::kSize;
|
| - }
|
| -
|
| - base_size += IsFastDoubleElementsKind(kind_)
|
| - ? FixedDoubleArray::SizeFor(initial_capacity())
|
| - : FixedArray::SizeFor(initial_capacity());
|
| -
|
| return builder()->Add<HConstant>(base_size);
|
| }
|
|
|
|
|
| HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
|
| - HValue* size_in_bytes = EstablishEmptyArrayAllocationSize();
|
| HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
|
| - return AllocateArray(size_in_bytes,
|
| - capacity,
|
| + return AllocateArray(capacity,
|
| builder()->graph()->GetConstant0());
|
| }
|
|
|
| @@ -2731,15 +2700,6 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
|
| HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* capacity,
|
| HValue* length_field,
|
| FillMode fill_mode) {
|
| - HValue* size_in_bytes = EstablishAllocationSize(capacity);
|
| - return AllocateArray(size_in_bytes, capacity, length_field, fill_mode);
|
| -}
|
| -
|
| -
|
| -HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
| - HValue* capacity,
|
| - HValue* length_field,
|
| - FillMode fill_mode) {
|
| // These HForceRepresentations are because we store these as fields in the
|
| // objects we construct, and an int32-to-smi HChange could deopt. Accept
|
| // the deopt possibility now, before allocation occurs.
|
| @@ -2749,15 +2709,16 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
| length_field =
|
| builder()->AddUncasted<HForceRepresentation>(length_field,
|
| Representation::Smi());
|
| +
|
| + // Generate size calculation code here in order to make it dominate
|
| + // the JSArray allocation.
|
| + HValue* elms_size = builder()->BuildCalculateElementsSize(kind_, capacity);
|
| +
|
| // Allocate (dealing with failure appropriately)
|
| - HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
|
| + HValue* array_object_size = EstablishHeaderAllocationSize();
|
| + HAllocate* array_object = builder()->Add<HAllocate>(array_object_size,
|
| HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
|
|
|
| - // Folded array allocation should be aligned if it has fast double elements.
|
| - if (IsFastDoubleElementsKind(kind_)) {
|
| - new_object->MakeDoubleAligned();
|
| - }
|
| -
|
| // Fill in the fields: map, properties, length
|
| HValue* map;
|
| if (allocation_site_payload_ == NULL) {
|
| @@ -2765,22 +2726,30 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
|
| } else {
|
| map = EmitMapCode();
|
| }
|
| - elements_location_ = builder()->BuildJSArrayHeader(new_object,
|
| - map,
|
| - mode_,
|
| - kind_,
|
| - allocation_site_payload_,
|
| - length_field);
|
|
|
| - // Initialize the elements
|
| + builder()->BuildJSArrayHeader(array_object,
|
| + map,
|
| + mode_,
|
| + kind_,
|
| + allocation_site_payload_,
|
| + length_field);
|
| +
|
| + // Allocate and initialize the elements
|
| + elements_location_ =
|
| + builder()->BuildAllocateElements(kind_, elms_size, NOT_TENURED);
|
| +
|
| builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity);
|
|
|
| + // Set the elements
|
| + builder()->Add<HStoreNamedField>(
|
| + array_object, HObjectAccess::ForElementsPointer(), elements_location_);
|
| +
|
| if (fill_mode == FILL_WITH_HOLE) {
|
| builder()->BuildFillElementsWithHole(elements_location_, kind_,
|
| graph()->GetConstant0(), capacity);
|
| }
|
|
|
| - return new_object;
|
| + return array_object;
|
| }
|
|
|
|
|
|
|