OLD | NEW |
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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 allocations_count_(0), | 105 allocations_count_(0), |
106 raw_allocations_hash_(0), | 106 raw_allocations_hash_(0), |
107 ms_count_(0), | 107 ms_count_(0), |
108 gc_count_(0), | 108 gc_count_(0), |
109 remembered_unmapped_pages_index_(0), | 109 remembered_unmapped_pages_index_(0), |
110 #ifdef DEBUG | 110 #ifdef DEBUG |
111 allocation_timeout_(0), | 111 allocation_timeout_(0), |
112 #endif // DEBUG | 112 #endif // DEBUG |
113 old_generation_allocation_limit_(initial_old_generation_size_), | 113 old_generation_allocation_limit_(initial_old_generation_size_), |
114 old_gen_exhausted_(false), | 114 old_gen_exhausted_(false), |
115 optimize_for_memory_usage_(false), | |
116 inline_allocation_disabled_(false), | 115 inline_allocation_disabled_(false), |
117 total_regexp_code_generated_(0), | 116 total_regexp_code_generated_(0), |
118 tracer_(nullptr), | 117 tracer_(nullptr), |
119 high_survival_rate_period_length_(0), | 118 high_survival_rate_period_length_(0), |
120 promoted_objects_size_(0), | 119 promoted_objects_size_(0), |
121 promotion_ratio_(0), | 120 promotion_ratio_(0), |
122 semi_space_copied_object_size_(0), | 121 semi_space_copied_object_size_(0), |
123 previous_semi_space_copied_object_size_(0), | 122 previous_semi_space_copied_object_size_(0), |
124 semi_space_copied_rate_(0), | 123 semi_space_copied_rate_(0), |
125 nodes_died_in_new_space_(0), | 124 nodes_died_in_new_space_(0), |
(...skipping 3976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4102 } | 4101 } |
4103 | 4102 |
4104 | 4103 |
4105 bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) { | 4104 bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) { |
4106 const intptr_t kSlack = 16 * MB; | 4105 const intptr_t kSlack = 16 * MB; |
4107 // Fragmentation is high if committed > 2 * used + kSlack. | 4106 // Fragmentation is high if committed > 2 * used + kSlack. |
4108 // Rewrite the exression to avoid overflow. | 4107 // Rewrite the exression to avoid overflow. |
4109 return committed - used > used + kSlack; | 4108 return committed - used > used + kSlack; |
4110 } | 4109 } |
4111 | 4110 |
4112 void Heap::SetOptimizeForMemoryUsage() { | 4111 bool Heap::ShouldOptimizeForMemoryUsage() { |
| 4112 return FLAG_optimize_for_size || isolate()->IsIsolateInBackground() || |
| 4113 HighMemoryPressure() || IsLowMemoryDevice(); |
| 4114 } |
| 4115 |
| 4116 void Heap::ActivateMemoryReducerIfNeeded() { |
4113 // Activate memory reducer when switching to background if | 4117 // Activate memory reducer when switching to background if |
4114 // - there was no mark compact since the start. | 4118 // - there was no mark compact since the start. |
4115 // - the committed memory can be potentially reduced. | 4119 // - the committed memory can be potentially reduced. |
4116 // 2 pages for the old, code, and map space + 1 page for new space. | 4120 // 2 pages for the old, code, and map space + 1 page for new space. |
4117 const int kMinCommittedMemory = 7 * Page::kPageSize; | 4121 const int kMinCommittedMemory = 7 * Page::kPageSize; |
4118 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory) { | 4122 if (ms_count_ == 0 && CommittedMemory() > kMinCommittedMemory && |
| 4123 isolate()->IsIsolateInBackground()) { |
4119 MemoryReducer::Event event; | 4124 MemoryReducer::Event event; |
4120 event.type = MemoryReducer::kPossibleGarbage; | 4125 event.type = MemoryReducer::kPossibleGarbage; |
4121 event.time_ms = MonotonicallyIncreasingTimeInMs(); | 4126 event.time_ms = MonotonicallyIncreasingTimeInMs(); |
4122 memory_reducer_->NotifyPossibleGarbage(event); | 4127 memory_reducer_->NotifyPossibleGarbage(event); |
4123 } | 4128 } |
4124 optimize_for_memory_usage_ = true; | |
4125 } | 4129 } |
4126 | 4130 |
4127 void Heap::ReduceNewSpaceSize() { | 4131 void Heap::ReduceNewSpaceSize() { |
4128 // TODO(ulan): Unify this constant with the similar constant in | 4132 // TODO(ulan): Unify this constant with the similar constant in |
4129 // GCIdleTimeHandler once the change is merged to 4.5. | 4133 // GCIdleTimeHandler once the change is merged to 4.5. |
4130 static const size_t kLowAllocationThroughput = 1000; | 4134 static const size_t kLowAllocationThroughput = 1000; |
4131 const double allocation_throughput = | 4135 const double allocation_throughput = |
4132 tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); | 4136 tracer()->CurrentAllocationThroughputInBytesPerMillisecond(); |
4133 | 4137 |
4134 if (FLAG_predictable) return; | 4138 if (FLAG_predictable) return; |
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5074 int64_t Heap::PromotedExternalMemorySize() { | 5078 int64_t Heap::PromotedExternalMemorySize() { |
5075 if (external_memory_ <= external_memory_at_last_mark_compact_) return 0; | 5079 if (external_memory_ <= external_memory_at_last_mark_compact_) return 0; |
5076 return external_memory_ - external_memory_at_last_mark_compact_; | 5080 return external_memory_ - external_memory_at_last_mark_compact_; |
5077 } | 5081 } |
5078 | 5082 |
5079 | 5083 |
5080 const double Heap::kMinHeapGrowingFactor = 1.1; | 5084 const double Heap::kMinHeapGrowingFactor = 1.1; |
5081 const double Heap::kMaxHeapGrowingFactor = 4.0; | 5085 const double Heap::kMaxHeapGrowingFactor = 4.0; |
5082 const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0; | 5086 const double Heap::kMaxHeapGrowingFactorMemoryConstrained = 2.0; |
5083 const double Heap::kMaxHeapGrowingFactorIdle = 1.5; | 5087 const double Heap::kMaxHeapGrowingFactorIdle = 1.5; |
| 5088 const double Heap::kConservativeHeapGrowingFactor = 1.3; |
5084 const double Heap::kTargetMutatorUtilization = 0.97; | 5089 const double Heap::kTargetMutatorUtilization = 0.97; |
5085 | 5090 |
5086 | 5091 |
5087 // Given GC speed in bytes per ms, the allocation throughput in bytes per ms | 5092 // Given GC speed in bytes per ms, the allocation throughput in bytes per ms |
5088 // (mutator speed), this function returns the heap growing factor that will | 5093 // (mutator speed), this function returns the heap growing factor that will |
5089 // achieve the kTargetMutatorUtilisation if the GC speed and the mutator speed | 5094 // achieve the kTargetMutatorUtilisation if the GC speed and the mutator speed |
5090 // remain the same until the next GC. | 5095 // remain the same until the next GC. |
5091 // | 5096 // |
5092 // For a fixed time-frame T = TM + TG, the mutator utilization is the ratio | 5097 // For a fixed time-frame T = TM + TG, the mutator utilization is the ratio |
5093 // TM / (TM + TG), where TM is the time spent in the mutator and TG is the | 5098 // TM / (TM + TG), where TM is the time spent in the mutator and TG is the |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5149 limit = Max(limit, old_gen_size + kMinimumOldGenerationAllocationLimit); | 5154 limit = Max(limit, old_gen_size + kMinimumOldGenerationAllocationLimit); |
5150 limit += new_space_.Capacity(); | 5155 limit += new_space_.Capacity(); |
5151 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; | 5156 intptr_t halfway_to_the_max = (old_gen_size + max_old_generation_size_) / 2; |
5152 return Min(limit, halfway_to_the_max); | 5157 return Min(limit, halfway_to_the_max); |
5153 } | 5158 } |
5154 | 5159 |
5155 | 5160 |
5156 void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size, | 5161 void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size, |
5157 double gc_speed, | 5162 double gc_speed, |
5158 double mutator_speed) { | 5163 double mutator_speed) { |
5159 const double kConservativeHeapGrowingFactor = 1.3; | |
5160 | |
5161 double factor = HeapGrowingFactor(gc_speed, mutator_speed); | 5164 double factor = HeapGrowingFactor(gc_speed, mutator_speed); |
5162 | 5165 |
5163 if (FLAG_trace_gc_verbose) { | 5166 if (FLAG_trace_gc_verbose) { |
5164 PrintIsolate(isolate_, | 5167 PrintIsolate(isolate_, |
5165 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f " | 5168 "Heap growing factor %.1f based on mu=%.3f, speed_ratio=%.f " |
5166 "(gc=%.f, mutator=%.f)\n", | 5169 "(gc=%.f, mutator=%.f)\n", |
5167 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, | 5170 factor, kTargetMutatorUtilization, gc_speed / mutator_speed, |
5168 gc_speed, mutator_speed); | 5171 gc_speed, mutator_speed); |
5169 } | 5172 } |
5170 | 5173 |
5171 // We set the old generation growing factor to 2 to grow the heap slower on | 5174 if (IsMemoryConstrainedDevice()) { |
5172 // memory-constrained devices. | |
5173 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice || | |
5174 FLAG_optimize_for_size) { | |
5175 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); | 5175 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); |
5176 } | 5176 } |
5177 | 5177 |
5178 if (memory_reducer_->ShouldGrowHeapSlowly() || optimize_for_memory_usage_) { | 5178 if (memory_reducer_->ShouldGrowHeapSlowly() || |
| 5179 ShouldOptimizeForMemoryUsage()) { |
5179 factor = Min(factor, kConservativeHeapGrowingFactor); | 5180 factor = Min(factor, kConservativeHeapGrowingFactor); |
5180 } | 5181 } |
5181 | 5182 |
5182 if (FLAG_stress_compaction || ShouldReduceMemory()) { | 5183 if (FLAG_stress_compaction || ShouldReduceMemory()) { |
5183 factor = kMinHeapGrowingFactor; | 5184 factor = kMinHeapGrowingFactor; |
5184 } | 5185 } |
5185 | 5186 |
5186 if (FLAG_heap_growing_percent > 0) { | 5187 if (FLAG_heap_growing_percent > 0) { |
5187 factor = 1.0 + FLAG_heap_growing_percent / 100.0; | 5188 factor = 1.0 + FLAG_heap_growing_percent / 100.0; |
5188 } | 5189 } |
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6460 } | 6461 } |
6461 | 6462 |
6462 | 6463 |
6463 // static | 6464 // static |
6464 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6465 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6465 return StaticVisitorBase::GetVisitorId(map); | 6466 return StaticVisitorBase::GetVisitorId(map); |
6466 } | 6467 } |
6467 | 6468 |
6468 } // namespace internal | 6469 } // namespace internal |
6469 } // namespace v8 | 6470 } // namespace v8 |
OLD | NEW |