| 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 <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 } | 1312 } |
| 1313 | 1313 |
| 1314 bool PagedSpace::Expand() { | 1314 bool PagedSpace::Expand() { |
| 1315 const int size = AreaSize(); | 1315 const int size = AreaSize(); |
| 1316 | 1316 |
| 1317 if (!heap()->CanExpandOldGeneration(size)) return false; | 1317 if (!heap()->CanExpandOldGeneration(size)) return false; |
| 1318 | 1318 |
| 1319 Page* p = heap()->memory_allocator()->AllocatePage(size, this, executable()); | 1319 Page* p = heap()->memory_allocator()->AllocatePage(size, this, executable()); |
| 1320 if (p == nullptr) return false; | 1320 if (p == nullptr) return false; |
| 1321 | 1321 |
| 1322 AccountCommitted(static_cast<intptr_t>(p->size())); | 1322 AccountCommitted(p->size()); |
| 1323 | 1323 |
| 1324 // Pages created during bootstrapping may contain immortal immovable objects. | 1324 // Pages created during bootstrapping may contain immortal immovable objects. |
| 1325 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); | 1325 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); |
| 1326 | 1326 |
| 1327 DCHECK(Capacity() <= heap()->MaxOldGenerationSize()); | 1327 DCHECK(Capacity() <= heap()->MaxOldGenerationSize()); |
| 1328 | 1328 |
| 1329 p->InsertAfter(anchor_.prev_page()); | 1329 p->InsertAfter(anchor_.prev_page()); |
| 1330 | 1330 |
| 1331 return true; | 1331 return true; |
| 1332 } | 1332 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1419 if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { | 1419 if (Page::FromAllocationAreaAddress(allocation_info_.top()) == page) { |
| 1420 allocation_info_.Reset(nullptr, nullptr); | 1420 allocation_info_.Reset(nullptr, nullptr); |
| 1421 } | 1421 } |
| 1422 | 1422 |
| 1423 // If page is still in a list, unlink it from that list. | 1423 // If page is still in a list, unlink it from that list. |
| 1424 if (page->next_chunk() != NULL) { | 1424 if (page->next_chunk() != NULL) { |
| 1425 DCHECK(page->prev_chunk() != NULL); | 1425 DCHECK(page->prev_chunk() != NULL); |
| 1426 page->Unlink(); | 1426 page->Unlink(); |
| 1427 } | 1427 } |
| 1428 | 1428 |
| 1429 AccountUncommitted(static_cast<intptr_t>(page->size())); | 1429 AccountUncommitted(page->size()); |
| 1430 accounting_stats_.ShrinkSpace(page->area_size()); | 1430 accounting_stats_.ShrinkSpace(page->area_size()); |
| 1431 heap()->memory_allocator()->Free<MemoryAllocator::kPreFreeAndQueue>(page); | 1431 heap()->memory_allocator()->Free<MemoryAllocator::kPreFreeAndQueue>(page); |
| 1432 } | 1432 } |
| 1433 | 1433 |
| 1434 std::unique_ptr<ObjectIterator> PagedSpace::GetObjectIterator() { | 1434 std::unique_ptr<ObjectIterator> PagedSpace::GetObjectIterator() { |
| 1435 return std::unique_ptr<ObjectIterator>(new HeapObjectIterator(this)); | 1435 return std::unique_ptr<ObjectIterator>(new HeapObjectIterator(this)); |
| 1436 } | 1436 } |
| 1437 | 1437 |
| 1438 #ifdef DEBUG | 1438 #ifdef DEBUG |
| 1439 void PagedSpace::Print() {} | 1439 void PagedSpace::Print() {} |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 // commit/uncommit memory from new space. | 1549 // commit/uncommit memory from new space. |
| 1550 CHECK(false); | 1550 CHECK(false); |
| 1551 } | 1551 } |
| 1552 } | 1552 } |
| 1553 } | 1553 } |
| 1554 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); | 1554 DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
| 1555 } | 1555 } |
| 1556 | 1556 |
| 1557 | 1557 |
| 1558 void NewSpace::Shrink() { | 1558 void NewSpace::Shrink() { |
| 1559 int new_capacity = Max(InitialTotalCapacity(), 2 * SizeAsInt()); | 1559 int new_capacity = Max(InitialTotalCapacity(), 2 * static_cast<int>(Size())); |
| 1560 int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize); | 1560 int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize); |
| 1561 if (rounded_new_capacity < TotalCapacity() && | 1561 if (rounded_new_capacity < TotalCapacity() && |
| 1562 to_space_.ShrinkTo(rounded_new_capacity)) { | 1562 to_space_.ShrinkTo(rounded_new_capacity)) { |
| 1563 // Only shrink from-space if we managed to shrink to-space. | 1563 // Only shrink from-space if we managed to shrink to-space. |
| 1564 from_space_.Reset(); | 1564 from_space_.Reset(); |
| 1565 if (!from_space_.ShrinkTo(rounded_new_capacity)) { | 1565 if (!from_space_.ShrinkTo(rounded_new_capacity)) { |
| 1566 // If we managed to shrink to-space but couldn't shrink from | 1566 // If we managed to shrink to-space but couldn't shrink from |
| 1567 // space, attempt to grow to-space again. | 1567 // space, attempt to grow to-space again. |
| 1568 if (!to_space_.GrowTo(from_space_.current_capacity())) { | 1568 if (!to_space_.GrowTo(from_space_.current_capacity())) { |
| 1569 // We are in an inconsistent state because we could not | 1569 // We are in an inconsistent state because we could not |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 if (new_page == nullptr) { | 1980 if (new_page == nullptr) { |
| 1981 RewindPages(last_page, pages_added); | 1981 RewindPages(last_page, pages_added); |
| 1982 return false; | 1982 return false; |
| 1983 } | 1983 } |
| 1984 new_page->InsertAfter(last_page); | 1984 new_page->InsertAfter(last_page); |
| 1985 new_page->ClearLiveness(); | 1985 new_page->ClearLiveness(); |
| 1986 // Duplicate the flags that was set on the old page. | 1986 // Duplicate the flags that was set on the old page. |
| 1987 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); | 1987 new_page->SetFlags(last_page->GetFlags(), Page::kCopyOnFlipFlagsMask); |
| 1988 last_page = new_page; | 1988 last_page = new_page; |
| 1989 } | 1989 } |
| 1990 AccountCommitted(static_cast<intptr_t>(delta)); | 1990 AccountCommitted(delta); |
| 1991 current_capacity_ = new_capacity; | 1991 current_capacity_ = new_capacity; |
| 1992 return true; | 1992 return true; |
| 1993 } | 1993 } |
| 1994 | 1994 |
| 1995 void SemiSpace::RewindPages(Page* start, int num_pages) { | 1995 void SemiSpace::RewindPages(Page* start, int num_pages) { |
| 1996 Page* new_last_page = nullptr; | 1996 Page* new_last_page = nullptr; |
| 1997 Page* last_page = start; | 1997 Page* last_page = start; |
| 1998 while (num_pages > 0) { | 1998 while (num_pages > 0) { |
| 1999 DCHECK_NE(last_page, anchor()); | 1999 DCHECK_NE(last_page, anchor()); |
| 2000 new_last_page = last_page->prev_page(); | 2000 new_last_page = last_page->prev_page(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2017 Page* last_page; | 2017 Page* last_page; |
| 2018 while (delta_pages > 0) { | 2018 while (delta_pages > 0) { |
| 2019 last_page = anchor()->prev_page(); | 2019 last_page = anchor()->prev_page(); |
| 2020 new_last_page = last_page->prev_page(); | 2020 new_last_page = last_page->prev_page(); |
| 2021 new_last_page->set_next_page(anchor()); | 2021 new_last_page->set_next_page(anchor()); |
| 2022 anchor()->set_prev_page(new_last_page); | 2022 anchor()->set_prev_page(new_last_page); |
| 2023 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>( | 2023 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>( |
| 2024 last_page); | 2024 last_page); |
| 2025 delta_pages--; | 2025 delta_pages--; |
| 2026 } | 2026 } |
| 2027 AccountUncommitted(static_cast<intptr_t>(delta)); | 2027 AccountUncommitted(delta); |
| 2028 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); | 2028 heap()->memory_allocator()->unmapper()->FreeQueuedChunks(); |
| 2029 } | 2029 } |
| 2030 current_capacity_ = new_capacity; | 2030 current_capacity_ = new_capacity; |
| 2031 return true; | 2031 return true; |
| 2032 } | 2032 } |
| 2033 | 2033 |
| 2034 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { | 2034 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { |
| 2035 anchor_.set_owner(this); | 2035 anchor_.set_owner(this); |
| 2036 anchor_.prev_page()->set_next_page(&anchor_); | 2036 anchor_.prev_page()->set_next_page(&anchor_); |
| 2037 anchor_.next_page()->set_prev_page(&anchor_); | 2037 anchor_.next_page()->set_prev_page(&anchor_); |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3018 if (!heap()->CanExpandOldGeneration(object_size)) { | 3018 if (!heap()->CanExpandOldGeneration(object_size)) { |
| 3019 return AllocationResult::Retry(identity()); | 3019 return AllocationResult::Retry(identity()); |
| 3020 } | 3020 } |
| 3021 | 3021 |
| 3022 LargePage* page = heap()->memory_allocator()->AllocateLargePage( | 3022 LargePage* page = heap()->memory_allocator()->AllocateLargePage( |
| 3023 object_size, this, executable); | 3023 object_size, this, executable); |
| 3024 if (page == NULL) return AllocationResult::Retry(identity()); | 3024 if (page == NULL) return AllocationResult::Retry(identity()); |
| 3025 DCHECK(page->area_size() >= object_size); | 3025 DCHECK(page->area_size() >= object_size); |
| 3026 | 3026 |
| 3027 size_ += static_cast<int>(page->size()); | 3027 size_ += static_cast<int>(page->size()); |
| 3028 AccountCommitted(static_cast<intptr_t>(page->size())); | 3028 AccountCommitted(page->size()); |
| 3029 objects_size_ += object_size; | 3029 objects_size_ += object_size; |
| 3030 page_count_++; | 3030 page_count_++; |
| 3031 page->set_next_page(first_page_); | 3031 page->set_next_page(first_page_); |
| 3032 first_page_ = page; | 3032 first_page_ = page; |
| 3033 | 3033 |
| 3034 InsertChunkMapEntries(page); | 3034 InsertChunkMapEntries(page); |
| 3035 | 3035 |
| 3036 HeapObject* object = page->GetObject(); | 3036 HeapObject* object = page->GetObject(); |
| 3037 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), object_size); | 3037 MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), object_size); |
| 3038 | 3038 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3155 // Cut the chunk out from the chunk list. | 3155 // Cut the chunk out from the chunk list. |
| 3156 current = current->next_page(); | 3156 current = current->next_page(); |
| 3157 if (previous == NULL) { | 3157 if (previous == NULL) { |
| 3158 first_page_ = current; | 3158 first_page_ = current; |
| 3159 } else { | 3159 } else { |
| 3160 previous->set_next_page(current); | 3160 previous->set_next_page(current); |
| 3161 } | 3161 } |
| 3162 | 3162 |
| 3163 // Free the chunk. | 3163 // Free the chunk. |
| 3164 size_ -= static_cast<int>(page->size()); | 3164 size_ -= static_cast<int>(page->size()); |
| 3165 AccountUncommitted(static_cast<intptr_t>(page->size())); | 3165 AccountUncommitted(page->size()); |
| 3166 objects_size_ -= object->Size(); | 3166 objects_size_ -= object->Size(); |
| 3167 page_count_--; | 3167 page_count_--; |
| 3168 | 3168 |
| 3169 RemoveChunkMapEntries(page); | 3169 RemoveChunkMapEntries(page); |
| 3170 heap()->memory_allocator()->Free<MemoryAllocator::kPreFreeAndQueue>(page); | 3170 heap()->memory_allocator()->Free<MemoryAllocator::kPreFreeAndQueue>(page); |
| 3171 } | 3171 } |
| 3172 } | 3172 } |
| 3173 } | 3173 } |
| 3174 | 3174 |
| 3175 | 3175 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3281 object->ShortPrint(); | 3281 object->ShortPrint(); |
| 3282 PrintF("\n"); | 3282 PrintF("\n"); |
| 3283 } | 3283 } |
| 3284 printf(" --------------------------------------\n"); | 3284 printf(" --------------------------------------\n"); |
| 3285 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3285 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
| 3286 } | 3286 } |
| 3287 | 3287 |
| 3288 #endif // DEBUG | 3288 #endif // DEBUG |
| 3289 } // namespace internal | 3289 } // namespace internal |
| 3290 } // namespace v8 | 3290 } // namespace v8 |
| OLD | NEW |