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/assembler-inl.h" | 9 #include "src/assembler-inl.h" |
10 #include "src/ast/context-slot-cache.h" | 10 #include "src/ast/context-slot-cache.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 code_range_size_(0), | 80 code_range_size_(0), |
81 // semispace_size_ should be a power of 2 and old_generation_size_ should | 81 // semispace_size_ should be a power of 2 and old_generation_size_ should |
82 // be a multiple of Page::kPageSize. | 82 // be a multiple of Page::kPageSize. |
83 max_semi_space_size_(8 * (kPointerSize / 4) * MB), | 83 max_semi_space_size_(8 * (kPointerSize / 4) * MB), |
84 initial_semispace_size_(MB), | 84 initial_semispace_size_(MB), |
85 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), | 85 max_old_generation_size_(700ul * (kPointerSize / 4) * MB), |
86 initial_max_old_generation_size_(max_old_generation_size_), | 86 initial_max_old_generation_size_(max_old_generation_size_), |
87 initial_old_generation_size_(max_old_generation_size_ / | 87 initial_old_generation_size_(max_old_generation_size_ / |
88 kInitalOldGenerationLimitFactor), | 88 kInitalOldGenerationLimitFactor), |
89 old_generation_size_configured_(false), | 89 old_generation_size_configured_(false), |
90 max_executable_size_(256ul * (kPointerSize / 4) * MB), | |
91 // Variables set based on semispace_size_ and old_generation_size_ in | 90 // Variables set based on semispace_size_ and old_generation_size_ in |
92 // ConfigureHeap. | 91 // ConfigureHeap. |
93 // Will be 4 * reserved_semispace_size_ to ensure that young | 92 // Will be 4 * reserved_semispace_size_ to ensure that young |
94 // generation can be aligned to its size. | 93 // generation can be aligned to its size. |
95 maximum_committed_(0), | 94 maximum_committed_(0), |
96 survived_since_last_expansion_(0), | 95 survived_since_last_expansion_(0), |
97 survived_last_scavenge_(0), | 96 survived_last_scavenge_(0), |
98 always_allocate_scope_count_(0), | 97 always_allocate_scope_count_(0), |
99 memory_pressure_level_(MemoryPressureLevel::kNone), | 98 memory_pressure_level_(MemoryPressureLevel::kNone), |
100 out_of_memory_callback_(nullptr), | 99 out_of_memory_callback_(nullptr), |
(...skipping 4960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5061 // output a flag to the snapshot. However at this point the serializer and | 5060 // output a flag to the snapshot. However at this point the serializer and |
5062 // deserializer are deliberately a little unsynchronized (see above) so the | 5061 // deserializer are deliberately a little unsynchronized (see above) so the |
5063 // checking of the sync flag in the snapshot would fail. | 5062 // checking of the sync flag in the snapshot would fail. |
5064 } | 5063 } |
5065 | 5064 |
5066 | 5065 |
5067 // TODO(1236194): Since the heap size is configurable on the command line | 5066 // TODO(1236194): Since the heap size is configurable on the command line |
5068 // and through the API, we should gracefully handle the case that the heap | 5067 // and through the API, we should gracefully handle the case that the heap |
5069 // size is not big enough to fit all the initial objects. | 5068 // size is not big enough to fit all the initial objects. |
5070 bool Heap::ConfigureHeap(size_t max_semi_space_size, size_t max_old_space_size, | 5069 bool Heap::ConfigureHeap(size_t max_semi_space_size, size_t max_old_space_size, |
5071 size_t max_executable_size, size_t code_range_size) { | 5070 size_t code_range_size) { |
5072 if (HasBeenSetUp()) return false; | 5071 if (HasBeenSetUp()) return false; |
5073 | 5072 |
5074 // Overwrite default configuration. | 5073 // Overwrite default configuration. |
5075 if (max_semi_space_size != 0) { | 5074 if (max_semi_space_size != 0) { |
5076 max_semi_space_size_ = max_semi_space_size * MB; | 5075 max_semi_space_size_ = max_semi_space_size * MB; |
5077 } | 5076 } |
5078 if (max_old_space_size != 0) { | 5077 if (max_old_space_size != 0) { |
5079 max_old_generation_size_ = max_old_space_size * MB; | 5078 max_old_generation_size_ = max_old_space_size * MB; |
5080 } | 5079 } |
5081 if (max_executable_size != 0) { | |
5082 max_executable_size_ = max_executable_size * MB; | |
5083 } | |
5084 | 5080 |
5085 // If max space size flags are specified overwrite the configuration. | 5081 // If max space size flags are specified overwrite the configuration. |
5086 if (FLAG_max_semi_space_size > 0) { | 5082 if (FLAG_max_semi_space_size > 0) { |
5087 max_semi_space_size_ = static_cast<size_t>(FLAG_max_semi_space_size) * MB; | 5083 max_semi_space_size_ = static_cast<size_t>(FLAG_max_semi_space_size) * MB; |
5088 } | 5084 } |
5089 if (FLAG_max_old_space_size > 0) { | 5085 if (FLAG_max_old_space_size > 0) { |
5090 max_old_generation_size_ = | 5086 max_old_generation_size_ = |
5091 static_cast<size_t>(FLAG_max_old_space_size) * MB; | 5087 static_cast<size_t>(FLAG_max_old_space_size) * MB; |
5092 } | 5088 } |
5093 if (FLAG_max_executable_size > 0) { | |
5094 max_executable_size_ = static_cast<size_t>(FLAG_max_executable_size) * MB; | |
5095 } | |
5096 | 5089 |
5097 if (Page::kPageSize > MB) { | 5090 if (Page::kPageSize > MB) { |
5098 max_semi_space_size_ = ROUND_UP(max_semi_space_size_, Page::kPageSize); | 5091 max_semi_space_size_ = ROUND_UP(max_semi_space_size_, Page::kPageSize); |
5099 max_old_generation_size_ = | 5092 max_old_generation_size_ = |
5100 ROUND_UP(max_old_generation_size_, Page::kPageSize); | 5093 ROUND_UP(max_old_generation_size_, Page::kPageSize); |
5101 max_executable_size_ = ROUND_UP(max_executable_size_, Page::kPageSize); | |
5102 } | 5094 } |
5103 | 5095 |
5104 if (FLAG_stress_compaction) { | 5096 if (FLAG_stress_compaction) { |
5105 // This will cause more frequent GCs when stressing. | 5097 // This will cause more frequent GCs when stressing. |
5106 max_semi_space_size_ = MB; | 5098 max_semi_space_size_ = MB; |
5107 } | 5099 } |
5108 | 5100 |
5109 // The new space size must be a power of two to support single-bit testing | 5101 // The new space size must be a power of two to support single-bit testing |
5110 // for containment. | 5102 // for containment. |
5111 max_semi_space_size_ = base::bits::RoundUpToPowerOfTwo32( | 5103 max_semi_space_size_ = base::bits::RoundUpToPowerOfTwo32( |
(...skipping 21 matching lines...) Expand all Loading... |
5133 if (FLAG_semi_space_growth_factor < 2) { | 5125 if (FLAG_semi_space_growth_factor < 2) { |
5134 FLAG_semi_space_growth_factor = 2; | 5126 FLAG_semi_space_growth_factor = 2; |
5135 } | 5127 } |
5136 | 5128 |
5137 // The old generation is paged and needs at least one page for each space. | 5129 // The old generation is paged and needs at least one page for each space. |
5138 int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; | 5130 int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1; |
5139 initial_max_old_generation_size_ = max_old_generation_size_ = | 5131 initial_max_old_generation_size_ = max_old_generation_size_ = |
5140 Max(static_cast<size_t>(paged_space_count * Page::kPageSize), | 5132 Max(static_cast<size_t>(paged_space_count * Page::kPageSize), |
5141 max_old_generation_size_); | 5133 max_old_generation_size_); |
5142 | 5134 |
5143 // The max executable size must be less than or equal to the max old | |
5144 // generation size. | |
5145 if (max_executable_size_ > max_old_generation_size_) { | |
5146 max_executable_size_ = max_old_generation_size_; | |
5147 } | |
5148 | |
5149 if (FLAG_initial_old_space_size > 0) { | 5135 if (FLAG_initial_old_space_size > 0) { |
5150 initial_old_generation_size_ = FLAG_initial_old_space_size * MB; | 5136 initial_old_generation_size_ = FLAG_initial_old_space_size * MB; |
5151 } else { | 5137 } else { |
5152 initial_old_generation_size_ = | 5138 initial_old_generation_size_ = |
5153 max_old_generation_size_ / kInitalOldGenerationLimitFactor; | 5139 max_old_generation_size_ / kInitalOldGenerationLimitFactor; |
5154 } | 5140 } |
5155 old_generation_allocation_limit_ = initial_old_generation_size_; | 5141 old_generation_allocation_limit_ = initial_old_generation_size_; |
5156 | 5142 |
5157 // We rely on being able to allocate new arrays in paged spaces. | 5143 // We rely on being able to allocate new arrays in paged spaces. |
5158 DCHECK(kMaxRegularHeapObjectSize >= | 5144 DCHECK(kMaxRegularHeapObjectSize >= |
(...skipping 24 matching lines...) Expand all Loading... |
5183 | 5169 |
5184 void Heap::GetFromRingBuffer(char* buffer) { | 5170 void Heap::GetFromRingBuffer(char* buffer) { |
5185 size_t copied = 0; | 5171 size_t copied = 0; |
5186 if (ring_buffer_full_) { | 5172 if (ring_buffer_full_) { |
5187 copied = kTraceRingBufferSize - ring_buffer_end_; | 5173 copied = kTraceRingBufferSize - ring_buffer_end_; |
5188 memcpy(buffer, trace_ring_buffer_ + ring_buffer_end_, copied); | 5174 memcpy(buffer, trace_ring_buffer_ + ring_buffer_end_, copied); |
5189 } | 5175 } |
5190 memcpy(buffer + copied, trace_ring_buffer_, ring_buffer_end_); | 5176 memcpy(buffer + copied, trace_ring_buffer_, ring_buffer_end_); |
5191 } | 5177 } |
5192 | 5178 |
5193 | 5179 bool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0); } |
5194 bool Heap::ConfigureHeapDefault() { return ConfigureHeap(0, 0, 0, 0); } | |
5195 | |
5196 | 5180 |
5197 void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { | 5181 void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { |
5198 *stats->start_marker = HeapStats::kStartMarker; | 5182 *stats->start_marker = HeapStats::kStartMarker; |
5199 *stats->end_marker = HeapStats::kEndMarker; | 5183 *stats->end_marker = HeapStats::kEndMarker; |
5200 *stats->new_space_size = new_space_->Size(); | 5184 *stats->new_space_size = new_space_->Size(); |
5201 *stats->new_space_capacity = new_space_->Capacity(); | 5185 *stats->new_space_capacity = new_space_->Capacity(); |
5202 *stats->old_space_size = old_space_->SizeOfObjects(); | 5186 *stats->old_space_size = old_space_->SizeOfObjects(); |
5203 *stats->old_space_capacity = old_space_->Capacity(); | 5187 *stats->old_space_capacity = old_space_->Capacity(); |
5204 *stats->code_space_size = code_space_->SizeOfObjects(); | 5188 *stats->code_space_size = code_space_->SizeOfObjects(); |
5205 *stats->code_space_capacity = code_space_->Capacity(); | 5189 *stats->code_space_capacity = code_space_->Capacity(); |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5504 // size) and old-space-size if set or the initial values of semispace_size_ | 5488 // size) and old-space-size if set or the initial values of semispace_size_ |
5505 // and old_generation_size_ otherwise. | 5489 // and old_generation_size_ otherwise. |
5506 if (!configured_) { | 5490 if (!configured_) { |
5507 if (!ConfigureHeapDefault()) return false; | 5491 if (!ConfigureHeapDefault()) return false; |
5508 } | 5492 } |
5509 | 5493 |
5510 base::CallOnce(&initialize_gc_once, &InitializeGCOnce); | 5494 base::CallOnce(&initialize_gc_once, &InitializeGCOnce); |
5511 | 5495 |
5512 // Set up memory allocator. | 5496 // Set up memory allocator. |
5513 memory_allocator_ = new MemoryAllocator(isolate_); | 5497 memory_allocator_ = new MemoryAllocator(isolate_); |
5514 if (!memory_allocator_->SetUp(MaxReserved(), MaxExecutableSize(), | 5498 if (!memory_allocator_->SetUp(MaxReserved(), code_range_size_)) return false; |
5515 code_range_size_)) | |
5516 return false; | |
5517 | 5499 |
5518 store_buffer_ = new StoreBuffer(this); | 5500 store_buffer_ = new StoreBuffer(this); |
5519 | 5501 |
5520 incremental_marking_ = new IncrementalMarking(this); | 5502 incremental_marking_ = new IncrementalMarking(this); |
5521 | 5503 |
5522 concurrent_marking_ = new ConcurrentMarking(this); | 5504 concurrent_marking_ = new ConcurrentMarking(this); |
5523 | 5505 |
5524 for (int i = 0; i <= LAST_SPACE; i++) { | 5506 for (int i = 0; i <= LAST_SPACE; i++) { |
5525 space_[i] = nullptr; | 5507 space_[i] = nullptr; |
5526 } | 5508 } |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6439 case LO_SPACE: | 6421 case LO_SPACE: |
6440 return "LO_SPACE"; | 6422 return "LO_SPACE"; |
6441 default: | 6423 default: |
6442 UNREACHABLE(); | 6424 UNREACHABLE(); |
6443 } | 6425 } |
6444 return NULL; | 6426 return NULL; |
6445 } | 6427 } |
6446 | 6428 |
6447 } // namespace internal | 6429 } // namespace internal |
6448 } // namespace v8 | 6430 } // namespace v8 |
OLD | NEW |