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 4584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4595 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4595 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4596 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4596 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4597 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); | 4597 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
4598 gc_idle_time_handler_.NotifyIdleMarkCompact(); | 4598 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4599 return true; | 4599 return true; |
4600 } | 4600 } |
4601 return false; | 4601 return false; |
4602 } | 4602 } |
4603 | 4603 |
4604 | 4604 |
4605 GCIdleTimeHandler::HeapState Heap::ComputeHeapState(bool reduce_memory) { | 4605 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { |
4606 GCIdleTimeHandler::HeapState heap_state; | 4606 GCIdleTimeHandler::HeapState heap_state; |
4607 heap_state.contexts_disposed = contexts_disposed_; | 4607 heap_state.contexts_disposed = contexts_disposed_; |
4608 heap_state.contexts_disposal_rate = | 4608 heap_state.contexts_disposal_rate = |
4609 tracer()->ContextDisposalRateInMilliseconds(); | 4609 tracer()->ContextDisposalRateInMilliseconds(); |
4610 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); | 4610 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); |
4611 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); | 4611 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); |
4612 // TODO(ulan): Start incremental marking only for large heaps. | |
4613 intptr_t limit = old_generation_allocation_limit_; | |
4614 if (reduce_memory) { | |
4615 limit = idle_old_generation_allocation_limit_; | |
4616 } | |
4617 | |
4618 heap_state.can_start_incremental_marking = | |
4619 incremental_marking()->CanBeActivated() && | |
4620 HeapIsFullEnoughToStartIncrementalMarking(limit) && | |
4621 !mark_compact_collector()->sweeping_in_progress(); | |
4622 heap_state.sweeping_in_progress = | 4612 heap_state.sweeping_in_progress = |
4623 mark_compact_collector()->sweeping_in_progress(); | 4613 mark_compact_collector()->sweeping_in_progress(); |
4624 heap_state.sweeping_completed = | 4614 heap_state.sweeping_completed = |
4625 mark_compact_collector()->IsSweepingCompleted(); | 4615 mark_compact_collector()->IsSweepingCompleted(); |
4626 heap_state.mark_compact_speed_in_bytes_per_ms = | 4616 heap_state.mark_compact_speed_in_bytes_per_ms = |
4627 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); | 4617 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); |
4628 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( | 4618 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( |
4629 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); | 4619 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); |
4630 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = | 4620 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = |
4631 static_cast<size_t>( | 4621 static_cast<size_t>( |
4632 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4622 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4633 heap_state.scavenge_speed_in_bytes_per_ms = | 4623 heap_state.scavenge_speed_in_bytes_per_ms = |
4634 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4624 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4635 heap_state.used_new_space_size = new_space_.Size(); | 4625 heap_state.used_new_space_size = new_space_.Size(); |
4636 heap_state.new_space_capacity = new_space_.Capacity(); | 4626 heap_state.new_space_capacity = new_space_.Capacity(); |
4637 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4627 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4638 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4628 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
4639 heap_state.current_new_space_allocation_throughput_in_bytes_per_ms = | 4629 heap_state.current_new_space_allocation_throughput_in_bytes_per_ms = |
4640 tracer()->CurrentNewSpaceAllocationThroughputInBytesPerMillisecond(); | 4630 tracer()->CurrentNewSpaceAllocationThroughputInBytesPerMillisecond(); |
| 4631 intptr_t limit = old_generation_allocation_limit_; |
| 4632 if (HasLowAllocationRate( |
| 4633 heap_state.current_new_space_allocation_throughput_in_bytes_per_ms)) { |
| 4634 limit = idle_old_generation_allocation_limit_; |
| 4635 } |
| 4636 heap_state.can_start_incremental_marking = |
| 4637 incremental_marking()->CanBeActivated() && |
| 4638 HeapIsFullEnoughToStartIncrementalMarking(limit) && |
| 4639 !mark_compact_collector()->sweeping_in_progress(); |
4641 return heap_state; | 4640 return heap_state; |
4642 } | 4641 } |
4643 | 4642 |
4644 | 4643 |
4645 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4644 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4646 GCIdleTimeHandler::HeapState heap_state, | 4645 GCIdleTimeHandler::HeapState heap_state, |
4647 double deadline_in_ms, | 4646 double deadline_in_ms, |
4648 bool is_long_idle_notification) { | 4647 bool is_long_idle_notification) { |
4649 bool result = false; | 4648 bool result = false; |
4650 switch (action.type) { | 4649 switch (action.type) { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4766 bool Heap::IdleNotification(int idle_time_in_ms) { | 4765 bool Heap::IdleNotification(int idle_time_in_ms) { |
4767 return IdleNotification( | 4766 return IdleNotification( |
4768 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + | 4767 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + |
4769 (static_cast<double>(idle_time_in_ms) / | 4768 (static_cast<double>(idle_time_in_ms) / |
4770 static_cast<double>(base::Time::kMillisecondsPerSecond))); | 4769 static_cast<double>(base::Time::kMillisecondsPerSecond))); |
4771 } | 4770 } |
4772 | 4771 |
4773 | 4772 |
4774 bool Heap::IdleNotification(double deadline_in_seconds) { | 4773 bool Heap::IdleNotification(double deadline_in_seconds) { |
4775 CHECK(HasBeenSetUp()); | 4774 CHECK(HasBeenSetUp()); |
4776 static const double kLastGCTimeTreshold = 1000; | |
4777 double deadline_in_ms = | 4775 double deadline_in_ms = |
4778 deadline_in_seconds * | 4776 deadline_in_seconds * |
4779 static_cast<double>(base::Time::kMillisecondsPerSecond); | 4777 static_cast<double>(base::Time::kMillisecondsPerSecond); |
4780 HistogramTimerScope idle_notification_scope( | 4778 HistogramTimerScope idle_notification_scope( |
4781 isolate_->counters()->gc_idle_notification()); | 4779 isolate_->counters()->gc_idle_notification()); |
4782 double start_ms = MonotonicallyIncreasingTimeInMs(); | 4780 double start_ms = MonotonicallyIncreasingTimeInMs(); |
4783 double idle_time_in_ms = deadline_in_ms - start_ms; | 4781 double idle_time_in_ms = deadline_in_ms - start_ms; |
4784 bool is_long_idle_notification = | 4782 bool is_long_idle_notification = |
4785 static_cast<size_t>(idle_time_in_ms) > | 4783 static_cast<size_t>(idle_time_in_ms) > |
4786 GCIdleTimeHandler::kMaxFrameRenderingIdleTime; | 4784 GCIdleTimeHandler::kMaxFrameRenderingIdleTime; |
4787 bool has_low_gc_activity = (start_ms - last_gc_time_) > kLastGCTimeTreshold; | |
4788 | 4785 |
4789 if (is_long_idle_notification) { | 4786 if (is_long_idle_notification) { |
4790 tracer()->SampleNewSpaceAllocation(start_ms, NewSpaceAllocationCounter()); | 4787 tracer()->SampleNewSpaceAllocation(start_ms, NewSpaceAllocationCounter()); |
4791 } | 4788 } |
4792 | 4789 |
4793 GCIdleTimeHandler::HeapState heap_state = | 4790 GCIdleTimeHandler::HeapState heap_state = ComputeHeapState(); |
4794 ComputeHeapState(is_long_idle_notification && has_low_gc_activity); | |
4795 | 4791 |
4796 GCIdleTimeAction action = | 4792 GCIdleTimeAction action = |
4797 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); | 4793 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); |
4798 | 4794 |
4799 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms, | 4795 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms, |
4800 is_long_idle_notification); | 4796 is_long_idle_notification); |
4801 | 4797 |
4802 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms, | 4798 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms, |
4803 is_long_idle_notification); | 4799 is_long_idle_notification); |
4804 return result; | 4800 return result; |
(...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6590 *object_type = "CODE_TYPE"; \ | 6586 *object_type = "CODE_TYPE"; \ |
6591 *object_sub_type = "CODE_AGE/" #name; \ | 6587 *object_sub_type = "CODE_AGE/" #name; \ |
6592 return true; | 6588 return true; |
6593 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6589 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6594 #undef COMPARE_AND_RETURN_NAME | 6590 #undef COMPARE_AND_RETURN_NAME |
6595 } | 6591 } |
6596 return false; | 6592 return false; |
6597 } | 6593 } |
6598 } | 6594 } |
6599 } // namespace v8::internal | 6595 } // namespace v8::internal |
OLD | NEW |