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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 max_alive_after_gc_(0), | 131 max_alive_after_gc_(0), |
132 min_in_mutator_(kMaxInt), | 132 min_in_mutator_(kMaxInt), |
133 marking_time_(0.0), | 133 marking_time_(0.0), |
134 sweeping_time_(0.0), | 134 sweeping_time_(0.0), |
135 last_idle_notification_time_(0.0), | 135 last_idle_notification_time_(0.0), |
136 last_gc_time_(0.0), | 136 last_gc_time_(0.0), |
137 mark_compact_collector_(this), | 137 mark_compact_collector_(this), |
138 store_buffer_(this), | 138 store_buffer_(this), |
139 marking_(this), | 139 marking_(this), |
140 incremental_marking_(this), | 140 incremental_marking_(this), |
141 gc_count_at_last_idle_gc_(0), | |
142 full_codegen_bytes_generated_(0), | 141 full_codegen_bytes_generated_(0), |
143 crankshaft_codegen_bytes_generated_(0), | 142 crankshaft_codegen_bytes_generated_(0), |
144 new_space_allocation_counter_(0), | 143 new_space_allocation_counter_(0), |
145 old_generation_allocation_counter_(0), | 144 old_generation_allocation_counter_(0), |
146 old_generation_size_at_last_gc_(0), | 145 old_generation_size_at_last_gc_(0), |
147 gcs_since_last_deopt_(0), | 146 gcs_since_last_deopt_(0), |
148 allocation_sites_scratchpad_length_(0), | 147 allocation_sites_scratchpad_length_(0), |
149 ring_buffer_full_(false), | 148 ring_buffer_full_(false), |
150 ring_buffer_end_(0), | 149 ring_buffer_end_(0), |
151 promotion_queue_(this), | 150 promotion_queue_(this), |
(...skipping 4432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4584 heap_state.can_start_incremental_marking = | 4583 heap_state.can_start_incremental_marking = |
4585 incremental_marking()->CanBeActivated() && | 4584 incremental_marking()->CanBeActivated() && |
4586 HeapIsFullEnoughToStartIncrementalMarking(limit) && | 4585 HeapIsFullEnoughToStartIncrementalMarking(limit) && |
4587 !mark_compact_collector()->sweeping_in_progress(); | 4586 !mark_compact_collector()->sweeping_in_progress(); |
4588 return heap_state; | 4587 return heap_state; |
4589 } | 4588 } |
4590 | 4589 |
4591 | 4590 |
4592 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4591 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4593 GCIdleTimeHandler::HeapState heap_state, | 4592 GCIdleTimeHandler::HeapState heap_state, |
4594 double deadline_in_ms, | 4593 double deadline_in_ms) { |
4595 bool is_long_idle_notification) { | |
4596 bool result = false; | 4594 bool result = false; |
4597 switch (action.type) { | 4595 switch (action.type) { |
4598 case DONE: | 4596 case DONE: |
4599 result = true; | 4597 result = true; |
4600 break; | 4598 break; |
4601 case DO_INCREMENTAL_MARKING: { | 4599 case DO_INCREMENTAL_MARKING: { |
4602 if (incremental_marking()->IsStopped()) { | 4600 if (incremental_marking()->IsStopped()) { |
4603 incremental_marking()->Start( | 4601 incremental_marking()->Start( |
4604 action.reduce_memory ? kReduceMemoryFootprintMask : kNoGCFlags); | 4602 action.reduce_memory ? kReduceMemoryFootprintMask : kNoGCFlags); |
4605 } | 4603 } |
(...skipping 10 matching lines...) Expand all Loading... |
4616 !incremental_marking()->IsComplete() && | 4614 !incremental_marking()->IsComplete() && |
4617 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4615 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4618 if (remaining_idle_time_in_ms > 0.0) { | 4616 if (remaining_idle_time_in_ms > 0.0) { |
4619 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4617 action.additional_work = TryFinalizeIdleIncrementalMarking( |
4620 remaining_idle_time_in_ms, heap_state.size_of_objects, | 4618 remaining_idle_time_in_ms, heap_state.size_of_objects, |
4621 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4619 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
4622 } | 4620 } |
4623 break; | 4621 break; |
4624 } | 4622 } |
4625 case DO_FULL_GC: { | 4623 case DO_FULL_GC: { |
4626 if (is_long_idle_notification && gc_count_at_last_idle_gc_ == gc_count_) { | 4624 if (action.reduce_memory) { |
4627 isolate_->compilation_cache()->Clear(); | 4625 isolate_->compilation_cache()->Clear(); |
4628 } | 4626 } |
4629 if (contexts_disposed_) { | 4627 if (contexts_disposed_) { |
4630 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 4628 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
4631 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); | 4629 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); |
4632 } else { | 4630 } else { |
4633 CollectAllGarbage(kReduceMemoryFootprintMask, | 4631 CollectAllGarbage(kReduceMemoryFootprintMask, |
4634 "idle notification: finalize idle round"); | 4632 "idle notification: finalize idle round"); |
4635 } | 4633 } |
4636 gc_count_at_last_idle_gc_ = gc_count_; | |
4637 gc_idle_time_handler_.NotifyIdleMarkCompact(); | 4634 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4638 break; | 4635 break; |
4639 } | 4636 } |
4640 case DO_SCAVENGE: | 4637 case DO_SCAVENGE: |
4641 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); | 4638 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); |
4642 break; | 4639 break; |
4643 case DO_FINALIZE_SWEEPING: | 4640 case DO_FINALIZE_SWEEPING: |
4644 mark_compact_collector()->EnsureSweepingCompleted(); | 4641 mark_compact_collector()->EnsureSweepingCompleted(); |
4645 break; | 4642 break; |
4646 case DO_NOTHING: | 4643 case DO_NOTHING: |
4647 break; | 4644 break; |
4648 } | 4645 } |
4649 | 4646 |
4650 return result; | 4647 return result; |
4651 } | 4648 } |
4652 | 4649 |
4653 | 4650 |
4654 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, | 4651 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, |
4655 GCIdleTimeHandler::HeapState heap_state, | 4652 GCIdleTimeHandler::HeapState heap_state, |
4656 double start_ms, double deadline_in_ms, | 4653 double start_ms, double deadline_in_ms) { |
4657 bool is_long_idle_notification) { | |
4658 double idle_time_in_ms = deadline_in_ms - start_ms; | 4654 double idle_time_in_ms = deadline_in_ms - start_ms; |
4659 double current_time = MonotonicallyIncreasingTimeInMs(); | 4655 double current_time = MonotonicallyIncreasingTimeInMs(); |
4660 last_idle_notification_time_ = current_time; | 4656 last_idle_notification_time_ = current_time; |
4661 double deadline_difference = deadline_in_ms - current_time; | 4657 double deadline_difference = deadline_in_ms - current_time; |
4662 | 4658 |
4663 contexts_disposed_ = 0; | 4659 contexts_disposed_ = 0; |
4664 | 4660 |
4665 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( | 4661 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( |
4666 static_cast<int>(idle_time_in_ms)); | 4662 static_cast<int>(idle_time_in_ms)); |
4667 | 4663 |
4668 if (is_long_idle_notification) { | |
4669 int committed_memory = static_cast<int>(CommittedMemory() / KB); | |
4670 int used_memory = static_cast<int>(heap_state.size_of_objects / KB); | |
4671 isolate()->counters()->aggregated_memory_heap_committed()->AddSample( | |
4672 start_ms, committed_memory); | |
4673 isolate()->counters()->aggregated_memory_heap_used()->AddSample( | |
4674 start_ms, used_memory); | |
4675 } | |
4676 | |
4677 if (deadline_difference >= 0) { | 4664 if (deadline_difference >= 0) { |
4678 if (action.type != DONE && action.type != DO_NOTHING) { | 4665 if (action.type != DONE && action.type != DO_NOTHING) { |
4679 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( | 4666 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( |
4680 static_cast<int>(deadline_difference)); | 4667 static_cast<int>(deadline_difference)); |
4681 } | 4668 } |
4682 } else { | 4669 } else { |
4683 isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( | 4670 isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( |
4684 static_cast<int>(-deadline_difference)); | 4671 static_cast<int>(-deadline_difference)); |
4685 } | 4672 } |
4686 | 4673 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4720 | 4707 |
4721 bool Heap::IdleNotification(double deadline_in_seconds) { | 4708 bool Heap::IdleNotification(double deadline_in_seconds) { |
4722 CHECK(HasBeenSetUp()); | 4709 CHECK(HasBeenSetUp()); |
4723 double deadline_in_ms = | 4710 double deadline_in_ms = |
4724 deadline_in_seconds * | 4711 deadline_in_seconds * |
4725 static_cast<double>(base::Time::kMillisecondsPerSecond); | 4712 static_cast<double>(base::Time::kMillisecondsPerSecond); |
4726 HistogramTimerScope idle_notification_scope( | 4713 HistogramTimerScope idle_notification_scope( |
4727 isolate_->counters()->gc_idle_notification()); | 4714 isolate_->counters()->gc_idle_notification()); |
4728 double start_ms = MonotonicallyIncreasingTimeInMs(); | 4715 double start_ms = MonotonicallyIncreasingTimeInMs(); |
4729 double idle_time_in_ms = deadline_in_ms - start_ms; | 4716 double idle_time_in_ms = deadline_in_ms - start_ms; |
4730 bool is_long_idle_notification = | |
4731 static_cast<size_t>(idle_time_in_ms) > | |
4732 GCIdleTimeHandler::kMaxFrameRenderingIdleTime; | |
4733 | 4717 |
4734 if (is_long_idle_notification) { | 4718 tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(), |
4735 tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(), | 4719 OldGenerationAllocationCounter()); |
4736 OldGenerationAllocationCounter()); | |
4737 } | |
4738 | 4720 |
4739 GCIdleTimeHandler::HeapState heap_state = ComputeHeapState(); | 4721 GCIdleTimeHandler::HeapState heap_state = ComputeHeapState(); |
4740 | 4722 |
4741 GCIdleTimeAction action = | 4723 GCIdleTimeAction action = |
4742 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); | 4724 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); |
4743 | 4725 |
4744 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms, | 4726 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms); |
4745 is_long_idle_notification); | |
4746 | 4727 |
4747 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms, | 4728 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms); |
4748 is_long_idle_notification); | |
4749 return result; | 4729 return result; |
4750 } | 4730 } |
4751 | 4731 |
4752 | 4732 |
4753 bool Heap::RecentIdleNotificationHappened() { | 4733 bool Heap::RecentIdleNotificationHappened() { |
4754 return (last_idle_notification_time_ + | 4734 return (last_idle_notification_time_ + |
4755 GCIdleTimeHandler::kMaxScheduledIdleTime) > | 4735 GCIdleTimeHandler::kMaxScheduledIdleTime) > |
4756 MonotonicallyIncreasingTimeInMs(); | 4736 MonotonicallyIncreasingTimeInMs(); |
4757 } | 4737 } |
4758 | 4738 |
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6573 *object_type = "CODE_TYPE"; \ | 6553 *object_type = "CODE_TYPE"; \ |
6574 *object_sub_type = "CODE_AGE/" #name; \ | 6554 *object_sub_type = "CODE_AGE/" #name; \ |
6575 return true; | 6555 return true; |
6576 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6556 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6577 #undef COMPARE_AND_RETURN_NAME | 6557 #undef COMPARE_AND_RETURN_NAME |
6578 } | 6558 } |
6579 return false; | 6559 return false; |
6580 } | 6560 } |
6581 } // namespace internal | 6561 } // namespace internal |
6582 } // namespace v8 | 6562 } // namespace v8 |
OLD | NEW |