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

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

Issue 2379663002: Reland "[heap] New heuristics for starting of incremental marking. (patchset #9 id:160001 of https:… (Closed)
Patch Set: fix Created 4 years, 2 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') | src/heap/heap-inl.h » ('j') | 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/heap/heap.h" 5 #include "src/heap/heap.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/ast/context-slot-cache.h" 9 #include "src/ast/context-slot-cache.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 isolate_->counters()->gc_compactor_caused_by_request()->Increment(); 259 isolate_->counters()->gc_compactor_caused_by_request()->Increment();
260 *reason = "GC in old space requested"; 260 *reason = "GC in old space requested";
261 return MARK_COMPACTOR; 261 return MARK_COMPACTOR;
262 } 262 }
263 263
264 if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) { 264 if (FLAG_gc_global || (FLAG_stress_compaction && (gc_count_ & 1) != 0)) {
265 *reason = "GC in old space forced by flags"; 265 *reason = "GC in old space forced by flags";
266 return MARK_COMPACTOR; 266 return MARK_COMPACTOR;
267 } 267 }
268 268
269 // Is enough data promoted to justify a global GC?
270 if (OldGenerationAllocationLimitReached()) {
271 isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
272 *reason = "promotion limit reached";
273 return MARK_COMPACTOR;
274 }
275
276 // Is there enough space left in OLD to guarantee that a scavenge can 269 // Is there enough space left in OLD to guarantee that a scavenge can
277 // succeed? 270 // succeed?
278 // 271 //
279 // Note that MemoryAllocator->MaxAvailable() undercounts the memory available 272 // Note that MemoryAllocator->MaxAvailable() undercounts the memory available
280 // for object promotion. It counts only the bytes that the memory 273 // for object promotion. It counts only the bytes that the memory
281 // allocator has not yet allocated from the OS and assigned to any space, 274 // allocator has not yet allocated from the OS and assigned to any space,
282 // and does not count available bytes already in the old space or code 275 // and does not count available bytes already in the old space or code
283 // space. Undercounting is safe---we may get an unrequested full GC when 276 // space. Undercounting is safe---we may get an unrequested full GC when
284 // a scavenge would have succeeded. 277 // a scavenge would have succeeded.
285 if (memory_allocator()->MaxAvailable() <= new_space_->Size()) { 278 if (memory_allocator()->MaxAvailable() <= new_space_->Size()) {
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) { 953 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
961 if (FLAG_trace_incremental_marking) { 954 if (FLAG_trace_incremental_marking) {
962 isolate()->PrintWithTimestamp( 955 isolate()->PrintWithTimestamp(
963 "[IncrementalMarking] Scavenge during marking.\n"); 956 "[IncrementalMarking] Scavenge during marking.\n");
964 } 957 }
965 } 958 }
966 959
967 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() && 960 if (collector == MARK_COMPACTOR && !ShouldFinalizeIncrementalMarking() &&
968 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() && 961 !ShouldAbortIncrementalMarking() && !incremental_marking()->IsStopped() &&
969 !incremental_marking()->should_hurry() && FLAG_incremental_marking && 962 !incremental_marking()->should_hurry() && FLAG_incremental_marking &&
970 OldGenerationAllocationLimitReached()) { 963 OldGenerationSpaceAvailable() <= 0) {
971 if (!incremental_marking()->IsComplete() && 964 if (!incremental_marking()->IsComplete() &&
972 !mark_compact_collector()->marking_deque_.IsEmpty() && 965 !mark_compact_collector()->marking_deque_.IsEmpty() &&
973 !FLAG_gc_global) { 966 !FLAG_gc_global) {
974 if (FLAG_trace_incremental_marking) { 967 if (FLAG_trace_incremental_marking) {
975 isolate()->PrintWithTimestamp( 968 isolate()->PrintWithTimestamp(
976 "[IncrementalMarking] Delaying MarkSweep.\n"); 969 "[IncrementalMarking] Delaying MarkSweep.\n");
977 } 970 }
978 collector = SCAVENGER; 971 collector = SCAVENGER;
979 collector_reason = "incremental marking delaying mark-sweep"; 972 collector_reason = "incremental marking delaying mark-sweep";
980 } 973 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 GarbageCollectionReason gc_reason, 1065 GarbageCollectionReason gc_reason,
1073 GCCallbackFlags gc_callback_flags) { 1066 GCCallbackFlags gc_callback_flags) {
1074 DCHECK(incremental_marking()->IsStopped()); 1067 DCHECK(incremental_marking()->IsStopped());
1075 set_current_gc_flags(gc_flags); 1068 set_current_gc_flags(gc_flags);
1076 current_gc_callback_flags_ = gc_callback_flags; 1069 current_gc_callback_flags_ = gc_callback_flags;
1077 incremental_marking()->Start(gc_reason); 1070 incremental_marking()->Start(gc_reason);
1078 } 1071 }
1079 1072
1080 void Heap::StartIncrementalMarkingIfAllocationLimitIsReached( 1073 void Heap::StartIncrementalMarkingIfAllocationLimitIsReached(
1081 int gc_flags, const GCCallbackFlags gc_callback_flags) { 1074 int gc_flags, const GCCallbackFlags gc_callback_flags) {
1082 if (incremental_marking()->IsStopped() && 1075 if (incremental_marking()->IsStopped()) {
1083 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { 1076 IncrementalMarkingLimit reached_limit = IncrementalMarkingLimitReached();
1084 StartIncrementalMarking(gc_flags, GarbageCollectionReason::kAllocationLimit, 1077 if (reached_limit == IncrementalMarkingLimit::kSoftLimit) {
1085 gc_callback_flags); 1078 incremental_marking()->incremental_marking_job()->ScheduleTask(this);
1079 } else if (reached_limit == IncrementalMarkingLimit::kHardLimit) {
1080 StartIncrementalMarking(gc_flags,
1081 GarbageCollectionReason::kAllocationLimit,
1082 gc_callback_flags);
1083 }
1086 } 1084 }
1087 } 1085 }
1088 1086
1089 void Heap::StartIdleIncrementalMarking(GarbageCollectionReason gc_reason) { 1087 void Heap::StartIdleIncrementalMarking(GarbageCollectionReason gc_reason) {
1090 gc_idle_time_handler_->ResetNoProgressCounter(); 1088 gc_idle_time_handler_->ResetNoProgressCounter();
1091 StartIncrementalMarking(kReduceMemoryFootprintMask, gc_reason, 1089 StartIncrementalMarking(kReduceMemoryFootprintMask, gc_reason,
1092 kNoGCCallbackFlags); 1090 kNoGCCallbackFlags);
1093 } 1091 }
1094 1092
1095 1093
(...skipping 4226 matching lines...) Expand 10 before | Expand all | Expand 10 after
5322 CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5320 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5323 5321
5324 if (FLAG_trace_gc_verbose) { 5322 if (FLAG_trace_gc_verbose) {
5325 isolate_->PrintWithTimestamp("Grow: old size: %" V8PRIdPTR 5323 isolate_->PrintWithTimestamp("Grow: old size: %" V8PRIdPTR
5326 " KB, new limit: %" V8PRIdPTR " KB (%.1f)\n", 5324 " KB, new limit: %" V8PRIdPTR " KB (%.1f)\n",
5327 old_gen_size / KB, 5325 old_gen_size / KB,
5328 old_generation_allocation_limit_ / KB, factor); 5326 old_generation_allocation_limit_ / KB, factor);
5329 } 5327 }
5330 } 5328 }
5331 5329
5332
5333 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, 5330 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size,
5334 double gc_speed, 5331 double gc_speed,
5335 double mutator_speed) { 5332 double mutator_speed) {
5336 double factor = HeapGrowingFactor(gc_speed, mutator_speed); 5333 double factor = HeapGrowingFactor(gc_speed, mutator_speed);
5337 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); 5334 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5338 if (limit < old_generation_allocation_limit_) { 5335 if (limit < old_generation_allocation_limit_) {
5339 if (FLAG_trace_gc_verbose) { 5336 if (FLAG_trace_gc_verbose) {
5340 isolate_->PrintWithTimestamp( 5337 isolate_->PrintWithTimestamp(
5341 "Dampen: old size: %" V8PRIdPTR " KB, old limit: %" V8PRIdPTR 5338 "Dampen: old size: %" V8PRIdPTR " KB, old limit: %" V8PRIdPTR
5342 " KB, " 5339 " KB, "
5343 "new limit: %" V8PRIdPTR " KB (%.1f)\n", 5340 "new limit: %" V8PRIdPTR " KB (%.1f)\n",
5344 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB, 5341 old_gen_size / KB, old_generation_allocation_limit_ / KB, limit / KB,
5345 factor); 5342 factor);
5346 } 5343 }
5347 old_generation_allocation_limit_ = limit; 5344 old_generation_allocation_limit_ = limit;
5348 } 5345 }
5349 } 5346 }
5350 5347
5348 // This predicate is called when an old generation space cannot allocated from
5349 // the free list and is about to add a new page. Returning false will cause a
5350 // major GC. It happens when the old generation allocation limit is reached and
5351 // - either we need to optimize for memory usage,
5352 // - or the incremental marking is not in progress and we cannot start it.
5353 bool Heap::ShouldExpandOldGenerationOnAllocationFailure() {
5354 if (always_allocate() || OldGenerationSpaceAvailable() > 0) return true;
5355 // We reached the old generation allocation limit.
5356
5357 if (ShouldOptimizeForMemoryUsage()) return false;
5358
5359 if (incremental_marking()->IsStopped() &&
5360 IncrementalMarkingLimitReached() == IncrementalMarkingLimit::kNoLimit) {
5361 // We cannot start incremental marking.
5362 return false;
5363 }
5364 return true;
5365 }
5366
5367 // This function returns either kNoLimit, kSoftLimit, or kHardLimit.
5368 // The kNoLimit means that either incremental marking is disabled or it is too
5369 // early to start incremental marking.
5370 // The kSoftLimit means that incremental marking should be started soon.
5371 // The kHardLimit means that incremental marking should be started immediately.
5372 Heap::IncrementalMarkingLimit Heap::IncrementalMarkingLimitReached() {
5373 if (!incremental_marking()->CanBeActivated() ||
5374 PromotedSpaceSizeOfObjects() < IncrementalMarking::kActivationThreshold) {
5375 // Incremental marking is disabled or it is too early to start.
5376 return IncrementalMarkingLimit::kNoLimit;
5377 }
5378 if ((FLAG_stress_compaction && (gc_count_ & 1) != 0) ||
5379 HighMemoryPressure()) {
5380 // If there is high memory pressure or stress testing is enabled, then
5381 // start marking immediately.
5382 return IncrementalMarkingLimit::kHardLimit;
5383 }
5384 intptr_t old_generation_space_available = OldGenerationSpaceAvailable();
5385 if (old_generation_space_available > new_space_->Capacity()) {
5386 return IncrementalMarkingLimit::kNoLimit;
5387 }
5388 // We are close to the allocation limit.
5389 // Choose between the hard and the soft limits.
5390 if (old_generation_space_available <= 0 || ShouldOptimizeForMemoryUsage()) {
5391 return IncrementalMarkingLimit::kHardLimit;
5392 }
5393 return IncrementalMarkingLimit::kSoftLimit;
5394 }
5351 5395
5352 void Heap::EnableInlineAllocation() { 5396 void Heap::EnableInlineAllocation() {
5353 if (!inline_allocation_disabled_) return; 5397 if (!inline_allocation_disabled_) return;
5354 inline_allocation_disabled_ = false; 5398 inline_allocation_disabled_ = false;
5355 5399
5356 // Update inline allocation limit for new space. 5400 // Update inline allocation limit for new space.
5357 new_space()->UpdateInlineAllocationLimit(0); 5401 new_space()->UpdateInlineAllocationLimit(0);
5358 } 5402 }
5359 5403
5360 5404
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
6475 } 6519 }
6476 6520
6477 6521
6478 // static 6522 // static
6479 int Heap::GetStaticVisitorIdForMap(Map* map) { 6523 int Heap::GetStaticVisitorIdForMap(Map* map) {
6480 return StaticVisitorBase::GetVisitorId(map); 6524 return StaticVisitorBase::GetVisitorId(map);
6481 } 6525 }
6482 6526
6483 } // namespace internal 6527 } // namespace internal
6484 } // namespace v8 6528 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698