OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/spaces.h" | 5 #include "src/heap/spaces.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/full-codegen/full-codegen.h" | 9 #include "src/full-codegen/full-codegen.h" |
10 #include "src/heap/mark-compact.h" | 10 #include "src/heap/mark-compact.h" |
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 available_in_small_free_list_ = 0; | 722 available_in_small_free_list_ = 0; |
723 available_in_medium_free_list_ = 0; | 723 available_in_medium_free_list_ = 0; |
724 available_in_large_free_list_ = 0; | 724 available_in_large_free_list_ = 0; |
725 available_in_huge_free_list_ = 0; | 725 available_in_huge_free_list_ = 0; |
726 } | 726 } |
727 | 727 |
728 | 728 |
729 Page* MemoryAllocator::AllocatePage(intptr_t size, PagedSpace* owner, | 729 Page* MemoryAllocator::AllocatePage(intptr_t size, PagedSpace* owner, |
730 Executability executable) { | 730 Executability executable) { |
731 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); | 731 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); |
732 | |
733 if (chunk == NULL) return NULL; | 732 if (chunk == NULL) return NULL; |
734 | |
735 return Page::Initialize(isolate_->heap(), chunk, executable, owner); | 733 return Page::Initialize(isolate_->heap(), chunk, executable, owner); |
736 } | 734 } |
737 | 735 |
738 | 736 |
739 LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size, | 737 LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size, |
740 Space* owner, | 738 Space* owner, |
741 Executability executable) { | 739 Executability executable) { |
742 MemoryChunk* chunk = | 740 MemoryChunk* chunk = |
743 AllocateChunk(object_size, object_size, executable, owner); | 741 AllocateChunk(object_size, object_size, executable, owner); |
744 if (chunk == NULL) return NULL; | 742 if (chunk == NULL) return NULL; |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 PageIterator iterator(this); | 994 PageIterator iterator(this); |
997 while (iterator.has_next()) { | 995 while (iterator.has_next()) { |
998 heap()->isolate()->memory_allocator()->Free(iterator.next()); | 996 heap()->isolate()->memory_allocator()->Free(iterator.next()); |
999 } | 997 } |
1000 anchor_.set_next_page(&anchor_); | 998 anchor_.set_next_page(&anchor_); |
1001 anchor_.set_prev_page(&anchor_); | 999 anchor_.set_prev_page(&anchor_); |
1002 accounting_stats_.Clear(); | 1000 accounting_stats_.Clear(); |
1003 } | 1001 } |
1004 | 1002 |
1005 | 1003 |
| 1004 void PagedSpace::MergeCompactionSpace(CompactionSpace* other) { |
| 1005 // Unmerged fields: |
| 1006 // area_size_ |
| 1007 // allocation_info_ |
| 1008 // emergency_memory_ |
| 1009 // end_of_unswept_pages_ |
| 1010 // unswept_free_bytes_ |
| 1011 // anchor_ |
| 1012 |
| 1013 // It only makes sense to merge compatible spaces. |
| 1014 DCHECK(identity() == other->identity()); |
| 1015 |
| 1016 // Destroy the linear allocation space of {other}. This is needed to (a) not |
| 1017 // waste the memory and (b) keep the rest of the chunk in an iterable state |
| 1018 // (filler is needed). |
| 1019 int linear_size = static_cast<int>(other->limit() - other->top()); |
| 1020 other->Free(other->top(), linear_size); |
| 1021 |
| 1022 // Move over the free list. |
| 1023 free_list_.Concatenate(other->free_list()); |
| 1024 |
| 1025 // Update and clear accounting statistics. |
| 1026 accounting_stats_.Merge(other->accounting_stats_); |
| 1027 other->accounting_stats_.Clear(); |
| 1028 |
| 1029 // Move over pages. |
| 1030 PageIterator it(other); |
| 1031 Page* p = nullptr; |
| 1032 while (it.has_next()) { |
| 1033 p = it.next(); |
| 1034 p->Unlink(); |
| 1035 p->set_owner(this); |
| 1036 p->InsertAfter(anchor_.prev_page()); |
| 1037 } |
| 1038 } |
| 1039 |
| 1040 |
1006 size_t PagedSpace::CommittedPhysicalMemory() { | 1041 size_t PagedSpace::CommittedPhysicalMemory() { |
1007 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); | 1042 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); |
1008 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); | 1043 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
1009 size_t size = 0; | 1044 size_t size = 0; |
1010 PageIterator it(this); | 1045 PageIterator it(this); |
1011 while (it.has_next()) { | 1046 while (it.has_next()) { |
1012 size += it.next()->CommittedPhysicalMemory(); | 1047 size += it.next()->CommittedPhysicalMemory(); |
1013 } | 1048 } |
1014 return size; | 1049 return size; |
1015 } | 1050 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 if (!heap()->CanExpandOldGeneration(Page::kPageSize)) return false; | 1090 if (!heap()->CanExpandOldGeneration(Page::kPageSize)) return false; |
1056 | 1091 |
1057 return true; | 1092 return true; |
1058 } | 1093 } |
1059 | 1094 |
1060 | 1095 |
1061 bool PagedSpace::Expand() { | 1096 bool PagedSpace::Expand() { |
1062 if (!CanExpand()) return false; | 1097 if (!CanExpand()) return false; |
1063 | 1098 |
1064 intptr_t size = AreaSize(); | 1099 intptr_t size = AreaSize(); |
1065 | 1100 if (snapshotable() && !HasPages()) { |
1066 if (anchor_.next_page() == &anchor_) { | |
1067 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); | 1101 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); |
1068 } | 1102 } |
1069 | 1103 |
1070 Page* p = heap()->isolate()->memory_allocator()->AllocatePage(size, this, | 1104 Page* p = heap()->isolate()->memory_allocator()->AllocatePage(size, this, |
1071 executable()); | 1105 executable()); |
1072 if (p == NULL) return false; | 1106 if (p == NULL) return false; |
1073 | 1107 |
1074 // Pages created during bootstrapping may contain immortal immovable objects. | 1108 // Pages created during bootstrapping may contain immortal immovable objects. |
1075 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); | 1109 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); |
1076 | 1110 |
(...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2645 if (!heap()->always_allocate() && | 2679 if (!heap()->always_allocate() && |
2646 heap()->OldGenerationAllocationLimitReached()) { | 2680 heap()->OldGenerationAllocationLimitReached()) { |
2647 // If sweeper threads are active, wait for them at that point and steal | 2681 // If sweeper threads are active, wait for them at that point and steal |
2648 // elements form their free-lists. | 2682 // elements form their free-lists. |
2649 HeapObject* object = WaitForSweeperThreadsAndRetryAllocation(size_in_bytes); | 2683 HeapObject* object = WaitForSweeperThreadsAndRetryAllocation(size_in_bytes); |
2650 return object; | 2684 return object; |
2651 } | 2685 } |
2652 | 2686 |
2653 // Try to expand the space and allocate in the new next page. | 2687 // Try to expand the space and allocate in the new next page. |
2654 if (Expand()) { | 2688 if (Expand()) { |
2655 DCHECK(CountTotalPages() > 1 || size_in_bytes <= free_list_.available()); | 2689 DCHECK((CountTotalPages() > 1) || |
| 2690 (size_in_bytes <= free_list_.available())); |
2656 return free_list_.Allocate(size_in_bytes); | 2691 return free_list_.Allocate(size_in_bytes); |
2657 } | 2692 } |
2658 | 2693 |
2659 // If sweeper threads are active, wait for them at that point and steal | 2694 // If sweeper threads are active, wait for them at that point and steal |
2660 // elements form their free-lists. Allocation may still fail their which | 2695 // elements form their free-lists. Allocation may still fail their which |
2661 // would indicate that there is not enough memory for the given allocation. | 2696 // would indicate that there is not enough memory for the given allocation. |
2662 return WaitForSweeperThreadsAndRetryAllocation(size_in_bytes); | 2697 return WaitForSweeperThreadsAndRetryAllocation(size_in_bytes); |
2663 } | 2698 } |
2664 | 2699 |
2665 | 2700 |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3149 object->ShortPrint(); | 3184 object->ShortPrint(); |
3150 PrintF("\n"); | 3185 PrintF("\n"); |
3151 } | 3186 } |
3152 printf(" --------------------------------------\n"); | 3187 printf(" --------------------------------------\n"); |
3153 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3188 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3154 } | 3189 } |
3155 | 3190 |
3156 #endif // DEBUG | 3191 #endif // DEBUG |
3157 } // namespace internal | 3192 } // namespace internal |
3158 } // namespace v8 | 3193 } // namespace v8 |
OLD | NEW |