| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + | 540 kSizeOffset + kPointerSize + kPointerSize + kPointerSize + |
| 541 kPointerSize + kPointerSize + | 541 kPointerSize + kPointerSize + |
| 542 kPointerSize + kPointerSize + kPointerSize + kIntSize; | 542 kPointerSize + kPointerSize + kPointerSize + kIntSize; |
| 543 | 543 |
| 544 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; | 544 static const size_t kSlotsBufferOffset = kLiveBytesOffset + kIntSize; |
| 545 | 545 |
| 546 static const size_t kWriteBarrierCounterOffset = | 546 static const size_t kWriteBarrierCounterOffset = |
| 547 kSlotsBufferOffset + kPointerSize + kPointerSize; | 547 kSlotsBufferOffset + kPointerSize + kPointerSize; |
| 548 | 548 |
| 549 static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize + | 549 static const size_t kHeaderSize = kWriteBarrierCounterOffset + kPointerSize + |
| 550 kIntSize + kIntSize + kPointerSize + | 550 kIntSize + kIntSize + kPointerSize; |
| 551 5 * kPointerSize; | |
| 552 | 551 |
| 553 static const int kBodyOffset = | 552 static const int kBodyOffset = |
| 554 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); | 553 CODE_POINTER_ALIGN(kHeaderSize + Bitmap::kSize); |
| 555 | 554 |
| 556 // The start offset of the object area in a page. Aligned to both maps and | 555 // The start offset of the object area in a page. Aligned to both maps and |
| 557 // code alignment to be suitable for both. Also aligned to 32 words because | 556 // code alignment to be suitable for both. Also aligned to 32 words because |
| 558 // the marking bitmap is arranged in 32 bit chunks. | 557 // the marking bitmap is arranged in 32 bit chunks. |
| 559 static const int kObjectStartAlignment = 32 * kPointerSize; | 558 static const int kObjectStartAlignment = 32 * kPointerSize; |
| 560 static const int kObjectStartOffset = kBodyOffset - 1 + | 559 static const int kObjectStartOffset = kBodyOffset - 1 + |
| 561 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); | 560 (kObjectStartAlignment - (kBodyOffset - 1) % kObjectStartAlignment); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 intptr_t write_barrier_counter_; | 694 intptr_t write_barrier_counter_; |
| 696 // Used by the incremental marker to keep track of the scanning progress in | 695 // Used by the incremental marker to keep track of the scanning progress in |
| 697 // large objects that have a progress bar and are scanned in increments. | 696 // large objects that have a progress bar and are scanned in increments. |
| 698 int progress_bar_; | 697 int progress_bar_; |
| 699 // Assuming the initial allocation on a page is sequential, | 698 // Assuming the initial allocation on a page is sequential, |
| 700 // count highest number of bytes ever allocated on the page. | 699 // count highest number of bytes ever allocated on the page. |
| 701 int high_water_mark_; | 700 int high_water_mark_; |
| 702 | 701 |
| 703 intptr_t parallel_sweeping_; | 702 intptr_t parallel_sweeping_; |
| 704 | 703 |
| 705 // PagedSpace free-list statistics. | |
| 706 intptr_t available_in_small_free_list_; | |
| 707 intptr_t available_in_medium_free_list_; | |
| 708 intptr_t available_in_large_free_list_; | |
| 709 intptr_t available_in_huge_free_list_; | |
| 710 intptr_t non_available_small_blocks_; | |
| 711 | |
| 712 static MemoryChunk* Initialize(Heap* heap, | 704 static MemoryChunk* Initialize(Heap* heap, |
| 713 Address base, | 705 Address base, |
| 714 size_t size, | 706 size_t size, |
| 715 Address area_start, | 707 Address area_start, |
| 716 Address area_end, | 708 Address area_end, |
| 717 Executability executable, | 709 Executability executable, |
| 718 Space* owner); | 710 Space* owner); |
| 719 | 711 |
| 720 friend class MemoryAllocator; | 712 friend class MemoryAllocator; |
| 721 }; | 713 }; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 798 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } | 790 bool WasSweptPrecisely() { return IsFlagSet(WAS_SWEPT_PRECISELY); } |
| 799 bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); } | 791 bool WasSweptConservatively() { return IsFlagSet(WAS_SWEPT_CONSERVATIVELY); } |
| 800 bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); } | 792 bool WasSwept() { return WasSweptPrecisely() || WasSweptConservatively(); } |
| 801 | 793 |
| 802 void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); } | 794 void MarkSweptPrecisely() { SetFlag(WAS_SWEPT_PRECISELY); } |
| 803 void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); } | 795 void MarkSweptConservatively() { SetFlag(WAS_SWEPT_CONSERVATIVELY); } |
| 804 | 796 |
| 805 void ClearSweptPrecisely() { ClearFlag(WAS_SWEPT_PRECISELY); } | 797 void ClearSweptPrecisely() { ClearFlag(WAS_SWEPT_PRECISELY); } |
| 806 void ClearSweptConservatively() { ClearFlag(WAS_SWEPT_CONSERVATIVELY); } | 798 void ClearSweptConservatively() { ClearFlag(WAS_SWEPT_CONSERVATIVELY); } |
| 807 | 799 |
| 808 void ResetFreeListStatistics(); | |
| 809 | |
| 810 #define FRAGMENTATION_STATS_ACCESSORS(type, name) \ | |
| 811 type name() { return name##_; } \ | |
| 812 void set_##name(type name) { name##_ = name; } \ | |
| 813 void add_##name(type name) { name##_ += name; } | |
| 814 | |
| 815 FRAGMENTATION_STATS_ACCESSORS(intptr_t, non_available_small_blocks) | |
| 816 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_small_free_list) | |
| 817 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_medium_free_list) | |
| 818 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_large_free_list) | |
| 819 FRAGMENTATION_STATS_ACCESSORS(intptr_t, available_in_huge_free_list) | |
| 820 | |
| 821 #undef FRAGMENTATION_STATS_ACCESSORS | |
| 822 | |
| 823 #ifdef DEBUG | 800 #ifdef DEBUG |
| 824 void Print(); | 801 void Print(); |
| 825 #endif // DEBUG | 802 #endif // DEBUG |
| 826 | 803 |
| 827 friend class MemoryAllocator; | 804 friend class MemoryAllocator; |
| 828 }; | 805 }; |
| 829 | 806 |
| 830 | 807 |
| 831 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); | 808 STATIC_CHECK(sizeof(Page) <= MemoryChunk::kHeaderSize); |
| 832 | 809 |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 } | 1425 } |
| 1449 | 1426 |
| 1450 intptr_t Concatenate(FreeListCategory* category); | 1427 intptr_t Concatenate(FreeListCategory* category); |
| 1451 | 1428 |
| 1452 void Reset(); | 1429 void Reset(); |
| 1453 | 1430 |
| 1454 void Free(FreeListNode* node, int size_in_bytes); | 1431 void Free(FreeListNode* node, int size_in_bytes); |
| 1455 | 1432 |
| 1456 FreeListNode* PickNodeFromList(int *node_size); | 1433 FreeListNode* PickNodeFromList(int *node_size); |
| 1457 | 1434 |
| 1435 intptr_t CountFreeListItemsInList(Page* p); |
| 1436 |
| 1458 intptr_t EvictFreeListItemsInList(Page* p); | 1437 intptr_t EvictFreeListItemsInList(Page* p); |
| 1459 | 1438 |
| 1460 void RepairFreeList(Heap* heap); | 1439 void RepairFreeList(Heap* heap); |
| 1461 | 1440 |
| 1462 FreeListNode** GetTopAddress() { return &top_; } | 1441 FreeListNode** GetTopAddress() { return &top_; } |
| 1463 FreeListNode* top() const { return top_; } | 1442 FreeListNode* top() const { return top_; } |
| 1464 void set_top(FreeListNode* top) { top_ = top; } | 1443 void set_top(FreeListNode* top) { top_ = top; } |
| 1465 | 1444 |
| 1466 FreeListNode** GetEndAddress() { return &end_; } | 1445 FreeListNode** GetEndAddress() { return &end_; } |
| 1467 FreeListNode* end() const { return end_; } | 1446 FreeListNode* end() const { return end_; } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 | 1521 |
| 1543 #ifdef DEBUG | 1522 #ifdef DEBUG |
| 1544 void Zap(); | 1523 void Zap(); |
| 1545 intptr_t SumFreeLists(); | 1524 intptr_t SumFreeLists(); |
| 1546 bool IsVeryLong(); | 1525 bool IsVeryLong(); |
| 1547 #endif | 1526 #endif |
| 1548 | 1527 |
| 1549 // Used after booting the VM. | 1528 // Used after booting the VM. |
| 1550 void RepairLists(Heap* heap); | 1529 void RepairLists(Heap* heap); |
| 1551 | 1530 |
| 1531 struct SizeStats { |
| 1532 intptr_t Total() { |
| 1533 return small_size_ + medium_size_ + large_size_ + huge_size_; |
| 1534 } |
| 1535 |
| 1536 intptr_t small_size_; |
| 1537 intptr_t medium_size_; |
| 1538 intptr_t large_size_; |
| 1539 intptr_t huge_size_; |
| 1540 }; |
| 1541 |
| 1542 void CountFreeListItems(Page* p, SizeStats* sizes); |
| 1543 |
| 1552 intptr_t EvictFreeListItems(Page* p); | 1544 intptr_t EvictFreeListItems(Page* p); |
| 1553 | 1545 |
| 1554 FreeListCategory* small_list() { return &small_list_; } | 1546 FreeListCategory* small_list() { return &small_list_; } |
| 1555 FreeListCategory* medium_list() { return &medium_list_; } | 1547 FreeListCategory* medium_list() { return &medium_list_; } |
| 1556 FreeListCategory* large_list() { return &large_list_; } | 1548 FreeListCategory* large_list() { return &large_list_; } |
| 1557 FreeListCategory* huge_list() { return &huge_list_; } | 1549 FreeListCategory* huge_list() { return &huge_list_; } |
| 1558 | 1550 |
| 1559 private: | 1551 private: |
| 1560 // The size range of blocks, in bytes. | 1552 // The size range of blocks, in bytes. |
| 1561 static const int kMinBlockSize = 3 * kPointerSize; | 1553 static const int kMinBlockSize = 3 * kPointerSize; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1626 // Current capacity without growing (Size() + Available()). | 1618 // Current capacity without growing (Size() + Available()). |
| 1627 intptr_t Capacity() { return accounting_stats_.Capacity(); } | 1619 intptr_t Capacity() { return accounting_stats_.Capacity(); } |
| 1628 | 1620 |
| 1629 // Total amount of memory committed for this space. For paged | 1621 // Total amount of memory committed for this space. For paged |
| 1630 // spaces this equals the capacity. | 1622 // spaces this equals the capacity. |
| 1631 intptr_t CommittedMemory() { return Capacity(); } | 1623 intptr_t CommittedMemory() { return Capacity(); } |
| 1632 | 1624 |
| 1633 // Approximate amount of physical memory committed for this space. | 1625 // Approximate amount of physical memory committed for this space. |
| 1634 size_t CommittedPhysicalMemory(); | 1626 size_t CommittedPhysicalMemory(); |
| 1635 | 1627 |
| 1636 struct SizeStats { | |
| 1637 intptr_t Total() { | |
| 1638 return small_size_ + medium_size_ + large_size_ + huge_size_; | |
| 1639 } | |
| 1640 | |
| 1641 intptr_t small_size_; | |
| 1642 intptr_t medium_size_; | |
| 1643 intptr_t large_size_; | |
| 1644 intptr_t huge_size_; | |
| 1645 }; | |
| 1646 | |
| 1647 void ObtainFreeListStatistics(Page* p, SizeStats* sizes); | |
| 1648 void ResetFreeListStatistics(); | |
| 1649 | |
| 1650 // Sets the capacity, the available space and the wasted space to zero. | 1628 // Sets the capacity, the available space and the wasted space to zero. |
| 1651 // The stats are rebuilt during sweeping by adding each page to the | 1629 // The stats are rebuilt during sweeping by adding each page to the |
| 1652 // capacity and the size when it is encountered. As free spaces are | 1630 // capacity and the size when it is encountered. As free spaces are |
| 1653 // discovered during the sweeping they are subtracted from the size and added | 1631 // discovered during the sweeping they are subtracted from the size and added |
| 1654 // to the available and wasted totals. | 1632 // to the available and wasted totals. |
| 1655 void ClearStats() { | 1633 void ClearStats() { |
| 1656 accounting_stats_.ClearSizeWaste(); | 1634 accounting_stats_.ClearSizeWaste(); |
| 1657 ResetFreeListStatistics(); | |
| 1658 } | 1635 } |
| 1659 | 1636 |
| 1660 // Increases the number of available bytes of that space. | 1637 // Increases the number of available bytes of that space. |
| 1661 void AddToAccountingStats(intptr_t bytes) { | 1638 void AddToAccountingStats(intptr_t bytes) { |
| 1662 accounting_stats_.DeallocateBytes(bytes); | 1639 accounting_stats_.DeallocateBytes(bytes); |
| 1663 } | 1640 } |
| 1664 | 1641 |
| 1665 // Available bytes without growing. These are the bytes on the free list. | 1642 // Available bytes without growing. These are the bytes on the free list. |
| 1666 // The bytes in the linear allocation area are not included in this total | 1643 // The bytes in the linear allocation area are not included in this total |
| 1667 // because updating the stats would slow down allocation. New pages are | 1644 // because updating the stats would slow down allocation. New pages are |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 // AdvanceSweeper with size_in_bytes is called. | 1778 // AdvanceSweeper with size_in_bytes is called. |
| 1802 bool EnsureSweeperProgress(intptr_t size_in_bytes); | 1779 bool EnsureSweeperProgress(intptr_t size_in_bytes); |
| 1803 | 1780 |
| 1804 bool IsLazySweepingComplete() { | 1781 bool IsLazySweepingComplete() { |
| 1805 return !first_unswept_page_->is_valid(); | 1782 return !first_unswept_page_->is_valid(); |
| 1806 } | 1783 } |
| 1807 | 1784 |
| 1808 Page* FirstPage() { return anchor_.next_page(); } | 1785 Page* FirstPage() { return anchor_.next_page(); } |
| 1809 Page* LastPage() { return anchor_.prev_page(); } | 1786 Page* LastPage() { return anchor_.prev_page(); } |
| 1810 | 1787 |
| 1788 void CountFreeListItems(Page* p, FreeList::SizeStats* sizes) { |
| 1789 free_list_.CountFreeListItems(p, sizes); |
| 1790 } |
| 1791 |
| 1811 void EvictEvacuationCandidatesFromFreeLists(); | 1792 void EvictEvacuationCandidatesFromFreeLists(); |
| 1812 | 1793 |
| 1813 bool CanExpand(); | 1794 bool CanExpand(); |
| 1814 | 1795 |
| 1815 // Returns the number of total pages in this space. | 1796 // Returns the number of total pages in this space. |
| 1816 int CountTotalPages(); | 1797 int CountTotalPages(); |
| 1817 | 1798 |
| 1818 // Return size of allocatable area on a page in this space. | 1799 // Return size of allocatable area on a page in this space. |
| 1819 inline int AreaSize() { | 1800 inline int AreaSize() { |
| 1820 return area_size_; | 1801 return area_size_; |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2845 } | 2826 } |
| 2846 // Must be small, since an iteration is used for lookup. | 2827 // Must be small, since an iteration is used for lookup. |
| 2847 static const int kMaxComments = 64; | 2828 static const int kMaxComments = 64; |
| 2848 }; | 2829 }; |
| 2849 #endif | 2830 #endif |
| 2850 | 2831 |
| 2851 | 2832 |
| 2852 } } // namespace v8::internal | 2833 } } // namespace v8::internal |
| 2853 | 2834 |
| 2854 #endif // V8_SPACES_H_ | 2835 #endif // V8_SPACES_H_ |
| OLD | NEW |