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

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

Issue 1038653003: Change halfway-to-the-max GC trigger to measure committed pages, not allocated objects Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include "src/mips/regexp-macro-assembler-mips.h" // NOLINT 47 #include "src/mips/regexp-macro-assembler-mips.h" // NOLINT
48 #endif 48 #endif
49 #if V8_TARGET_ARCH_MIPS64 && !V8_INTERPRETED_REGEXP 49 #if V8_TARGET_ARCH_MIPS64 && !V8_INTERPRETED_REGEXP
50 #include "src/regexp-macro-assembler.h" 50 #include "src/regexp-macro-assembler.h"
51 #include "src/mips64/regexp-macro-assembler-mips64.h" 51 #include "src/mips64/regexp-macro-assembler-mips64.h"
52 #endif 52 #endif
53 53
54 namespace v8 { 54 namespace v8 {
55 namespace internal { 55 namespace internal {
56 56
57 static const intptr_t kDefaultMaxOldGenSize = 700ul * (kPointerSize / 4) * MB;
Hannes Payer (out of office) 2015/03/25 14:30:06 Please define the constant next to the other heap
Erik Corry Chromium.org 2015/03/25 15:16:06 Done.
57 58
58 Heap::Heap() 59 Heap::Heap()
59 : amount_of_external_allocated_memory_(0), 60 : amount_of_external_allocated_memory_(0),
60 amount_of_external_allocated_memory_at_last_global_gc_(0), 61 amount_of_external_allocated_memory_at_last_global_gc_(0),
61 isolate_(NULL), 62 isolate_(NULL),
62 code_range_size_(0), 63 code_range_size_(0),
63 // semispace_size_ should be a power of 2 and old_generation_size_ should 64 // semispace_size_ should be a power of 2 and old_generation_size_ should
64 // be a multiple of Page::kPageSize. 65 // be a multiple of Page::kPageSize.
65 reserved_semispace_size_(8 * (kPointerSize / 4) * MB), 66 reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
66 max_semi_space_size_(8 * (kPointerSize / 4) * MB), 67 max_semi_space_size_(8 * (kPointerSize / 4) * MB),
67 initial_semispace_size_(Page::kPageSize), 68 initial_semispace_size_(Page::kPageSize),
68 target_semispace_size_(Page::kPageSize), 69 target_semispace_size_(Page::kPageSize),
69 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), 70 max_old_generation_size_(kDefaultMaxOldGenSize),
70 initial_old_generation_size_(max_old_generation_size_ / 71 initial_old_generation_size_(max_old_generation_size_ /
71 kInitalOldGenerationLimitFactor), 72 kInitalOldGenerationLimitFactor),
72 old_generation_size_configured_(false), 73 old_generation_size_configured_(false),
73 max_executable_size_(256ul * (kPointerSize / 4) * MB), 74 max_executable_size_(256ul * (kPointerSize / 4) * MB),
74 // Variables set based on semispace_size_ and old_generation_size_ in 75 // Variables set based on semispace_size_ and old_generation_size_ in
75 // ConfigureHeap. 76 // ConfigureHeap.
76 // Will be 4 * reserved_semispace_size_ to ensure that young 77 // Will be 4 * reserved_semispace_size_ to ensure that young
77 // generation can be aligned to its size. 78 // generation can be aligned to its size.
78 maximum_committed_(0), 79 maximum_committed_(0),
79 survived_since_last_expansion_(0), 80 survived_since_last_expansion_(0),
(...skipping 16 matching lines...) Expand all
96 raw_allocations_hash_(0), 97 raw_allocations_hash_(0),
97 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), 98 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc),
98 ms_count_(0), 99 ms_count_(0),
99 gc_count_(0), 100 gc_count_(0),
100 remembered_unmapped_pages_index_(0), 101 remembered_unmapped_pages_index_(0),
101 unflattened_strings_length_(0), 102 unflattened_strings_length_(0),
102 #ifdef DEBUG 103 #ifdef DEBUG
103 allocation_timeout_(0), 104 allocation_timeout_(0),
104 #endif // DEBUG 105 #endif // DEBUG
105 old_generation_allocation_limit_(initial_old_generation_size_), 106 old_generation_allocation_limit_(initial_old_generation_size_),
107 old_generation_committed_memory_limit_(kDefaultMaxOldGenSize >> 1),
Hannes Payer (out of office) 2015/03/25 14:30:06 why not set it to initial_old_generation_size_?
Erik Corry Chromium.org 2015/03/25 15:16:06 This is "halfway from here to the limit", which is
106 old_gen_exhausted_(false), 108 old_gen_exhausted_(false),
107 inline_allocation_disabled_(false), 109 inline_allocation_disabled_(false),
108 store_buffer_rebuilder_(store_buffer()), 110 store_buffer_rebuilder_(store_buffer()),
109 hidden_string_(NULL), 111 hidden_string_(NULL),
110 gc_safe_size_of_old_object_(NULL), 112 gc_safe_size_of_old_object_(NULL),
111 total_regexp_code_generated_(0), 113 total_regexp_code_generated_(0),
112 tracer_(this), 114 tracer_(this),
113 high_survival_rate_period_length_(0), 115 high_survival_rate_period_length_(0),
114 promoted_objects_size_(0), 116 promoted_objects_size_(0),
115 promotion_ratio_(0), 117 promotion_ratio_(0),
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 855
854 EnsureFillerObjectAtTop(); 856 EnsureFillerObjectAtTop();
855 857
856 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) { 858 if (collector == SCAVENGER && !incremental_marking()->IsStopped()) {
857 if (FLAG_trace_incremental_marking) { 859 if (FLAG_trace_incremental_marking) {
858 PrintF("[IncrementalMarking] Scavenge during marking.\n"); 860 PrintF("[IncrementalMarking] Scavenge during marking.\n");
859 } 861 }
860 } 862 }
861 863
862 if (collector == MARK_COMPACTOR && 864 if (collector == MARK_COMPACTOR &&
863 !mark_compact_collector()->abort_incremental_marking() && 865 !mark_compact_collector()->incremental_marking_abort_requested() &&
864 !incremental_marking()->IsStopped() && 866 !incremental_marking()->IsStopped() &&
865 !incremental_marking()->should_hurry() && 867 !incremental_marking()->should_hurry() &&
866 FLAG_incremental_marking_steps) { 868 FLAG_incremental_marking_steps) {
867 // Make progress in incremental marking. 869 // Make progress in incremental marking.
868 const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB; 870 const intptr_t kStepSizeWhenDelayedByScavenge = 1 * MB;
869 incremental_marking()->Step(kStepSizeWhenDelayedByScavenge, 871 incremental_marking()->Step(kStepSizeWhenDelayedByScavenge,
870 IncrementalMarking::NO_GC_VIA_STACK_GUARD); 872 IncrementalMarking::NO_GC_VIA_STACK_GUARD);
871 if (!incremental_marking()->IsComplete() && 873 if (!incremental_marking()->IsComplete() &&
872 !mark_compact_collector_.marking_deque_.IsEmpty() && !FLAG_gc_global) { 874 !mark_compact_collector_.marking_deque_.IsEmpty() && !FLAG_gc_global) {
873 if (FLAG_trace_incremental_marking) { 875 if (FLAG_trace_incremental_marking) {
(...skipping 22 matching lines...) Expand all
896 898
897 GarbageCollectionEpilogue(); 899 GarbageCollectionEpilogue();
898 if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) { 900 if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) {
899 isolate()->CheckDetachedContextsAfterGC(); 901 isolate()->CheckDetachedContextsAfterGC();
900 } 902 }
901 tracer()->Stop(collector); 903 tracer()->Stop(collector);
902 } 904 }
903 905
904 // Start incremental marking for the next cycle. The heap snapshot 906 // Start incremental marking for the next cycle. The heap snapshot
905 // generator needs incremental marking to stay off after it aborted. 907 // generator needs incremental marking to stay off after it aborted.
906 if (!mark_compact_collector()->abort_incremental_marking() && 908 if (!mark_compact_collector()->incremental_marking_abort_requested() &&
907 WorthActivatingIncrementalMarking()) { 909 incremental_marking()->IsStopped() &&
910 incremental_marking()->ShouldActivate()) {
908 incremental_marking()->Start(); 911 incremental_marking()->Start();
909 } 912 }
910 913
911 return next_gc_likely_to_collect_more; 914 return next_gc_likely_to_collect_more;
912 } 915 }
913 916
914 917
915 int Heap::NotifyContextDisposed(bool dependant_context) { 918 int Heap::NotifyContextDisposed(bool dependant_context) {
916 if (!dependant_context) { 919 if (!dependant_context) {
917 tracer()->ResetSurvivalEvents(); 920 tracer()->ResetSurvivalEvents();
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 incremental_marking()->NotifyOfHighPromotionRate(); 1157 incremental_marking()->NotifyOfHighPromotionRate();
1155 } 1158 }
1156 1159
1157 if (collector == MARK_COMPACTOR) { 1160 if (collector == MARK_COMPACTOR) {
1158 // Perform mark-sweep with optional compaction. 1161 // Perform mark-sweep with optional compaction.
1159 MarkCompact(); 1162 MarkCompact();
1160 sweep_generation_++; 1163 sweep_generation_++;
1161 // Temporarily set the limit for case when PostGarbageCollectionProcessing 1164 // Temporarily set the limit for case when PostGarbageCollectionProcessing
1162 // allocates and triggers GC. The real limit is set at after 1165 // allocates and triggers GC. The real limit is set at after
1163 // PostGarbageCollectionProcessing. 1166 // PostGarbageCollectionProcessing.
1164 old_generation_allocation_limit_ = 1167 SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1165 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1166 old_gen_exhausted_ = false; 1168 old_gen_exhausted_ = false;
1167 old_generation_size_configured_ = true; 1169 old_generation_size_configured_ = true;
1168 } else { 1170 } else {
1169 Scavenge(); 1171 Scavenge();
1170 } 1172 }
1171 1173
1172 UpdateSurvivalStatistics(start_new_space_size); 1174 UpdateSurvivalStatistics(start_new_space_size);
1173 ConfigureInitialOldGenerationSize(); 1175 ConfigureInitialOldGenerationSize();
1174 1176
1175 isolate_->counters()->objs_since_last_young()->Set(0); 1177 isolate_->counters()->objs_since_last_young()->Set(0);
(...skipping 13 matching lines...) Expand all
1189 1191
1190 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this); 1192 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1191 1193
1192 // Update relocatables. 1194 // Update relocatables.
1193 Relocatable::PostGarbageCollectionProcessing(isolate_); 1195 Relocatable::PostGarbageCollectionProcessing(isolate_);
1194 1196
1195 if (collector == MARK_COMPACTOR) { 1197 if (collector == MARK_COMPACTOR) {
1196 // Register the amount of external allocated memory. 1198 // Register the amount of external allocated memory.
1197 amount_of_external_allocated_memory_at_last_global_gc_ = 1199 amount_of_external_allocated_memory_at_last_global_gc_ =
1198 amount_of_external_allocated_memory_; 1200 amount_of_external_allocated_memory_;
1199 old_generation_allocation_limit_ = OldGenerationAllocationLimit( 1201 SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(),
1200 PromotedSpaceSizeOfObjects(), freed_global_handles); 1202 freed_global_handles);
1201 // We finished a marking cycle. We can uncommit the marking deque until 1203 // We finished a marking cycle. We can uncommit the marking deque until
1202 // we start marking again. 1204 // we start marking again.
1203 mark_compact_collector_.UncommitMarkingDeque(); 1205 mark_compact_collector_.UncommitMarkingDeque();
1204 } 1206 }
1205 1207
1206 { 1208 {
1207 GCCallbacksScope scope(this); 1209 GCCallbacksScope scope(this);
1208 if (scope.CheckReenter()) { 1210 if (scope.CheckReenter()) {
1209 AllowHeapAllocation allow_allocation; 1211 AllowHeapAllocation allow_allocation;
1210 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1212 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
(...skipping 3356 matching lines...) Expand 10 before | Expand all | Expand 10 after
4567 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( 4569 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
4568 static_cast<size_t>(idle_time_in_ms), size_of_objects, 4570 static_cast<size_t>(idle_time_in_ms), size_of_objects,
4569 final_incremental_mark_compact_speed_in_bytes_per_ms))) { 4571 final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4570 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); 4572 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
4571 return true; 4573 return true;
4572 } 4574 }
4573 return false; 4575 return false;
4574 } 4576 }
4575 4577
4576 4578
4577 bool Heap::WorthActivatingIncrementalMarking() {
4578 return incremental_marking()->IsStopped() &&
4579 incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull();
4580 }
4581
4582
4583 static double MonotonicallyIncreasingTimeInMs() { 4579 static double MonotonicallyIncreasingTimeInMs() {
4584 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * 4580 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4585 static_cast<double>(base::Time::kMillisecondsPerSecond); 4581 static_cast<double>(base::Time::kMillisecondsPerSecond);
4586 } 4582 }
4587 4583
4588 4584
4589 bool Heap::IdleNotification(int idle_time_in_ms) { 4585 bool Heap::IdleNotification(int idle_time_in_ms) {
4590 return IdleNotification( 4586 return IdleNotification(
4591 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + 4587 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4592 (static_cast<double>(idle_time_in_ms) / 4588 (static_cast<double>(idle_time_in_ms) /
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
5224 5220
5225 int64_t Heap::PromotedExternalMemorySize() { 5221 int64_t Heap::PromotedExternalMemorySize() {
5226 if (amount_of_external_allocated_memory_ <= 5222 if (amount_of_external_allocated_memory_ <=
5227 amount_of_external_allocated_memory_at_last_global_gc_) 5223 amount_of_external_allocated_memory_at_last_global_gc_)
5228 return 0; 5224 return 0;
5229 return amount_of_external_allocated_memory_ - 5225 return amount_of_external_allocated_memory_ -
5230 amount_of_external_allocated_memory_at_last_global_gc_; 5226 amount_of_external_allocated_memory_at_last_global_gc_;
5231 } 5227 }
5232 5228
5233 5229
5234 intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, 5230 void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
5235 int freed_global_handles) { 5231 int freed_global_handles) {
5236 const int kMaxHandles = 1000; 5232 const int kMaxHandles = 1000;
5237 const int kMinHandles = 100; 5233 const int kMinHandles = 100;
5238 double min_factor = 1.1; 5234 double min_factor = 1.1;
5239 double max_factor = 4; 5235 double max_factor = 4;
5240 // We set the old generation growing factor to 2 to grow the heap slower on 5236 // We set the old generation growing factor to 2 to grow the heap slower on
5241 // memory-constrained devices. 5237 // memory-constrained devices.
5242 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { 5238 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
5243 max_factor = 2; 5239 max_factor = 2;
5244 } 5240 }
5245 // If there are many freed global handles, then the next full GC will 5241 // If there are many freed global handles, then the next full GC will
(...skipping 13 matching lines...) Expand all
5259 (kMaxHandles - kMinHandles); 5255 (kMaxHandles - kMinHandles);
5260 } 5256 }
5261 5257
5262 if (FLAG_stress_compaction || 5258 if (FLAG_stress_compaction ||
5263 mark_compact_collector()->reduce_memory_footprint_) { 5259 mark_compact_collector()->reduce_memory_footprint_) {
5264 factor = min_factor; 5260 factor = min_factor;
5265 } 5261 }
5266 5262
5267 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); 5263 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5268 limit = Max(limit, kMinimumOldGenerationAllocationLimit); 5264 limit = Max(limit, kMinimumOldGenerationAllocationLimit);
5269 limit += new_space_.Capacity(); 5265
5270 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; 5266 old_generation_allocation_limit_ = limit + new_space_.Capacity();
5271 return Min(limit, halfway_to_the_max); 5267 old_generation_committed_memory_limit_ =
5268 CommittedOldGenerationMemory() / 2 + max_old_generation_size_ / 2;
5269
5270 if (FLAG_trace_gc) {
Hannes Payer (out of office) 2015/03/25 14:30:05 We may want to print that behind a different flag
Erik Corry Chromium.org 2015/03/25 15:16:06 I'd like to keep this one, but I put the other one
5271 PrintF("Next GC at %.1f (%.1f) -> %.1f (%.1f)\n", old_gen_size * 1.0 / MB,
5272 CommittedOldGenerationMemory() * 1.0 / MB, limit * 1.0 / MB,
5273 old_generation_committed_memory_limit_ * 1.0 / MB);
5274 }
5272 } 5275 }
5273 5276
5274 5277
5275 void Heap::EnableInlineAllocation() { 5278 void Heap::EnableInlineAllocation() {
5276 if (!inline_allocation_disabled_) return; 5279 if (!inline_allocation_disabled_) return;
5277 inline_allocation_disabled_ = false; 5280 inline_allocation_disabled_ = false;
5278 5281
5279 // Update inline allocation limit for new space. 5282 // Update inline allocation limit for new space.
5280 new_space()->UpdateInlineAllocationLimit(0); 5283 new_space()->UpdateInlineAllocationLimit(0);
5281 } 5284 }
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
6390 static_cast<int>(object_sizes_last_time_[index])); 6393 static_cast<int>(object_sizes_last_time_[index]));
6391 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6394 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6392 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6395 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6393 6396
6394 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6397 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6395 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6398 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6396 ClearObjectStats(); 6399 ClearObjectStats();
6397 } 6400 }
6398 } 6401 }
6399 } // namespace v8::internal 6402 } // namespace v8::internal
OLDNEW
« src/heap/heap.h ('K') | « src/heap/heap.h ('k') | src/heap/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698