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

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: 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 | « no previous file | src/heap/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 #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: Thread-safe.
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 // For debug builds we accurately compute free lists lengths up until
1634 // {kVeryLongFreeList} by manually walking the list.
1635 static const int kVeryLongFreeList = 500;
1636
1633 FreeSpace* top() { return top_.Value(); } 1637 FreeSpace* top() { return top_.Value(); }
1634 void set_top(FreeSpace* top) { top_.SetValue(top); } 1638 void set_top(FreeSpace* top) { top_.SetValue(top); }
1635 1639
1636 FreeSpace* end() const { return end_; } 1640 FreeSpace* end() const { return end_; }
1637 void set_end(FreeSpace* end) { end_ = end; } 1641 void set_end(FreeSpace* end) { end_ = end; }
1638 1642
1639 // |type_|: The type of this free list category. 1643 // |type_|: The type of this free list category.
1640 FreeListCategoryType type_; 1644 FreeListCategoryType type_;
1641 1645
1642 // |top_|: Points to the top FreeSpace* in the free list category. 1646 // |top_|: Points to the top FreeSpace* in the free list category.
1643 AtomicValue<FreeSpace*> top_; 1647 AtomicValue<FreeSpace*> top_;
1644 1648
1645 // |end_|: Points to the end FreeSpace* in the free list category. 1649 // |end_|: Points to the end FreeSpace* in the free list category.
1646 FreeSpace* end_; 1650 FreeSpace* end_;
1647 1651
1648 // |available_|: Total available bytes in all blocks of this free list 1652 // |available_|: Total available bytes in all blocks of this free list
1649 // category. 1653 // category.
1650 int available_; 1654 int available_;
1651 1655
1652 // |owner_|: The owning free list of this category. 1656 // |owner_|: The owning free list of this category.
1653 FreeList* owner_; 1657 FreeList* owner_;
1654 }; 1658 };
1655 1659
1656 1660 // 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 1661 // 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 1662 // 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 1663 // 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 1664 // 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 1665 // divided up into rough categories to cut down on waste. Having finer
1663 // categories would scatter allocation more. 1666 // categories would scatter allocation more.
1664 1667
1665 // The old space free list is organized in categories. 1668 // The free list is organized in categories as follows:
1666 // 1-31 words: Such small free areas are discarded for efficiency reasons. 1669 // 1-31 words (too small): Such small free areas are discarded for efficiency
1667 // They can be reclaimed by the compactor. However the distance between top 1670 // reasons. They can be reclaimed by the compactor. However the distance
1668 // and limit may be this small. 1671 // between top and limit may be this small.
1669 // 32-255 words: There is a list of spaces this large. It is used for top and 1672 // 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 1673 // size.
1671 // spaces are called small. 1674 // 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 1675 // in size.
1673 // limit when the object we need to allocate is 32-255 words in size. These 1676 // 1048-16383 words (large): Used for allocating free space between 256-2047
1674 // spaces are called medium. 1677 // words in size.
1675 // 1048-16383 words: There is a list of spaces this large. It is used for top 1678 // 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. 1679 // 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 { 1680 class FreeList {
1681 public: 1681 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 1682 // This method returns how much memory can be allocated after freeing
1710 // maximum_freed memory. 1683 // maximum_freed memory.
1711 static inline int GuaranteedAllocatable(int maximum_freed) { 1684 static inline int GuaranteedAllocatable(int maximum_freed) {
1712 if (maximum_freed <= kSmallListMin) { 1685 if (maximum_freed <= kSmallListMin) {
1713 return 0; 1686 return 0;
1714 } else if (maximum_freed <= kSmallListMax) { 1687 } else if (maximum_freed <= kSmallListMax) {
1715 return kSmallAllocationMax; 1688 return kSmallAllocationMax;
1716 } else if (maximum_freed <= kMediumListMax) { 1689 } else if (maximum_freed <= kMediumListMax) {
1717 return kMediumAllocationMax; 1690 return kMediumAllocationMax;
1718 } else if (maximum_freed <= kLargeListMax) { 1691 } else if (maximum_freed <= kLargeListMax) {
1719 return kLargeAllocationMax; 1692 return kLargeAllocationMax;
1720 } 1693 }
1721 return maximum_freed; 1694 return maximum_freed;
1722 } 1695 }
1723 1696
1724 // Allocate a block of size 'size_in_bytes' from the free list. The block 1697 explicit FreeList(PagedSpace* owner);
1725 // is unitialized. A failure is returned if no block is available. 1698
1726 // The size should be a non-zero multiple of the word size. 1699 // The method concatenates {other} into {this} and returns the added bytes,
1700 // including waste.
1701 //
1702 // Note: Thread-safe.
1703 intptr_t Concatenate(FreeList* other);
1704
1705 // Adds a node on the free list. The block of size {size_in_bytes} starting
1706 // at {start} is placed on the free list. The return value is the number of
1707 // bytes that were not added to the free list, because they freed memory block
1708 // was too small. Bookkeeping information will be written to the block, i.e.,
1709 // its contents will be destroyed. The start address should be word aligned,
1710 // and the size should be a non-zero multiple of the word size.
1711 int Free(Address start, int size_in_bytes);
1712
1713 // Allocate a block of size {size_in_bytes} from the free list. The block is
1714 // unitialized. A failure is returned if no block is available. The size
1715 // should be a non-zero multiple of the word size.
1727 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); 1716 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes);
1728 1717
1718 // Clear the free list.
1719 void Reset();
1720
1721 void ResetStats() { wasted_bytes_ = 0; }
1722
1723 // Return the number of bytes available on the free list.
1724 intptr_t Available() {
1725 return small_list_.available() + medium_list_.available() +
1726 large_list_.available() + huge_list_.available();
1727 }
1728
1729 bool IsEmpty() { 1729 bool IsEmpty() {
1730 return small_list_.IsEmpty() && medium_list_.IsEmpty() && 1730 return small_list_.IsEmpty() && medium_list_.IsEmpty() &&
1731 large_list_.IsEmpty() && huge_list_.IsEmpty(); 1731 large_list_.IsEmpty() && huge_list_.IsEmpty();
1732 } 1732 }
1733 1733
1734 #ifdef DEBUG
1735 void Zap();
1736 intptr_t SumFreeLists();
1737 bool IsVeryLong();
1738 #endif
1739
1740 // Used after booting the VM. 1734 // Used after booting the VM.
1741 void RepairLists(Heap* heap); 1735 void RepairLists(Heap* heap);
1742 1736
1743 intptr_t EvictFreeListItems(Page* p); 1737 intptr_t EvictFreeListItems(Page* p);
1744 bool ContainsPageFreeListItems(Page* p); 1738 bool ContainsPageFreeListItems(Page* p);
1745 1739
1746 PagedSpace* owner() { return owner_; } 1740 PagedSpace* owner() { return owner_; }
1747 intptr_t wasted_bytes() { return wasted_bytes_; } 1741 intptr_t wasted_bytes() { return wasted_bytes_; }
1748 base::Mutex* mutex() { return &mutex_; } 1742 base::Mutex* mutex() { return &mutex_; }
1749 1743
1744 #ifdef DEBUG
1745 void Zap();
1746 intptr_t SumFreeLists();
1747 bool IsVeryLong();
1748 #endif
1749
1750 private: 1750 private:
1751 // The size range of blocks, in bytes. 1751 // The size range of blocks, in bytes.
1752 static const int kMinBlockSize = 3 * kPointerSize; 1752 static const int kMinBlockSize = 3 * kPointerSize;
1753 static const int kMaxBlockSize = Page::kAllocatableMemory; 1753 static const int kMaxBlockSize = Page::kAllocatableMemory;
1754 1754
1755 static const int kSmallListMin = 0x1f * kPointerSize; 1755 static const int kSmallListMin = 0x1f * kPointerSize;
1756 static const int kSmallListMax = 0xff * kPointerSize; 1756 static const int kSmallListMax = 0xff * kPointerSize;
1757 static const int kMediumListMax = 0x7ff * kPointerSize; 1757 static const int kMediumListMax = 0x7ff * kPointerSize;
1758 static const int kLargeListMax = 0x3fff * kPointerSize; 1758 static const int kLargeListMax = 0x3fff * kPointerSize;
1759 static const int kSmallAllocationMax = kSmallListMin; 1759 static const int kSmallAllocationMax = kSmallListMin;
(...skipping 13 matching lines...) Expand all
1773 return &large_list_; 1773 return &large_list_;
1774 case kHuge: 1774 case kHuge:
1775 return &huge_list_; 1775 return &huge_list_;
1776 default: 1776 default:
1777 UNREACHABLE(); 1777 UNREACHABLE();
1778 } 1778 }
1779 UNREACHABLE(); 1779 UNREACHABLE();
1780 return nullptr; 1780 return nullptr;
1781 } 1781 }
1782 1782
1783
1784 PagedSpace* owner_; 1783 PagedSpace* owner_;
1785 Heap* heap_;
1786 base::Mutex mutex_; 1784 base::Mutex mutex_;
1787 intptr_t wasted_bytes_; 1785 intptr_t wasted_bytes_;
1788 FreeListCategory small_list_; 1786 FreeListCategory small_list_;
1789 FreeListCategory medium_list_; 1787 FreeListCategory medium_list_;
1790 FreeListCategory large_list_; 1788 FreeListCategory large_list_;
1791 FreeListCategory huge_list_; 1789 FreeListCategory huge_list_;
1792 1790
1793 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList); 1791 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList);
1794 }; 1792 };
1795 1793
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 1893
1896 // Increases the number of available bytes of that space. 1894 // Increases the number of available bytes of that space.
1897 void AddToAccountingStats(intptr_t bytes) { 1895 void AddToAccountingStats(intptr_t bytes) {
1898 accounting_stats_.DeallocateBytes(bytes); 1896 accounting_stats_.DeallocateBytes(bytes);
1899 } 1897 }
1900 1898
1901 // Available bytes without growing. These are the bytes on the free list. 1899 // 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 1900 // 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 1901 // because updating the stats would slow down allocation. New pages are
1904 // immediately added to the free list so they show up here. 1902 // immediately added to the free list so they show up here.
1905 intptr_t Available() override { return free_list_.available(); } 1903 intptr_t Available() override { return free_list_.Available(); }
1906 1904
1907 // Allocated bytes in this space. Garbage bytes that were not found due to 1905 // 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 1906 // concurrent sweeping are counted as being allocated! The bytes in the
1909 // current linear allocation area (between top and limit) are also counted 1907 // current linear allocation area (between top and limit) are also counted
1910 // here. 1908 // here.
1911 intptr_t Size() override { return accounting_stats_.Size(); } 1909 intptr_t Size() override { return accounting_stats_.Size(); }
1912 1910
1913 // As size, but the bytes in lazily swept pages are estimated and the bytes 1911 // As size, but the bytes in lazily swept pages are estimated and the bytes
1914 // in the current linear allocation area are not included. 1912 // in the current linear allocation area are not included.
1915 intptr_t SizeOfObjects() override; 1913 intptr_t SizeOfObjects() override;
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after
3009 count = 0; 3007 count = 0;
3010 } 3008 }
3011 // Must be small, since an iteration is used for lookup. 3009 // Must be small, since an iteration is used for lookup.
3012 static const int kMaxComments = 64; 3010 static const int kMaxComments = 64;
3013 }; 3011 };
3014 #endif 3012 #endif
3015 } // namespace internal 3013 } // namespace internal
3016 } // namespace v8 3014 } // namespace v8
3017 3015
3018 #endif // V8_HEAP_SPACES_H_ 3016 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698