Chromium Code Reviews| 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 |