Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Side by Side Diff: src/heap/heap.cc

Issue 1108133003: Shrink new space and uncommit from space in idle notification during long idle times. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/heap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4486 matching lines...) Expand 10 before | Expand all | Expand 10 after
4497 if (!IsHeapIterable()) { 4497 if (!IsHeapIterable()) {
4498 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable"); 4498 CollectAllGarbage(kMakeHeapIterableMask, "Heap::MakeHeapIterable");
4499 } 4499 }
4500 if (mark_compact_collector()->sweeping_in_progress()) { 4500 if (mark_compact_collector()->sweeping_in_progress()) {
4501 mark_compact_collector()->EnsureSweepingCompleted(); 4501 mark_compact_collector()->EnsureSweepingCompleted();
4502 } 4502 }
4503 DCHECK(IsHeapIterable()); 4503 DCHECK(IsHeapIterable());
4504 } 4504 }
4505 4505
4506 4506
4507 void Heap::IdleMarkCompact(const char* message) { 4507 void Heap::ReduceNewSpaceSize(bool long_idle_time) {
rmcilroy 2015/04/28 11:19:09 nit - would be clearer as is_long_idle_notificatio
Hannes Payer (out of office) 2015/04/28 11:27:47 Done.
4508 bool uncommit = false; 4508 if (long_idle_time) {
4509 if (gc_count_at_last_idle_gc_ == gc_count_) {
4510 // No GC since the last full GC, the mutator is probably not active.
4511 isolate_->compilation_cache()->Clear();
4512 uncommit = true;
4513 }
4514 CollectAllGarbage(kReduceMemoryFootprintMask, message);
4515 gc_idle_time_handler_.NotifyIdleMarkCompact();
4516 gc_count_at_last_idle_gc_ = gc_count_;
4517 if (uncommit) {
4518 new_space_.Shrink(); 4509 new_space_.Shrink();
4519 UncommitFromSpace(); 4510 UncommitFromSpace();
4520 } 4511 }
4521 } 4512 }
4522 4513
4523 4514
4524 bool Heap::TryFinalizeIdleIncrementalMarking( 4515 bool Heap::TryFinalizeIdleIncrementalMarking(
4525 double idle_time_in_ms, size_t size_of_objects, 4516 bool long_idle_time, double idle_time_in_ms, size_t size_of_objects,
rmcilroy 2015/04/28 11:19:08 ditto
Hannes Payer (out of office) 2015/04/28 11:27:46 Done.
4526 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { 4517 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
4527 if (FLAG_overapproximate_weak_closure && 4518 if (FLAG_overapproximate_weak_closure &&
4528 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || 4519 (incremental_marking()->IsReadyToOverApproximateWeakClosure() ||
4529 (!incremental_marking()->weak_closure_was_overapproximated() && 4520 (!incremental_marking()->weak_closure_was_overapproximated() &&
4530 mark_compact_collector_.marking_deque()->IsEmpty() && 4521 mark_compact_collector_.marking_deque()->IsEmpty() &&
4531 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( 4522 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure(
4532 static_cast<size_t>(idle_time_in_ms))))) { 4523 static_cast<size_t>(idle_time_in_ms))))) {
4533 OverApproximateWeakClosure( 4524 OverApproximateWeakClosure(
4534 "Idle notification: overapproximate weak closure"); 4525 "Idle notification: overapproximate weak closure");
4535 return true; 4526 return true;
4536 } else if (incremental_marking()->IsComplete() || 4527 } else if (incremental_marking()->IsComplete() ||
4537 (mark_compact_collector_.marking_deque()->IsEmpty() && 4528 (mark_compact_collector_.marking_deque()->IsEmpty() &&
4538 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( 4529 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
4539 static_cast<size_t>(idle_time_in_ms), size_of_objects, 4530 static_cast<size_t>(idle_time_in_ms), size_of_objects,
4540 final_incremental_mark_compact_speed_in_bytes_per_ms))) { 4531 final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4541 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); 4532 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
4533 ReduceNewSpaceSize(long_idle_time);
4542 return true; 4534 return true;
4543 } 4535 }
4544 return false; 4536 return false;
4545 } 4537 }
4546 4538
4547 4539
4548 static double MonotonicallyIncreasingTimeInMs() { 4540 static double MonotonicallyIncreasingTimeInMs() {
4549 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * 4541 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4550 static_cast<double>(base::Time::kMillisecondsPerSecond); 4542 static_cast<double>(base::Time::kMillisecondsPerSecond);
4551 } 4543 }
4552 4544
4553 4545
4554 bool Heap::IdleNotification(int idle_time_in_ms) { 4546 bool Heap::IdleNotification(int idle_time_in_ms) {
4555 return IdleNotification( 4547 return IdleNotification(
4556 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + 4548 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4557 (static_cast<double>(idle_time_in_ms) / 4549 (static_cast<double>(idle_time_in_ms) /
4558 static_cast<double>(base::Time::kMillisecondsPerSecond))); 4550 static_cast<double>(base::Time::kMillisecondsPerSecond)));
4559 } 4551 }
4560 4552
4561 4553
4562 bool Heap::IdleNotification(double deadline_in_seconds) { 4554 bool Heap::IdleNotification(double deadline_in_seconds) {
4563 CHECK(HasBeenSetUp()); // http://crbug.com/425035 4555 CHECK(HasBeenSetUp()); // http://crbug.com/425035
4564 double deadline_in_ms = 4556 double deadline_in_ms =
4565 deadline_in_seconds * 4557 deadline_in_seconds *
4566 static_cast<double>(base::Time::kMillisecondsPerSecond); 4558 static_cast<double>(base::Time::kMillisecondsPerSecond);
4567 HistogramTimerScope idle_notification_scope( 4559 HistogramTimerScope idle_notification_scope(
4568 isolate_->counters()->gc_idle_notification()); 4560 isolate_->counters()->gc_idle_notification());
4569 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); 4561 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4562 bool long_idle_time = static_cast<size_t>(idle_time_in_ms) >
rmcilroy 2015/04/28 11:19:08 nit - would be clearer as is_long_idle_notificatio
Hannes Payer (out of office) 2015/04/28 11:27:46 Done.
4563 GCIdleTimeHandler::kMaxFrameRenderingIdleTime;
4570 4564
4571 GCIdleTimeHandler::HeapState heap_state; 4565 GCIdleTimeHandler::HeapState heap_state;
4572 heap_state.contexts_disposed = contexts_disposed_; 4566 heap_state.contexts_disposed = contexts_disposed_;
4573 heap_state.contexts_disposal_rate = 4567 heap_state.contexts_disposal_rate =
4574 tracer()->ContextDisposalRateInMilliseconds(); 4568 tracer()->ContextDisposalRateInMilliseconds();
4575 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); 4569 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4576 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); 4570 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4577 // TODO(ulan): Start incremental marking only for large heaps. 4571 // TODO(ulan): Start incremental marking only for large heaps.
4578 intptr_t limit = old_generation_allocation_limit_; 4572 intptr_t limit = old_generation_allocation_limit_;
4579 if (static_cast<size_t>(idle_time_in_ms) > 4573 if (long_idle_time) {
4580 GCIdleTimeHandler::kMaxFrameRenderingIdleTime) {
4581 limit = idle_old_generation_allocation_limit_; 4574 limit = idle_old_generation_allocation_limit_;
4582 } 4575 }
4583 4576
4584 heap_state.can_start_incremental_marking = 4577 heap_state.can_start_incremental_marking =
4585 incremental_marking()->CanBeActivated() && 4578 incremental_marking()->CanBeActivated() &&
4586 HeapIsFullEnoughToStartIncrementalMarking(limit) && 4579 HeapIsFullEnoughToStartIncrementalMarking(limit) &&
4587 !mark_compact_collector()->sweeping_in_progress(); 4580 !mark_compact_collector()->sweeping_in_progress();
4588 heap_state.sweeping_in_progress = 4581 heap_state.sweeping_in_progress =
4589 mark_compact_collector()->sweeping_in_progress(); 4582 mark_compact_collector()->sweeping_in_progress();
4590 heap_state.sweeping_completed = 4583 heap_state.sweeping_completed =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4625 IncrementalMarking::FORCE_MARKING, 4618 IncrementalMarking::FORCE_MARKING,
4626 IncrementalMarking::DO_NOT_FORCE_COMPLETION); 4619 IncrementalMarking::DO_NOT_FORCE_COMPLETION);
4627 remaining_idle_time_in_ms = 4620 remaining_idle_time_in_ms =
4628 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); 4621 deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4629 } while (remaining_idle_time_in_ms >= 4622 } while (remaining_idle_time_in_ms >=
4630 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && 4623 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
4631 !incremental_marking()->IsComplete() && 4624 !incremental_marking()->IsComplete() &&
4632 !mark_compact_collector_.marking_deque()->IsEmpty()); 4625 !mark_compact_collector_.marking_deque()->IsEmpty());
4633 if (remaining_idle_time_in_ms > 0.0) { 4626 if (remaining_idle_time_in_ms > 0.0) {
4634 action.additional_work = TryFinalizeIdleIncrementalMarking( 4627 action.additional_work = TryFinalizeIdleIncrementalMarking(
4635 remaining_idle_time_in_ms, heap_state.size_of_objects, 4628 long_idle_time, remaining_idle_time_in_ms,
4629 heap_state.size_of_objects,
4636 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); 4630 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms);
4637 } 4631 }
4638 break; 4632 break;
4639 } 4633 }
4640 case DO_FULL_GC: { 4634 case DO_FULL_GC: {
4635 if (long_idle_time && gc_count_at_last_idle_gc_ == gc_count) {
4636 isolate_->compilation_cache()->Clear();
4637 }
4641 if (contexts_disposed_) { 4638 if (contexts_disposed_) {
4642 HistogramTimerScope scope(isolate_->counters()->gc_context()); 4639 HistogramTimerScope scope(isolate_->counters()->gc_context());
4643 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); 4640 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed");
4644 gc_idle_time_handler_.NotifyIdleMarkCompact();
4645 gc_count_at_last_idle_gc_ = gc_count_;
4646 } else { 4641 } else {
4647 IdleMarkCompact("idle notification: finalize idle round"); 4642 CollectAllGarbage(kReduceMemoryFootprintMask,
4643 "idle notification: finalize idle round");
4648 } 4644 }
4645 gc_count_at_last_idle_gc_ = gc_count_;
4646 ReduceNewSpaceSize(long_idle_time);
4647 gc_idle_time_handler_.NotifyIdleMarkCompact();
4649 break; 4648 break;
4650 } 4649 }
4651 case DO_SCAVENGE: 4650 case DO_SCAVENGE:
4652 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); 4651 CollectGarbage(NEW_SPACE, "idle notification: scavenge");
4652 ReduceNewSpaceSize(idle_time_in_ms);
rmcilroy 2015/04/28 11:19:08 You are passing idle_time_in_ms to this ReduceNewS
Hannes Payer (out of office) 2015/04/28 11:27:46 long_idle_time should be there. thanks, done
4653 break; 4653 break;
4654 case DO_FINALIZE_SWEEPING: 4654 case DO_FINALIZE_SWEEPING:
4655 mark_compact_collector()->EnsureSweepingCompleted(); 4655 mark_compact_collector()->EnsureSweepingCompleted();
4656 break; 4656 break;
4657 case DO_NOTHING: 4657 case DO_NOTHING:
4658 break; 4658 break;
4659 } 4659 }
4660 4660
4661 double current_time = MonotonicallyIncreasingTimeInMs(); 4661 double current_time = MonotonicallyIncreasingTimeInMs();
4662 last_idle_notification_time_ = current_time; 4662 last_idle_notification_time_ = current_time;
(...skipping 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after
6381 static_cast<int>(object_sizes_last_time_[index])); 6381 static_cast<int>(object_sizes_last_time_[index]));
6382 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6382 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6383 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6383 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6384 6384
6385 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6385 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6386 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6386 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6387 ClearObjectStats(); 6387 ClearObjectStats();
6388 } 6388 }
6389 } 6389 }
6390 } // namespace v8::internal 6390 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698