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

Unified Diff: src/heap/heap.cc

Issue 1218863002: Replace reduce-memory mode in idle notification with delayed clean-up GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix test Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/memory-reducer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 27c24f34b15fd5a9bedd121cad06463456da8f6b..d962167e17090098bf84765780dab11b882653dd 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -20,6 +20,7 @@
#include "src/heap/gc-idle-time-handler.h"
#include "src/heap/incremental-marking.h"
#include "src/heap/mark-compact.h"
+#include "src/heap/memory-reducer.h"
#include "src/heap/objects-visiting-inl.h"
#include "src/heap/objects-visiting.h"
#include "src/heap/store-buffer.h"
@@ -107,8 +108,6 @@ Heap::Heap()
allocation_timeout_(0),
#endif // DEBUG
old_generation_allocation_limit_(initial_old_generation_size_),
- idle_old_generation_allocation_limit_(
- kMinimumOldGenerationAllocationLimit),
old_gen_exhausted_(false),
inline_allocation_disabled_(false),
store_buffer_rebuilder_(store_buffer()),
@@ -143,6 +142,7 @@ Heap::Heap()
store_buffer_(this),
marking_(this),
incremental_marking_(this),
+ memory_reducer_(this),
full_codegen_bytes_generated_(0),
crankshaft_codegen_bytes_generated_(0),
new_space_allocation_counter_(0),
@@ -926,6 +926,11 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
}
bool next_gc_likely_to_collect_more = false;
+ intptr_t committed_memory_before;
+
+ if (collector == MARK_COMPACTOR) {
+ committed_memory_before = CommittedOldGenerationMemory();
+ }
{
tracer()->Start(collector, gc_reason, collector_reason);
@@ -947,9 +952,20 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
}
if (collector == MARK_COMPACTOR) {
- gc_idle_time_handler_.NotifyMarkCompact(next_gc_likely_to_collect_more);
- } else {
- gc_idle_time_handler_.NotifyScavenge();
+ intptr_t committed_memory_after = CommittedOldGenerationMemory();
+ intptr_t used_memory_after = PromotedSpaceSizeOfObjects();
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kMarkCompact;
+ event.time_ms = MonotonicallyIncreasingTimeInMs();
+ // Trigger one more GC if
+ // - this GC decreased committed memory,
+ // - there is high fragmentation,
+ // - there are live detached contexts.
+ event.next_gc_likely_to_collect_more =
+ (committed_memory_before - committed_memory_after) > MB ||
+ HasHighFragmentation(used_memory_after, committed_memory_after) ||
+ (detached_contexts()->length() > 0);
+ memory_reducer_.NotifyMarkCompact(event);
}
tracer()->Stop(collector);
@@ -984,10 +1000,20 @@ int Heap::NotifyContextDisposed(bool dependant_context) {
AgeInlineCaches();
set_retained_maps(ArrayList::cast(empty_fixed_array()));
tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis());
+ MemoryReducer::Event event;
+ event.type = MemoryReducer::kContextDisposed;
+ event.time_ms = MonotonicallyIncreasingTimeInMs();
+ memory_reducer_.NotifyContextDisposed(event);
return ++contexts_disposed_;
}
+void Heap::StartIdleIncrementalMarking() {
+ gc_idle_time_handler_.ResetNoProgressCounter();
+ incremental_marking()->Start(kReduceMemoryFootprintMask);
+}
+
+
void Heap::MoveElements(FixedArray* array, int dst_index, int src_index,
int len) {
if (len == 0) return;
@@ -4746,6 +4772,21 @@ bool Heap::HasLowAllocationRate() {
}
+bool Heap::HasHighFragmentation() {
+ intptr_t used = PromotedSpaceSizeOfObjects();
+ intptr_t committed = CommittedOldGenerationMemory();
+ return HasHighFragmentation(used, committed);
+}
+
+
+bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) {
+ const intptr_t kSlack = 16 * MB;
+ // Fragmentation is high if committed > 2 * used + kSlack.
+ // Rewrite the exression to avoid overflow.
+ return committed - used > used + kSlack;
+}
+
+
void Heap::ReduceNewSpaceSize() {
if (!FLAG_predictable && HasLowAllocationRate()) {
new_space_.Shrink();
@@ -4772,7 +4813,6 @@ bool Heap::TryFinalizeIdleIncrementalMarking(
static_cast<size_t>(idle_time_in_ms), size_of_objects,
final_incremental_mark_compact_speed_in_bytes_per_ms))) {
CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
- gc_idle_time_handler_.NotifyIdleMarkCompact();
return true;
}
return false;
@@ -4803,15 +4843,6 @@ GCIdleTimeHandler::HeapState Heap::ComputeHeapState() {
heap_state.new_space_capacity = new_space_.Capacity();
heap_state.new_space_allocation_throughput_in_bytes_per_ms =
tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond();
- heap_state.has_low_allocation_rate = HasLowAllocationRate();
- intptr_t limit = old_generation_allocation_limit_;
- if (heap_state.has_low_allocation_rate) {
- limit = idle_old_generation_allocation_limit_;
- }
- heap_state.can_start_incremental_marking =
- incremental_marking()->CanBeActivated() &&
- HeapIsFullEnoughToStartIncrementalMarking(limit) &&
- !mark_compact_collector()->sweeping_in_progress();
return heap_state;
}
@@ -4825,10 +4856,7 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
result = true;
break;
case DO_INCREMENTAL_MARKING: {
- if (incremental_marking()->IsStopped()) {
- incremental_marking()->Start(
- action.reduce_memory ? kReduceMemoryFootprintMask : kNoGCFlags);
- }
+ DCHECK(!incremental_marking()->IsStopped());
double remaining_idle_time_in_ms = 0.0;
do {
incremental_marking()->Step(
@@ -4849,17 +4877,9 @@ bool Heap::PerformIdleTimeAction(GCIdleTimeAction action,
break;
}
case DO_FULL_GC: {
- if (action.reduce_memory) {
- isolate_->compilation_cache()->Clear();
- }
- if (contexts_disposed_) {
- HistogramTimerScope scope(isolate_->counters()->gc_context());
- CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed");
- } else {
- CollectAllGarbage(kReduceMemoryFootprintMask,
- "idle notification: finalize idle round");
- }
- gc_idle_time_handler_.NotifyIdleMarkCompact();
+ DCHECK(contexts_disposed_ > 0);
+ HistogramTimerScope scope(isolate_->counters()->gc_context());
+ CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed");
break;
}
case DO_SCAVENGE:
@@ -5594,23 +5614,14 @@ void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
factor = kMinHeapGrowingFactor;
}
- // TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still
- // needed after taking the allocation rate for the old generation limit into
- // account.
- double idle_factor = Min(factor, kMaxHeapGrowingFactorIdle);
-
old_generation_allocation_limit_ =
CalculateOldGenerationAllocationLimit(factor, old_gen_size);
- idle_old_generation_allocation_limit_ =
- CalculateOldGenerationAllocationLimit(idle_factor, old_gen_size);
if (FLAG_trace_gc_verbose) {
- PrintIsolate(
- isolate_,
- "Grow: old size: %" V8_PTR_PREFIX "d KB, new limit: %" V8_PTR_PREFIX
- "d KB (%.1f), new idle limit: %" V8_PTR_PREFIX "d KB (%.1f)\n",
- old_gen_size / KB, old_generation_allocation_limit_ / KB, factor,
- idle_old_generation_allocation_limit_ / KB, idle_factor);
+ PrintIsolate(isolate_, "Grow: old size: %" V8_PTR_PREFIX
+ "d KB, new limit: %" V8_PTR_PREFIX "d KB (%.1f)\n",
+ old_gen_size / KB, old_generation_allocation_limit_ / KB,
+ factor);
}
}
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/memory-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698