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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
745 AtomicValue<MemoryChunk*> prev_chunk_; | 745 AtomicValue<MemoryChunk*> prev_chunk_; |
746 | 746 |
747 private: | 747 private: |
748 void InitializeReservedMemory() { reservation_.Reset(); } | 748 void InitializeReservedMemory() { reservation_.Reset(); } |
749 | 749 |
750 friend class MemoryAllocator; | 750 friend class MemoryAllocator; |
751 friend class MemoryChunkValidator; | 751 friend class MemoryChunkValidator; |
752 }; | 752 }; |
753 | 753 |
754 | 754 |
755 enum FreeListCategoryType { kSmall, kMedium, kLarge, kHuge }; | |
Michael Lippautz
2015/10/01 12:06:59
This one will come in handy for programmatically s
| |
756 | |
757 | |
755 // ----------------------------------------------------------------------------- | 758 // ----------------------------------------------------------------------------- |
756 // A page is a memory chunk of a size 1MB. Large object pages may be larger. | 759 // A page is a memory chunk of a size 1MB. Large object pages may be larger. |
757 // | 760 // |
758 // The only way to get a page pointer is by calling factory methods: | 761 // The only way to get a page pointer is by calling factory methods: |
759 // Page* p = Page::FromAddress(addr); or | 762 // Page* p = Page::FromAddress(addr); or |
760 // Page* p = Page::FromAllocationTop(top); | 763 // Page* p = Page::FromAllocationTop(top); |
761 class Page : public MemoryChunk { | 764 class Page : public MemoryChunk { |
762 public: | 765 public: |
763 // Returns the page containing a given address. The address ranges | 766 // Returns the page containing a given address. The address ranges |
764 // from [page_addr .. page_addr + kPageSize[ | 767 // from [page_addr .. page_addr + kPageSize[ |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
846 void add_##name(type name) { name##_.Increment(name); } | 849 void add_##name(type name) { name##_.Increment(name); } |
847 | 850 |
848 FRAGMENTATION_STATS_ACCESSORS(intptr_t, non_available_small_blocks) | 851 FRAGMENTATION_STATS_ACCESSORS(intptr_t, non_available_small_blocks) |
849 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_small_free_list) | 852 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_small_free_list) |
850 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_medium_free_list) | 853 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_medium_free_list) |
851 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_large_free_list) | 854 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_large_free_list) |
852 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_huge_free_list) | 855 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_huge_free_list) |
853 | 856 |
854 #undef FRAGMENTATION_STATS_ACCESSORS | 857 #undef FRAGMENTATION_STATS_ACCESSORS |
855 | 858 |
859 void add_available_in_free_list(FreeListCategoryType type, intptr_t bytes) { | |
860 switch (type) { | |
861 case kSmall: | |
862 add_available_in_small_free_list(bytes); | |
863 break; | |
864 case kMedium: | |
865 add_available_in_medium_free_list(bytes); | |
866 break; | |
867 case kLarge: | |
868 add_available_in_large_free_list(bytes); | |
869 break; | |
870 case kHuge: | |
871 add_available_in_huge_free_list(bytes); | |
872 break; | |
873 default: | |
874 UNREACHABLE(); | |
875 } | |
876 } | |
877 | |
856 #ifdef DEBUG | 878 #ifdef DEBUG |
857 void Print(); | 879 void Print(); |
858 #endif // DEBUG | 880 #endif // DEBUG |
859 | 881 |
860 friend class MemoryAllocator; | 882 friend class MemoryAllocator; |
861 }; | 883 }; |
862 | 884 |
863 | 885 |
864 class LargePage : public MemoryChunk { | 886 class LargePage : public MemoryChunk { |
865 public: | 887 public: |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1511 }; | 1533 }; |
1512 | 1534 |
1513 | 1535 |
1514 // ----------------------------------------------------------------------------- | 1536 // ----------------------------------------------------------------------------- |
1515 // Free lists for old object spaces | 1537 // Free lists for old object spaces |
1516 | 1538 |
1517 // The free list category holds a pointer to the top element and a pointer to | 1539 // The free list category holds a pointer to the top element and a pointer to |
1518 // the end element of the linked list of free memory blocks. | 1540 // the end element of the linked list of free memory blocks. |
1519 class FreeListCategory { | 1541 class FreeListCategory { |
1520 public: | 1542 public: |
1521 explicit FreeListCategory(FreeList* owner) | 1543 explicit FreeListCategory(FreeList* owner, FreeListCategoryType type) |
1522 : top_(0), end_(NULL), available_(0), owner_(owner) {} | 1544 : type_(type), |
1545 top_(nullptr), | |
1546 end_(nullptr), | |
1547 available_(0), | |
1548 owner_(owner) {} | |
1523 | 1549 |
1524 intptr_t Concatenate(FreeListCategory* category); | 1550 intptr_t Concatenate(FreeListCategory* category); |
1525 | 1551 |
1526 void Reset(); | 1552 void Reset(); |
1527 | 1553 |
1528 void Free(FreeSpace* node, int size_in_bytes); | 1554 void Free(FreeSpace* node, int size_in_bytes); |
1529 | 1555 |
1556 // Pick a node from the list. | |
1530 FreeSpace* PickNodeFromList(int* node_size); | 1557 FreeSpace* PickNodeFromList(int* node_size); |
1558 | |
1559 // Pick a node from the list and compare it against {size_in_bytes}. If the | |
1560 // node's size is greater or equal return the node and null otherwise. | |
1531 FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size); | 1561 FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size); |
1532 | 1562 |
1563 // Search for a node of size {size_in_bytes}. | |
1564 FreeSpace* SearchForNodeInList(int size_in_bytes, int* node_size); | |
1565 | |
1533 intptr_t EvictFreeListItemsInList(Page* p); | 1566 intptr_t EvictFreeListItemsInList(Page* p); |
1534 bool ContainsPageFreeListItemsInList(Page* p); | 1567 bool ContainsPageFreeListItemsInList(Page* p); |
1535 | 1568 |
1536 void RepairFreeList(Heap* heap); | 1569 void RepairFreeList(Heap* heap); |
1537 | 1570 |
1538 FreeSpace* top() const { | 1571 bool IsEmpty() { return top() == nullptr; } |
1539 return reinterpret_cast<FreeSpace*>(base::NoBarrier_Load(&top_)); | |
1540 } | |
1541 | 1572 |
1542 void set_top(FreeSpace* top) { | 1573 FreeList* owner() { return owner_; } |
1543 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); | |
1544 } | |
1545 | |
1546 FreeSpace* end() const { return end_; } | |
1547 void set_end(FreeSpace* end) { end_ = end; } | |
1548 | |
1549 int* GetAvailableAddress() { return &available_; } | |
1550 int available() const { return available_; } | 1574 int available() const { return available_; } |
1551 void set_available(int available) { available_ = available; } | |
1552 | |
1553 bool IsEmpty() { return top() == 0; } | |
1554 | 1575 |
1555 #ifdef DEBUG | 1576 #ifdef DEBUG |
1556 intptr_t SumFreeList(); | 1577 intptr_t SumFreeList(); |
1557 int FreeListLength(); | 1578 int FreeListLength(); |
1558 #endif | 1579 #endif |
1559 | 1580 |
1560 FreeList* owner() { return owner_; } | 1581 private: |
1582 FreeSpace* top() { return top_.Value(); } | |
1583 void set_top(FreeSpace* top) { top_.SetValue(top); } | |
1561 | 1584 |
1562 private: | 1585 FreeSpace* end() const { return end_; } |
1563 // top_ points to the top FreeSpace* in the free list category. | 1586 void set_end(FreeSpace* end) { end_ = end; } |
1564 base::AtomicWord top_; | 1587 |
1588 // |type_|: The type of this free list category. | |
1589 FreeListCategoryType type_; | |
1590 | |
1591 // |top_|: Points to the top FreeSpace* in the free list category. | |
1592 AtomicValue<FreeSpace*> top_; | |
1593 | |
1594 // |end_|: Points to the end FreeSpace* in the free list category. | |
1565 FreeSpace* end_; | 1595 FreeSpace* end_; |
1566 // Total available bytes in all blocks of this free list category. | 1596 |
1597 // |available_|: Total available bytes in all blocks of this free list | |
1598 // category. | |
1567 int available_; | 1599 int available_; |
1568 | 1600 |
1601 // |owner_|: The owning free list of this category. | |
1569 FreeList* owner_; | 1602 FreeList* owner_; |
1570 }; | 1603 }; |
1571 | 1604 |
1572 | 1605 |
1573 // The free list for the old space. The free list is organized in such a way | 1606 // The free list for the old space. The free list is organized in such a way |
1574 // as to encourage objects allocated around the same time to be near each | 1607 // as to encourage objects allocated around the same time to be near each |
1575 // other. The normal way to allocate is intended to be by bumping a 'top' | 1608 // other. The normal way to allocate is intended to be by bumping a 'top' |
1576 // pointer until it hits a 'limit' pointer. When the limit is hit we need to | 1609 // pointer until it hits a 'limit' pointer. When the limit is hit we need to |
1577 // find a new space to allocate from. This is done with the free list, which | 1610 // find a new space to allocate from. This is done with the free list, which |
1578 // is divided up into rough categories to cut down on waste. Having finer | 1611 // is divided up into rough categories to cut down on waste. Having finer |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2954 count = 0; | 2987 count = 0; |
2955 } | 2988 } |
2956 // Must be small, since an iteration is used for lookup. | 2989 // Must be small, since an iteration is used for lookup. |
2957 static const int kMaxComments = 64; | 2990 static const int kMaxComments = 64; |
2958 }; | 2991 }; |
2959 #endif | 2992 #endif |
2960 } // namespace internal | 2993 } // namespace internal |
2961 } // namespace v8 | 2994 } // namespace v8 |
2962 | 2995 |
2963 #endif // V8_HEAP_SPACES_H_ | 2996 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |