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 |