| OLD | NEW |
| 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 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 AtomicValue<MemoryChunk*> prev_chunk_; | 717 AtomicValue<MemoryChunk*> prev_chunk_; |
| 718 | 718 |
| 719 private: | 719 private: |
| 720 void InitializeReservedMemory() { reservation_.Reset(); } | 720 void InitializeReservedMemory() { reservation_.Reset(); } |
| 721 | 721 |
| 722 friend class MemoryAllocator; | 722 friend class MemoryAllocator; |
| 723 friend class MemoryChunkValidator; | 723 friend class MemoryChunkValidator; |
| 724 }; | 724 }; |
| 725 | 725 |
| 726 enum FreeListCategoryType { | 726 enum FreeListCategoryType { |
| 727 kTiniest, |
| 728 kTiny, |
| 727 kSmall, | 729 kSmall, |
| 728 kMedium, | 730 kMedium, |
| 729 kLarge, | 731 kLarge, |
| 730 kHuge, | 732 kHuge, |
| 731 | 733 |
| 732 kFirstCategory = kSmall, | 734 kFirstCategory = kTiniest, |
| 733 kLastCategory = kHuge, | 735 kLastCategory = kHuge, |
| 734 kNumberOfCategories = kLastCategory + 1 | 736 kNumberOfCategories = kLastCategory + 1 |
| 735 }; | 737 }; |
| 736 | 738 |
| 737 // ----------------------------------------------------------------------------- | 739 // ----------------------------------------------------------------------------- |
| 738 // A page is a memory chunk of a size 1MB. Large object pages may be larger. | 740 // A page is a memory chunk of a size 1MB. Large object pages may be larger. |
| 739 // | 741 // |
| 740 // The only way to get a page pointer is by calling factory methods: | 742 // The only way to get a page pointer is by calling factory methods: |
| 741 // Page* p = Page::FromAddress(addr); or | 743 // Page* p = Page::FromAddress(addr); or |
| 742 // Page* p = Page::FromAllocationTop(top); | 744 // Page* p = Page::FromAllocationTop(top); |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 | 1645 |
| 1644 // A free list maintaining free blocks of memory. The free list is organized in | 1646 // A free list maintaining free blocks of memory. The free list is organized in |
| 1645 // a way to encourage objects allocated around the same time to be near each | 1647 // a way to encourage objects allocated around the same time to be near each |
| 1646 // other. The normal way to allocate is intended to be by bumping a 'top' | 1648 // other. The normal way to allocate is intended to be by bumping a 'top' |
| 1647 // pointer until it hits a 'limit' pointer. When the limit is hit we need to | 1649 // pointer until it hits a 'limit' pointer. When the limit is hit we need to |
| 1648 // find a new space to allocate from. This is done with the free list, which is | 1650 // find a new space to allocate from. This is done with the free list, which is |
| 1649 // divided up into rough categories to cut down on waste. Having finer | 1651 // divided up into rough categories to cut down on waste. Having finer |
| 1650 // categories would scatter allocation more. | 1652 // categories would scatter allocation more. |
| 1651 | 1653 |
| 1652 // The free list is organized in categories as follows: | 1654 // The free list is organized in categories as follows: |
| 1653 // 1-31 words (too small): Such small free areas are discarded for efficiency | 1655 // kMinBlockSize-10 words (tiniest): The tiniest blocks are only used for |
| 1654 // reasons. They can be reclaimed by the compactor. However the distance | 1656 // allocation, when categories >= small do not have entries anymore. |
| 1655 // between top and limit may be this small. | 1657 // 11-31 words (tiny): The tiny blocks are only used for allocation, when |
| 1658 // categories >= small do not have entries anymore. |
| 1656 // 32-255 words (small): Used for allocating free space between 1-31 words in | 1659 // 32-255 words (small): Used for allocating free space between 1-31 words in |
| 1657 // size. | 1660 // size. |
| 1658 // 256-2047 words (medium): Used for allocating free space between 32-255 words | 1661 // 256-2047 words (medium): Used for allocating free space between 32-255 words |
| 1659 // in size. | 1662 // in size. |
| 1660 // 1048-16383 words (large): Used for allocating free space between 256-2047 | 1663 // 1048-16383 words (large): Used for allocating free space between 256-2047 |
| 1661 // words in size. | 1664 // words in size. |
| 1662 // At least 16384 words (huge): This list is for objects of 2048 words or | 1665 // At least 16384 words (huge): This list is for objects of 2048 words or |
| 1663 // larger. Empty pages are also added to this list. | 1666 // larger. Empty pages are also added to this list. |
| 1664 class FreeList { | 1667 class FreeList { |
| 1665 public: | 1668 public: |
| 1666 // This method returns how much memory can be allocated after freeing | 1669 // This method returns how much memory can be allocated after freeing |
| 1667 // maximum_freed memory. | 1670 // maximum_freed memory. |
| 1668 static inline int GuaranteedAllocatable(int maximum_freed) { | 1671 static inline int GuaranteedAllocatable(int maximum_freed) { |
| 1669 if (maximum_freed <= kSmallListMin) { | 1672 if (maximum_freed <= kTiniestListMax) { |
| 1673 // Since we are not iterating over all list entries, we cannot guarantee |
| 1674 // that we can find the maximum freed block in that free list. |
| 1670 return 0; | 1675 return 0; |
| 1676 } else if (maximum_freed <= kTinyListMax) { |
| 1677 return kTinyAllocationMax; |
| 1671 } else if (maximum_freed <= kSmallListMax) { | 1678 } else if (maximum_freed <= kSmallListMax) { |
| 1672 return kSmallAllocationMax; | 1679 return kSmallAllocationMax; |
| 1673 } else if (maximum_freed <= kMediumListMax) { | 1680 } else if (maximum_freed <= kMediumListMax) { |
| 1674 return kMediumAllocationMax; | 1681 return kMediumAllocationMax; |
| 1675 } else if (maximum_freed <= kLargeListMax) { | 1682 } else if (maximum_freed <= kLargeListMax) { |
| 1676 return kLargeAllocationMax; | 1683 return kLargeAllocationMax; |
| 1677 } | 1684 } |
| 1678 return maximum_freed; | 1685 return maximum_freed; |
| 1679 } | 1686 } |
| 1680 | 1687 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1742 void Zap(); | 1749 void Zap(); |
| 1743 intptr_t SumFreeLists(); | 1750 intptr_t SumFreeLists(); |
| 1744 bool IsVeryLong(); | 1751 bool IsVeryLong(); |
| 1745 #endif | 1752 #endif |
| 1746 | 1753 |
| 1747 private: | 1754 private: |
| 1748 // The size range of blocks, in bytes. | 1755 // The size range of blocks, in bytes. |
| 1749 static const int kMinBlockSize = 3 * kPointerSize; | 1756 static const int kMinBlockSize = 3 * kPointerSize; |
| 1750 static const int kMaxBlockSize = Page::kAllocatableMemory; | 1757 static const int kMaxBlockSize = Page::kAllocatableMemory; |
| 1751 | 1758 |
| 1752 static const int kSmallListMin = 0x1f * kPointerSize; | 1759 static const int kTiniestListMax = 0xa * kPointerSize; |
| 1760 static const int kTinyListMax = 0x1f * kPointerSize; |
| 1753 static const int kSmallListMax = 0xff * kPointerSize; | 1761 static const int kSmallListMax = 0xff * kPointerSize; |
| 1754 static const int kMediumListMax = 0x7ff * kPointerSize; | 1762 static const int kMediumListMax = 0x7ff * kPointerSize; |
| 1755 static const int kLargeListMax = 0x3fff * kPointerSize; | 1763 static const int kLargeListMax = 0x3fff * kPointerSize; |
| 1756 static const int kSmallAllocationMax = kSmallListMin; | 1764 static const int kTinyAllocationMax = kTiniestListMax; |
| 1765 static const int kSmallAllocationMax = kTinyListMax; |
| 1757 static const int kMediumAllocationMax = kSmallListMax; | 1766 static const int kMediumAllocationMax = kSmallListMax; |
| 1758 static const int kLargeAllocationMax = kMediumListMax; | 1767 static const int kLargeAllocationMax = kMediumListMax; |
| 1759 | 1768 |
| 1760 FreeSpace* FindNodeFor(int size_in_bytes, int* node_size); | 1769 FreeSpace* FindNodeFor(int size_in_bytes, int* node_size); |
| 1761 FreeSpace* FindNodeIn(FreeListCategoryType category, int* node_size); | 1770 FreeSpace* FindNodeIn(FreeListCategoryType category, int* node_size); |
| 1762 | 1771 |
| 1763 FreeListCategory* GetFreeListCategory(FreeListCategoryType category) { | 1772 FreeListCategory* GetFreeListCategory(FreeListCategoryType category) { |
| 1764 return &category_[category]; | 1773 return &category_[category]; |
| 1765 } | 1774 } |
| 1766 | 1775 |
| 1767 FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes) { | 1776 FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes) { |
| 1768 if (size_in_bytes <= kSmallListMax) { | 1777 if (size_in_bytes <= kTiniestListMax) { |
| 1778 return kTiniest; |
| 1779 } else if (size_in_bytes <= kTinyListMax) { |
| 1780 return kTiny; |
| 1781 } else if (size_in_bytes <= kSmallListMax) { |
| 1769 return kSmall; | 1782 return kSmall; |
| 1770 } else if (size_in_bytes <= kMediumListMax) { | 1783 } else if (size_in_bytes <= kMediumListMax) { |
| 1771 return kMedium; | 1784 return kMedium; |
| 1772 } else if (size_in_bytes <= kLargeListMax) { | 1785 } else if (size_in_bytes <= kLargeListMax) { |
| 1773 return kLarge; | 1786 return kLarge; |
| 1774 } | 1787 } |
| 1775 return kHuge; | 1788 return kHuge; |
| 1776 } | 1789 } |
| 1777 | 1790 |
| 1791 // The tiny categories are not used for fast allocation. |
| 1778 FreeListCategoryType SelectFastAllocationFreeListCategoryType( | 1792 FreeListCategoryType SelectFastAllocationFreeListCategoryType( |
| 1779 size_t size_in_bytes) { | 1793 size_t size_in_bytes) { |
| 1780 if (size_in_bytes <= kSmallAllocationMax) { | 1794 if (size_in_bytes <= kSmallAllocationMax) { |
| 1781 return kSmall; | 1795 return kSmall; |
| 1782 } else if (size_in_bytes <= kMediumAllocationMax) { | 1796 } else if (size_in_bytes <= kMediumAllocationMax) { |
| 1783 return kMedium; | 1797 return kMedium; |
| 1784 } else if (size_in_bytes <= kLargeAllocationMax) { | 1798 } else if (size_in_bytes <= kLargeAllocationMax) { |
| 1785 return kLarge; | 1799 return kLarge; |
| 1786 } | 1800 } |
| 1787 return kHuge; | 1801 return kHuge; |
| (...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 count = 0; | 3058 count = 0; |
| 3045 } | 3059 } |
| 3046 // Must be small, since an iteration is used for lookup. | 3060 // Must be small, since an iteration is used for lookup. |
| 3047 static const int kMaxComments = 64; | 3061 static const int kMaxComments = 64; |
| 3048 }; | 3062 }; |
| 3049 #endif | 3063 #endif |
| 3050 } // namespace internal | 3064 } // namespace internal |
| 3051 } // namespace v8 | 3065 } // namespace v8 |
| 3052 | 3066 |
| 3053 #endif // V8_HEAP_SPACES_H_ | 3067 #endif // V8_HEAP_SPACES_H_ |
| OLD | NEW |