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

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

Issue 1392343004: [heap] Cleanup: Enforce coding style in FreeList and FreeListCategory (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | src/heap/spaces.cc » ('j') | src/heap/spaces.cc » ('J')
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 #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 "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/atomic-utils.h" 9 #include "src/atomic-utils.h"
10 #include "src/base/atomicops.h" 10 #include "src/base/atomicops.h"
(...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 intptr_t capacity_; 1577 intptr_t capacity_;
1578 1578
1579 // |max_capacity_|: The maximum capacity ever observed. 1579 // |max_capacity_|: The maximum capacity ever observed.
1580 intptr_t max_capacity_; 1580 intptr_t max_capacity_;
1581 1581
1582 // |size_|: The number of allocated bytes. 1582 // |size_|: The number of allocated bytes.
1583 intptr_t size_; 1583 intptr_t size_;
1584 }; 1584 };
1585 1585
1586 1586
1587 // ----------------------------------------------------------------------------- 1587 // A free list category maintains a linked list of free memory blocks.
1588 // Free lists for old object spaces
1589
1590 // The free list category holds a pointer to the top element and a pointer to
1591 // the end element of the linked list of free memory blocks.
1592 class FreeListCategory { 1588 class FreeListCategory {
1593 public: 1589 public:
1594 explicit FreeListCategory(FreeList* owner, FreeListCategoryType type) 1590 explicit FreeListCategory(FreeList* owner, FreeListCategoryType type)
1595 : type_(type), 1591 : type_(type),
1596 top_(nullptr), 1592 top_(nullptr),
1597 end_(nullptr), 1593 end_(nullptr),
1598 available_(0), 1594 available_(0),
1599 owner_(owner) {} 1595 owner_(owner) {}
1600 1596
1597 // Concatenates {category} into {this}.
1598 //
1599 // Note: Concurrency safe.
Hannes Payer (out of office) 2015/10/15 12:23:42 thread-safe.
Michael Lippautz 2015/10/15 12:31:34 Done.
1601 intptr_t Concatenate(FreeListCategory* category); 1600 intptr_t Concatenate(FreeListCategory* category);
1602 1601
1603 void Reset(); 1602 void Reset();
1604 1603
1605 void Free(FreeSpace* node, int size_in_bytes); 1604 void Free(FreeSpace* node, int size_in_bytes);
1606 1605
1607 // Pick a node from the list. 1606 // Pick a node from the list.
1608 FreeSpace* PickNodeFromList(int* node_size); 1607 FreeSpace* PickNodeFromList(int* node_size);
1609 1608
1610 // Pick a node from the list and compare it against {size_in_bytes}. If the 1609 // Pick a node from the list and compare it against {size_in_bytes}. If the
1611 // node's size is greater or equal return the node and null otherwise. 1610 // node's size is greater or equal return the node and null otherwise.
1612 FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size); 1611 FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size);
1613 1612
1614 // Search for a node of size {size_in_bytes}. 1613 // Search for a node of size {size_in_bytes}.
1615 FreeSpace* SearchForNodeInList(int size_in_bytes, int* node_size); 1614 FreeSpace* SearchForNodeInList(int size_in_bytes, int* node_size);
1616 1615
1617 intptr_t EvictFreeListItemsInList(Page* p); 1616 intptr_t EvictFreeListItemsInList(Page* p);
1618 bool ContainsPageFreeListItemsInList(Page* p); 1617 bool ContainsPageFreeListItemsInList(Page* p);
1619 1618
1620 void RepairFreeList(Heap* heap); 1619 void RepairFreeList(Heap* heap);
1621 1620
1622 bool IsEmpty() { return top() == nullptr; } 1621 bool IsEmpty() { return top() == nullptr; }
1623 1622
1624 FreeList* owner() { return owner_; } 1623 FreeList* owner() { return owner_; }
1625 int available() const { return available_; } 1624 int available() const { return available_; }
1626 1625
1627 #ifdef DEBUG 1626 #ifdef DEBUG
1628 intptr_t SumFreeList(); 1627 intptr_t SumFreeList();
1629 int FreeListLength(); 1628 int FreeListLength();
1629 bool IsVeryLong();
1630 #endif 1630 #endif
1631 1631
1632 private: 1632 private:
1633 static const int kVeryLongFreeList = 500;
Hannes Payer (out of office) 2015/10/15 12:23:42 Let's add a comment that describes that constant.
Michael Lippautz 2015/10/15 12:31:34 Done.
1634
1633 FreeSpace* top() { return top_.Value(); } 1635 FreeSpace* top() { return top_.Value(); }
1634 void set_top(FreeSpace* top) { top_.SetValue(top); } 1636 void set_top(FreeSpace* top) { top_.SetValue(top); }
1635 1637
1636 FreeSpace* end() const { return end_; } 1638 FreeSpace* end() const { return end_; }
1637 void set_end(FreeSpace* end) { end_ = end; } 1639 void set_end(FreeSpace* end) { end_ = end; }
1638 1640
1639 // |type_|: The type of this free list category. 1641 // |type_|: The type of this free list category.
1640 FreeListCategoryType type_; 1642 FreeListCategoryType type_;
1641 1643
1642 // |top_|: Points to the top FreeSpace* in the free list category. 1644 // |top_|: Points to the top FreeSpace* in the free list category.
1643 AtomicValue<FreeSpace*> top_; 1645 AtomicValue<FreeSpace*> top_;
1644 1646
1645 // |end_|: Points to the end FreeSpace* in the free list category. 1647 // |end_|: Points to the end FreeSpace* in the free list category.
1646 FreeSpace* end_; 1648 FreeSpace* end_;
1647 1649
1648 // |available_|: Total available bytes in all blocks of this free list 1650 // |available_|: Total available bytes in all blocks of this free list
1649 // category. 1651 // category.
1650 int available_; 1652 int available_;
1651 1653
1652 // |owner_|: The owning free list of this category. 1654 // |owner_|: The owning free list of this category.
1653 FreeList* owner_; 1655 FreeList* owner_;
1654 }; 1656 };
1655 1657
1656 1658 // A free list maintaining free blocks of memory. The free list is organized in
1657 // The free list for the old space. The free list is organized in such a way 1659 // a way to encourage objects allocated around the same time to be near each
1658 // as to encourage objects allocated around the same time to be near each 1660 // other. The normal way to allocate is intended to be by bumping a 'top'
1659 // other. The normal way to allocate is intended to be by bumping a 'top'
1660 // pointer until it hits a 'limit' pointer. When the limit is hit we need to 1661 // pointer until it hits a 'limit' pointer. When the limit is hit we need to
1661 // find a new space to allocate from. This is done with the free list, which 1662 // find a new space to allocate from. This is done with the free list, which is
1662 // is divided up into rough categories to cut down on waste. Having finer 1663 // divided up into rough categories to cut down on waste. Having finer
1663 // categories would scatter allocation more. 1664 // categories would scatter allocation more.
1664 1665
1665 // The old space free list is organized in categories. 1666 // The free list is organized in categories as follows:
1666 // 1-31 words: Such small free areas are discarded for efficiency reasons. 1667 // 1-31 words: Such small free areas are discarded for efficiency reasons. They
Hannes Payer (out of office) 2015/10/15 12:23:42 We could call this category "too small". WDYT?
Michael Lippautz 2015/10/15 12:31:34 Done.
1667 // They can be reclaimed by the compactor. However the distance between top 1668 // can be reclaimed by the compactor. However the distance between top and
1668 // and limit may be this small. 1669 // limit may be this small.
1669 // 32-255 words: There is a list of spaces this large. It is used for top and 1670 // 32-255 words (small): Used for allocating free space between 1-31 words in
1670 // limit when the object we need to allocate is 1-31 words in size. These 1671 // size.
1671 // spaces are called small. 1672 // 256-2047 words (medium): Used for allocating free space between 32-255 words
1672 // 256-2047 words: There is a list of spaces this large. It is used for top and 1673 // in size.
1673 // limit when the object we need to allocate is 32-255 words in size. These 1674 // 1048-16383 words (large): Used for allocating free space between 256-2047
1674 // spaces are called medium. 1675 // words in size.
1675 // 1048-16383 words: There is a list of spaces this large. It is used for top 1676 // At least 16384 words (huge): This list is for objects of 2048 words or
1676 // and limit when the object we need to allocate is 256-2047 words in size. 1677 // larger. Empty pages are also added to this list.
1677 // These spaces are call large.
1678 // At least 16384 words. This list is for objects of 2048 words or larger.
1679 // Empty pages are added to this list. These spaces are called huge.
1680 class FreeList { 1678 class FreeList {
1681 public: 1679 public:
1682 explicit FreeList(PagedSpace* owner);
1683
1684 // The method concatenates {other} into {this} and returns the added bytes,
1685 // including waste.
1686 //
1687 // Can be used concurrently.
1688 intptr_t Concatenate(FreeList* other);
1689
1690 // Clear the free list.
1691 void Reset();
1692
1693 void ResetStats() { wasted_bytes_ = 0; }
1694
1695 // Return the number of bytes available on the free list.
1696 intptr_t available() {
1697 return small_list_.available() + medium_list_.available() +
1698 large_list_.available() + huge_list_.available();
1699 }
1700
1701 // Place a node on the free list. The block of size 'size_in_bytes'
1702 // starting at 'start' is placed on the free list. The return value is the
1703 // number of bytes that have been lost due to internal fragmentation by
1704 // freeing the block. Bookkeeping information will be written to the block,
1705 // i.e., its contents will be destroyed. The start address should be word
1706 // aligned, and the size should be a non-zero multiple of the word size.
1707 int Free(Address start, int size_in_bytes);
1708
1709 // This method returns how much memory can be allocated after freeing 1680 // This method returns how much memory can be allocated after freeing
1710 // maximum_freed memory. 1681 // maximum_freed memory.
1711 static inline int GuaranteedAllocatable(int maximum_freed) { 1682 static inline int GuaranteedAllocatable(int maximum_freed) {
1712 if (maximum_freed <= kSmallListMin) { 1683 if (maximum_freed <= kSmallListMin) {
1713 return 0; 1684 return 0;
1714 } else if (maximum_freed <= kSmallListMax) { 1685 } else if (maximum_freed <= kSmallListMax) {
1715 return kSmallAllocationMax; 1686 return kSmallAllocationMax;
1716 } else if (maximum_freed <= kMediumListMax) { 1687 } else if (maximum_freed <= kMediumListMax) {
1717 return kMediumAllocationMax; 1688 return kMediumAllocationMax;
1718 } else if (maximum_freed <= kLargeListMax) { 1689 } else if (maximum_freed <= kLargeListMax) {
1719 return kLargeAllocationMax; 1690 return kLargeAllocationMax;
1720 } 1691 }
1721 return maximum_freed; 1692 return maximum_freed;
1722 } 1693 }
1723 1694
1724 // Allocate a block of size 'size_in_bytes' from the free list. The block 1695 explicit FreeList(PagedSpace* owner);
1725 // is unitialized. A failure is returned if no block is available. 1696
1726 // The size should be a non-zero multiple of the word size. 1697 // The method concatenates {other} into {this} and returns the added bytes,
1698 // including waste.
1699 //
1700 // Note: Concurrency safe.
Hannes Payer (out of office) 2015/10/15 12:23:42 thread-safe.
Michael Lippautz 2015/10/15 12:31:34 Done.
1701 intptr_t Concatenate(FreeList* other);
1702
1703 // Place a node on the free list. The block of size {size_in_bytes} starting
Hannes Payer (out of office) 2015/10/15 12:23:42 Adds
Michael Lippautz 2015/10/15 12:31:34 Done.
1704 // at {start} is placed on the free list. The return value is the number of
1705 // bytes that have been lost due to internal fragmentation by freeing the
Hannes Payer (out of office) 2015/10/15 12:23:42 ...bytes that were not added to the free list, bec
Michael Lippautz 2015/10/15 12:31:34 Done.
1706 // block. Bookkeeping information will be written to the block, i.e., its
1707 // contents will be destroyed. The start address should be word aligned, and
1708 // the size should be a non-zero multiple of the word size.
1709 int Free(Address start, int size_in_bytes);
1710
1711 // Allocate a block of size {size_in_bytes} from the free list. The block is
1712 // unitialized. A failure is returned if no block is available. The size
1713 // should be a non-zero multiple of the word size.
1727 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); 1714 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes);
1728 1715
1716 // Clear the free list.
1717 void Reset();
1718
1719 void ResetStats() { wasted_bytes_ = 0; }
1720
1721 // Return the number of bytes available on the free list.
1722 intptr_t Available() {
1723 return small_list_.available() + medium_list_.available() +
1724 large_list_.available() + huge_list_.available();
1725 }
1726
1729 bool IsEmpty() { 1727 bool IsEmpty() {
1730 return small_list_.IsEmpty() && medium_list_.IsEmpty() && 1728 return small_list_.IsEmpty() && medium_list_.IsEmpty() &&
1731 large_list_.IsEmpty() && huge_list_.IsEmpty(); 1729 large_list_.IsEmpty() && huge_list_.IsEmpty();
1732 } 1730 }
1733 1731
1734 #ifdef DEBUG
1735 void Zap();
1736 intptr_t SumFreeLists();
1737 bool IsVeryLong();
1738 #endif
1739
1740 // Used after booting the VM. 1732 // Used after booting the VM.
1741 void RepairLists(Heap* heap); 1733 void RepairLists(Heap* heap);
1742 1734
1743 intptr_t EvictFreeListItems(Page* p); 1735 intptr_t EvictFreeListItems(Page* p);
1744 bool ContainsPageFreeListItems(Page* p); 1736 bool ContainsPageFreeListItems(Page* p);
1745 1737
1746 PagedSpace* owner() { return owner_; } 1738 PagedSpace* owner() { return owner_; }
1747 intptr_t wasted_bytes() { return wasted_bytes_; } 1739 intptr_t wasted_bytes() { return wasted_bytes_; }
1748 base::Mutex* mutex() { return &mutex_; } 1740 base::Mutex* mutex() { return &mutex_; }
1749 1741
1742 #ifdef DEBUG
1743 void Zap();
1744 intptr_t SumFreeLists();
1745 bool IsVeryLong();
1746 #endif
1747
1750 private: 1748 private:
1751 // The size range of blocks, in bytes. 1749 // The size range of blocks, in bytes.
1752 static const int kMinBlockSize = 3 * kPointerSize; 1750 static const int kMinBlockSize = 3 * kPointerSize;
1753 static const int kMaxBlockSize = Page::kAllocatableMemory; 1751 static const int kMaxBlockSize = Page::kAllocatableMemory;
1754 1752
1755 static const int kSmallListMin = 0x1f * kPointerSize; 1753 static const int kSmallListMin = 0x1f * kPointerSize;
1756 static const int kSmallListMax = 0xff * kPointerSize; 1754 static const int kSmallListMax = 0xff * kPointerSize;
1757 static const int kMediumListMax = 0x7ff * kPointerSize; 1755 static const int kMediumListMax = 0x7ff * kPointerSize;
1758 static const int kLargeListMax = 0x3fff * kPointerSize; 1756 static const int kLargeListMax = 0x3fff * kPointerSize;
1759 static const int kSmallAllocationMax = kSmallListMin; 1757 static const int kSmallAllocationMax = kSmallListMin;
(...skipping 13 matching lines...) Expand all
1773 return &large_list_; 1771 return &large_list_;
1774 case kHuge: 1772 case kHuge:
1775 return &huge_list_; 1773 return &huge_list_;
1776 default: 1774 default:
1777 UNREACHABLE(); 1775 UNREACHABLE();
1778 } 1776 }
1779 UNREACHABLE(); 1777 UNREACHABLE();
1780 return nullptr; 1778 return nullptr;
1781 } 1779 }
1782 1780
1783
1784 PagedSpace* owner_; 1781 PagedSpace* owner_;
1785 Heap* heap_;
1786 base::Mutex mutex_; 1782 base::Mutex mutex_;
1787 intptr_t wasted_bytes_; 1783 intptr_t wasted_bytes_;
1788 FreeListCategory small_list_; 1784 FreeListCategory small_list_;
1789 FreeListCategory medium_list_; 1785 FreeListCategory medium_list_;
1790 FreeListCategory large_list_; 1786 FreeListCategory large_list_;
1791 FreeListCategory huge_list_; 1787 FreeListCategory huge_list_;
1792 1788
1793 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); 1789 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList);
1794 }; 1790 };
1795 1791
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 1891
1896 // Increases the number of available bytes of that space. 1892 // Increases the number of available bytes of that space.
1897 void AddToAccountingStats(intptr_t bytes) { 1893 void AddToAccountingStats(intptr_t bytes) {
1898 accounting_stats_.DeallocateBytes(bytes); 1894 accounting_stats_.DeallocateBytes(bytes);
1899 } 1895 }
1900 1896
1901 // Available bytes without growing. These are the bytes on the free list. 1897 // Available bytes without growing. These are the bytes on the free list.
1902 // The bytes in the linear allocation area are not included in this total 1898 // The bytes in the linear allocation area are not included in this total
1903 // because updating the stats would slow down allocation. New pages are 1899 // because updating the stats would slow down allocation. New pages are
1904 // immediately added to the free list so they show up here. 1900 // immediately added to the free list so they show up here.
1905 intptr_t Available() override { return free_list_.available(); } 1901 intptr_t Available() override { return free_list_.Available(); }
1906 1902
1907 // Allocated bytes in this space. Garbage bytes that were not found due to 1903 // Allocated bytes in this space. Garbage bytes that were not found due to
1908 // concurrent sweeping are counted as being allocated! The bytes in the 1904 // concurrent sweeping are counted as being allocated! The bytes in the
1909 // current linear allocation area (between top and limit) are also counted 1905 // current linear allocation area (between top and limit) are also counted
1910 // here. 1906 // here.
1911 intptr_t Size() override { return accounting_stats_.Size(); } 1907 intptr_t Size() override { return accounting_stats_.Size(); }
1912 1908
1913 // As size, but the bytes in lazily swept pages are estimated and the bytes 1909 // As size, but the bytes in lazily swept pages are estimated and the bytes
1914 // in the current linear allocation area are not included. 1910 // in the current linear allocation area are not included.
1915 intptr_t SizeOfObjects() override; 1911 intptr_t SizeOfObjects() override;
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 count = 0; 3005 count = 0;
3010 } 3006 }
3011 // Must be small, since an iteration is used for lookup. 3007 // Must be small, since an iteration is used for lookup.
3012 static const int kMaxComments = 64; 3008 static const int kMaxComments = 64;
3013 }; 3009 };
3014 #endif 3010 #endif
3015 } // namespace internal 3011 } // namespace internal
3016 } // namespace v8 3012 } // namespace v8
3017 3013
3018 #endif // V8_HEAP_SPACES_H_ 3014 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/spaces.cc » ('j') | src/heap/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698