| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index 2c4435cc4cb2d1c89917ee5f11e701b7f737cfac..d9f4fd56eb8a90d9103af0b216b81fdad68cf54c 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -2517,8 +2517,25 @@ HValue* HGraphBuilder::BuildAllocateArrayFromLength(
|
| if (array_length == 0) {
|
| return array_builder->AllocateEmptyArray();
|
| } else {
|
| - return array_builder->AllocateArray(length_argument,
|
| - array_length,
|
| + // If we have capacity feedback, we want the capacity to be
|
| + // max(array_length, feedback).
|
| + HValue* capacity_value = length_argument;
|
| + HValue* site_value = array_builder->allocation_site();
|
| + if (site_value != NULL && site_value->IsConstant()) {
|
| + Handle<AllocationSite> site = Handle<AllocationSite>::cast(
|
| + HConstant::cast(site_value)->handle(isolate()));
|
| + int capacity_feedback = site->GetInitialElementsCapacity();
|
| + if (capacity_feedback > array_length) {
|
| + if (FLAG_trace_track_allocation_sites) {
|
| + PrintF("site %p, capacity adjusted from %d to %d\n",
|
| + static_cast<void*>(*site), array_length,
|
| + capacity_feedback);
|
| + }
|
| + array_length = capacity_feedback;
|
| + capacity_value = Add<HConstant>(capacity_feedback);
|
| + }
|
| + }
|
| + return array_builder->AllocateArray(capacity_value, array_length,
|
| length_argument);
|
| }
|
| }
|
| @@ -2532,9 +2549,7 @@ HValue* HGraphBuilder::BuildAllocateArrayFromLength(
|
| if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero,
|
| Token::EQ);
|
| if_builder.Then();
|
| - const int initial_capacity = JSArray::kPreallocatedArrayElements;
|
| - HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
|
| - Push(initial_capacity_node); // capacity
|
| + Push(constant_zero); // capacity
|
| Push(constant_zero); // length
|
| if_builder.Else();
|
| if (!(top_info()->IsStub()) &&
|
| @@ -2772,8 +2787,7 @@ void HGraphBuilder::BuildFillElementsWithValue(HValue* elements,
|
| }
|
|
|
| // Special loop unfolding case
|
| - STATIC_ASSERT(JSArray::kPreallocatedArrayElements <=
|
| - kElementLoopUnrollThreshold);
|
| + DCHECK(JSArray::PreallocatedArrayElements() <= kElementLoopUnrollThreshold);
|
| int initial_capacity = -1;
|
| if (from->IsInteger32Constant() && to->IsInteger32Constant()) {
|
| int constant_from = from->GetInteger32Constant();
|
| @@ -3225,8 +3239,30 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
|
| }
|
|
|
|
|
| +HConstant* HGraphBuilder::JSArrayBuilder::initial_capacity() {
|
| + int capacity = 0;
|
| + if (allocation_site_payload_ != NULL) {
|
| + if (allocation_site_payload_->IsConstant()) {
|
| + Handle<AllocationSite> site =
|
| + Handle<AllocationSite>::cast(HConstant::cast(allocation_site_payload_)
|
| + ->handle(builder()->isolate()));
|
| + int possible_capacity = site->GetInitialElementsCapacity();
|
| + if (possible_capacity > 0) {
|
| + capacity = possible_capacity;
|
| + if (FLAG_trace_track_allocation_sites) {
|
| + PrintF("site %p, feedback adjusted to %d\n",
|
| + static_cast<void*>(*site), possible_capacity);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return HConstant::New(zone(), builder()->context(), capacity);
|
| +}
|
| +
|
| +
|
| HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() {
|
| - HConstant* capacity = builder()->Add<HConstant>(initial_capacity());
|
| + HConstant* capacity = initial_capacity();
|
| + builder()->AddInstruction(capacity);
|
| return AllocateArray(capacity,
|
| capacity,
|
| builder()->graph()->GetConstant0());
|
|
|