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 4560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4571 DCHECK(AllowHeapAllocation::IsAllowed()); | 4571 DCHECK(AllowHeapAllocation::IsAllowed()); |
4572 if (!IsHeapIterable()) { | 4572 if (!IsHeapIterable()) { |
4573 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); | 4573 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); |
4574 } | 4574 } |
4575 if (mark_compact_collector()->sweeping_in_progress()) { | 4575 if (mark_compact_collector()->sweeping_in_progress()) { |
4576 mark_compact_collector()->EnsureSweepingCompleted(); | 4576 mark_compact_collector()->EnsureSweepingCompleted(); |
4577 } | 4577 } |
4578 DCHECK(IsHeapIterable()); | 4578 DCHECK(IsHeapIterable()); |
4579 } | 4579 } |
4580 | 4580 |
4581 | |
4582 void Heap::ReduceNewSpaceSize(bool is_long_idle_notification) { | |
4583 if (is_long_idle_notification) { | |
4584 new_space_.Shrink(); | |
4585 UncommitFromSpace(); | |
4586 } | |
4587 } | |
4588 | |
4589 | |
4590 bool Heap::TryFinalizeIdleIncrementalMarking( | 4581 bool Heap::TryFinalizeIdleIncrementalMarking( |
4591 bool is_long_idle_notification, double idle_time_in_ms, | 4582 double idle_time_in_ms, size_t size_of_objects, |
4592 size_t size_of_objects, | |
4593 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 4583 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
4594 if (FLAG_overapproximate_weak_closure && | 4584 if (FLAG_overapproximate_weak_closure && |
4595 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4585 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
4596 (!incremental_marking()->weak_closure_was_overapproximated() && | 4586 (!incremental_marking()->weak_closure_was_overapproximated() && |
4597 mark_compact_collector_.marking_deque()->IsEmpty() && | 4587 mark_compact_collector_.marking_deque()->IsEmpty() && |
4598 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( | 4588 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( |
4599 static_cast<size_t>(idle_time_in_ms))))) { | 4589 static_cast<size_t>(idle_time_in_ms))))) { |
4600 OverApproximateWeakClosure( | 4590 OverApproximateWeakClosure( |
4601 "Idle notification: overapproximate weak closure"); | 4591 "Idle notification: overapproximate weak closure"); |
4602 return true; | 4592 return true; |
4603 } else if (incremental_marking()->IsComplete() || | 4593 } else if (incremental_marking()->IsComplete() || |
4604 (mark_compact_collector_.marking_deque()->IsEmpty() && | 4594 (mark_compact_collector_.marking_deque()->IsEmpty() && |
4605 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( | 4595 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( |
4606 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4596 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4607 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4597 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4608 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); | 4598 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
4609 gc_idle_time_handler_.NotifyIdleMarkCompact(); | 4599 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4610 ReduceNewSpaceSize(is_long_idle_notification); | |
4611 return true; | 4600 return true; |
4612 } | 4601 } |
4613 return false; | 4602 return false; |
4614 } | 4603 } |
4615 | 4604 |
4616 | 4605 |
4617 double Heap::MonotonicallyIncreasingTimeInMs() { | 4606 double Heap::MonotonicallyIncreasingTimeInMs() { |
4618 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * | 4607 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * |
4619 static_cast<double>(base::Time::kMillisecondsPerSecond); | 4608 static_cast<double>(base::Time::kMillisecondsPerSecond); |
4620 } | 4609 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4707 IncrementalMarking::FORCE_MARKING, | 4696 IncrementalMarking::FORCE_MARKING, |
4708 IncrementalMarking::DO_NOT_FORCE_COMPLETION); | 4697 IncrementalMarking::DO_NOT_FORCE_COMPLETION); |
4709 remaining_idle_time_in_ms = | 4698 remaining_idle_time_in_ms = |
4710 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4699 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
4711 } while (remaining_idle_time_in_ms >= | 4700 } while (remaining_idle_time_in_ms >= |
4712 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4701 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
4713 !incremental_marking()->IsComplete() && | 4702 !incremental_marking()->IsComplete() && |
4714 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4703 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4715 if (remaining_idle_time_in_ms > 0.0) { | 4704 if (remaining_idle_time_in_ms > 0.0) { |
4716 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4705 action.additional_work = TryFinalizeIdleIncrementalMarking( |
4717 is_long_idle_notification, remaining_idle_time_in_ms, | 4706 remaining_idle_time_in_ms, heap_state.size_of_objects, |
4718 heap_state.size_of_objects, | |
4719 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4707 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
4720 } | 4708 } |
4721 break; | 4709 break; |
4722 } | 4710 } |
4723 case DO_FULL_GC: { | 4711 case DO_FULL_GC: { |
4724 if (is_long_idle_notification && gc_count_at_last_idle_gc_ == gc_count_) { | 4712 if (is_long_idle_notification && gc_count_at_last_idle_gc_ == gc_count_) { |
4725 isolate_->compilation_cache()->Clear(); | 4713 isolate_->compilation_cache()->Clear(); |
4726 } | 4714 } |
4727 if (contexts_disposed_) { | 4715 if (contexts_disposed_) { |
4728 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 4716 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
4729 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); | 4717 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); |
4730 } else { | 4718 } else { |
4731 CollectAllGarbage(kReduceMemoryFootprintMask, | 4719 CollectAllGarbage(kReduceMemoryFootprintMask, |
4732 "idle notification: finalize idle round"); | 4720 "idle notification: finalize idle round"); |
4733 } | 4721 } |
4734 gc_count_at_last_idle_gc_ = gc_count_; | 4722 gc_count_at_last_idle_gc_ = gc_count_; |
4735 ReduceNewSpaceSize(is_long_idle_notification); | |
4736 gc_idle_time_handler_.NotifyIdleMarkCompact(); | 4723 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4737 break; | 4724 break; |
4738 } | 4725 } |
4739 case DO_SCAVENGE: | 4726 case DO_SCAVENGE: |
4740 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); | 4727 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); |
4741 ReduceNewSpaceSize(is_long_idle_notification); | |
4742 break; | 4728 break; |
4743 case DO_FINALIZE_SWEEPING: | 4729 case DO_FINALIZE_SWEEPING: |
4744 mark_compact_collector()->EnsureSweepingCompleted(); | 4730 mark_compact_collector()->EnsureSweepingCompleted(); |
4745 break; | 4731 break; |
4746 case DO_NOTHING: | 4732 case DO_NOTHING: |
4747 break; | 4733 break; |
4748 } | 4734 } |
4749 | 4735 |
| 4736 if (action.reduce_memory) { |
| 4737 new_space_.Shrink(); |
| 4738 UncommitFromSpace(); |
| 4739 } |
| 4740 |
4750 double current_time = MonotonicallyIncreasingTimeInMs(); | 4741 double current_time = MonotonicallyIncreasingTimeInMs(); |
4751 last_idle_notification_time_ = current_time; | 4742 last_idle_notification_time_ = current_time; |
4752 double deadline_difference = deadline_in_ms - current_time; | 4743 double deadline_difference = deadline_in_ms - current_time; |
4753 | 4744 |
4754 if (deadline_difference >= 0) { | 4745 if (deadline_difference >= 0) { |
4755 if (action.type != DONE && action.type != DO_NOTHING) { | 4746 if (action.type != DONE && action.type != DO_NOTHING) { |
4756 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( | 4747 isolate()->counters()->gc_idle_time_limit_undershot()->AddSample( |
4757 static_cast<int>(deadline_difference)); | 4748 static_cast<int>(deadline_difference)); |
4758 } | 4749 } |
4759 } else { | 4750 } else { |
(...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6530 } | 6521 } |
6531 delete list; | 6522 delete list; |
6532 } else { | 6523 } else { |
6533 prev = list; | 6524 prev = list; |
6534 } | 6525 } |
6535 list = next; | 6526 list = next; |
6536 } | 6527 } |
6537 } | 6528 } |
6538 } | 6529 } |
6539 } // namespace v8::internal | 6530 } // namespace v8::internal |
OLD | NEW |