| 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 <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 2499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2510 | 2510 |
| 2511 HValue* HGraphBuilder::BuildAllocateArrayFromLength( | 2511 HValue* HGraphBuilder::BuildAllocateArrayFromLength( |
| 2512 JSArrayBuilder* array_builder, | 2512 JSArrayBuilder* array_builder, |
| 2513 HValue* length_argument) { | 2513 HValue* length_argument) { |
| 2514 if (length_argument->IsConstant() && | 2514 if (length_argument->IsConstant() && |
| 2515 HConstant::cast(length_argument)->HasSmiValue()) { | 2515 HConstant::cast(length_argument)->HasSmiValue()) { |
| 2516 int array_length = HConstant::cast(length_argument)->Integer32Value(); | 2516 int array_length = HConstant::cast(length_argument)->Integer32Value(); |
| 2517 if (array_length == 0) { | 2517 if (array_length == 0) { |
| 2518 return array_builder->AllocateEmptyArray(); | 2518 return array_builder->AllocateEmptyArray(); |
| 2519 } else { | 2519 } else { |
| 2520 return array_builder->AllocateArray(length_argument, | 2520 // If we have capacity feedback, we want the capacity to be |
| 2521 array_length, | 2521 // max(array_length, feedback). |
| 2522 HValue* capacity_value = length_argument; |
| 2523 HValue* site_value = array_builder->allocation_site(); |
| 2524 if (site_value != NULL && site_value->IsConstant()) { |
| 2525 Handle<AllocationSite> site = Handle<AllocationSite>::cast( |
| 2526 HConstant::cast(site_value)->handle(isolate())); |
| 2527 int capacity_feedback = site->GetInitialElementsCapacity(); |
| 2528 if (capacity_feedback > array_length) { |
| 2529 if (FLAG_trace_track_allocation_sites) { |
| 2530 PrintF("site %p, capacity adjusted from %d to %d\n", |
| 2531 static_cast<void*>(*site), array_length, |
| 2532 capacity_feedback); |
| 2533 } |
| 2534 array_length = capacity_feedback; |
| 2535 capacity_value = Add<HConstant>(capacity_feedback); |
| 2536 } |
| 2537 } |
| 2538 return array_builder->AllocateArray(capacity_value, array_length, |
| 2522 length_argument); | 2539 length_argument); |
| 2523 } | 2540 } |
| 2524 } | 2541 } |
| 2525 | 2542 |
| 2526 HValue* constant_zero = graph()->GetConstant0(); | 2543 HValue* constant_zero = graph()->GetConstant0(); |
| 2527 HConstant* max_alloc_length = | 2544 HConstant* max_alloc_length = |
| 2528 Add<HConstant>(JSObject::kInitialMaxFastElementArray); | 2545 Add<HConstant>(JSObject::kInitialMaxFastElementArray); |
| 2529 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, | 2546 HInstruction* checked_length = Add<HBoundsCheck>(length_argument, |
| 2530 max_alloc_length); | 2547 max_alloc_length); |
| 2531 IfBuilder if_builder(this); | 2548 IfBuilder if_builder(this); |
| 2532 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, | 2549 if_builder.If<HCompareNumericAndBranch>(checked_length, constant_zero, |
| 2533 Token::EQ); | 2550 Token::EQ); |
| 2534 if_builder.Then(); | 2551 if_builder.Then(); |
| 2535 const int initial_capacity = JSArray::kPreallocatedArrayElements; | 2552 Push(constant_zero); // capacity |
| 2536 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity); | |
| 2537 Push(initial_capacity_node); // capacity | |
| 2538 Push(constant_zero); // length | 2553 Push(constant_zero); // length |
| 2539 if_builder.Else(); | 2554 if_builder.Else(); |
| 2540 if (!(top_info()->IsStub()) && | 2555 if (!(top_info()->IsStub()) && |
| 2541 IsFastPackedElementsKind(array_builder->kind())) { | 2556 IsFastPackedElementsKind(array_builder->kind())) { |
| 2542 // We'll come back later with better (holey) feedback. | 2557 // We'll come back later with better (holey) feedback. |
| 2543 if_builder.Deopt("Holey array despite packed elements_kind feedback"); | 2558 if_builder.Deopt("Holey array despite packed elements_kind feedback"); |
| 2544 } else { | 2559 } else { |
| 2545 Push(checked_length); // capacity | 2560 Push(checked_length); // capacity |
| 2546 Push(checked_length); // length | 2561 Push(checked_length); // length |
| 2547 } | 2562 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2765 void HGraphBuilder::BuildFillElementsWithValue(HValue* elements, | 2780 void HGraphBuilder::BuildFillElementsWithValue(HValue* elements, |
| 2766 ElementsKind elements_kind, | 2781 ElementsKind elements_kind, |
| 2767 HValue* from, | 2782 HValue* from, |
| 2768 HValue* to, | 2783 HValue* to, |
| 2769 HValue* value) { | 2784 HValue* value) { |
| 2770 if (to == NULL) { | 2785 if (to == NULL) { |
| 2771 to = AddLoadFixedArrayLength(elements); | 2786 to = AddLoadFixedArrayLength(elements); |
| 2772 } | 2787 } |
| 2773 | 2788 |
| 2774 // Special loop unfolding case | 2789 // Special loop unfolding case |
| 2775 STATIC_ASSERT(JSArray::kPreallocatedArrayElements <= | 2790 DCHECK(JSArray::PreallocatedArrayElements() <= kElementLoopUnrollThreshold); |
| 2776 kElementLoopUnrollThreshold); | |
| 2777 int initial_capacity = -1; | 2791 int initial_capacity = -1; |
| 2778 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { | 2792 if (from->IsInteger32Constant() && to->IsInteger32Constant()) { |
| 2779 int constant_from = from->GetInteger32Constant(); | 2793 int constant_from = from->GetInteger32Constant(); |
| 2780 int constant_to = to->GetInteger32Constant(); | 2794 int constant_to = to->GetInteger32Constant(); |
| 2781 | 2795 |
| 2782 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { | 2796 if (constant_from == 0 && constant_to <= kElementLoopUnrollThreshold) { |
| 2783 initial_capacity = constant_to; | 2797 initial_capacity = constant_to; |
| 2784 } | 2798 } |
| 2785 } | 2799 } |
| 2786 | 2800 |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3218 | 3232 |
| 3219 | 3233 |
| 3220 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 3234 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 3221 // Find the map near the constructor function | 3235 // Find the map near the constructor function |
| 3222 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3236 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3223 return builder()->Add<HLoadNamedField>( | 3237 return builder()->Add<HLoadNamedField>( |
| 3224 constructor_function_, static_cast<HValue*>(NULL), access); | 3238 constructor_function_, static_cast<HValue*>(NULL), access); |
| 3225 } | 3239 } |
| 3226 | 3240 |
| 3227 | 3241 |
| 3242 HConstant* HGraphBuilder::JSArrayBuilder::initial_capacity() { |
| 3243 int capacity = 0; |
| 3244 if (allocation_site_payload_ != NULL) { |
| 3245 if (allocation_site_payload_->IsConstant()) { |
| 3246 Handle<AllocationSite> site = |
| 3247 Handle<AllocationSite>::cast(HConstant::cast(allocation_site_payload_) |
| 3248 ->handle(builder()->isolate())); |
| 3249 int possible_capacity = site->GetInitialElementsCapacity(); |
| 3250 if (possible_capacity > 0) { |
| 3251 capacity = possible_capacity; |
| 3252 if (FLAG_trace_track_allocation_sites) { |
| 3253 PrintF("site %p, feedback adjusted to %d\n", |
| 3254 static_cast<void*>(*site), possible_capacity); |
| 3255 } |
| 3256 } |
| 3257 } |
| 3258 } |
| 3259 return HConstant::New(zone(), builder()->context(), capacity); |
| 3260 } |
| 3261 |
| 3262 |
| 3228 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 3263 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 3229 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 3264 HConstant* capacity = initial_capacity(); |
| 3265 builder()->AddInstruction(capacity); |
| 3230 return AllocateArray(capacity, | 3266 return AllocateArray(capacity, |
| 3231 capacity, | 3267 capacity, |
| 3232 builder()->graph()->GetConstant0()); | 3268 builder()->graph()->GetConstant0()); |
| 3233 } | 3269 } |
| 3234 | 3270 |
| 3235 | 3271 |
| 3236 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( | 3272 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateArray( |
| 3237 HValue* capacity, | 3273 HValue* capacity, |
| 3238 HConstant* capacity_upper_bound, | 3274 HConstant* capacity_upper_bound, |
| 3239 HValue* length_field, | 3275 HValue* length_field, |
| (...skipping 9293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12533 if (ShouldProduceTraceOutput()) { | 12569 if (ShouldProduceTraceOutput()) { |
| 12534 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12570 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12535 } | 12571 } |
| 12536 | 12572 |
| 12537 #ifdef DEBUG | 12573 #ifdef DEBUG |
| 12538 graph_->Verify(false); // No full verify. | 12574 graph_->Verify(false); // No full verify. |
| 12539 #endif | 12575 #endif |
| 12540 } | 12576 } |
| 12541 | 12577 |
| 12542 } } // namespace v8::internal | 12578 } } // namespace v8::internal |
| OLD | NEW |