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

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

Issue 1388383002: [heap] Unify accounting committed memory across all spaces. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 5 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') | test/cctest/test-spaces.cc » ('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/slots-buffer.h" 10 #include "src/heap/slots-buffer.h"
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 // end_of_unswept_pages_ 1009 // end_of_unswept_pages_
1010 // unswept_free_bytes_ 1010 // unswept_free_bytes_
1011 // anchor_ 1011 // anchor_
1012 1012
1013 MoveOverFreeMemory(other); 1013 MoveOverFreeMemory(other);
1014 1014
1015 // Update and clear accounting statistics. 1015 // Update and clear accounting statistics.
1016 accounting_stats_.Merge(other->accounting_stats_); 1016 accounting_stats_.Merge(other->accounting_stats_);
1017 other->accounting_stats_.Reset(); 1017 other->accounting_stats_.Reset();
1018 1018
1019 AccountCommitted(other->CommittedMemory());
1020
1019 // Move over pages. 1021 // Move over pages.
1020 PageIterator it(other); 1022 PageIterator it(other);
1021 Page* p = nullptr; 1023 Page* p = nullptr;
1022 while (it.has_next()) { 1024 while (it.has_next()) {
1023 p = it.next(); 1025 p = it.next();
1024 p->Unlink(); 1026 p->Unlink();
1025 p->set_owner(this); 1027 p->set_owner(this);
1026 p->InsertAfter(anchor_.prev_page()); 1028 p->InsertAfter(anchor_.prev_page());
1027 } 1029 }
1028 } 1030 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 if (snapshotable() && !HasPages()) { 1089 if (snapshotable() && !HasPages()) {
1088 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity()); 1090 size = Snapshot::SizeOfFirstPage(heap()->isolate(), identity());
1089 } 1091 }
1090 1092
1091 if (!CanExpand(size)) return false; 1093 if (!CanExpand(size)) return false;
1092 1094
1093 Page* p = heap()->isolate()->memory_allocator()->AllocatePage(size, this, 1095 Page* p = heap()->isolate()->memory_allocator()->AllocatePage(size, this,
1094 executable()); 1096 executable());
1095 if (p == NULL) return false; 1097 if (p == NULL) return false;
1096 1098
1099 AccountCommitted(static_cast<intptr_t>(p->size()));
1100
1097 // Pages created during bootstrapping may contain immortal immovable objects. 1101 // Pages created during bootstrapping may contain immortal immovable objects.
1098 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); 1102 if (!heap()->deserialization_complete()) p->MarkNeverEvacuate();
1099 1103
1100 DCHECK(Capacity() <= heap()->MaxOldGenerationSize()); 1104 DCHECK(Capacity() <= heap()->MaxOldGenerationSize());
1101 1105
1102 p->InsertAfter(anchor_.prev_page()); 1106 p->InsertAfter(anchor_.prev_page());
1103 1107
1104 return true; 1108 return true;
1105 } 1109 }
1106 1110
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 allocation_info_.set_top(NULL); 1157 allocation_info_.set_top(NULL);
1154 allocation_info_.set_limit(NULL); 1158 allocation_info_.set_limit(NULL);
1155 } 1159 }
1156 1160
1157 // If page is still in a list, unlink it from that list. 1161 // If page is still in a list, unlink it from that list.
1158 if (page->next_chunk() != NULL) { 1162 if (page->next_chunk() != NULL) {
1159 DCHECK(page->prev_chunk() != NULL); 1163 DCHECK(page->prev_chunk() != NULL);
1160 page->Unlink(); 1164 page->Unlink();
1161 } 1165 }
1162 1166
1167 AccountUncommitted(static_cast<intptr_t>(page->size()));
1163 heap()->QueueMemoryChunkForFree(page); 1168 heap()->QueueMemoryChunkForFree(page);
1164 1169
1165 DCHECK(Capacity() > 0); 1170 DCHECK(Capacity() > 0);
1166 accounting_stats_.ShrinkSpace(AreaSize()); 1171 accounting_stats_.ShrinkSpace(AreaSize());
1167 } 1172 }
1168 1173
1169 1174
1170 #ifdef DEBUG 1175 #ifdef DEBUG
1171 void PagedSpace::Print() {} 1176 void PagedSpace::Print() {}
1172 #endif 1177 #endif
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 // otherwise. In the mark-compact collector, the memory region of the from 1584 // otherwise. In the mark-compact collector, the memory region of the from
1580 // space is used as the marking stack. It requires contiguous memory 1585 // space is used as the marking stack. It requires contiguous memory
1581 // addresses. 1586 // addresses.
1582 DCHECK(maximum_capacity >= Page::kPageSize); 1587 DCHECK(maximum_capacity >= Page::kPageSize);
1583 DCHECK(initial_capacity <= target_capacity); 1588 DCHECK(initial_capacity <= target_capacity);
1584 DCHECK(target_capacity <= maximum_capacity); 1589 DCHECK(target_capacity <= maximum_capacity);
1585 initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize); 1590 initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
1586 total_capacity_ = initial_capacity; 1591 total_capacity_ = initial_capacity;
1587 target_capacity_ = RoundDown(target_capacity, Page::kPageSize); 1592 target_capacity_ = RoundDown(target_capacity, Page::kPageSize);
1588 maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize); 1593 maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
1589 maximum_committed_ = 0;
1590 committed_ = false; 1594 committed_ = false;
1591 start_ = start; 1595 start_ = start;
1592 address_mask_ = ~(maximum_capacity - 1); 1596 address_mask_ = ~(maximum_capacity - 1);
1593 object_mask_ = address_mask_ | kHeapObjectTagMask; 1597 object_mask_ = address_mask_ | kHeapObjectTagMask;
1594 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag; 1598 object_expected_ = reinterpret_cast<uintptr_t>(start) | kHeapObjectTag;
1595 age_mark_ = start_ + NewSpacePage::kObjectStartOffset; 1599 age_mark_ = start_ + NewSpacePage::kObjectStartOffset;
1596 } 1600 }
1597 1601
1598 1602
1599 void SemiSpace::TearDown() { 1603 void SemiSpace::TearDown() {
1600 start_ = NULL; 1604 start_ = NULL;
1601 total_capacity_ = 0; 1605 total_capacity_ = 0;
1602 } 1606 }
1603 1607
1604 1608
1605 bool SemiSpace::Commit() { 1609 bool SemiSpace::Commit() {
1606 DCHECK(!is_committed()); 1610 DCHECK(!is_committed());
1607 int pages = total_capacity_ / Page::kPageSize; 1611 int pages = total_capacity_ / Page::kPageSize;
1608 if (!heap()->isolate()->memory_allocator()->CommitBlock( 1612 if (!heap()->isolate()->memory_allocator()->CommitBlock(
1609 start_, total_capacity_, executable())) { 1613 start_, total_capacity_, executable())) {
1610 return false; 1614 return false;
1611 } 1615 }
1616 AccountCommitted(total_capacity_);
1612 1617
1613 NewSpacePage* current = anchor(); 1618 NewSpacePage* current = anchor();
1614 for (int i = 0; i < pages; i++) { 1619 for (int i = 0; i < pages; i++) {
1615 NewSpacePage* new_page = 1620 NewSpacePage* new_page =
1616 NewSpacePage::Initialize(heap(), start_ + i * Page::kPageSize, this); 1621 NewSpacePage::Initialize(heap(), start_ + i * Page::kPageSize, this);
1617 new_page->InsertAfter(current); 1622 new_page->InsertAfter(current);
1618 current = new_page; 1623 current = new_page;
1619 } 1624 }
1620 1625
1621 SetCapacity(total_capacity_); 1626 SetCapacity(total_capacity_);
1622 committed_ = true; 1627 committed_ = true;
1623 Reset(); 1628 Reset();
1624 return true; 1629 return true;
1625 } 1630 }
1626 1631
1627 1632
1628 bool SemiSpace::Uncommit() { 1633 bool SemiSpace::Uncommit() {
1629 DCHECK(is_committed()); 1634 DCHECK(is_committed());
1630 Address start = start_ + maximum_total_capacity_ - total_capacity_; 1635 Address start = start_ + maximum_total_capacity_ - total_capacity_;
1631 if (!heap()->isolate()->memory_allocator()->UncommitBlock(start, 1636 if (!heap()->isolate()->memory_allocator()->UncommitBlock(start,
1632 total_capacity_)) { 1637 total_capacity_)) {
1633 return false; 1638 return false;
1634 } 1639 }
1640 AccountUncommitted(total_capacity_);
1641
1635 anchor()->set_next_page(anchor()); 1642 anchor()->set_next_page(anchor());
1636 anchor()->set_prev_page(anchor()); 1643 anchor()->set_prev_page(anchor());
1637 1644
1638 committed_ = false; 1645 committed_ = false;
1639 return true; 1646 return true;
1640 } 1647 }
1641 1648
1642 1649
1643 size_t SemiSpace::CommittedPhysicalMemory() { 1650 size_t SemiSpace::CommittedPhysicalMemory() {
1644 if (!is_committed()) return 0; 1651 if (!is_committed()) return 0;
(...skipping 16 matching lines...) Expand all
1661 int pages_before = total_capacity_ / Page::kPageSize; 1668 int pages_before = total_capacity_ / Page::kPageSize;
1662 int pages_after = new_capacity / Page::kPageSize; 1669 int pages_after = new_capacity / Page::kPageSize;
1663 1670
1664 size_t delta = new_capacity - total_capacity_; 1671 size_t delta = new_capacity - total_capacity_;
1665 1672
1666 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); 1673 DCHECK(IsAligned(delta, base::OS::AllocateAlignment()));
1667 if (!heap()->isolate()->memory_allocator()->CommitBlock( 1674 if (!heap()->isolate()->memory_allocator()->CommitBlock(
1668 start_ + total_capacity_, delta, executable())) { 1675 start_ + total_capacity_, delta, executable())) {
1669 return false; 1676 return false;
1670 } 1677 }
1678 AccountCommitted(static_cast<intptr_t>(delta));
1671 SetCapacity(new_capacity); 1679 SetCapacity(new_capacity);
1672 NewSpacePage* last_page = anchor()->prev_page(); 1680 NewSpacePage* last_page = anchor()->prev_page();
1673 DCHECK(last_page != anchor()); 1681 DCHECK(last_page != anchor());
1674 for (int i = pages_before; i < pages_after; i++) { 1682 for (int i = pages_before; i < pages_after; i++) {
1675 Address page_address = start_ + i * Page::kPageSize; 1683 Address page_address = start_ + i * Page::kPageSize;
1676 NewSpacePage* new_page = 1684 NewSpacePage* new_page =
1677 NewSpacePage::Initialize(heap(), page_address, this); 1685 NewSpacePage::Initialize(heap(), page_address, this);
1678 new_page->InsertAfter(last_page); 1686 new_page->InsertAfter(last_page);
1679 Bitmap::Clear(new_page); 1687 Bitmap::Clear(new_page);
1680 // Duplicate the flags that was set on the old page. 1688 // Duplicate the flags that was set on the old page.
(...skipping 10 matching lines...) Expand all
1691 DCHECK(new_capacity >= initial_total_capacity_); 1699 DCHECK(new_capacity >= initial_total_capacity_);
1692 DCHECK(new_capacity < total_capacity_); 1700 DCHECK(new_capacity < total_capacity_);
1693 if (is_committed()) { 1701 if (is_committed()) {
1694 size_t delta = total_capacity_ - new_capacity; 1702 size_t delta = total_capacity_ - new_capacity;
1695 DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); 1703 DCHECK(IsAligned(delta, base::OS::AllocateAlignment()));
1696 1704
1697 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); 1705 MemoryAllocator* allocator = heap()->isolate()->memory_allocator();
1698 if (!allocator->UncommitBlock(start_ + new_capacity, delta)) { 1706 if (!allocator->UncommitBlock(start_ + new_capacity, delta)) {
1699 return false; 1707 return false;
1700 } 1708 }
1709 AccountUncommitted(static_cast<intptr_t>(delta));
1701 1710
1702 int pages_after = new_capacity / Page::kPageSize; 1711 int pages_after = new_capacity / Page::kPageSize;
1703 NewSpacePage* new_last_page = 1712 NewSpacePage* new_last_page =
1704 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize); 1713 NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize);
1705 new_last_page->set_next_page(anchor()); 1714 new_last_page->set_next_page(anchor());
1706 anchor()->set_prev_page(new_last_page); 1715 anchor()->set_prev_page(new_last_page);
1707 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page)); 1716 DCHECK((current_page_ >= first_page()) && (current_page_ <= new_last_page));
1708 } 1717 }
1709 1718
1710 SetCapacity(new_capacity); 1719 SetCapacity(new_capacity);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 // Copy GC flags from old active space (from-space) to new (to-space). 1785 // Copy GC flags from old active space (from-space) to new (to-space).
1777 intptr_t flags = from->current_page()->GetFlags(); 1786 intptr_t flags = from->current_page()->GetFlags();
1778 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask); 1787 to->FlipPages(flags, NewSpacePage::kCopyOnFlipFlagsMask);
1779 1788
1780 from->FlipPages(0, 0); 1789 from->FlipPages(0, 0);
1781 } 1790 }
1782 1791
1783 1792
1784 void SemiSpace::SetCapacity(int new_capacity) { 1793 void SemiSpace::SetCapacity(int new_capacity) {
1785 total_capacity_ = new_capacity; 1794 total_capacity_ = new_capacity;
1786 if (total_capacity_ > maximum_committed_) {
1787 maximum_committed_ = total_capacity_;
1788 }
1789 } 1795 }
1790 1796
1791 1797
1792 void SemiSpace::set_age_mark(Address mark) { 1798 void SemiSpace::set_age_mark(Address mark) {
1793 DCHECK(NewSpacePage::FromLimit(mark)->semi_space() == this); 1799 DCHECK(NewSpacePage::FromLimit(mark)->semi_space() == this);
1794 age_mark_ = mark; 1800 age_mark_ = mark;
1795 // Mark all pages up to the one containing mark. 1801 // Mark all pages up to the one containing mark.
1796 NewSpacePageIterator it(space_start(), mark); 1802 NewSpacePageIterator it(space_start(), mark);
1797 while (it.has_next()) { 1803 while (it.has_next()) {
1798 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); 1804 it.next()->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK);
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
2856 objects_size_(0), 2862 objects_size_(0),
2857 chunk_map_(ComparePointers, 1024) {} 2863 chunk_map_(ComparePointers, 1024) {}
2858 2864
2859 2865
2860 LargeObjectSpace::~LargeObjectSpace() {} 2866 LargeObjectSpace::~LargeObjectSpace() {}
2861 2867
2862 2868
2863 bool LargeObjectSpace::SetUp() { 2869 bool LargeObjectSpace::SetUp() {
2864 first_page_ = NULL; 2870 first_page_ = NULL;
2865 size_ = 0; 2871 size_ = 0;
2866 maximum_committed_ = 0;
2867 page_count_ = 0; 2872 page_count_ = 0;
2868 objects_size_ = 0; 2873 objects_size_ = 0;
2869 chunk_map_.Clear(); 2874 chunk_map_.Clear();
2870 return true; 2875 return true;
2871 } 2876 }
2872 2877
2873 2878
2874 void LargeObjectSpace::TearDown() { 2879 void LargeObjectSpace::TearDown() {
2875 while (first_page_ != NULL) { 2880 while (first_page_ != NULL) {
2876 LargePage* page = first_page_; 2881 LargePage* page = first_page_;
(...skipping 17 matching lines...) Expand all
2894 !heap()->CanExpandOldGeneration(object_size)) { 2899 !heap()->CanExpandOldGeneration(object_size)) {
2895 return AllocationResult::Retry(identity()); 2900 return AllocationResult::Retry(identity());
2896 } 2901 }
2897 2902
2898 LargePage* page = heap()->isolate()->memory_allocator()->AllocateLargePage( 2903 LargePage* page = heap()->isolate()->memory_allocator()->AllocateLargePage(
2899 object_size, this, executable); 2904 object_size, this, executable);
2900 if (page == NULL) return AllocationResult::Retry(identity()); 2905 if (page == NULL) return AllocationResult::Retry(identity());
2901 DCHECK(page->area_size() >= object_size); 2906 DCHECK(page->area_size() >= object_size);
2902 2907
2903 size_ += static_cast<int>(page->size()); 2908 size_ += static_cast<int>(page->size());
2909 AccountCommitted(static_cast<intptr_t>(page->size()));
2904 objects_size_ += object_size; 2910 objects_size_ += object_size;
2905 page_count_++; 2911 page_count_++;
2906 page->set_next_page(first_page_); 2912 page->set_next_page(first_page_);
2907 first_page_ = page; 2913 first_page_ = page;
2908 2914
2909 if (size_ > maximum_committed_) {
2910 maximum_committed_ = size_;
2911 }
2912
2913 // Register all MemoryChunk::kAlignment-aligned chunks covered by 2915 // Register all MemoryChunk::kAlignment-aligned chunks covered by
2914 // this large page in the chunk map. 2916 // this large page in the chunk map.
2915 uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment; 2917 uintptr_t base = reinterpret_cast<uintptr_t>(page) / MemoryChunk::kAlignment;
2916 uintptr_t limit = base + (page->size() - 1) / MemoryChunk::kAlignment; 2918 uintptr_t limit = base + (page->size() - 1) / MemoryChunk::kAlignment;
2917 for (uintptr_t key = base; key <= limit; key++) { 2919 for (uintptr_t key = base; key <= limit; key++) {
2918 HashMap::Entry* entry = chunk_map_.LookupOrInsert( 2920 HashMap::Entry* entry = chunk_map_.LookupOrInsert(
2919 reinterpret_cast<void*>(key), static_cast<uint32_t>(key)); 2921 reinterpret_cast<void*>(key), static_cast<uint32_t>(key));
2920 DCHECK(entry != NULL); 2922 DCHECK(entry != NULL);
2921 entry->value = page; 2923 entry->value = page;
2922 } 2924 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
3006 if (previous == NULL) { 3008 if (previous == NULL) {
3007 first_page_ = current; 3009 first_page_ = current;
3008 } else { 3010 } else {
3009 previous->set_next_page(current); 3011 previous->set_next_page(current);
3010 } 3012 }
3011 3013
3012 // Free the chunk. 3014 // Free the chunk.
3013 heap()->mark_compact_collector()->ReportDeleteIfNeeded(object, 3015 heap()->mark_compact_collector()->ReportDeleteIfNeeded(object,
3014 heap()->isolate()); 3016 heap()->isolate());
3015 size_ -= static_cast<int>(page->size()); 3017 size_ -= static_cast<int>(page->size());
3018 AccountUncommitted(static_cast<intptr_t>(page->size()));
3016 objects_size_ -= object->Size(); 3019 objects_size_ -= object->Size();
3017 page_count_--; 3020 page_count_--;
3018 3021
3019 // Remove entries belonging to this page. 3022 // Remove entries belonging to this page.
3020 // Use variable alignment to help pass length check (<= 80 characters) 3023 // Use variable alignment to help pass length check (<= 80 characters)
3021 // of single line in tools/presubmit.py. 3024 // of single line in tools/presubmit.py.
3022 const intptr_t alignment = MemoryChunk::kAlignment; 3025 const intptr_t alignment = MemoryChunk::kAlignment;
3023 uintptr_t base = reinterpret_cast<uintptr_t>(page) / alignment; 3026 uintptr_t base = reinterpret_cast<uintptr_t>(page) / alignment;
3024 uintptr_t limit = base + (page->size() - 1) / alignment; 3027 uintptr_t limit = base + (page->size() - 1) / alignment;
3025 for (uintptr_t key = base; key <= limit; key++) { 3028 for (uintptr_t key = base; key <= limit; key++) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 object->ShortPrint(); 3164 object->ShortPrint();
3162 PrintF("\n"); 3165 PrintF("\n");
3163 } 3166 }
3164 printf(" --------------------------------------\n"); 3167 printf(" --------------------------------------\n");
3165 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3168 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3166 } 3169 }
3167 3170
3168 #endif // DEBUG 3171 #endif // DEBUG
3169 } // namespace internal 3172 } // namespace internal
3170 } // namespace v8 3173 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | test/cctest/test-spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698