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

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

Issue 1100743003: Version 4.2.77.18 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@4.2
Patch Set: Merge conflict resolved. Created 5 years, 8 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/incremental-marking.cc » ('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/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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 raw_allocations_hash_(0), 97 raw_allocations_hash_(0),
98 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), 98 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc),
99 ms_count_(0), 99 ms_count_(0),
100 gc_count_(0), 100 gc_count_(0),
101 remembered_unmapped_pages_index_(0), 101 remembered_unmapped_pages_index_(0),
102 unflattened_strings_length_(0), 102 unflattened_strings_length_(0),
103 #ifdef DEBUG 103 #ifdef DEBUG
104 allocation_timeout_(0), 104 allocation_timeout_(0),
105 #endif // DEBUG 105 #endif // DEBUG
106 old_generation_allocation_limit_(initial_old_generation_size_), 106 old_generation_allocation_limit_(initial_old_generation_size_),
107 idle_old_generation_allocation_limit_(
108 kMinimumOldGenerationAllocationLimit),
107 old_gen_exhausted_(false), 109 old_gen_exhausted_(false),
108 inline_allocation_disabled_(false), 110 inline_allocation_disabled_(false),
109 store_buffer_rebuilder_(store_buffer()), 111 store_buffer_rebuilder_(store_buffer()),
110 hidden_string_(NULL), 112 hidden_string_(NULL),
111 gc_safe_size_of_old_object_(NULL), 113 gc_safe_size_of_old_object_(NULL),
112 total_regexp_code_generated_(0), 114 total_regexp_code_generated_(0),
113 tracer_(this), 115 tracer_(this),
114 high_survival_rate_period_length_(0), 116 high_survival_rate_period_length_(0),
115 promoted_objects_size_(0), 117 promoted_objects_size_(0),
116 promotion_ratio_(0), 118 promotion_ratio_(0),
(...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 incremental_marking()->NotifyOfHighPromotionRate(); 1154 incremental_marking()->NotifyOfHighPromotionRate();
1153 } 1155 }
1154 1156
1155 if (collector == MARK_COMPACTOR) { 1157 if (collector == MARK_COMPACTOR) {
1156 // Perform mark-sweep with optional compaction. 1158 // Perform mark-sweep with optional compaction.
1157 MarkCompact(); 1159 MarkCompact();
1158 sweep_generation_++; 1160 sweep_generation_++;
1159 // Temporarily set the limit for case when PostGarbageCollectionProcessing 1161 // Temporarily set the limit for case when PostGarbageCollectionProcessing
1160 // allocates and triggers GC. The real limit is set at after 1162 // allocates and triggers GC. The real limit is set at after
1161 // PostGarbageCollectionProcessing. 1163 // PostGarbageCollectionProcessing.
1162 old_generation_allocation_limit_ = 1164 SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1163 OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
1164 old_gen_exhausted_ = false; 1165 old_gen_exhausted_ = false;
1165 old_generation_size_configured_ = true; 1166 old_generation_size_configured_ = true;
1166 } else { 1167 } else {
1167 Scavenge(); 1168 Scavenge();
1168 } 1169 }
1169 1170
1170 UpdateSurvivalStatistics(start_new_space_size); 1171 UpdateSurvivalStatistics(start_new_space_size);
1171 ConfigureInitialOldGenerationSize(); 1172 ConfigureInitialOldGenerationSize();
1172 1173
1173 isolate_->counters()->objs_since_last_young()->Set(0); 1174 isolate_->counters()->objs_since_last_young()->Set(0);
(...skipping 13 matching lines...) Expand all
1187 1188
1188 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this); 1189 isolate_->eternal_handles()->PostGarbageCollectionProcessing(this);
1189 1190
1190 // Update relocatables. 1191 // Update relocatables.
1191 Relocatable::PostGarbageCollectionProcessing(isolate_); 1192 Relocatable::PostGarbageCollectionProcessing(isolate_);
1192 1193
1193 if (collector == MARK_COMPACTOR) { 1194 if (collector == MARK_COMPACTOR) {
1194 // Register the amount of external allocated memory. 1195 // Register the amount of external allocated memory.
1195 amount_of_external_allocated_memory_at_last_global_gc_ = 1196 amount_of_external_allocated_memory_at_last_global_gc_ =
1196 amount_of_external_allocated_memory_; 1197 amount_of_external_allocated_memory_;
1197 old_generation_allocation_limit_ = OldGenerationAllocationLimit( 1198 SetOldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(),
1198 PromotedSpaceSizeOfObjects(), freed_global_handles); 1199 freed_global_handles);
1199 // We finished a marking cycle. We can uncommit the marking deque until 1200 // We finished a marking cycle. We can uncommit the marking deque until
1200 // we start marking again. 1201 // we start marking again.
1201 mark_compact_collector_.UncommitMarkingDeque(); 1202 mark_compact_collector_.UncommitMarkingDeque();
1202 } 1203 }
1203 1204
1204 { 1205 {
1205 GCCallbacksScope scope(this); 1206 GCCallbacksScope scope(this);
1206 if (scope.CheckReenter()) { 1207 if (scope.CheckReenter()) {
1207 AllowHeapAllocation allow_allocation; 1208 AllowHeapAllocation allow_allocation;
1208 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL); 1209 GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
(...skipping 3342 matching lines...) Expand 10 before | Expand all | Expand 10 after
4551 final_incremental_mark_compact_speed_in_bytes_per_ms))) { 4552 final_incremental_mark_compact_speed_in_bytes_per_ms))) {
4552 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); 4553 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
4553 return true; 4554 return true;
4554 } 4555 }
4555 return false; 4556 return false;
4556 } 4557 }
4557 4558
4558 4559
4559 bool Heap::WorthActivatingIncrementalMarking() { 4560 bool Heap::WorthActivatingIncrementalMarking() {
4560 return incremental_marking()->IsStopped() && 4561 return incremental_marking()->IsStopped() &&
4561 incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull(); 4562 incremental_marking()->ShouldActivate();
4562 } 4563 }
4563 4564
4564 4565
4565 static double MonotonicallyIncreasingTimeInMs() { 4566 static double MonotonicallyIncreasingTimeInMs() {
4566 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() * 4567 return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
4567 static_cast<double>(base::Time::kMillisecondsPerSecond); 4568 static_cast<double>(base::Time::kMillisecondsPerSecond);
4568 } 4569 }
4569 4570
4570 4571
4571 bool Heap::IdleNotification(int idle_time_in_ms) { 4572 bool Heap::IdleNotification(int idle_time_in_ms) {
4572 return IdleNotification( 4573 return IdleNotification(
4573 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() + 4574 V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
4574 (static_cast<double>(idle_time_in_ms) / 4575 (static_cast<double>(idle_time_in_ms) /
4575 static_cast<double>(base::Time::kMillisecondsPerSecond))); 4576 static_cast<double>(base::Time::kMillisecondsPerSecond)));
4576 } 4577 }
4577 4578
4578 4579
4579 bool Heap::IdleNotification(double deadline_in_seconds) { 4580 bool Heap::IdleNotification(double deadline_in_seconds) {
4580 CHECK(HasBeenSetUp()); // http://crbug.com/425035 4581 CHECK(HasBeenSetUp()); // http://crbug.com/425035
4581 double deadline_in_ms = 4582 double deadline_in_ms =
4582 deadline_in_seconds * 4583 deadline_in_seconds *
4583 static_cast<double>(base::Time::kMillisecondsPerSecond); 4584 static_cast<double>(base::Time::kMillisecondsPerSecond);
4584 HistogramTimerScope idle_notification_scope( 4585 HistogramTimerScope idle_notification_scope(
4585 isolate_->counters()->gc_idle_notification()); 4586 isolate_->counters()->gc_idle_notification());
4587 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4586 4588
4587 GCIdleTimeHandler::HeapState heap_state; 4589 GCIdleTimeHandler::HeapState heap_state;
4588 heap_state.contexts_disposed = contexts_disposed_; 4590 heap_state.contexts_disposed = contexts_disposed_;
4589 heap_state.contexts_disposal_rate = 4591 heap_state.contexts_disposal_rate =
4590 tracer()->ContextDisposalRateInMilliseconds(); 4592 tracer()->ContextDisposalRateInMilliseconds();
4591 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects()); 4593 heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
4592 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); 4594 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
4593 // TODO(ulan): Start incremental marking only for large heaps. 4595 // TODO(ulan): Start incremental marking only for large heaps.
4596 intptr_t limit = old_generation_allocation_limit_;
4597 if (static_cast<size_t>(idle_time_in_ms) >
4598 GCIdleTimeHandler::kMinIdleTimeToStartIncrementalMarking) {
4599 limit = idle_old_generation_allocation_limit_;
4600 }
4601
4594 heap_state.can_start_incremental_marking = 4602 heap_state.can_start_incremental_marking =
4595 incremental_marking()->ShouldActivate() && FLAG_incremental_marking; 4603 incremental_marking()->WorthActivating() &&
4604 NextGCIsLikelyToBeFull(limit) && FLAG_incremental_marking;
4596 heap_state.sweeping_in_progress = 4605 heap_state.sweeping_in_progress =
4597 mark_compact_collector()->sweeping_in_progress(); 4606 mark_compact_collector()->sweeping_in_progress();
4598 heap_state.mark_compact_speed_in_bytes_per_ms = 4607 heap_state.mark_compact_speed_in_bytes_per_ms =
4599 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); 4608 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
4600 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>( 4609 heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
4601 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); 4610 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
4602 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = 4611 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms =
4603 static_cast<size_t>( 4612 static_cast<size_t>(
4604 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); 4613 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond());
4605 heap_state.scavenge_speed_in_bytes_per_ms = 4614 heap_state.scavenge_speed_in_bytes_per_ms =
4606 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); 4615 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
4607 heap_state.used_new_space_size = new_space_.Size(); 4616 heap_state.used_new_space_size = new_space_.Size();
4608 heap_state.new_space_capacity = new_space_.Capacity(); 4617 heap_state.new_space_capacity = new_space_.Capacity();
4609 heap_state.new_space_allocation_throughput_in_bytes_per_ms = 4618 heap_state.new_space_allocation_throughput_in_bytes_per_ms =
4610 static_cast<size_t>( 4619 static_cast<size_t>(
4611 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond()); 4620 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
4612 4621
4613 double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
4614 GCIdleTimeAction action = 4622 GCIdleTimeAction action =
4615 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); 4623 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
4616 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( 4624 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
4617 static_cast<int>(idle_time_in_ms)); 4625 static_cast<int>(idle_time_in_ms));
4618 4626
4619 bool result = false; 4627 bool result = false;
4620 switch (action.type) { 4628 switch (action.type) {
4621 case DONE: 4629 case DONE:
4622 result = true; 4630 result = true;
4623 break; 4631 break;
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
5351 5359
5352 int64_t Heap::PromotedExternalMemorySize() { 5360 int64_t Heap::PromotedExternalMemorySize() {
5353 if (amount_of_external_allocated_memory_ <= 5361 if (amount_of_external_allocated_memory_ <=
5354 amount_of_external_allocated_memory_at_last_global_gc_) 5362 amount_of_external_allocated_memory_at_last_global_gc_)
5355 return 0; 5363 return 0;
5356 return amount_of_external_allocated_memory_ - 5364 return amount_of_external_allocated_memory_ -
5357 amount_of_external_allocated_memory_at_last_global_gc_; 5365 amount_of_external_allocated_memory_at_last_global_gc_;
5358 } 5366 }
5359 5367
5360 5368
5361 intptr_t Heap::OldGenerationAllocationLimit(intptr_t old_gen_size, 5369 intptr_t Heap::CalculateOldGenerationAllocationLimit(double factor,
5362 int freed_global_handles) { 5370 intptr_t old_gen_size) {
5371 CHECK(factor > 1.0);
5372 CHECK(old_gen_size > 0);
5373 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor);
5374 limit = Max(limit, kMinimumOldGenerationAllocationLimit);
5375 limit += new_space_.Capacity();
5376 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2;
5377 return Min(limit, halfway_to_the_max);
5378 }
5379
5380
5381 void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
5382 int freed_global_handles) {
5363 const int kMaxHandles = 1000; 5383 const int kMaxHandles = 1000;
5364 const int kMinHandles = 100; 5384 const int kMinHandles = 100;
5365 double min_factor = 1.1; 5385 const double min_factor = 1.1;
5366 double max_factor = 4; 5386 double max_factor = 4;
5387 const double idle_max_factor = 1.5;
5367 // We set the old generation growing factor to 2 to grow the heap slower on 5388 // We set the old generation growing factor to 2 to grow the heap slower on
5368 // memory-constrained devices. 5389 // memory-constrained devices.
5369 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { 5390 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) {
5370 max_factor = 2; 5391 max_factor = 2;
5371 } 5392 }
5393
5372 // If there are many freed global handles, then the next full GC will 5394 // If there are many freed global handles, then the next full GC will
5373 // likely collect a lot of garbage. Choose the heap growing factor 5395 // likely collect a lot of garbage. Choose the heap growing factor
5374 // depending on freed global handles. 5396 // depending on freed global handles.
5375 // TODO(ulan, hpayer): Take into account mutator utilization. 5397 // TODO(ulan, hpayer): Take into account mutator utilization.
5398 // TODO(hpayer): The idle factor could make the handles heuristic obsolete.
5399 // Look into that.
5376 double factor; 5400 double factor;
5377 if (freed_global_handles <= kMinHandles) { 5401 if (freed_global_handles <= kMinHandles) {
5378 factor = max_factor; 5402 factor = max_factor;
5379 } else if (freed_global_handles >= kMaxHandles) { 5403 } else if (freed_global_handles >= kMaxHandles) {
5380 factor = min_factor; 5404 factor = min_factor;
5381 } else { 5405 } else {
5382 // Compute factor using linear interpolation between points 5406 // Compute factor using linear interpolation between points
5383 // (kMinHandles, max_factor) and (kMaxHandles, min_factor). 5407 // (kMinHandles, max_factor) and (kMaxHandles, min_factor).
5384 factor = max_factor - 5408 factor = max_factor -
5385 (freed_global_handles - kMinHandles) * (max_factor - min_factor) / 5409 (freed_global_handles - kMinHandles) * (max_factor - min_factor) /
5386 (kMaxHandles - kMinHandles); 5410 (kMaxHandles - kMinHandles);
5387 } 5411 }
5388 5412
5389 if (FLAG_stress_compaction || 5413 if (FLAG_stress_compaction ||
5390 mark_compact_collector()->reduce_memory_footprint_) { 5414 mark_compact_collector()->reduce_memory_footprint_) {
5391 factor = min_factor; 5415 factor = min_factor;
5392 } 5416 }
5393 5417
5394 intptr_t limit = static_cast<intptr_t>(old_gen_size * factor); 5418 old_generation_allocation_limit_ =
5395 limit = Max(limit, kMinimumOldGenerationAllocationLimit); 5419 CalculateOldGenerationAllocationLimit(factor, old_gen_size);
5396 limit += new_space_.Capacity(); 5420 idle_old_generation_allocation_limit_ = CalculateOldGenerationAllocationLimit(
5397 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; 5421 Min(factor, idle_max_factor), old_gen_size);
5398 return Min(limit, halfway_to_the_max);
5399 } 5422 }
5400 5423
5401 5424
5402 void Heap::EnableInlineAllocation() { 5425 void Heap::EnableInlineAllocation() {
5403 if (!inline_allocation_disabled_) return; 5426 if (!inline_allocation_disabled_) return;
5404 inline_allocation_disabled_ = false; 5427 inline_allocation_disabled_ = false;
5405 5428
5406 // Update inline allocation limit for new space. 5429 // Update inline allocation limit for new space.
5407 new_space()->UpdateInlineAllocationLimit(0); 5430 new_space()->UpdateInlineAllocationLimit(0);
5408 } 5431 }
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after
6522 static_cast<int>(object_sizes_last_time_[index])); 6545 static_cast<int>(object_sizes_last_time_[index]));
6523 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6546 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6524 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6547 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6525 6548
6526 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6549 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6527 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6550 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6528 ClearObjectStats(); 6551 ClearObjectStats();
6529 } 6552 }
6530 } 6553 }
6531 } // namespace v8::internal 6554 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/heap/incremental-marking.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698