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/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 old_generation_size_at_last_gc_(0), | 150 old_generation_size_at_last_gc_(0), |
151 gcs_since_last_deopt_(0), | 151 gcs_since_last_deopt_(0), |
152 global_pretenuring_feedback_(nullptr), | 152 global_pretenuring_feedback_(nullptr), |
153 ring_buffer_full_(false), | 153 ring_buffer_full_(false), |
154 ring_buffer_end_(0), | 154 ring_buffer_end_(0), |
155 promotion_queue_(this), | 155 promotion_queue_(this), |
156 configured_(false), | 156 configured_(false), |
157 current_gc_flags_(Heap::kNoGCFlags), | 157 current_gc_flags_(Heap::kNoGCFlags), |
158 current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags), | 158 current_gc_callback_flags_(GCCallbackFlags::kNoGCCallbackFlags), |
159 external_string_table_(this), | 159 external_string_table_(this), |
160 chunks_queued_for_free_(NULL), | |
161 concurrent_unmapping_tasks_active_(0), | |
162 pending_unmapping_tasks_semaphore_(0), | |
163 gc_callbacks_depth_(0), | 160 gc_callbacks_depth_(0), |
164 deserialization_complete_(false), | 161 deserialization_complete_(false), |
165 strong_roots_list_(NULL), | 162 strong_roots_list_(NULL), |
166 array_buffer_tracker_(NULL), | 163 array_buffer_tracker_(NULL), |
167 heap_iterator_depth_(0), | 164 heap_iterator_depth_(0), |
168 force_oom_(false) { | 165 force_oom_(false) { |
169 // Allow build-time customization of the max semispace size. Building | 166 // Allow build-time customization of the max semispace size. Building |
170 // V8 with snapshots and a non-default max semispace size is much | 167 // V8 with snapshots and a non-default max semispace size is much |
171 // easier if you can define it as part of the build environment. | 168 // easier if you can define it as part of the build environment. |
172 #if defined(V8_MAX_SEMISPACE_SIZE) | 169 #if defined(V8_MAX_SEMISPACE_SIZE) |
(...skipping 5265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5438 delete memory_reducer_; | 5435 delete memory_reducer_; |
5439 memory_reducer_ = nullptr; | 5436 memory_reducer_ = nullptr; |
5440 } | 5437 } |
5441 | 5438 |
5442 delete object_stats_; | 5439 delete object_stats_; |
5443 object_stats_ = nullptr; | 5440 object_stats_ = nullptr; |
5444 | 5441 |
5445 delete scavenge_job_; | 5442 delete scavenge_job_; |
5446 scavenge_job_ = nullptr; | 5443 scavenge_job_ = nullptr; |
5447 | 5444 |
5448 WaitUntilUnmappingOfFreeChunksCompleted(); | |
5449 | |
5450 delete array_buffer_tracker_; | 5445 delete array_buffer_tracker_; |
5451 array_buffer_tracker_ = nullptr; | 5446 array_buffer_tracker_ = nullptr; |
5452 | 5447 |
5453 isolate_->global_handles()->TearDown(); | 5448 isolate_->global_handles()->TearDown(); |
5454 | 5449 |
5455 external_string_table_.TearDown(); | 5450 external_string_table_.TearDown(); |
5456 | 5451 |
5457 delete tracer_; | 5452 delete tracer_; |
5458 tracer_ = nullptr; | 5453 tracer_ = nullptr; |
5459 | 5454 |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6245 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); | 6240 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); |
6246 } | 6241 } |
6247 new_space_strings_.Free(); | 6242 new_space_strings_.Free(); |
6248 for (int i = 0; i < old_space_strings_.length(); ++i) { | 6243 for (int i = 0; i < old_space_strings_.length(); ++i) { |
6249 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); | 6244 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); |
6250 } | 6245 } |
6251 old_space_strings_.Free(); | 6246 old_space_strings_.Free(); |
6252 } | 6247 } |
6253 | 6248 |
6254 | 6249 |
6255 class Heap::UnmapFreeMemoryTask : public v8::Task { | |
6256 public: | |
6257 UnmapFreeMemoryTask(Heap* heap, MemoryChunk* head) | |
6258 : heap_(heap), head_(head) {} | |
6259 virtual ~UnmapFreeMemoryTask() {} | |
6260 | |
6261 private: | |
6262 // v8::Task overrides. | |
6263 void Run() override { | |
6264 heap_->FreeQueuedChunks(head_); | |
6265 heap_->pending_unmapping_tasks_semaphore_.Signal(); | |
6266 } | |
6267 | |
6268 Heap* heap_; | |
6269 MemoryChunk* head_; | |
6270 | |
6271 DISALLOW_COPY_AND_ASSIGN(UnmapFreeMemoryTask); | |
6272 }; | |
6273 | |
6274 | |
6275 void Heap::WaitUntilUnmappingOfFreeChunksCompleted() { | |
6276 while (concurrent_unmapping_tasks_active_ > 0) { | |
6277 pending_unmapping_tasks_semaphore_.Wait(); | |
6278 concurrent_unmapping_tasks_active_--; | |
6279 } | |
6280 } | |
6281 | |
6282 | |
6283 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { | |
6284 // PreFree logically frees the memory chunk. However, the actual freeing | |
6285 // will happen on a separate thread sometime later. | |
6286 memory_allocator()->PreFreeMemory(chunk); | |
6287 | |
6288 // The chunks added to this queue will be freed by a concurrent thread. | |
6289 chunk->set_next_chunk(chunks_queued_for_free_); | |
6290 chunks_queued_for_free_ = chunk; | |
6291 } | |
6292 | |
6293 | |
6294 void Heap::FreeQueuedChunks() { | |
6295 if (chunks_queued_for_free_ != NULL) { | |
6296 if (FLAG_concurrent_sweeping) { | |
6297 V8::GetCurrentPlatform()->CallOnBackgroundThread( | |
6298 new UnmapFreeMemoryTask(this, chunks_queued_for_free_), | |
6299 v8::Platform::kShortRunningTask); | |
6300 } else { | |
6301 FreeQueuedChunks(chunks_queued_for_free_); | |
6302 pending_unmapping_tasks_semaphore_.Signal(); | |
6303 } | |
6304 chunks_queued_for_free_ = NULL; | |
6305 } else { | |
6306 // If we do not have anything to unmap, we just signal the semaphore | |
6307 // that we are done. | |
6308 pending_unmapping_tasks_semaphore_.Signal(); | |
6309 } | |
6310 concurrent_unmapping_tasks_active_++; | |
6311 } | |
6312 | |
6313 | |
6314 void Heap::FreeQueuedChunks(MemoryChunk* list_head) { | |
6315 MemoryChunk* next; | |
6316 MemoryChunk* chunk; | |
6317 for (chunk = list_head; chunk != NULL; chunk = next) { | |
6318 next = chunk->next_chunk(); | |
6319 memory_allocator()->PerformFreeMemory(chunk); | |
6320 } | |
6321 } | |
6322 | |
6323 | |
6324 void Heap::RememberUnmappedPage(Address page, bool compacted) { | 6250 void Heap::RememberUnmappedPage(Address page, bool compacted) { |
6325 uintptr_t p = reinterpret_cast<uintptr_t>(page); | 6251 uintptr_t p = reinterpret_cast<uintptr_t>(page); |
6326 // Tag the page pointer to make it findable in the dump file. | 6252 // Tag the page pointer to make it findable in the dump file. |
6327 if (compacted) { | 6253 if (compacted) { |
6328 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. | 6254 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. |
6329 } else { | 6255 } else { |
6330 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 6256 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
6331 } | 6257 } |
6332 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 6258 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
6333 reinterpret_cast<Address>(p); | 6259 reinterpret_cast<Address>(p); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6421 } | 6347 } |
6422 | 6348 |
6423 | 6349 |
6424 // static | 6350 // static |
6425 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6351 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6426 return StaticVisitorBase::GetVisitorId(map); | 6352 return StaticVisitorBase::GetVisitorId(map); |
6427 } | 6353 } |
6428 | 6354 |
6429 } // namespace internal | 6355 } // namespace internal |
6430 } // namespace v8 | 6356 } // namespace v8 |
OLD | NEW |