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

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

Issue 1632913003: [heap] Move to page lookups for SemiSpace, NewSpace, and Heap containment methods (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: mips ports Created 4 years, 10 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 "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/slot-set.h" 10 #include "src/heap/slot-set.h"
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory(); 1094 if (!base::VirtualMemory::HasLazyCommits()) return CommittedMemory();
1095 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); 1095 MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
1096 size_t size = 0; 1096 size_t size = 0;
1097 PageIterator it(this); 1097 PageIterator it(this);
1098 while (it.has_next()) { 1098 while (it.has_next()) {
1099 size += it.next()->CommittedPhysicalMemory(); 1099 size += it.next()->CommittedPhysicalMemory();
1100 } 1100 }
1101 return size; 1101 return size;
1102 } 1102 }
1103 1103
1104 1104 bool PagedSpace::ContainsSlow(Address addr) {
1105 bool PagedSpace::ContainsSafe(Address addr) {
1106 Page* p = Page::FromAddress(addr); 1105 Page* p = Page::FromAddress(addr);
1107 PageIterator iterator(this); 1106 PageIterator iterator(this);
1108 while (iterator.has_next()) { 1107 while (iterator.has_next()) {
1109 if (iterator.next() == p) return true; 1108 if (iterator.next() == p) return true;
1110 } 1109 }
1111 return false; 1110 return false;
1112 } 1111 }
1113 1112
1114 1113
1115 Object* PagedSpace::FindObject(Address addr) { 1114 Object* PagedSpace::FindObject(Address addr) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 to_space_.SetUp(chunk_base_, initial_semispace_capacity, 1316 to_space_.SetUp(chunk_base_, initial_semispace_capacity,
1318 maximum_semispace_capacity); 1317 maximum_semispace_capacity);
1319 from_space_.SetUp(chunk_base_ + reserved_semispace_capacity, 1318 from_space_.SetUp(chunk_base_ + reserved_semispace_capacity,
1320 initial_semispace_capacity, maximum_semispace_capacity); 1319 initial_semispace_capacity, maximum_semispace_capacity);
1321 if (!to_space_.Commit()) { 1320 if (!to_space_.Commit()) {
1322 return false; 1321 return false;
1323 } 1322 }
1324 DCHECK(!from_space_.is_committed()); // No need to use memory yet. 1323 DCHECK(!from_space_.is_committed()); // No need to use memory yet.
1325 1324
1326 start_ = chunk_base_; 1325 start_ = chunk_base_;
1327 address_mask_ = ~(2 * reserved_semispace_capacity - 1);
1328 object_mask_ = address_mask_ | kHeapObjectTagMask;
1329 object_expected_ = reinterpret_cast<uintptr_t>(start_) | kHeapObjectTag;
1330 1326
1331 ResetAllocationInfo(); 1327 ResetAllocationInfo();
1332 1328
1333 return true; 1329 return true;
1334 } 1330 }
1335 1331
1336 1332
1337 void NewSpace::TearDown() { 1333 void NewSpace::TearDown() {
1338 if (allocated_histogram_) { 1334 if (allocated_histogram_) {
1339 DeleteArray(allocated_histogram_); 1335 DeleteArray(allocated_histogram_);
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 // SemiSpace implementation 1676 // SemiSpace implementation
1681 1677
1682 void SemiSpace::SetUp(Address start, int initial_capacity, 1678 void SemiSpace::SetUp(Address start, int initial_capacity,
1683 int maximum_capacity) { 1679 int maximum_capacity) {
1684 DCHECK_GE(maximum_capacity, Page::kPageSize); 1680 DCHECK_GE(maximum_capacity, Page::kPageSize);
1685 minimum_capacity_ = RoundDown(initial_capacity, Page::kPageSize); 1681 minimum_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
1686 current_capacity_ = minimum_capacity_; 1682 current_capacity_ = minimum_capacity_;
1687 maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize); 1683 maximum_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
1688 committed_ = false; 1684 committed_ = false;
1689 start_ = start; 1685 start_ = start;
1690 address_mask_ = ~(maximum_capacity_ - 1);
1691 object_mask_ = address_mask_ | kHeapObjectTagMask;
1692 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag;
1693 age_mark_ = start_ + NewSpacePage::kObjectStartOffset; 1686 age_mark_ = start_ + NewSpacePage::kObjectStartOffset;
1694 } 1687 }
1695 1688
1696 1689
1697 void SemiSpace::TearDown() { 1690 void SemiSpace::TearDown() {
1698 start_ = nullptr; 1691 start_ = nullptr;
1699 current_capacity_ = 0; 1692 current_capacity_ = 0;
1700 } 1693 }
1701 1694
1702 1695
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 new_last_page->set_next_page(anchor()); 1801 new_last_page->set_next_page(anchor());
1809 anchor()->set_prev_page(new_last_page); 1802 anchor()->set_prev_page(new_last_page);
1810 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page)); 1803 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page));
1811 } 1804 }
1812 1805
1813 set_current_capacity(new_capacity); 1806 set_current_capacity(new_capacity);
1814 1807
1815 return true; 1808 return true;
1816 } 1809 }
1817 1810
1818 1811 void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) {
1819 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) {
1820 anchor_.set_owner(this); 1812 anchor_.set_owner(this);
1821 // Fixup back-pointers to anchor. Address of anchor changes when we swap. 1813 // Fixup back-pointers to anchor. Address of anchor changes when we swap.
1822 anchor_.prev_page()->set_next_page(&anchor_); 1814 anchor_.prev_page()->set_next_page(&anchor_);
1823 anchor_.next_page()->set_prev_page(&anchor_); 1815 anchor_.next_page()->set_prev_page(&anchor_);
1824 1816
1825 bool becomes_to_space = (id_ == kFromSpace);
1826 id_ = becomes_to_space ? kToSpace : kFromSpace;
1827 NewSpacePageIterator it(this); 1817 NewSpacePageIterator it(this);
1828 while (it.has_next()) { 1818 while (it.has_next()) {
1829 NewSpacePage* page = it.next(); 1819 NewSpacePage* page = it.next();
1830 page->set_owner(this); 1820 page->set_owner(this);
1831 page->SetFlags(flags, mask); 1821 page->SetFlags(flags, mask);
1832 if (becomes_to_space) { 1822 if (id_ == kToSpace) {
1833 page->ClearFlag(MemoryChunk::IN_FROM_SPACE); 1823 page->ClearFlag(MemoryChunk::IN_FROM_SPACE);
1834 page->SetFlag(MemoryChunk::IN_TO_SPACE); 1824 page->SetFlag(MemoryChunk::IN_TO_SPACE);
1835 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 1825 page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK);
1836 page->ResetLiveBytes(); 1826 page->ResetLiveBytes();
1837 } else { 1827 } else {
1838 page->SetFlag(MemoryChunk::IN_FROM_SPACE); 1828 page->SetFlag(MemoryChunk::IN_FROM_SPACE);
1839 page->ClearFlag(MemoryChunk::IN_TO_SPACE); 1829 page->ClearFlag(MemoryChunk::IN_TO_SPACE);
1840 } 1830 }
1841 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) || 1831 DCHECK(page->IsFlagSet(MemoryChunk::IN_TO_SPACE) ||
1842 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE)); 1832 page->IsFlagSet(MemoryChunk::IN_FROM_SPACE));
1843 } 1833 }
1844 } 1834 }
1845 1835
1846 1836
1847 void SemiSpace::Reset() { 1837 void SemiSpace::Reset() {
1848 DCHECK_NE(anchor_.next_page(), &anchor_); 1838 DCHECK_NE(anchor_.next_page(), &anchor_);
1849 current_page_ = anchor_.next_page(); 1839 current_page_ = anchor_.next_page();
1850 } 1840 }
1851 1841
1852 1842
1853 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { 1843 void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) {
1854 // We won't be swapping semispaces without data in them. 1844 // We won't be swapping semispaces without data in them.
1855 DCHECK_NE(from->anchor_.next_page(), &from->anchor_); 1845 DCHECK_NE(from->anchor_.next_page(), &from->anchor_);
1856 DCHECK_NE(to->anchor_.next_page(), &to->anchor_); 1846 DCHECK_NE(to->anchor_.next_page(), &to->anchor_);
1857 1847
1858 // Swap bits. 1848 intptr_t saved_to_space_flags = to->current_page()->GetFlags();
1859 SemiSpace tmp = *from;
1860 *from = *to;
1861 *to = tmp;
1862 1849
1863 // Fixup back-pointers to the page list anchor now that its address 1850 // We swap all properties but id_.
1864 // has changed. 1851 std::swap(from->current_capacity_, to->current_capacity_);
1865 // Swap to/from-space bits on pages. 1852 std::swap(from->maximum_capacity_, to->maximum_capacity_);
1866 // Copy GC flags from old active space (from-space) to new (to-space). 1853 std::swap(from->minimum_capacity_, to->minimum_capacity_);
1867 intptr_t flags = from->current_page()->GetFlags(); 1854 std::swap(from->start_, to->start_);
1868 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask); 1855 std::swap(from->age_mark_, to->age_mark_);
1856 std::swap(from->committed_, to->committed_);
1857 std::swap(from->anchor_, to->anchor_);
1858 std::swap(from->current_page_, to->current_page_);
1869 1859
1870 from->FlipPages(0, 0); 1860 to->FixPagesFlags(saved_to_space_flags, NewSpacePage::kCopyOnFlipFlagsMask);
1861 from->FixPagesFlags(0, 0);
1871 } 1862 }
1872 1863
1873 1864
1874 void SemiSpace::set_age_mark(Address mark) { 1865 void SemiSpace::set_age_mark(Address mark) {
1875 DCHECK_EQ(NewSpacePage::FromLimit(mark)->semi_space(), this); 1866 DCHECK_EQ(NewSpacePage::FromLimit(mark)->semi_space(), this);
1876 age_mark_ = mark; 1867 age_mark_ = mark;
1877 // Mark all pages up to the one containing mark. 1868 // Mark all pages up to the one containing mark.
1878 NewSpacePageIterator it(space_start(), mark); 1869 NewSpacePageIterator it(space_start(), mark);
1879 while (it.has_next()) { 1870 while (it.has_next()) {
1880 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 1871 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK);
(...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after
3130 MemoryChunk* chunk = MemoryChunk::FromAddress(address); 3121 MemoryChunk* chunk = MemoryChunk::FromAddress(address);
3131 3122
3132 bool owned = (chunk->owner() == this); 3123 bool owned = (chunk->owner() == this);
3133 3124
3134 SLOW_DCHECK(!owned || FindObject(address)->IsHeapObject()); 3125 SLOW_DCHECK(!owned || FindObject(address)->IsHeapObject());
3135 3126
3136 return owned; 3127 return owned;
3137 } 3128 }
3138 3129
3139 3130
3140 bool LargeObjectSpace::Contains(Address address) {
3141 return FindPage(address) != NULL;
3142 }
3143
3144
3145 #ifdef VERIFY_HEAP 3131 #ifdef VERIFY_HEAP
3146 // We do not assume that the large object iterator works, because it depends 3132 // We do not assume that the large object iterator works, because it depends
3147 // on the invariants we are checking during verification. 3133 // on the invariants we are checking during verification.
3148 void LargeObjectSpace::Verify() { 3134 void LargeObjectSpace::Verify() {
3149 for (LargePage* chunk = first_page_; chunk != NULL; 3135 for (LargePage* chunk = first_page_; chunk != NULL;
3150 chunk = chunk->next_page()) { 3136 chunk = chunk->next_page()) {
3151 // Each chunk contains an object that starts at the large object page's 3137 // Each chunk contains an object that starts at the large object page's
3152 // object area start. 3138 // object area start.
3153 HeapObject* object = chunk->GetObject(); 3139 HeapObject* object = chunk->GetObject();
3154 Page* page = Page::FromAddress(object->address()); 3140 Page* page = Page::FromAddress(object->address());
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 object->ShortPrint(); 3234 object->ShortPrint();
3249 PrintF("\n"); 3235 PrintF("\n");
3250 } 3236 }
3251 printf(" --------------------------------------\n"); 3237 printf(" --------------------------------------\n");
3252 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3238 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3253 } 3239 }
3254 3240
3255 #endif // DEBUG 3241 #endif // DEBUG
3256 } // namespace internal 3242 } // namespace internal
3257 } // namespace v8 3243 } // 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