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 4567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4578 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4578 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4579 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4579 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4580 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); | 4580 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
4581 gc_idle_time_handler_.NotifyIdleMarkCompact(); | 4581 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4582 return true; | 4582 return true; |
4583 } | 4583 } |
4584 return false; | 4584 return false; |
4585 } | 4585 } |
4586 | 4586 |
4587 | 4587 |
4588 double Heap::MonotonicallyIncreasingTimeInMs() { | 4588 GCIdleTimeHandler::HeapState Heap::ComputeHeapState( |
4589 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * | 4589 bool is_long_idle_notification) { |
4590 static_cast<double>(base::Time::kMillisecondsPerSecond); | |
4591 } | |
4592 | |
4593 | |
4594 bool Heap::IdleNotification(int idle_time_in_ms) { | |
4595 return IdleNotification( | |
4596 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + | |
4597 (static_cast<double>(idle_time_in_ms) / | |
4598 static_cast<double>(base::Time::kMillisecondsPerSecond))); | |
4599 } | |
4600 | |
4601 | |
4602 bool Heap::IdleNotification(double deadline_in_seconds) { | |
4603 CHECK(HasBeenSetUp()); // http://crbug.com/425035 | |
4604 double deadline_in_ms = | |
4605 deadline_in_seconds * | |
4606 static_cast<double>(base::Time::kMillisecondsPerSecond); | |
4607 HistogramTimerScope idle_notification_scope( | |
4608 isolate_->counters()->gc_idle_notification()); | |
4609 double start_ms = MonotonicallyIncreasingTimeInMs(); | |
4610 double idle_time_in_ms = deadline_in_ms - start_ms; | |
4611 bool is_long_idle_notification = | |
4612 static_cast<size_t>(idle_time_in_ms) > | |
4613 GCIdleTimeHandler::kMaxFrameRenderingIdleTime; | |
4614 | |
4615 GCIdleTimeHandler::HeapState heap_state; | 4590 GCIdleTimeHandler::HeapState heap_state; |
4616 heap_state.contexts_disposed = contexts_disposed_; | 4591 heap_state.contexts_disposed = contexts_disposed_; |
4617 heap_state.contexts_disposal_rate = | 4592 heap_state.contexts_disposal_rate = |
4618 tracer()->ContextDisposalRateInMilliseconds(); | 4593 tracer()->ContextDisposalRateInMilliseconds(); |
4619 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); | 4594 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); |
4620 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); | 4595 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); |
4621 // TODO(ulan): Start incremental marking only for large heaps. | 4596 // TODO(ulan): Start incremental marking only for large heaps. |
4622 intptr_t limit = old_generation_allocation_limit_; | 4597 intptr_t limit = old_generation_allocation_limit_; |
4623 if (is_long_idle_notification) { | 4598 if (is_long_idle_notification) { |
4624 limit = idle_old_generation_allocation_limit_; | 4599 limit = idle_old_generation_allocation_limit_; |
(...skipping 14 matching lines...) Expand all Loading... | |
4639 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = | 4614 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = |
4640 static_cast<size_t>( | 4615 static_cast<size_t>( |
4641 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4616 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4642 heap_state.scavenge_speed_in_bytes_per_ms = | 4617 heap_state.scavenge_speed_in_bytes_per_ms = |
4643 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4618 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4644 heap_state.used_new_space_size = new_space_.Size(); | 4619 heap_state.used_new_space_size = new_space_.Size(); |
4645 heap_state.new_space_capacity = new_space_.Capacity(); | 4620 heap_state.new_space_capacity = new_space_.Capacity(); |
4646 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4621 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4647 static_cast<size_t>( | 4622 static_cast<size_t>( |
4648 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); | 4623 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); |
4624 return heap_state; | |
4625 } | |
4649 | 4626 |
4650 GCIdleTimeAction action = | |
4651 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); | |
4652 | 4627 |
4653 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( | 4628 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4654 static_cast<int>(idle_time_in_ms)); | 4629 GCIdleTimeHandler::HeapState heap_state, |
4655 if (is_long_idle_notification) { | 4630 double deadline_in_ms, |
4656 int committed_memory = static_cast<int>(CommittedMemory() / KB); | 4631 bool is_long_idle_notification) { |
4657 int used_memory = static_cast<int>(heap_state.size_of_objects / KB); | |
4658 isolate()->counters()->aggregated_memory_heap_committed()->AddSample( | |
4659 start_ms, committed_memory); | |
4660 isolate()->counters()->aggregated_memory_heap_used()->AddSample( | |
4661 start_ms, used_memory); | |
4662 } | |
4663 | |
4664 bool result = false; | 4632 bool result = false; |
4665 switch (action.type) { | 4633 switch (action.type) { |
4666 case DONE: | 4634 case DONE: |
4667 result = true; | 4635 result = true; |
4668 break; | 4636 break; |
4669 case DO_INCREMENTAL_MARKING: { | 4637 case DO_INCREMENTAL_MARKING: { |
4670 if (incremental_marking()->IsStopped()) { | 4638 if (incremental_marking()->IsStopped()) { |
4671 // TODO(ulan): take reduce_memory into account. | 4639 // TODO(ulan): take reduce_memory into account. |
4672 incremental_marking()->Start(); | 4640 incremental_marking()->Start(); |
4673 } | 4641 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4712 mark_compact_collector()->EnsureSweepingCompleted(); | 4680 mark_compact_collector()->EnsureSweepingCompleted(); |
4713 break; | 4681 break; |
4714 case DO_NOTHING: | 4682 case DO_NOTHING: |
4715 break; | 4683 break; |
4716 } | 4684 } |
4717 | 4685 |
4718 if (action.reduce_memory) { | 4686 if (action.reduce_memory) { |
4719 new_space_.Shrink(); | 4687 new_space_.Shrink(); |
4720 UncommitFromSpace(); | 4688 UncommitFromSpace(); |
4721 } | 4689 } |
4690 return result; | |
4691 } | |
4722 | 4692 |
4693 | |
4694 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, | |
4695 GCIdleTimeHandler::HeapState heap_state, | |
4696 double start_ms, double deadline_in_ms, | |
4697 bool is_long_idle_notification) { | |
4698 double idle_time_in_ms = deadline_in_ms - start_ms; | |
4723 double current_time = MonotonicallyIncreasingTimeInMs(); | 4699 double current_time = MonotonicallyIncreasingTimeInMs(); |
4724 last_idle_notification_time_ = current_time; | 4700 last_idle_notification_time_ = current_time; |
4725 double deadline_difference = deadline_in_ms - current_time; | 4701 double deadline_difference = deadline_in_ms - current_time; |
4726 | 4702 |
4703 contexts_disposed_ = 0; | |
4704 | |
4705 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( | |
4706 idle_time_in_ms); | |
4707 | |
4708 if (is_long_idle_notification) { | |
Hannes Payer (out of office)
2015/05/20 06:39:32
Diff: this got moved down to the Epilogue.
| |
4709 int committed_memory = static_cast<int>(CommittedMemory() / KB); | |
4710 int used_memory = static_cast<int>(heap_state.size_of_objects / KB); | |
4711 isolate()->counters()->aggregated_memory_heap_committed()->AddSample( | |
4712 start_ms, committed_memory); | |
4713 isolate()->counters()->aggregated_memory_heap_used()->AddSample( | |
4714 start_ms, used_memory); | |
4715 } | |
4716 | |
4727 if (deadline_difference >= 0) { | 4717 if (deadline_difference >= 0) { |
4728 if (action.type != DONE && action.type != DO_NOTHING) { | 4718 if (action.type != DONE && action.type != DO_NOTHING) { |
4729 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( | 4719 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( |
4730 static_cast<int>(deadline_difference)); | 4720 static_cast<int>(deadline_difference)); |
4731 } | 4721 } |
4732 } else { | 4722 } else { |
4733 isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( | 4723 isolate()->counters()->gc_idle_time_limit_overshot()->AddSample( |
4734 static_cast<int>(-deadline_difference)); | 4724 static_cast<int>(-deadline_difference)); |
4735 } | 4725 } |
4736 | 4726 |
4737 if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) || | 4727 if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) || |
4738 FLAG_trace_idle_notification_verbose) { | 4728 FLAG_trace_idle_notification_verbose) { |
4739 PrintIsolate(isolate_, "%8.0f ms: ", isolate()->time_millis_since_init()); | 4729 PrintIsolate(isolate_, "%8.0f ms: ", isolate()->time_millis_since_init()); |
4740 PrintF( | 4730 PrintF( |
4741 "Idle notification: requested idle time %.2f ms, used idle time %.2f " | 4731 "Idle notification: requested idle time %.2f ms, used idle time %.2f " |
4742 "ms, deadline usage %.2f ms [", | 4732 "ms, deadline usage %.2f ms [", |
4743 idle_time_in_ms, idle_time_in_ms - deadline_difference, | 4733 idle_time_in_ms, idle_time_in_ms - deadline_difference, |
4744 deadline_difference); | 4734 deadline_difference); |
4745 action.Print(); | 4735 action.Print(); |
4746 PrintF("]"); | 4736 PrintF("]"); |
4747 if (FLAG_trace_idle_notification_verbose) { | 4737 if (FLAG_trace_idle_notification_verbose) { |
4748 PrintF("["); | 4738 PrintF("["); |
4749 heap_state.Print(); | 4739 heap_state.Print(); |
4750 PrintF("]"); | 4740 PrintF("]"); |
4751 } | 4741 } |
4752 PrintF("\n"); | 4742 PrintF("\n"); |
4753 } | 4743 } |
4744 } | |
4754 | 4745 |
4755 contexts_disposed_ = 0; | 4746 |
4747 double Heap::MonotonicallyIncreasingTimeInMs() { | |
4748 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * | |
4749 static_cast<double>(base::Time::kMillisecondsPerSecond); | |
4750 } | |
4751 | |
4752 | |
4753 bool Heap::IdleNotification(int idle_time_in_ms) { | |
4754 return IdleNotification( | |
4755 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + | |
4756 (static_cast<double>(idle_time_in_ms) / | |
4757 static_cast<double>(base::Time::kMillisecondsPerSecond))); | |
4758 } | |
4759 | |
4760 | |
4761 bool Heap::IdleNotification(double deadline_in_seconds) { | |
4762 CHECK(HasBeenSetUp()); | |
4763 double deadline_in_ms = | |
4764 deadline_in_seconds * | |
4765 static_cast<double>(base::Time::kMillisecondsPerSecond); | |
4766 HistogramTimerScope idle_notification_scope( | |
4767 isolate_->counters()->gc_idle_notification()); | |
4768 double start_ms = MonotonicallyIncreasingTimeInMs(); | |
4769 double idle_time_in_ms = deadline_in_ms - start_ms; | |
4770 bool is_long_idle_notification = | |
4771 static_cast<size_t>(idle_time_in_ms) > | |
4772 GCIdleTimeHandler::kMaxFrameRenderingIdleTime; | |
4773 | |
4774 GCIdleTimeHandler::HeapState heap_state = | |
4775 ComputeHeapState(is_long_idle_notification); | |
4776 | |
4777 GCIdleTimeAction action = | |
4778 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); | |
4779 | |
4780 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms, | |
4781 is_long_idle_notification); | |
4782 | |
4783 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms, | |
4784 is_long_idle_notification); | |
4756 return result; | 4785 return result; |
4757 } | 4786 } |
4758 | 4787 |
4759 | 4788 |
4760 bool Heap::RecentIdleNotificationHappened() { | 4789 bool Heap::RecentIdleNotificationHappened() { |
4761 return (last_idle_notification_time_ + | 4790 return (last_idle_notification_time_ + |
4762 GCIdleTimeHandler::kMaxScheduledIdleTime) > | 4791 GCIdleTimeHandler::kMaxScheduledIdleTime) > |
4763 MonotonicallyIncreasingTimeInMs(); | 4792 MonotonicallyIncreasingTimeInMs(); |
4764 } | 4793 } |
4765 | 4794 |
(...skipping 1775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6541 *object_type = "CODE_TYPE"; \ | 6570 *object_type = "CODE_TYPE"; \ |
6542 *object_sub_type = "CODE_AGE/" #name; \ | 6571 *object_sub_type = "CODE_AGE/" #name; \ |
6543 return true; | 6572 return true; |
6544 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6573 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6545 #undef COMPARE_AND_RETURN_NAME | 6574 #undef COMPARE_AND_RETURN_NAME |
6546 } | 6575 } |
6547 return false; | 6576 return false; |
6548 } | 6577 } |
6549 } | 6578 } |
6550 } // namespace v8::internal | 6579 } // namespace v8::internal |
OLD | NEW |