Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/heap/spaces.cc

Issue 2209583002: [heap] Remove border page (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Allow empty intermediate generation Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/spaces.h ('k') | src/heap/spaces-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 } 1477 }
1478 CHECK(allocation_pointer_found_in_space); 1478 CHECK(allocation_pointer_found_in_space);
1479 } 1479 }
1480 #endif // VERIFY_HEAP 1480 #endif // VERIFY_HEAP
1481 1481
1482 // ----------------------------------------------------------------------------- 1482 // -----------------------------------------------------------------------------
1483 // NewSpace implementation 1483 // NewSpace implementation
1484 1484
1485 bool NewSpace::SetUp(int initial_semispace_capacity, 1485 bool NewSpace::SetUp(int initial_semispace_capacity,
1486 int maximum_semispace_capacity) { 1486 int maximum_semispace_capacity) {
1487 DCHECK(initial_semispace_capacity <= maximum_semispace_capacity); 1487 DCHECK_LE(initial_semispace_capacity, maximum_semispace_capacity);
1488 DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity)); 1488 DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity));
1489 DCHECK_GE(initial_semispace_capacity, 2 * Page::kPageSize);
1489 1490
1490 to_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity); 1491 to_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity);
1491 from_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity); 1492 from_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity);
1492 if (!to_space_.Commit()) { 1493 if (!to_space_.Commit()) {
1493 return false; 1494 return false;
1494 } 1495 }
1495 DCHECK(!from_space_.is_committed()); // No need to use memory yet. 1496 DCHECK(!from_space_.is_committed()); // No need to use memory yet.
1496 ResetAllocationInfo(); 1497 ResetAllocationInfo();
1497 1498
1498 // Allocate and set up the histogram arrays if necessary. 1499 // Allocate and set up the histogram arrays if necessary.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 bool SemiSpace::EnsureCurrentCapacity() { 1580 bool SemiSpace::EnsureCurrentCapacity() {
1580 if (is_committed()) { 1581 if (is_committed()) {
1581 const int expected_pages = current_capacity_ / Page::kPageSize; 1582 const int expected_pages = current_capacity_ / Page::kPageSize;
1582 int actual_pages = 0; 1583 int actual_pages = 0;
1583 Page* current_page = anchor()->next_page(); 1584 Page* current_page = anchor()->next_page();
1584 while (current_page != anchor()) { 1585 while (current_page != anchor()) {
1585 actual_pages++; 1586 actual_pages++;
1586 current_page = current_page->next_page(); 1587 current_page = current_page->next_page();
1587 if (actual_pages > expected_pages) { 1588 if (actual_pages > expected_pages) {
1588 Page* to_remove = current_page->prev_page(); 1589 Page* to_remove = current_page->prev_page();
1589 // Make sure we don't overtake the actual top pointer. 1590 if (to_remove == current_page_) {
1590 CHECK_NE(to_remove, current_page_); 1591 // Corner case: All pages have been moved within new space. We are
1592 // removing the page that contains the top pointer and need to set
1593 // it to the end of the intermediate generation.
1594 NewSpace* new_space = heap()->new_space();
1595 CHECK_EQ(new_space->top(), current_page_->area_start());
1596 current_page_ = to_remove->prev_page();
1597 CHECK(current_page_->InIntermediateGeneration());
1598 new_space->SetAllocationInfo(page_high(), page_high());
1599 }
1591 to_remove->Unlink(); 1600 to_remove->Unlink();
1592 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>( 1601 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>(
1593 to_remove); 1602 to_remove);
1594 } 1603 }
1595 } 1604 }
1596 while (actual_pages < expected_pages) { 1605 while (actual_pages < expected_pages) {
1597 actual_pages++; 1606 actual_pages++;
1598 current_page = 1607 current_page =
1599 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( 1608 heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>(
1600 Page::kAllocatableMemory, this, executable()); 1609 Page::kAllocatableMemory, this, executable());
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 Page::kAllocatableMemory, this, executable()); 1915 Page::kAllocatableMemory, this, executable());
1907 if (new_page == nullptr) { 1916 if (new_page == nullptr) {
1908 RewindPages(current, pages_added); 1917 RewindPages(current, pages_added);
1909 return false; 1918 return false;
1910 } 1919 }
1911 new_page->InsertAfter(current); 1920 new_page->InsertAfter(current);
1912 current = new_page; 1921 current = new_page;
1913 } 1922 }
1914 Reset(); 1923 Reset();
1915 AccountCommitted(current_capacity_); 1924 AccountCommitted(current_capacity_);
1916 if (age_mark_ == nullptr) {
1917 age_mark_ = first_page()->area_start();
1918 }
1919 committed_ = true; 1925 committed_ = true;
1920 return true; 1926 return true;
1921 } 1927 }
1922 1928
1923 1929
1924 bool SemiSpace::Uncommit() { 1930 bool SemiSpace::Uncommit() {
1925 DCHECK(is_committed()); 1931 DCHECK(is_committed());
1926 for (auto it = begin(); it != end();) { 1932 for (auto it = begin(); it != end();) {
1927 Page* p = *(it++); 1933 Page* p = *(it++);
1928 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>(p); 1934 heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>(p);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 anchor_.set_owner(this); 2026 anchor_.set_owner(this);
2021 anchor_.prev_page()->set_next_page(&anchor_); 2027 anchor_.prev_page()->set_next_page(&anchor_);
2022 anchor_.next_page()->set_prev_page(&anchor_); 2028 anchor_.next_page()->set_prev_page(&anchor_);
2023 2029
2024 for (Page* page : *this) { 2030 for (Page* page : *this) {
2025 page->set_owner(this); 2031 page->set_owner(this);
2026 page->SetFlags(flags, mask); 2032 page->SetFlags(flags, mask);
2027 if (id_ == kToSpace) { 2033 if (id_ == kToSpace) {
2028 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); 2034 page->ClearFlag(MemoryChunk::IN_FROM_SPACE);
2029 page->SetFlag(MemoryChunk::IN_TO_SPACE); 2035 page->SetFlag(MemoryChunk::IN_TO_SPACE);
2030 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 2036 page->ClearFlag(MemoryChunk::IN_INTERMEDIATE_GENERATION);
2031 page->ResetLiveBytes(); 2037 page->ResetLiveBytes();
2032 } else { 2038 } else {
2033 page->SetFlag(MemoryChunk::IN_FROM_SPACE); 2039 page->SetFlag(MemoryChunk::IN_FROM_SPACE);
2034 page->ClearFlag(MemoryChunk::IN_TO_SPACE); 2040 page->ClearFlag(MemoryChunk::IN_TO_SPACE);
2035 } 2041 }
2036 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || 2042 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) ||
2037 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); 2043 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE));
2038 } 2044 }
2039 } 2045 }
2040 2046
(...skipping 22 matching lines...) Expand all
2063 // We won't be swapping semispaces without data in them. 2069 // We won't be swapping semispaces without data in them.
2064 DCHECK_NE(from->anchor_.next_page(), &from->anchor_); 2070 DCHECK_NE(from->anchor_.next_page(), &from->anchor_);
2065 DCHECK_NE(to->anchor_.next_page(), &to->anchor_); 2071 DCHECK_NE(to->anchor_.next_page(), &to->anchor_);
2066 2072
2067 intptr_t saved_to_space_flags = to->current_page()->GetFlags(); 2073 intptr_t saved_to_space_flags = to->current_page()->GetFlags();
2068 2074
2069 // We swap all properties but id_. 2075 // We swap all properties but id_.
2070 std::swap(from->current_capacity_, to->current_capacity_); 2076 std::swap(from->current_capacity_, to->current_capacity_);
2071 std::swap(from->maximum_capacity_, to->maximum_capacity_); 2077 std::swap(from->maximum_capacity_, to->maximum_capacity_);
2072 std::swap(from->minimum_capacity_, to->minimum_capacity_); 2078 std::swap(from->minimum_capacity_, to->minimum_capacity_);
2073 std::swap(from->age_mark_, to->age_mark_);
2074 std::swap(from->committed_, to->committed_); 2079 std::swap(from->committed_, to->committed_);
2075 std::swap(from->anchor_, to->anchor_); 2080 std::swap(from->anchor_, to->anchor_);
2076 std::swap(from->current_page_, to->current_page_); 2081 std::swap(from->current_page_, to->current_page_);
2077 2082
2078 to->FixPagesFlags(saved_to_space_flags, Page::kCopyOnFlipFlagsMask); 2083 to->FixPagesFlags(saved_to_space_flags, Page::kCopyOnFlipFlagsMask);
2079 from->FixPagesFlags(0, 0); 2084 from->FixPagesFlags(0, 0);
2080 } 2085 }
2081 2086
2087 void NewSpace::SealIntermediateGeneration() {
2088 fragmentation_in_intermediate_generation_ = 0;
2089 const Address mark = top();
2082 2090
2083 void SemiSpace::set_age_mark(Address mark) { 2091 if (mark == to_space_.space_start()) {
2084 DCHECK_EQ(Page::FromAllocationAreaAddress(mark)->owner(), this); 2092 // Do not mark any pages as being part of the intermediate generation if no
2085 age_mark_ = mark; 2093 // objects got moved.
2086 // Mark all pages up to the one containing mark. 2094 return;
2087 for (Page* p : NewSpacePageRange(space_start(), mark)) { 2095 }
2088 p->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 2096
2097 for (Page* p : NewSpacePageRange(to_space_.space_start(), mark)) {
2098 p->SetFlag(MemoryChunk::IN_INTERMEDIATE_GENERATION);
2099 }
2100
2101 Page* p = Page::FromAllocationAreaAddress(mark);
2102 if (mark < p->area_end()) {
2103 heap()->CreateFillerObjectAt(mark, static_cast<int>(p->area_end() - mark),
2104 ClearRecordedSlots::kNo);
2105 fragmentation_in_intermediate_generation_ =
2106 static_cast<size_t>(p->area_end() - mark);
2107 DCHECK_EQ(to_space_.current_page(), p);
2108 if (to_space_.AdvancePage()) {
2109 UpdateAllocationInfo();
2110 } else {
2111 allocation_info_.Reset(to_space_.page_high(), to_space_.page_high());
2112 }
2113 }
2114 if (FLAG_trace_gc_verbose) {
2115 PrintIsolate(heap()->isolate(),
2116 "Sealing intermediate generation: bytes_lost=%zu\n",
2117 fragmentation_in_intermediate_generation_);
2089 } 2118 }
2090 } 2119 }
2091 2120
2092
2093 #ifdef DEBUG 2121 #ifdef DEBUG
2094 void SemiSpace::Print() {} 2122 void SemiSpace::Print() {}
2095 #endif 2123 #endif
2096 2124
2097 #ifdef VERIFY_HEAP 2125 #ifdef VERIFY_HEAP
2098 void SemiSpace::Verify() { 2126 void SemiSpace::Verify() {
2099 bool is_from_space = (id_ == kFromSpace); 2127 bool is_from_space = (id_ == kFromSpace);
2100 Page* page = anchor_.next_page(); 2128 Page* page = anchor_.next_page();
2101 CHECK(anchor_.owner() == this); 2129 CHECK(anchor_.owner() == this);
2102 while (page != &anchor_) { 2130 while (page != &anchor_) {
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 object->ShortPrint(); 3263 object->ShortPrint();
3236 PrintF("\n"); 3264 PrintF("\n");
3237 } 3265 }
3238 printf(" --------------------------------------\n"); 3266 printf(" --------------------------------------\n");
3239 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3267 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3240 } 3268 }
3241 3269
3242 #endif // DEBUG 3270 #endif // DEBUG
3243 } // namespace internal 3271 } // namespace internal
3244 } // namespace v8 3272 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | src/heap/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698