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), |
160 gc_callbacks_depth_(0), | 163 gc_callbacks_depth_(0), |
161 deserialization_complete_(false), | 164 deserialization_complete_(false), |
162 strong_roots_list_(NULL), | 165 strong_roots_list_(NULL), |
163 array_buffer_tracker_(NULL), | 166 array_buffer_tracker_(NULL), |
164 heap_iterator_depth_(0), | 167 heap_iterator_depth_(0), |
165 force_oom_(false) { | 168 force_oom_(false) { |
166 // Allow build-time customization of the max semispace size. Building | 169 // Allow build-time customization of the max semispace size. Building |
167 // V8 with snapshots and a non-default max semispace size is much | 170 // V8 with snapshots and a non-default max semispace size is much |
168 // easier if you can define it as part of the build environment. | 171 // easier if you can define it as part of the build environment. |
169 #if defined(V8_MAX_SEMISPACE_SIZE) | 172 #if defined(V8_MAX_SEMISPACE_SIZE) |
(...skipping 5265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5435 delete memory_reducer_; | 5438 delete memory_reducer_; |
5436 memory_reducer_ = nullptr; | 5439 memory_reducer_ = nullptr; |
5437 } | 5440 } |
5438 | 5441 |
5439 delete object_stats_; | 5442 delete object_stats_; |
5440 object_stats_ = nullptr; | 5443 object_stats_ = nullptr; |
5441 | 5444 |
5442 delete scavenge_job_; | 5445 delete scavenge_job_; |
5443 scavenge_job_ = nullptr; | 5446 scavenge_job_ = nullptr; |
5444 | 5447 |
| 5448 WaitUntilUnmappingOfFreeChunksCompleted(); |
| 5449 |
5445 delete array_buffer_tracker_; | 5450 delete array_buffer_tracker_; |
5446 array_buffer_tracker_ = nullptr; | 5451 array_buffer_tracker_ = nullptr; |
5447 | 5452 |
5448 isolate_->global_handles()->TearDown(); | 5453 isolate_->global_handles()->TearDown(); |
5449 | 5454 |
5450 external_string_table_.TearDown(); | 5455 external_string_table_.TearDown(); |
5451 | 5456 |
5452 delete tracer_; | 5457 delete tracer_; |
5453 tracer_ = nullptr; | 5458 tracer_ = nullptr; |
5454 | 5459 |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6240 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); | 6245 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); |
6241 } | 6246 } |
6242 new_space_strings_.Free(); | 6247 new_space_strings_.Free(); |
6243 for (int i = 0; i < old_space_strings_.length(); ++i) { | 6248 for (int i = 0; i < old_space_strings_.length(); ++i) { |
6244 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); | 6249 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); |
6245 } | 6250 } |
6246 old_space_strings_.Free(); | 6251 old_space_strings_.Free(); |
6247 } | 6252 } |
6248 | 6253 |
6249 | 6254 |
| 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 |
6250 void Heap::RememberUnmappedPage(Address page, bool compacted) { | 6324 void Heap::RememberUnmappedPage(Address page, bool compacted) { |
6251 uintptr_t p = reinterpret_cast<uintptr_t>(page); | 6325 uintptr_t p = reinterpret_cast<uintptr_t>(page); |
6252 // Tag the page pointer to make it findable in the dump file. | 6326 // Tag the page pointer to make it findable in the dump file. |
6253 if (compacted) { | 6327 if (compacted) { |
6254 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. | 6328 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. |
6255 } else { | 6329 } else { |
6256 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 6330 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
6257 } | 6331 } |
6258 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 6332 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
6259 reinterpret_cast<Address>(p); | 6333 reinterpret_cast<Address>(p); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6347 } | 6421 } |
6348 | 6422 |
6349 | 6423 |
6350 // static | 6424 // static |
6351 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6425 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6352 return StaticVisitorBase::GetVisitorId(map); | 6426 return StaticVisitorBase::GetVisitorId(map); |
6353 } | 6427 } |
6354 | 6428 |
6355 } // namespace internal | 6429 } // namespace internal |
6356 } // namespace v8 | 6430 } // namespace v8 |
OLD | NEW |