| 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/base/atomicops.h" | 9 #include "src/base/atomicops.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 private: | 1404 private: |
| 1405 intptr_t capacity_; | 1405 intptr_t capacity_; |
| 1406 intptr_t max_capacity_; | 1406 intptr_t max_capacity_; |
| 1407 intptr_t size_; | 1407 intptr_t size_; |
| 1408 intptr_t waste_; | 1408 intptr_t waste_; |
| 1409 }; | 1409 }; |
| 1410 | 1410 |
| 1411 | 1411 |
| 1412 // ----------------------------------------------------------------------------- | 1412 // ----------------------------------------------------------------------------- |
| 1413 // Free lists for old object spaces | 1413 // Free lists for old object spaces |
| 1414 // | |
| 1415 // Free-list nodes are free blocks in the heap. They look like heap objects | |
| 1416 // (free-list node pointers have the heap object tag, and they have a map like | |
| 1417 // a heap object). They have a size and a next pointer. The next pointer is | |
| 1418 // the raw address of the next free list node (or NULL). | |
| 1419 class FreeListNode : public HeapObject { | |
| 1420 public: | |
| 1421 // Obtain a free-list node from a raw address. This is not a cast because | |
| 1422 // it does not check nor require that the first word at the address is a map | |
| 1423 // pointer. | |
| 1424 static FreeListNode* FromAddress(Address address) { | |
| 1425 return reinterpret_cast<FreeListNode*>(HeapObject::FromAddress(address)); | |
| 1426 } | |
| 1427 | |
| 1428 static inline bool IsFreeListNode(HeapObject* object); | |
| 1429 | |
| 1430 // Set the size in bytes, which can be read with HeapObject::Size(). This | |
| 1431 // function also writes a map to the first word of the block so that it | |
| 1432 // looks like a heap object to the garbage collector and heap iteration | |
| 1433 // functions. | |
| 1434 void set_size(Heap* heap, int size_in_bytes); | |
| 1435 | |
| 1436 // Accessors for the next field. | |
| 1437 inline FreeListNode* next(); | |
| 1438 inline FreeListNode** next_address(); | |
| 1439 inline void set_next(FreeListNode* next); | |
| 1440 | |
| 1441 inline void Zap(); | |
| 1442 | |
| 1443 static inline FreeListNode* cast(Object* object) { | |
| 1444 return reinterpret_cast<FreeListNode*>(object); | |
| 1445 } | |
| 1446 | |
| 1447 private: | |
| 1448 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); | |
| 1449 | |
| 1450 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); | |
| 1451 }; | |
| 1452 | |
| 1453 | 1414 |
| 1454 // The free list category holds a pointer to the top element and a pointer to | 1415 // The free list category holds a pointer to the top element and a pointer to |
| 1455 // the end element of the linked list of free memory blocks. | 1416 // the end element of the linked list of free memory blocks. |
| 1456 class FreeListCategory { | 1417 class FreeListCategory { |
| 1457 public: | 1418 public: |
| 1458 FreeListCategory() : top_(0), end_(NULL), available_(0) {} | 1419 FreeListCategory() : top_(0), end_(NULL), available_(0) {} |
| 1459 | 1420 |
| 1460 intptr_t Concatenate(FreeListCategory* category); | 1421 intptr_t Concatenate(FreeListCategory* category); |
| 1461 | 1422 |
| 1462 void Reset(); | 1423 void Reset(); |
| 1463 | 1424 |
| 1464 void Free(FreeListNode* node, int size_in_bytes); | 1425 void Free(FreeSpace* node, int size_in_bytes); |
| 1465 | 1426 |
| 1466 FreeListNode* PickNodeFromList(int* node_size); | 1427 FreeSpace* PickNodeFromList(int* node_size); |
| 1467 FreeListNode* PickNodeFromList(int size_in_bytes, int* node_size); | 1428 FreeSpace* PickNodeFromList(int size_in_bytes, int* node_size); |
| 1468 | 1429 |
| 1469 intptr_t EvictFreeListItemsInList(Page* p); | 1430 intptr_t EvictFreeListItemsInList(Page* p); |
| 1470 bool ContainsPageFreeListItemsInList(Page* p); | 1431 bool ContainsPageFreeListItemsInList(Page* p); |
| 1471 | 1432 |
| 1472 void RepairFreeList(Heap* heap); | 1433 void RepairFreeList(Heap* heap); |
| 1473 | 1434 |
| 1474 FreeListNode* top() const { | 1435 FreeSpace* top() const { |
| 1475 return reinterpret_cast<FreeListNode*>(base::NoBarrier_Load(&top_)); | 1436 return reinterpret_cast<FreeSpace*>(base::NoBarrier_Load(&top_)); |
| 1476 } | 1437 } |
| 1477 | 1438 |
| 1478 void set_top(FreeListNode* top) { | 1439 void set_top(FreeSpace* top) { |
| 1479 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); | 1440 base::NoBarrier_Store(&top_, reinterpret_cast<base::AtomicWord>(top)); |
| 1480 } | 1441 } |
| 1481 | 1442 |
| 1482 FreeListNode** GetEndAddress() { return &end_; } | 1443 FreeSpace* end() const { return end_; } |
| 1483 FreeListNode* end() const { return end_; } | 1444 void set_end(FreeSpace* end) { end_ = end; } |
| 1484 void set_end(FreeListNode* end) { end_ = end; } | |
| 1485 | 1445 |
| 1486 int* GetAvailableAddress() { return &available_; } | 1446 int* GetAvailableAddress() { return &available_; } |
| 1487 int available() const { return available_; } | 1447 int available() const { return available_; } |
| 1488 void set_available(int available) { available_ = available; } | 1448 void set_available(int available) { available_ = available; } |
| 1489 | 1449 |
| 1490 base::Mutex* mutex() { return &mutex_; } | 1450 base::Mutex* mutex() { return &mutex_; } |
| 1491 | 1451 |
| 1492 bool IsEmpty() { return top() == 0; } | 1452 bool IsEmpty() { return top() == 0; } |
| 1493 | 1453 |
| 1494 #ifdef DEBUG | 1454 #ifdef DEBUG |
| 1495 intptr_t SumFreeList(); | 1455 intptr_t SumFreeList(); |
| 1496 int FreeListLength(); | 1456 int FreeListLength(); |
| 1497 #endif | 1457 #endif |
| 1498 | 1458 |
| 1499 private: | 1459 private: |
| 1500 // top_ points to the top FreeListNode* in the free list category. | 1460 // top_ points to the top FreeSpace* in the free list category. |
| 1501 base::AtomicWord top_; | 1461 base::AtomicWord top_; |
| 1502 FreeListNode* end_; | 1462 FreeSpace* end_; |
| 1503 base::Mutex mutex_; | 1463 base::Mutex mutex_; |
| 1504 | 1464 |
| 1505 // Total available bytes in all blocks of this free list category. | 1465 // Total available bytes in all blocks of this free list category. |
| 1506 int available_; | 1466 int available_; |
| 1507 }; | 1467 }; |
| 1508 | 1468 |
| 1509 | 1469 |
| 1510 // The free list for the old space. The free list is organized in such a way | 1470 // The free list for the old space. The free list is organized in such a way |
| 1511 // as to encourage objects allocated around the same time to be near each | 1471 // as to encourage objects allocated around the same time to be near each |
| 1512 // other. The normal way to allocate is intended to be by bumping a 'top' | 1472 // other. The normal way to allocate is intended to be by bumping a 'top' |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 void RepairLists(Heap* heap); | 1549 void RepairLists(Heap* heap); |
| 1590 | 1550 |
| 1591 intptr_t EvictFreeListItems(Page* p); | 1551 intptr_t EvictFreeListItems(Page* p); |
| 1592 bool ContainsPageFreeListItems(Page* p); | 1552 bool ContainsPageFreeListItems(Page* p); |
| 1593 | 1553 |
| 1594 FreeListCategory* small_list() { return &small_list_; } | 1554 FreeListCategory* small_list() { return &small_list_; } |
| 1595 FreeListCategory* medium_list() { return &medium_list_; } | 1555 FreeListCategory* medium_list() { return &medium_list_; } |
| 1596 FreeListCategory* large_list() { return &large_list_; } | 1556 FreeListCategory* large_list() { return &large_list_; } |
| 1597 FreeListCategory* huge_list() { return &huge_list_; } | 1557 FreeListCategory* huge_list() { return &huge_list_; } |
| 1598 | 1558 |
| 1559 static const int kSmallListMin = 0x20 * kPointerSize; |
| 1560 |
| 1599 private: | 1561 private: |
| 1600 // The size range of blocks, in bytes. | 1562 // The size range of blocks, in bytes. |
| 1601 static const int kMinBlockSize = 3 * kPointerSize; | 1563 static const int kMinBlockSize = 3 * kPointerSize; |
| 1602 static const int kMaxBlockSize = Page::kMaxRegularHeapObjectSize; | 1564 static const int kMaxBlockSize = Page::kMaxRegularHeapObjectSize; |
| 1603 | 1565 |
| 1604 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1566 FreeSpace* FindNodeFor(int size_in_bytes, int* node_size); |
| 1605 | 1567 |
| 1606 PagedSpace* owner_; | 1568 PagedSpace* owner_; |
| 1607 Heap* heap_; | 1569 Heap* heap_; |
| 1608 | 1570 |
| 1609 static const int kSmallListMin = 0x20 * kPointerSize; | |
| 1610 static const int kSmallListMax = 0xff * kPointerSize; | 1571 static const int kSmallListMax = 0xff * kPointerSize; |
| 1611 static const int kMediumListMax = 0x7ff * kPointerSize; | 1572 static const int kMediumListMax = 0x7ff * kPointerSize; |
| 1612 static const int kLargeListMax = 0x3fff * kPointerSize; | 1573 static const int kLargeListMax = 0x3fff * kPointerSize; |
| 1613 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; | 1574 static const int kSmallAllocationMax = kSmallListMin - kPointerSize; |
| 1614 static const int kMediumAllocationMax = kSmallListMax; | 1575 static const int kMediumAllocationMax = kSmallListMax; |
| 1615 static const int kLargeAllocationMax = kMediumListMax; | 1576 static const int kLargeAllocationMax = kMediumListMax; |
| 1616 FreeListCategory small_list_; | 1577 FreeListCategory small_list_; |
| 1617 FreeListCategory medium_list_; | 1578 FreeListCategory medium_list_; |
| 1618 FreeListCategory large_list_; | 1579 FreeListCategory large_list_; |
| 1619 FreeListCategory huge_list_; | 1580 FreeListCategory huge_list_; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 bool Contains(HeapObject* o) { return Contains(o->address()); } | 1656 bool Contains(HeapObject* o) { return Contains(o->address()); } |
| 1696 | 1657 |
| 1697 // Given an address occupied by a live object, return that object if it is | 1658 // Given an address occupied by a live object, return that object if it is |
| 1698 // in this space, or a Smi if it is not. The implementation iterates over | 1659 // in this space, or a Smi if it is not. The implementation iterates over |
| 1699 // objects in the page containing the address, the cost is linear in the | 1660 // objects in the page containing the address, the cost is linear in the |
| 1700 // number of objects in the page. It may be slow. | 1661 // number of objects in the page. It may be slow. |
| 1701 Object* FindObject(Address addr); | 1662 Object* FindObject(Address addr); |
| 1702 | 1663 |
| 1703 // During boot the free_space_map is created, and afterwards we may need | 1664 // During boot the free_space_map is created, and afterwards we may need |
| 1704 // to write it into the free list nodes that were already created. | 1665 // to write it into the free list nodes that were already created. |
| 1705 void RepairFreeListsAfterBoot(); | 1666 void RepairFreeListsAfterDeserialization(); |
| 1706 | 1667 |
| 1707 // Prepares for a mark-compact GC. | 1668 // Prepares for a mark-compact GC. |
| 1708 void PrepareForMarkCompact(); | 1669 void PrepareForMarkCompact(); |
| 1709 | 1670 |
| 1710 // Current capacity without growing (Size() + Available()). | 1671 // Current capacity without growing (Size() + Available()). |
| 1711 intptr_t Capacity() { return accounting_stats_.Capacity(); } | 1672 intptr_t Capacity() { return accounting_stats_.Capacity(); } |
| 1712 | 1673 |
| 1713 // Total amount of memory committed for this space. For paged | 1674 // Total amount of memory committed for this space. For paged |
| 1714 // spaces this equals the capacity. | 1675 // spaces this equals the capacity. |
| 1715 intptr_t CommittedMemory() { return Capacity(); } | 1676 intptr_t CommittedMemory() { return Capacity(); } |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1902 bool HasEmergencyMemory() { return emergency_memory_ != NULL; } | 1863 bool HasEmergencyMemory() { return emergency_memory_ != NULL; } |
| 1903 | 1864 |
| 1904 protected: | 1865 protected: |
| 1905 FreeList* free_list() { return &free_list_; } | 1866 FreeList* free_list() { return &free_list_; } |
| 1906 | 1867 |
| 1907 int area_size_; | 1868 int area_size_; |
| 1908 | 1869 |
| 1909 // Maximum capacity of this space. | 1870 // Maximum capacity of this space. |
| 1910 intptr_t max_capacity_; | 1871 intptr_t max_capacity_; |
| 1911 | 1872 |
| 1912 intptr_t SizeOfFirstPage(); | |
| 1913 | |
| 1914 // Accounting information for this space. | 1873 // Accounting information for this space. |
| 1915 AllocationStats accounting_stats_; | 1874 AllocationStats accounting_stats_; |
| 1916 | 1875 |
| 1917 // The dummy page that anchors the double linked list of pages. | 1876 // The dummy page that anchors the double linked list of pages. |
| 1918 Page anchor_; | 1877 Page anchor_; |
| 1919 | 1878 |
| 1920 // The space's free list. | 1879 // The space's free list. |
| 1921 FreeList free_list_; | 1880 FreeList free_list_; |
| 1922 | 1881 |
| 1923 // Normal allocation information. | 1882 // Normal allocation information. |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2917 count = 0; | 2876 count = 0; |
| 2918 } | 2877 } |
| 2919 // Must be small, since an iteration is used for lookup. | 2878 // Must be small, since an iteration is used for lookup. |
| 2920 static const int kMaxComments = 64; | 2879 static const int kMaxComments = 64; |
| 2921 }; | 2880 }; |
| 2922 #endif | 2881 #endif |
| 2923 } | 2882 } |
| 2924 } // namespace v8::internal | 2883 } // namespace v8::internal |
| 2925 | 2884 |
| 2926 #endif // V8_HEAP_SPACES_H_ | 2885 #endif // V8_HEAP_SPACES_H_ |
| OLD | NEW |