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

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

Issue 2796233003: [heap] Evacuation for young generation (Closed)
Patch Set: Rebase after smaller refactorings landed Created 3 years, 7 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
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 #ifndef V8_HEAP_SPACES_H_ 5 #ifndef V8_HEAP_SPACES_H_
6 #define V8_HEAP_SPACES_H_ 6 #define V8_HEAP_SPACES_H_
7 7
8 #include <list> 8 #include <list>
9 #include <memory> 9 #include <memory>
10 #include <unordered_set> 10 #include <unordered_set>
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 517
518 bool CanAllocate() { 518 bool CanAllocate() {
519 return !IsEvacuationCandidate() && !IsFlagSet(NEVER_ALLOCATE_ON_PAGE); 519 return !IsEvacuationCandidate() && !IsFlagSet(NEVER_ALLOCATE_ON_PAGE);
520 } 520 }
521 521
522 bool ShouldSkipEvacuationSlotRecording() { 522 bool ShouldSkipEvacuationSlotRecording() {
523 return ((flags_ & kSkipEvacuationSlotsRecordingMask) != 0) && 523 return ((flags_ & kSkipEvacuationSlotsRecordingMask) != 0) &&
524 !IsFlagSet(COMPACTION_WAS_ABORTED); 524 !IsFlagSet(COMPACTION_WAS_ABORTED);
525 } 525 }
526 526
527 bool CanUseForAllocation() { return CanAllocate() && !NeverEvacuate(); }
ulan 2017/04/26 09:51:28 Can you add a comment explaining how NeverEvacuate
Michael Lippautz 2017/05/02 11:22:00 This one is gone now since we take pages for which
528
527 Executability executable() { 529 Executability executable() {
528 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE; 530 return IsFlagSet(IS_EXECUTABLE) ? EXECUTABLE : NOT_EXECUTABLE;
529 } 531 }
530 532
531 bool InNewSpace() { return (flags_ & kIsInNewSpaceMask) != 0; } 533 bool InNewSpace() { return (flags_ & kIsInNewSpaceMask) != 0; }
532 534
533 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); } 535 bool InToSpace() { return IsFlagSet(IN_TO_SPACE); }
534 536
535 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); } 537 bool InFromSpace() { return IsFlagSet(IN_FROM_SPACE); }
536 538
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 // The stats are only set by functions that ensure they stay balanced. These 1605 // The stats are only set by functions that ensure they stay balanced. These
1604 // functions increase or decrease one of the non-capacity stats in conjunction 1606 // functions increase or decrease one of the non-capacity stats in conjunction
1605 // with capacity, or else they always balance increases and decreases to the 1607 // with capacity, or else they always balance increases and decreases to the
1606 // non-capacity stats. 1608 // non-capacity stats.
1607 class AllocationStats BASE_EMBEDDED { 1609 class AllocationStats BASE_EMBEDDED {
1608 public: 1610 public:
1609 AllocationStats() { Clear(); } 1611 AllocationStats() { Clear(); }
1610 1612
1611 // Zero out all the allocation statistics (i.e., no capacity). 1613 // Zero out all the allocation statistics (i.e., no capacity).
1612 void Clear() { 1614 void Clear() {
1613 capacity_ = 0; 1615 capacity_.SetValue(0);
1614 max_capacity_ = 0; 1616 max_capacity_.SetValue(0);
1615 size_ = 0; 1617 size_.SetValue(0);
1616 } 1618 }
1617 1619
1618 void ClearSize() { size_ = capacity_; } 1620 void ClearSize() { size_.SetValue(capacity_.Value()); }
1619 1621
1620 // Accessors for the allocation statistics. 1622 // Accessors for the allocation statistics.
1621 size_t Capacity() { return capacity_; } 1623 size_t Capacity() { return capacity_.Value(); }
1622 size_t MaxCapacity() { return max_capacity_; } 1624 size_t MaxCapacity() { return max_capacity_.Value(); }
1623 size_t Size() { return size_; } 1625 size_t Size() { return size_.Value(); }
1624 1626
1625 // Grow the space by adding available bytes. They are initially marked as 1627 // Grow the space by adding available bytes. They are initially marked as
1626 // being in use (part of the size), but will normally be immediately freed, 1628 // being in use (part of the size), but will normally be immediately freed,
1627 // putting them on the free list and removing them from size_. 1629 // putting them on the free list and removing them from size_.
1628 void ExpandSpace(size_t bytes) { 1630 void ExpandSpace(size_t bytes) {
1629 DCHECK_GE(size_ + bytes, size_); 1631 DCHECK_GE(size_.Value() + bytes, size_.Value());
1630 DCHECK_GE(capacity_ + bytes, capacity_); 1632 DCHECK_GE(capacity_.Value() + bytes, capacity_.Value());
1631 capacity_ += bytes; 1633 capacity_.Increment(bytes);
1632 size_ += bytes; 1634 size_.Increment(bytes);
1633 if (capacity_ > max_capacity_) { 1635 if (capacity_.Value() > max_capacity_.Value()) {
1634 max_capacity_ = capacity_; 1636 max_capacity_.SetValue(capacity_.Value());
1635 } 1637 }
1636 } 1638 }
1637 1639
1638 // Shrink the space by removing available bytes. Since shrinking is done 1640 // Shrink the space by removing available bytes. Since shrinking is done
1639 // during sweeping, bytes have been marked as being in use (part of the size) 1641 // during sweeping, bytes have been marked as being in use (part of the size)
1640 // and are hereby freed. 1642 // and are hereby freed.
1641 void ShrinkSpace(size_t bytes) { 1643 void ShrinkSpace(size_t bytes) {
1642 DCHECK_GE(capacity_, bytes); 1644 DCHECK_GE(capacity_.Value(), bytes);
1643 DCHECK_GE(size_, bytes); 1645 DCHECK_GE(size_.Value(), bytes);
1644 capacity_ -= bytes; 1646 capacity_.Decrement(bytes);
1645 size_ -= bytes; 1647 size_.Decrement(bytes);
1646 } 1648 }
1647 1649
1648 void AllocateBytes(size_t bytes) { 1650 void AllocateBytes(size_t bytes) {
1649 DCHECK_GE(size_ + bytes, size_); 1651 DCHECK_GE(size_.Value() + bytes, size_.Value());
1650 size_ += bytes; 1652 size_.Increment(bytes);
1651 } 1653 }
1652 1654
1653 void DeallocateBytes(size_t bytes) { 1655 void DeallocateBytes(size_t bytes) {
1654 DCHECK_GE(size_, bytes); 1656 DCHECK_GE(size_.Value(), bytes);
1655 size_ -= bytes; 1657 size_.Decrement(bytes);
1656 } 1658 }
1657 1659
1658 void DecreaseCapacity(size_t bytes) { 1660 void DecreaseCapacity(size_t bytes) {
1659 DCHECK_GE(capacity_, bytes); 1661 DCHECK_GE(capacity_.Value(), bytes);
1660 DCHECK_GE(capacity_ - bytes, size_); 1662 DCHECK_GE(capacity_.Value() - bytes, size_.Value());
1661 capacity_ -= bytes; 1663 capacity_.Decrement(bytes);
1662 } 1664 }
1663 1665
1664 void IncreaseCapacity(size_t bytes) { 1666 void IncreaseCapacity(size_t bytes) {
1665 DCHECK_GE(capacity_ + bytes, capacity_); 1667 DCHECK_GE(capacity_.Value() + bytes, capacity_.Value());
1666 capacity_ += bytes; 1668 capacity_.Increment(bytes);
1667 } 1669 }
1668 1670
1669 // Merge |other| into |this|. 1671 // Merge |other| into |this|.
1670 void Merge(const AllocationStats& other) { 1672 void Merge(const AllocationStats& other) {
1671 DCHECK_GE(capacity_ + other.capacity_, capacity_); 1673 DCHECK_GE(capacity_.Value() + other.capacity_.Value(), capacity_.Value());
1672 DCHECK_GE(size_ + other.size_, size_); 1674 DCHECK_GE(size_.Value() + other.size_.Value(), size_.Value());
1673 capacity_ += other.capacity_; 1675 capacity_.Increment(other.capacity_.Value());
1674 size_ += other.size_; 1676 size_.Increment(other.size_.Value());
1675 if (other.max_capacity_ > max_capacity_) { 1677 if (other.max_capacity_.Value() > max_capacity_.Value()) {
1676 max_capacity_ = other.max_capacity_; 1678 max_capacity_.SetValue(other.max_capacity_.Value());
1677 } 1679 }
1678 } 1680 }
1679 1681
1680 private: 1682 private:
1681 // |capacity_|: The number of object-area bytes (i.e., not including page 1683 // |capacity_|: The number of object-area bytes (i.e., not including page
1682 // bookkeeping structures) currently in the space. 1684 // bookkeeping structures) currently in the space.
1683 size_t capacity_; 1685 base::AtomicNumber<size_t> capacity_;
1684 1686
1685 // |max_capacity_|: The maximum capacity ever observed. 1687 // |max_capacity_|: The maximum capacity ever observed.
1686 size_t max_capacity_; 1688 base::AtomicNumber<size_t> max_capacity_;
1687 1689
1688 // |size_|: The number of allocated bytes. 1690 // |size_|: The number of allocated bytes.
1689 size_t size_; 1691 base::AtomicNumber<size_t> size_;
1690 }; 1692 };
1691 1693
1692 // A free list maintaining free blocks of memory. The free list is organized in 1694 // A free list maintaining free blocks of memory. The free list is organized in
1693 // a way to encourage objects allocated around the same time to be near each 1695 // a way to encourage objects allocated around the same time to be near each
1694 // other. The normal way to allocate is intended to be by bumping a 'top' 1696 // other. The normal way to allocate is intended to be by bumping a 'top'
1695 // pointer until it hits a 'limit' pointer. When the limit is hit we need to 1697 // pointer until it hits a 'limit' pointer. When the limit is hit we need to
1696 // find a new space to allocate from. This is done with the free list, which is 1698 // find a new space to allocate from. This is done with the free list, which is
1697 // divided up into rough categories to cut down on waste. Having finer 1699 // divided up into rough categories to cut down on waste. Having finer
1698 // categories would scatter allocation more. 1700 // categories would scatter allocation more.
1699 1701
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info); 1947 LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info);
1946 1948
1947 Heap* heap_; 1949 Heap* heap_;
1948 AllocationInfo allocation_info_; 1950 AllocationInfo allocation_info_;
1949 }; 1951 };
1950 1952
1951 class V8_EXPORT_PRIVATE PagedSpace : NON_EXPORTED_BASE(public Space) { 1953 class V8_EXPORT_PRIVATE PagedSpace : NON_EXPORTED_BASE(public Space) {
1952 public: 1954 public:
1953 typedef PageIterator iterator; 1955 typedef PageIterator iterator;
1954 1956
1957 // Reuse a page for allocation only if it has at least {kPageReuseThreshold}
1958 // memory available in its FreeList.
1959 static const size_t kPageReuseThreshold = 4 * KB;
1960
1955 static const intptr_t kCompactionMemoryWanted = 500 * KB; 1961 static const intptr_t kCompactionMemoryWanted = 500 * KB;
1956 1962
1957 // Creates a space with an id. 1963 // Creates a space with an id.
1958 PagedSpace(Heap* heap, AllocationSpace id, Executability executable); 1964 PagedSpace(Heap* heap, AllocationSpace id, Executability executable);
1959 1965
1960 ~PagedSpace() override { TearDown(); } 1966 ~PagedSpace() override { TearDown(); }
1961 1967
1962 // Set up the space using the given address range of virtual memory (from 1968 // Set up the space using the given address range of virtual memory (from
1963 // the memory allocator's initial chunk) if possible. If the block of 1969 // the memory allocator's initial chunk) if possible. If the block of
1964 // addresses is not big enough to contain a single page-aligned page, a 1970 // addresses is not big enough to contain a single page-aligned page, a
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 2157
2152 iterator begin() { return iterator(anchor_.next_page()); } 2158 iterator begin() { return iterator(anchor_.next_page()); }
2153 iterator end() { return iterator(&anchor_); } 2159 iterator end() { return iterator(&anchor_); }
2154 2160
2155 // Shrink immortal immovable pages of the space to be exactly the size needed 2161 // Shrink immortal immovable pages of the space to be exactly the size needed
2156 // using the high water mark. 2162 // using the high water mark.
2157 void ShrinkImmortalImmovablePages(); 2163 void ShrinkImmortalImmovablePages();
2158 2164
2159 std::unique_ptr<ObjectIterator> GetObjectIterator() override; 2165 std::unique_ptr<ObjectIterator> GetObjectIterator() override;
2160 2166
2167 Page* RemovePageSafe();
2168 void AddPage(Page* page);
2169
2161 protected: 2170 protected:
2162 // PagedSpaces that should be included in snapshots have different, i.e., 2171 // PagedSpaces that should be included in snapshots have different, i.e.,
2163 // smaller, initial pages. 2172 // smaller, initial pages.
2164 virtual bool snapshotable() { return true; } 2173 virtual bool snapshotable() { return true; }
2165 2174
2166 bool HasPages() { return anchor_.next_page() != &anchor_; } 2175 bool HasPages() { return anchor_.next_page() != &anchor_; }
2167 2176
2168 // Cleans up the space, frees all pages in this space except those belonging 2177 // Cleans up the space, frees all pages in this space except those belonging
2169 // to the initial chunk, uncommits addresses in the initial chunk. 2178 // to the initial chunk, uncommits addresses in the initial chunk.
2170 void TearDown(); 2179 void TearDown();
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
2963 PageIterator old_iterator_; 2972 PageIterator old_iterator_;
2964 PageIterator code_iterator_; 2973 PageIterator code_iterator_;
2965 PageIterator map_iterator_; 2974 PageIterator map_iterator_;
2966 LargePageIterator lo_iterator_; 2975 LargePageIterator lo_iterator_;
2967 }; 2976 };
2968 2977
2969 } // namespace internal 2978 } // namespace internal
2970 } // namespace v8 2979 } // namespace v8
2971 2980
2972 #endif // V8_HEAP_SPACES_H_ 2981 #endif // V8_HEAP_SPACES_H_
OLDNEW
« src/heap/mark-compact.cc ('K') | « src/heap/mark-compact.cc ('k') | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698