| 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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 old_generation_size_at_last_gc_(0), | 128 old_generation_size_at_last_gc_(0), |
| 129 gcs_since_last_deopt_(0), | 129 gcs_since_last_deopt_(0), |
| 130 allocation_sites_scratchpad_length_(0), | 130 allocation_sites_scratchpad_length_(0), |
| 131 ring_buffer_full_(false), | 131 ring_buffer_full_(false), |
| 132 ring_buffer_end_(0), | 132 ring_buffer_end_(0), |
| 133 promotion_queue_(this), | 133 promotion_queue_(this), |
| 134 configured_(false), | 134 configured_(false), |
| 135 current_gc_flags_(Heap::kNoGCFlags), | 135 current_gc_flags_(Heap::kNoGCFlags), |
| 136 external_string_table_(this), | 136 external_string_table_(this), |
| 137 chunks_queued_for_free_(NULL), | 137 chunks_queued_for_free_(NULL), |
| 138 pending_unmap_job_semaphore_(0), | |
| 139 gc_callbacks_depth_(0), | 138 gc_callbacks_depth_(0), |
| 140 deserialization_complete_(false), | 139 deserialization_complete_(false), |
| 141 concurrent_sweeping_enabled_(false), | 140 concurrent_sweeping_enabled_(false), |
| 142 strong_roots_list_(NULL) { | 141 strong_roots_list_(NULL) { |
| 143 // Allow build-time customization of the max semispace size. Building | 142 // Allow build-time customization of the max semispace size. Building |
| 144 // V8 with snapshots and a non-default max semispace size is much | 143 // V8 with snapshots and a non-default max semispace size is much |
| 145 // easier if you can define it as part of the build environment. | 144 // easier if you can define it as part of the build environment. |
| 146 #if defined(V8_MAX_SEMISPACE_SIZE) | 145 #if defined(V8_MAX_SEMISPACE_SIZE) |
| 147 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 146 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
| 148 #endif | 147 #endif |
| (...skipping 6407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6556 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); | 6555 heap_->FinalizeExternalString(ExternalString::cast(new_space_strings_[i])); |
| 6557 } | 6556 } |
| 6558 new_space_strings_.Free(); | 6557 new_space_strings_.Free(); |
| 6559 for (int i = 0; i < old_space_strings_.length(); ++i) { | 6558 for (int i = 0; i < old_space_strings_.length(); ++i) { |
| 6560 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); | 6559 heap_->FinalizeExternalString(ExternalString::cast(old_space_strings_[i])); |
| 6561 } | 6560 } |
| 6562 old_space_strings_.Free(); | 6561 old_space_strings_.Free(); |
| 6563 } | 6562 } |
| 6564 | 6563 |
| 6565 | 6564 |
| 6566 class Heap::UnmapFreeMemoryTask : public v8::Task { | |
| 6567 public: | |
| 6568 UnmapFreeMemoryTask(Heap* heap, MemoryChunk* head) | |
| 6569 : heap_(heap), head_(head) {} | |
| 6570 virtual ~UnmapFreeMemoryTask() {} | |
| 6571 | |
| 6572 private: | |
| 6573 // v8::Task overrides. | |
| 6574 void Run() override { | |
| 6575 heap_->FreeQueuedChunks(head_); | |
| 6576 heap_->pending_unmap_job_semaphore_.Signal(); | |
| 6577 } | |
| 6578 | |
| 6579 Heap* heap_; | |
| 6580 MemoryChunk* head_; | |
| 6581 | |
| 6582 DISALLOW_COPY_AND_ASSIGN(UnmapFreeMemoryTask); | |
| 6583 }; | |
| 6584 | |
| 6585 | |
| 6586 void Heap::WaitUntilUnmappingOfFreeChunksCompleted() { | |
| 6587 // We start an unmap job after sweeping and after compaction. | |
| 6588 pending_unmap_job_semaphore_.Wait(); | |
| 6589 pending_unmap_job_semaphore_.Wait(); | |
| 6590 } | |
| 6591 | |
| 6592 | |
| 6593 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { | 6565 void Heap::QueueMemoryChunkForFree(MemoryChunk* chunk) { |
| 6594 chunk->set_next_chunk(chunks_queued_for_free_); | 6566 chunk->set_next_chunk(chunks_queued_for_free_); |
| 6595 chunks_queued_for_free_ = chunk; | 6567 chunks_queued_for_free_ = chunk; |
| 6596 } | 6568 } |
| 6597 | 6569 |
| 6598 | 6570 |
| 6599 void Heap::FilterStoreBufferEntriesOnAboutToBeFreedPages() { | 6571 void Heap::FilterStoreBufferEntriesOnAboutToBeFreedPages() { |
| 6600 if (chunks_queued_for_free_ == NULL) return; | 6572 if (chunks_queued_for_free_ == NULL) return; |
| 6601 MemoryChunk* next; | 6573 MemoryChunk* next; |
| 6602 MemoryChunk* chunk; | 6574 MemoryChunk* chunk; |
| 6603 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6575 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6604 next = chunk->next_chunk(); | 6576 next = chunk->next_chunk(); |
| 6605 chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED); | 6577 chunk->SetFlag(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6606 } | 6578 } |
| 6607 store_buffer()->Compact(); | 6579 isolate_->heap()->store_buffer()->Compact(); |
| 6608 store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6580 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6609 } | 6581 } |
| 6610 | 6582 |
| 6611 | 6583 |
| 6612 void Heap::FreeQueuedChunks() { | 6584 void Heap::FreeQueuedChunks() { |
| 6613 if (chunks_queued_for_free_ != NULL) { | 6585 MemoryChunk* next; |
| 6614 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 6586 MemoryChunk* chunk; |
| 6615 new UnmapFreeMemoryTask(this, chunks_queued_for_free_), | 6587 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6616 v8::Platform::kShortRunningTask); | 6588 next = chunk->next_chunk(); |
| 6617 chunks_queued_for_free_ = NULL; | 6589 isolate_->memory_allocator()->Free(chunk); |
| 6618 } else { | |
| 6619 // If we do not have anything to unmap, we just signal the semaphore | |
| 6620 // that we are done. | |
| 6621 pending_unmap_job_semaphore_.Signal(); | |
| 6622 } | 6590 } |
| 6591 chunks_queued_for_free_ = NULL; |
| 6623 } | 6592 } |
| 6624 | 6593 |
| 6625 | 6594 |
| 6626 void Heap::FreeQueuedChunks(MemoryChunk* list_head) { | |
| 6627 MemoryChunk* next; | |
| 6628 MemoryChunk* chunk; | |
| 6629 for (chunk = list_head; chunk != NULL; chunk = next) { | |
| 6630 next = chunk->next_chunk(); | |
| 6631 isolate_->memory_allocator()->Free(chunk); | |
| 6632 } | |
| 6633 } | |
| 6634 | |
| 6635 | |
| 6636 void Heap::RememberUnmappedPage(Address page, bool compacted) { | 6595 void Heap::RememberUnmappedPage(Address page, bool compacted) { |
| 6637 uintptr_t p = reinterpret_cast<uintptr_t>(page); | 6596 uintptr_t p = reinterpret_cast<uintptr_t>(page); |
| 6638 // Tag the page pointer to make it findable in the dump file. | 6597 // Tag the page pointer to make it findable in the dump file. |
| 6639 if (compacted) { | 6598 if (compacted) { |
| 6640 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. | 6599 p ^= 0xc1ead & (Page::kPageSize - 1); // Cleared. |
| 6641 } else { | 6600 } else { |
| 6642 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 6601 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
| 6643 } | 6602 } |
| 6644 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 6603 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
| 6645 reinterpret_cast<Address>(p); | 6604 reinterpret_cast<Address>(p); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6826 *object_type = "CODE_TYPE"; \ | 6785 *object_type = "CODE_TYPE"; \ |
| 6827 *object_sub_type = "CODE_AGE/" #name; \ | 6786 *object_sub_type = "CODE_AGE/" #name; \ |
| 6828 return true; | 6787 return true; |
| 6829 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6788 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
| 6830 #undef COMPARE_AND_RETURN_NAME | 6789 #undef COMPARE_AND_RETURN_NAME |
| 6831 } | 6790 } |
| 6832 return false; | 6791 return false; |
| 6833 } | 6792 } |
| 6834 } // namespace internal | 6793 } // namespace internal |
| 6835 } // namespace v8 | 6794 } // namespace v8 |
| OLD | NEW |