| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 | 731 |
| 732 #ifdef DEBUG | 732 #ifdef DEBUG |
| 733 ReportStatisticsAfterGC(); | 733 ReportStatisticsAfterGC(); |
| 734 #endif // DEBUG | 734 #endif // DEBUG |
| 735 | 735 |
| 736 // Remember the last top pointer so that we can later find out | 736 // Remember the last top pointer so that we can later find out |
| 737 // whether we allocated in new space since the last GC. | 737 // whether we allocated in new space since the last GC. |
| 738 new_space_top_after_last_gc_ = new_space()->top(); | 738 new_space_top_after_last_gc_ = new_space()->top(); |
| 739 last_gc_time_ = MonotonicallyIncreasingTimeInMs(); | 739 last_gc_time_ = MonotonicallyIncreasingTimeInMs(); |
| 740 | 740 |
| 741 ReduceNewSpaceSize( | 741 ReduceNewSpaceSize(); |
| 742 tracer()->CurrentAllocationThroughputInBytesPerMillisecond()); | |
| 743 } | 742 } |
| 744 | 743 |
| 745 | 744 |
| 746 void Heap::PreprocessStackTraces() { | 745 void Heap::PreprocessStackTraces() { |
| 747 if (!weak_stack_trace_list()->IsWeakFixedArray()) return; | 746 if (!weak_stack_trace_list()->IsWeakFixedArray()) return; |
| 748 WeakFixedArray* array = WeakFixedArray::cast(weak_stack_trace_list()); | 747 WeakFixedArray* array = WeakFixedArray::cast(weak_stack_trace_list()); |
| 749 int length = array->Length(); | 748 int length = array->Length(); |
| 750 for (int i = 0; i < length; i++) { | 749 for (int i = 0; i < length; i++) { |
| 751 if (array->IsEmptySlot(i)) continue; | 750 if (array->IsEmptySlot(i)) continue; |
| 752 FixedArray* elements = FixedArray::cast(array->Get(i)); | 751 FixedArray* elements = FixedArray::cast(array->Get(i)); |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 VerifyNonPointerSpacePointersVisitor v(heap); | 1428 VerifyNonPointerSpacePointersVisitor v(heap); |
| 1430 HeapObjectIterator code_it(heap->code_space()); | 1429 HeapObjectIterator code_it(heap->code_space()); |
| 1431 for (HeapObject* object = code_it.Next(); object != NULL; | 1430 for (HeapObject* object = code_it.Next(); object != NULL; |
| 1432 object = code_it.Next()) | 1431 object = code_it.Next()) |
| 1433 object->Iterate(&v); | 1432 object->Iterate(&v); |
| 1434 } | 1433 } |
| 1435 #endif // VERIFY_HEAP | 1434 #endif // VERIFY_HEAP |
| 1436 | 1435 |
| 1437 | 1436 |
| 1438 void Heap::CheckNewSpaceExpansionCriteria() { | 1437 void Heap::CheckNewSpaceExpansionCriteria() { |
| 1438 if (!HasLowYoungGenerationAllocationUtilization()) { |
| 1439 if (FLAG_experimental_new_space_growth_heuristic) { | 1439 if (FLAG_experimental_new_space_growth_heuristic) { |
| 1440 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && | 1440 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && |
| 1441 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { | 1441 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { |
| 1442 // Grow the size of new space if there is room to grow, and more than 10% | 1442 // Grow the size of new space if there is room to grow, and more than 10% |
| 1443 // have survived the last scavenge. | 1443 // have survived the last scavenge. |
| 1444 new_space_.Grow(); | 1444 new_space_.Grow(); |
| 1445 survived_since_last_expansion_ = 0; | 1445 survived_since_last_expansion_ = 0; |
| 1446 } | 1446 } |
| 1447 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && | 1447 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && |
| 1448 survived_since_last_expansion_ > new_space_.TotalCapacity()) { | 1448 survived_since_last_expansion_ > new_space_.TotalCapacity()) { |
| 1449 // Grow the size of new space if there is room to grow, and enough data | 1449 // Grow the size of new space if there is room to grow, and enough data |
| 1450 // has survived scavenge since the last expansion. | 1450 // has survived scavenge since the last expansion. |
| 1451 new_space_.Grow(); | 1451 new_space_.Grow(); |
| 1452 survived_since_last_expansion_ = 0; | 1452 survived_since_last_expansion_ = 0; |
| 1453 } | 1453 } |
| 1454 } |
| 1454 } | 1455 } |
| 1455 | 1456 |
| 1456 | 1457 |
| 1457 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { | 1458 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |
| 1458 return heap->InNewSpace(*p) && | 1459 return heap->InNewSpace(*p) && |
| 1459 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 1460 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
| 1460 } | 1461 } |
| 1461 | 1462 |
| 1462 | 1463 |
| 1463 void Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page, | 1464 void Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page, |
| (...skipping 3038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4502 if (!IsHeapIterable()) { | 4503 if (!IsHeapIterable()) { |
| 4503 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); | 4504 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); |
| 4504 } | 4505 } |
| 4505 if (mark_compact_collector()->sweeping_in_progress()) { | 4506 if (mark_compact_collector()->sweeping_in_progress()) { |
| 4506 mark_compact_collector()->EnsureSweepingCompleted(); | 4507 mark_compact_collector()->EnsureSweepingCompleted(); |
| 4507 } | 4508 } |
| 4508 DCHECK(IsHeapIterable()); | 4509 DCHECK(IsHeapIterable()); |
| 4509 } | 4510 } |
| 4510 | 4511 |
| 4511 | 4512 |
| 4512 bool Heap::HasLowAllocationRate(size_t allocation_rate) { | 4513 bool Heap::HasLowAllocationRate() { |
| 4513 static const size_t kLowAllocationRate = 1000; | 4514 static const size_t kLowAllocationRate = 1000; |
| 4515 size_t allocation_rate = |
| 4516 tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); |
| 4514 if (allocation_rate == 0) return false; | 4517 if (allocation_rate == 0) return false; |
| 4515 return allocation_rate < kLowAllocationRate; | 4518 return allocation_rate < kLowAllocationRate; |
| 4516 } | 4519 } |
| 4517 | 4520 |
| 4518 | 4521 |
| 4519 void Heap::ReduceNewSpaceSize(size_t allocation_rate) { | 4522 bool Heap::HasLowYoungGenerationAllocationUtilization() { |
| 4520 if (!FLAG_predictable && HasLowAllocationRate(allocation_rate)) { | 4523 const double low_mutator_utilization = 0.01; |
| 4521 new_space_.Shrink(); | 4524 double allocation_speed = static_cast<double>( |
| 4522 UncommitFromSpace(); | 4525 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); |
| 4526 double scavenging_speed = |
| 4527 static_cast<double>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
| 4528 double mutator_utilization = |
| 4529 allocation_speed / (allocation_speed + scavenging_speed); |
| 4530 return mutator_utilization < low_mutator_utilization; |
| 4531 } |
| 4532 |
| 4533 |
| 4534 void Heap::ReduceNewSpaceSize() { |
| 4535 if (!FLAG_predictable) { |
| 4536 if (HasLowYoungGenerationAllocationUtilization()) { |
| 4537 new_space_.Shrink(); |
| 4538 } |
| 4539 if (HasLowAllocationRate()) { |
| 4540 UncommitFromSpace(); |
| 4541 } |
| 4523 } | 4542 } |
| 4524 } | 4543 } |
| 4525 | 4544 |
| 4526 | 4545 |
| 4527 bool Heap::TryFinalizeIdleIncrementalMarking( | 4546 bool Heap::TryFinalizeIdleIncrementalMarking( |
| 4528 double idle_time_in_ms, size_t size_of_objects, | 4547 double idle_time_in_ms, size_t size_of_objects, |
| 4529 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 4548 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
| 4530 if (FLAG_overapproximate_weak_closure && | 4549 if (FLAG_overapproximate_weak_closure && |
| 4531 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4550 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
| 4532 (!incremental_marking()->weak_closure_was_overapproximated() && | 4551 (!incremental_marking()->weak_closure_was_overapproximated() && |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4569 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4588 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
| 4570 heap_state.scavenge_speed_in_bytes_per_ms = | 4589 heap_state.scavenge_speed_in_bytes_per_ms = |
| 4571 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4590 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
| 4572 heap_state.used_new_space_size = new_space_.Size(); | 4591 heap_state.used_new_space_size = new_space_.Size(); |
| 4573 heap_state.new_space_capacity = new_space_.Capacity(); | 4592 heap_state.new_space_capacity = new_space_.Capacity(); |
| 4574 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4593 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
| 4575 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4594 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
| 4576 heap_state.current_allocation_throughput_in_bytes_per_ms = | 4595 heap_state.current_allocation_throughput_in_bytes_per_ms = |
| 4577 tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); | 4596 tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); |
| 4578 intptr_t limit = old_generation_allocation_limit_; | 4597 intptr_t limit = old_generation_allocation_limit_; |
| 4579 if (HasLowAllocationRate( | 4598 if (HasLowAllocationRate()) { |
| 4580 heap_state.current_allocation_throughput_in_bytes_per_ms)) { | |
| 4581 limit = idle_old_generation_allocation_limit_; | 4599 limit = idle_old_generation_allocation_limit_; |
| 4582 } | 4600 } |
| 4583 heap_state.can_start_incremental_marking = | 4601 heap_state.can_start_incremental_marking = |
| 4584 incremental_marking()->CanBeActivated() && | 4602 incremental_marking()->CanBeActivated() && |
| 4585 HeapIsFullEnoughToStartIncrementalMarking(limit) && | 4603 HeapIsFullEnoughToStartIncrementalMarking(limit) && |
| 4586 !mark_compact_collector()->sweeping_in_progress(); | 4604 !mark_compact_collector()->sweeping_in_progress(); |
| 4587 return heap_state; | 4605 return heap_state; |
| 4588 } | 4606 } |
| 4589 | 4607 |
| 4590 | 4608 |
| (...skipping 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6553 *object_type = "CODE_TYPE"; \ | 6571 *object_type = "CODE_TYPE"; \ |
| 6554 *object_sub_type = "CODE_AGE/" #name; \ | 6572 *object_sub_type = "CODE_AGE/" #name; \ |
| 6555 return true; | 6573 return true; |
| 6556 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6574 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
| 6557 #undef COMPARE_AND_RETURN_NAME | 6575 #undef COMPARE_AND_RETURN_NAME |
| 6558 } | 6576 } |
| 6559 return false; | 6577 return false; |
| 6560 } | 6578 } |
| 6561 } // namespace internal | 6579 } // namespace internal |
| 6562 } // namespace v8 | 6580 } // namespace v8 |
| OLD | NEW |