| 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 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 | 1310 |
| 1311 | 1311 |
| 1312 // ----------------------------------------------------------------------------- | 1312 // ----------------------------------------------------------------------------- |
| 1313 // A space has a circular list of pages. The next page can be accessed via | 1313 // A space has a circular list of pages. The next page can be accessed via |
| 1314 // Page::next_page() call. | 1314 // Page::next_page() call. |
| 1315 | 1315 |
| 1316 // An abstraction of allocation and relocation pointers in a page-structured | 1316 // An abstraction of allocation and relocation pointers in a page-structured |
| 1317 // space. | 1317 // space. |
| 1318 class AllocationInfo { | 1318 class AllocationInfo { |
| 1319 public: | 1319 public: |
| 1320 AllocationInfo() : top(NULL), limit(NULL) { | 1320 AllocationInfo() : top_(NULL), limit_(NULL) { |
| 1321 } | 1321 } |
| 1322 | 1322 |
| 1323 Address top; // Current allocation top. | 1323 INLINE(void set_top(Address top)) { |
| 1324 Address limit; // Current allocation limit. | 1324 SLOW_ASSERT(top == NULL || |
| 1325 (reinterpret_cast<intptr_t>(top) & HeapObjectTagMask()) == 0); |
| 1326 top_ = top; |
| 1327 } |
| 1328 |
| 1329 INLINE(Address top()) const { |
| 1330 SLOW_ASSERT(top_ == NULL || |
| 1331 (reinterpret_cast<intptr_t>(top_) & HeapObjectTagMask()) == 0); |
| 1332 return top_; |
| 1333 } |
| 1334 |
| 1335 Address* top_address() { |
| 1336 return &top_; |
| 1337 } |
| 1338 |
| 1339 INLINE(void set_limit(Address limit)) { |
| 1340 SLOW_ASSERT(limit == NULL || |
| 1341 (reinterpret_cast<intptr_t>(limit) & HeapObjectTagMask()) == 0); |
| 1342 limit_ = limit; |
| 1343 } |
| 1344 |
| 1345 INLINE(Address limit()) const { |
| 1346 SLOW_ASSERT(limit_ == NULL || |
| 1347 (reinterpret_cast<intptr_t>(limit_) & HeapObjectTagMask()) == 0); |
| 1348 return limit_; |
| 1349 } |
| 1350 |
| 1351 Address* limit_address() { |
| 1352 return &limit_; |
| 1353 } |
| 1325 | 1354 |
| 1326 #ifdef DEBUG | 1355 #ifdef DEBUG |
| 1327 bool VerifyPagedAllocation() { | 1356 bool VerifyPagedAllocation() { |
| 1328 return (Page::FromAllocationTop(top) == Page::FromAllocationTop(limit)) | 1357 return (Page::FromAllocationTop(top_) == Page::FromAllocationTop(limit_)) |
| 1329 && (top <= limit); | 1358 && (top_ <= limit_); |
| 1330 } | 1359 } |
| 1331 #endif | 1360 #endif |
| 1361 |
| 1362 private: |
| 1363 // Current allocation top. |
| 1364 Address top_; |
| 1365 // Current allocation limit. |
| 1366 Address limit_; |
| 1332 }; | 1367 }; |
| 1333 | 1368 |
| 1334 | 1369 |
| 1335 // An abstraction of the accounting statistics of a page-structured space. | 1370 // An abstraction of the accounting statistics of a page-structured space. |
| 1336 // The 'capacity' of a space is the number of object-area bytes (i.e., not | 1371 // The 'capacity' of a space is the number of object-area bytes (i.e., not |
| 1337 // including page bookkeeping structures) currently in the space. The 'size' | 1372 // including page bookkeeping structures) currently in the space. The 'size' |
| 1338 // of a space is the number of allocated bytes, the 'waste' in the space is | 1373 // of a space is the number of allocated bytes, the 'waste' in the space is |
| 1339 // the number of bytes that are not allocated and not available to | 1374 // the number of bytes that are not allocated and not available to |
| 1340 // allocation without reorganizing the space via a GC (e.g. small blocks due | 1375 // allocation without reorganizing the space via a GC (e.g. small blocks due |
| 1341 // to internal fragmentation, top of page areas in map space), and the bytes | 1376 // to internal fragmentation, top of page areas in map space), and the bytes |
| 1342 // 'available' is the number of unallocated bytes that are not waste. The | 1377 // 'available' is the number of unallocated bytes that are not waste. The |
| 1343 // capacity is the sum of size, waste, and available. | 1378 // capacity is the sum of size, waste, and available. |
| 1344 // | 1379 // |
| 1345 // The stats are only set by functions that ensure they stay balanced. These | 1380 // The stats are only set by functions that ensure they stay balanced. These |
| 1346 // functions increase or decrease one of the non-capacity stats in | 1381 // functions increase or decrease one of the non-capacity stats in |
| 1347 // conjunction with capacity, or else they always balance increases and | 1382 // conjunction with capacity, or else they always balance increases and |
| 1348 // decreases to the non-capacity stats. | 1383 // decreases to the non-capacity stats. |
| 1349 class AllocationStats BASE_EMBEDDED { | 1384 class AllocationStats BASE_EMBEDDED { |
| 1350 public: | 1385 public: |
| 1351 AllocationStats() { Clear(); } | 1386 AllocationStats() { Clear(); } |
| 1352 | 1387 |
| 1353 // Zero out all the allocation statistics (i.e., no capacity). | 1388 // Zero out all the allocation statistics (i.e., no capacity). |
| 1354 void Clear() { | 1389 void Clear() { |
| 1355 capacity_ = 0; | 1390 capacity_ = 0; |
| 1391 max_capacity_ = 0; |
| 1356 size_ = 0; | 1392 size_ = 0; |
| 1357 waste_ = 0; | 1393 waste_ = 0; |
| 1358 } | 1394 } |
| 1359 | 1395 |
| 1360 void ClearSizeWaste() { | 1396 void ClearSizeWaste() { |
| 1361 size_ = capacity_; | 1397 size_ = capacity_; |
| 1362 waste_ = 0; | 1398 waste_ = 0; |
| 1363 } | 1399 } |
| 1364 | 1400 |
| 1365 // Reset the allocation statistics (i.e., available = capacity with no | 1401 // Reset the allocation statistics (i.e., available = capacity with no |
| 1366 // wasted or allocated bytes). | 1402 // wasted or allocated bytes). |
| 1367 void Reset() { | 1403 void Reset() { |
| 1368 size_ = 0; | 1404 size_ = 0; |
| 1369 waste_ = 0; | 1405 waste_ = 0; |
| 1370 } | 1406 } |
| 1371 | 1407 |
| 1372 // Accessors for the allocation statistics. | 1408 // Accessors for the allocation statistics. |
| 1373 intptr_t Capacity() { return capacity_; } | 1409 intptr_t Capacity() { return capacity_; } |
| 1410 intptr_t MaxCapacity() { return max_capacity_; } |
| 1374 intptr_t Size() { return size_; } | 1411 intptr_t Size() { return size_; } |
| 1375 intptr_t Waste() { return waste_; } | 1412 intptr_t Waste() { return waste_; } |
| 1376 | 1413 |
| 1377 // Grow the space by adding available bytes. They are initially marked as | 1414 // Grow the space by adding available bytes. They are initially marked as |
| 1378 // being in use (part of the size), but will normally be immediately freed, | 1415 // being in use (part of the size), but will normally be immediately freed, |
| 1379 // putting them on the free list and removing them from size_. | 1416 // putting them on the free list and removing them from size_. |
| 1380 void ExpandSpace(int size_in_bytes) { | 1417 void ExpandSpace(int size_in_bytes) { |
| 1381 capacity_ += size_in_bytes; | 1418 capacity_ += size_in_bytes; |
| 1382 size_ += size_in_bytes; | 1419 size_ += size_in_bytes; |
| 1420 if (capacity_ > max_capacity_) { |
| 1421 max_capacity_ = capacity_; |
| 1422 } |
| 1383 ASSERT(size_ >= 0); | 1423 ASSERT(size_ >= 0); |
| 1384 } | 1424 } |
| 1385 | 1425 |
| 1386 // Shrink the space by removing available bytes. Since shrinking is done | 1426 // Shrink the space by removing available bytes. Since shrinking is done |
| 1387 // during sweeping, bytes have been marked as being in use (part of the size) | 1427 // during sweeping, bytes have been marked as being in use (part of the size) |
| 1388 // and are hereby freed. | 1428 // and are hereby freed. |
| 1389 void ShrinkSpace(int size_in_bytes) { | 1429 void ShrinkSpace(int size_in_bytes) { |
| 1390 capacity_ -= size_in_bytes; | 1430 capacity_ -= size_in_bytes; |
| 1391 size_ -= size_in_bytes; | 1431 size_ -= size_in_bytes; |
| 1392 ASSERT(size_ >= 0); | 1432 ASSERT(size_ >= 0); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1406 | 1446 |
| 1407 // Waste free bytes (available -> waste). | 1447 // Waste free bytes (available -> waste). |
| 1408 void WasteBytes(int size_in_bytes) { | 1448 void WasteBytes(int size_in_bytes) { |
| 1409 size_ -= size_in_bytes; | 1449 size_ -= size_in_bytes; |
| 1410 waste_ += size_in_bytes; | 1450 waste_ += size_in_bytes; |
| 1411 ASSERT(size_ >= 0); | 1451 ASSERT(size_ >= 0); |
| 1412 } | 1452 } |
| 1413 | 1453 |
| 1414 private: | 1454 private: |
| 1415 intptr_t capacity_; | 1455 intptr_t capacity_; |
| 1456 intptr_t max_capacity_; |
| 1416 intptr_t size_; | 1457 intptr_t size_; |
| 1417 intptr_t waste_; | 1458 intptr_t waste_; |
| 1418 }; | 1459 }; |
| 1419 | 1460 |
| 1420 | 1461 |
| 1421 // ----------------------------------------------------------------------------- | 1462 // ----------------------------------------------------------------------------- |
| 1422 // Free lists for old object spaces | 1463 // Free lists for old object spaces |
| 1423 // | 1464 // |
| 1424 // Free-list nodes are free blocks in the heap. They look like heap objects | 1465 // Free-list nodes are free blocks in the heap. They look like heap objects |
| 1425 // (free-list node pointers have the heap object tag, and they have a map like | 1466 // (free-list node pointers have the heap object tag, and they have a map like |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 bool Contains(HeapObject* o) { return Contains(o->address()); } | 1676 bool Contains(HeapObject* o) { return Contains(o->address()); } |
| 1636 | 1677 |
| 1637 // Given an address occupied by a live object, return that object if it is | 1678 // Given an address occupied by a live object, return that object if it is |
| 1638 // in this space, or Failure::Exception() if it is not. The implementation | 1679 // in this space, or Failure::Exception() if it is not. The implementation |
| 1639 // iterates over objects in the page containing the address, the cost is | 1680 // iterates over objects in the page containing the address, the cost is |
| 1640 // linear in the number of objects in the page. It may be slow. | 1681 // linear in the number of objects in the page. It may be slow. |
| 1641 MUST_USE_RESULT MaybeObject* FindObject(Address addr); | 1682 MUST_USE_RESULT MaybeObject* FindObject(Address addr); |
| 1642 | 1683 |
| 1643 // During boot the free_space_map is created, and afterwards we may need | 1684 // During boot the free_space_map is created, and afterwards we may need |
| 1644 // to write it into the free list nodes that were already created. | 1685 // to write it into the free list nodes that were already created. |
| 1645 virtual void RepairFreeListsAfterBoot(); | 1686 void RepairFreeListsAfterBoot(); |
| 1646 | 1687 |
| 1647 // Prepares for a mark-compact GC. | 1688 // Prepares for a mark-compact GC. |
| 1648 virtual void PrepareForMarkCompact(); | 1689 void PrepareForMarkCompact(); |
| 1649 | 1690 |
| 1650 // Current capacity without growing (Size() + Available()). | 1691 // Current capacity without growing (Size() + Available()). |
| 1651 intptr_t Capacity() { return accounting_stats_.Capacity(); } | 1692 intptr_t Capacity() { return accounting_stats_.Capacity(); } |
| 1652 | 1693 |
| 1653 // Total amount of memory committed for this space. For paged | 1694 // Total amount of memory committed for this space. For paged |
| 1654 // spaces this equals the capacity. | 1695 // spaces this equals the capacity. |
| 1655 intptr_t CommittedMemory() { return Capacity(); } | 1696 intptr_t CommittedMemory() { return Capacity(); } |
| 1656 | 1697 |
| 1698 // The maximum amount of memory ever committed for this space. |
| 1699 intptr_t MaximumCommittedMemory() { return accounting_stats_.MaxCapacity(); } |
| 1700 |
| 1657 // Approximate amount of physical memory committed for this space. | 1701 // Approximate amount of physical memory committed for this space. |
| 1658 size_t CommittedPhysicalMemory(); | 1702 size_t CommittedPhysicalMemory(); |
| 1659 | 1703 |
| 1660 struct SizeStats { | 1704 struct SizeStats { |
| 1661 intptr_t Total() { | 1705 intptr_t Total() { |
| 1662 return small_size_ + medium_size_ + large_size_ + huge_size_; | 1706 return small_size_ + medium_size_ + large_size_ + huge_size_; |
| 1663 } | 1707 } |
| 1664 | 1708 |
| 1665 intptr_t small_size_; | 1709 intptr_t small_size_; |
| 1666 intptr_t medium_size_; | 1710 intptr_t medium_size_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 // As size, but the bytes in lazily swept pages are estimated and the bytes | 1744 // As size, but the bytes in lazily swept pages are estimated and the bytes |
| 1701 // in the current linear allocation area are not included. | 1745 // in the current linear allocation area are not included. |
| 1702 virtual intptr_t SizeOfObjects(); | 1746 virtual intptr_t SizeOfObjects(); |
| 1703 | 1747 |
| 1704 // Wasted bytes in this space. These are just the bytes that were thrown away | 1748 // Wasted bytes in this space. These are just the bytes that were thrown away |
| 1705 // due to being too small to use for allocation. They do not include the | 1749 // due to being too small to use for allocation. They do not include the |
| 1706 // free bytes that were not found at all due to lazy sweeping. | 1750 // free bytes that were not found at all due to lazy sweeping. |
| 1707 virtual intptr_t Waste() { return accounting_stats_.Waste(); } | 1751 virtual intptr_t Waste() { return accounting_stats_.Waste(); } |
| 1708 | 1752 |
| 1709 // Returns the allocation pointer in this space. | 1753 // Returns the allocation pointer in this space. |
| 1710 Address top() { return allocation_info_.top; } | 1754 Address top() { return allocation_info_.top(); } |
| 1711 Address limit() { return allocation_info_.limit; } | 1755 Address limit() { return allocation_info_.limit(); } |
| 1712 | 1756 |
| 1713 // The allocation top and limit addresses. | 1757 // The allocation top address. |
| 1714 Address* allocation_top_address() { return &allocation_info_.top; } | 1758 Address* allocation_top_address() { |
| 1715 Address* allocation_limit_address() { return &allocation_info_.limit; } | 1759 return allocation_info_.top_address(); |
| 1760 } |
| 1716 | 1761 |
| 1717 enum AllocationType { | 1762 // The allocation limit address. |
| 1718 NEW_OBJECT, | 1763 Address* allocation_limit_address() { |
| 1719 MOVE_OBJECT | 1764 return allocation_info_.limit_address(); |
| 1720 }; | 1765 } |
| 1721 | 1766 |
| 1722 // Allocate the requested number of bytes in the space if possible, return a | 1767 // Allocate the requested number of bytes in the space if possible, return a |
| 1723 // failure object if not. | 1768 // failure object if not. |
| 1724 MUST_USE_RESULT inline MaybeObject* AllocateRaw( | 1769 MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes); |
| 1725 int size_in_bytes, | |
| 1726 AllocationType event = NEW_OBJECT); | |
| 1727 | |
| 1728 virtual bool ReserveSpace(int bytes); | |
| 1729 | 1770 |
| 1730 // Give a block of memory to the space's free list. It might be added to | 1771 // Give a block of memory to the space's free list. It might be added to |
| 1731 // the free list or accounted as waste. | 1772 // the free list or accounted as waste. |
| 1732 // If add_to_freelist is false then just accounting stats are updated and | 1773 // If add_to_freelist is false then just accounting stats are updated and |
| 1733 // no attempt to add area to free list is made. | 1774 // no attempt to add area to free list is made. |
| 1734 int Free(Address start, int size_in_bytes) { | 1775 int Free(Address start, int size_in_bytes) { |
| 1735 int wasted = free_list_.Free(start, size_in_bytes); | 1776 int wasted = free_list_.Free(start, size_in_bytes); |
| 1736 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 1777 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); |
| 1737 return size_in_bytes - wasted; | 1778 return size_in_bytes - wasted; |
| 1738 } | 1779 } |
| 1739 | 1780 |
| 1740 void ResetFreeList() { | 1781 void ResetFreeList() { |
| 1741 free_list_.Reset(); | 1782 free_list_.Reset(); |
| 1742 } | 1783 } |
| 1743 | 1784 |
| 1744 // Set space allocation info. | 1785 // Set space allocation info. |
| 1745 void SetTop(Address top, Address limit) { | 1786 void SetTop(Address top, Address limit) { |
| 1746 ASSERT(top == limit || | 1787 ASSERT(top == limit || |
| 1747 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | 1788 Page::FromAddress(top) == Page::FromAddress(limit - 1)); |
| 1748 MemoryChunk::UpdateHighWaterMark(allocation_info_.top); | 1789 MemoryChunk::UpdateHighWaterMark(allocation_info_.top()); |
| 1749 allocation_info_.top = top; | 1790 allocation_info_.set_top(top); |
| 1750 allocation_info_.limit = limit; | 1791 allocation_info_.set_limit(limit); |
| 1751 } | 1792 } |
| 1752 | 1793 |
| 1753 void Allocate(int bytes) { | 1794 void Allocate(int bytes) { |
| 1754 accounting_stats_.AllocateBytes(bytes); | 1795 accounting_stats_.AllocateBytes(bytes); |
| 1755 } | 1796 } |
| 1756 | 1797 |
| 1757 void IncreaseCapacity(int size) { | 1798 void IncreaseCapacity(int size); |
| 1758 accounting_stats_.ExpandSpace(size); | |
| 1759 } | |
| 1760 | 1799 |
| 1761 // Releases an unused page and shrinks the space. | 1800 // Releases an unused page and shrinks the space. |
| 1762 void ReleasePage(Page* page, bool unlink); | 1801 void ReleasePage(Page* page, bool unlink); |
| 1763 | 1802 |
| 1764 // The dummy page that anchors the linked list of pages. | 1803 // The dummy page that anchors the linked list of pages. |
| 1765 Page* anchor() { return &anchor_; } | 1804 Page* anchor() { return &anchor_; } |
| 1766 | 1805 |
| 1767 #ifdef VERIFY_HEAP | 1806 #ifdef VERIFY_HEAP |
| 1768 // Verify integrity of this space. | 1807 // Verify integrity of this space. |
| 1769 virtual void Verify(ObjectVisitor* visitor); | 1808 virtual void Verify(ObjectVisitor* visitor); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 | 1905 |
| 1867 // The dummy page that anchors the double linked list of pages. | 1906 // The dummy page that anchors the double linked list of pages. |
| 1868 Page anchor_; | 1907 Page anchor_; |
| 1869 | 1908 |
| 1870 // The space's free list. | 1909 // The space's free list. |
| 1871 FreeList free_list_; | 1910 FreeList free_list_; |
| 1872 | 1911 |
| 1873 // Normal allocation information. | 1912 // Normal allocation information. |
| 1874 AllocationInfo allocation_info_; | 1913 AllocationInfo allocation_info_; |
| 1875 | 1914 |
| 1876 // Bytes of each page that cannot be allocated. Possibly non-zero | |
| 1877 // for pages in spaces with only fixed-size objects. Always zero | |
| 1878 // for pages in spaces with variable sized objects (those pages are | |
| 1879 // padded with free-list nodes). | |
| 1880 int page_extra_; | |
| 1881 | |
| 1882 bool was_swept_conservatively_; | 1915 bool was_swept_conservatively_; |
| 1883 | 1916 |
| 1884 // The first page to be swept when the lazy sweeper advances. Is set | 1917 // The first page to be swept when the lazy sweeper advances. Is set |
| 1885 // to NULL when all pages have been swept. | 1918 // to NULL when all pages have been swept. |
| 1886 Page* first_unswept_page_; | 1919 Page* first_unswept_page_; |
| 1887 | 1920 |
| 1888 // The number of free bytes which could be reclaimed by advancing the | 1921 // The number of free bytes which could be reclaimed by advancing the |
| 1889 // lazy sweeper. This is only an estimation because lazy sweeping is | 1922 // lazy sweeper. This is only an estimation because lazy sweeping is |
| 1890 // done conservatively. | 1923 // done conservatively. |
| 1891 intptr_t unswept_free_bytes_; | 1924 intptr_t unswept_free_bytes_; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; | 2152 return (reinterpret_cast<uintptr_t>(o) & object_mask_) == object_expected_; |
| 2120 } | 2153 } |
| 2121 | 2154 |
| 2122 // If we don't have these here then SemiSpace will be abstract. However | 2155 // If we don't have these here then SemiSpace will be abstract. However |
| 2123 // they should never be called. | 2156 // they should never be called. |
| 2124 virtual intptr_t Size() { | 2157 virtual intptr_t Size() { |
| 2125 UNREACHABLE(); | 2158 UNREACHABLE(); |
| 2126 return 0; | 2159 return 0; |
| 2127 } | 2160 } |
| 2128 | 2161 |
| 2129 virtual bool ReserveSpace(int bytes) { | |
| 2130 UNREACHABLE(); | |
| 2131 return false; | |
| 2132 } | |
| 2133 | |
| 2134 bool is_committed() { return committed_; } | 2162 bool is_committed() { return committed_; } |
| 2135 bool Commit(); | 2163 bool Commit(); |
| 2136 bool Uncommit(); | 2164 bool Uncommit(); |
| 2137 | 2165 |
| 2138 NewSpacePage* first_page() { return anchor_.next_page(); } | 2166 NewSpacePage* first_page() { return anchor_.next_page(); } |
| 2139 NewSpacePage* current_page() { return current_page_; } | 2167 NewSpacePage* current_page() { return current_page_; } |
| 2140 | 2168 |
| 2141 #ifdef VERIFY_HEAP | 2169 #ifdef VERIFY_HEAP |
| 2142 virtual void Verify(); | 2170 virtual void Verify(); |
| 2143 #endif | 2171 #endif |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2159 // Returns the maximum capacity of the semi space. | 2187 // Returns the maximum capacity of the semi space. |
| 2160 int MaximumCapacity() { return maximum_capacity_; } | 2188 int MaximumCapacity() { return maximum_capacity_; } |
| 2161 | 2189 |
| 2162 // Returns the initial capacity of the semi space. | 2190 // Returns the initial capacity of the semi space. |
| 2163 int InitialCapacity() { return initial_capacity_; } | 2191 int InitialCapacity() { return initial_capacity_; } |
| 2164 | 2192 |
| 2165 SemiSpaceId id() { return id_; } | 2193 SemiSpaceId id() { return id_; } |
| 2166 | 2194 |
| 2167 static void Swap(SemiSpace* from, SemiSpace* to); | 2195 static void Swap(SemiSpace* from, SemiSpace* to); |
| 2168 | 2196 |
| 2197 // Returns the maximum amount of memory ever committed by the semi space. |
| 2198 size_t MaximumCommittedMemory() { return maximum_committed_; } |
| 2199 |
| 2169 // Approximate amount of physical memory committed for this space. | 2200 // Approximate amount of physical memory committed for this space. |
| 2170 size_t CommittedPhysicalMemory(); | 2201 size_t CommittedPhysicalMemory(); |
| 2171 | 2202 |
| 2172 private: | 2203 private: |
| 2173 // Flips the semispace between being from-space and to-space. | 2204 // Flips the semispace between being from-space and to-space. |
| 2174 // Copies the flags into the masked positions on all pages in the space. | 2205 // Copies the flags into the masked positions on all pages in the space. |
| 2175 void FlipPages(intptr_t flags, intptr_t flag_mask); | 2206 void FlipPages(intptr_t flags, intptr_t flag_mask); |
| 2176 | 2207 |
| 2208 // Updates Capacity and MaximumCommitted based on new capacity. |
| 2209 void SetCapacity(int new_capacity); |
| 2210 |
| 2177 NewSpacePage* anchor() { return &anchor_; } | 2211 NewSpacePage* anchor() { return &anchor_; } |
| 2178 | 2212 |
| 2179 // The current and maximum capacity of the space. | 2213 // The current and maximum capacity of the space. |
| 2180 int capacity_; | 2214 int capacity_; |
| 2181 int maximum_capacity_; | 2215 int maximum_capacity_; |
| 2182 int initial_capacity_; | 2216 int initial_capacity_; |
| 2183 | 2217 |
| 2218 intptr_t maximum_committed_; |
| 2219 |
| 2184 // The start address of the space. | 2220 // The start address of the space. |
| 2185 Address start_; | 2221 Address start_; |
| 2186 // Used to govern object promotion during mark-compact collection. | 2222 // Used to govern object promotion during mark-compact collection. |
| 2187 Address age_mark_; | 2223 Address age_mark_; |
| 2188 | 2224 |
| 2189 // Masks and comparison values to test for containment in this semispace. | 2225 // Masks and comparison values to test for containment in this semispace. |
| 2190 uintptr_t address_mask_; | 2226 uintptr_t address_mask_; |
| 2191 uintptr_t object_mask_; | 2227 uintptr_t object_mask_; |
| 2192 uintptr_t object_expected_; | 2228 uintptr_t object_expected_; |
| 2193 | 2229 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2359 ASSERT(to_space_.Capacity() == from_space_.Capacity()); | 2395 ASSERT(to_space_.Capacity() == from_space_.Capacity()); |
| 2360 return to_space_.Capacity(); | 2396 return to_space_.Capacity(); |
| 2361 } | 2397 } |
| 2362 | 2398 |
| 2363 // Return the total amount of memory committed for new space. | 2399 // Return the total amount of memory committed for new space. |
| 2364 intptr_t CommittedMemory() { | 2400 intptr_t CommittedMemory() { |
| 2365 if (from_space_.is_committed()) return 2 * Capacity(); | 2401 if (from_space_.is_committed()) return 2 * Capacity(); |
| 2366 return Capacity(); | 2402 return Capacity(); |
| 2367 } | 2403 } |
| 2368 | 2404 |
| 2405 // Return the total amount of memory committed for new space. |
| 2406 intptr_t MaximumCommittedMemory() { |
| 2407 return to_space_.MaximumCommittedMemory() + |
| 2408 from_space_.MaximumCommittedMemory(); |
| 2409 } |
| 2410 |
| 2369 // Approximate amount of physical memory committed for this space. | 2411 // Approximate amount of physical memory committed for this space. |
| 2370 size_t CommittedPhysicalMemory(); | 2412 size_t CommittedPhysicalMemory(); |
| 2371 | 2413 |
| 2372 // Return the available bytes without growing. | 2414 // Return the available bytes without growing. |
| 2373 intptr_t Available() { | 2415 intptr_t Available() { |
| 2374 return Capacity() - Size(); | 2416 return Capacity() - Size(); |
| 2375 } | 2417 } |
| 2376 | 2418 |
| 2377 // Return the maximum capacity of a semispace. | 2419 // Return the maximum capacity of a semispace. |
| 2378 int MaximumCapacity() { | 2420 int MaximumCapacity() { |
| 2379 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); | 2421 ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity()); |
| 2380 return to_space_.MaximumCapacity(); | 2422 return to_space_.MaximumCapacity(); |
| 2381 } | 2423 } |
| 2382 | 2424 |
| 2383 // Returns the initial capacity of a semispace. | 2425 // Returns the initial capacity of a semispace. |
| 2384 int InitialCapacity() { | 2426 int InitialCapacity() { |
| 2385 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); | 2427 ASSERT(to_space_.InitialCapacity() == from_space_.InitialCapacity()); |
| 2386 return to_space_.InitialCapacity(); | 2428 return to_space_.InitialCapacity(); |
| 2387 } | 2429 } |
| 2388 | 2430 |
| 2389 // Return the address of the allocation pointer in the active semispace. | 2431 // Return the address of the allocation pointer in the active semispace. |
| 2390 Address top() { | 2432 Address top() { |
| 2391 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); | 2433 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top())); |
| 2392 return allocation_info_.top; | 2434 return allocation_info_.top(); |
| 2393 } | 2435 } |
| 2436 |
| 2437 void set_top(Address top) { |
| 2438 ASSERT(to_space_.current_page()->ContainsLimit(top)); |
| 2439 allocation_info_.set_top(top); |
| 2440 } |
| 2441 |
| 2394 // Return the address of the first object in the active semispace. | 2442 // Return the address of the first object in the active semispace. |
| 2395 Address bottom() { return to_space_.space_start(); } | 2443 Address bottom() { return to_space_.space_start(); } |
| 2396 | 2444 |
| 2397 // Get the age mark of the inactive semispace. | 2445 // Get the age mark of the inactive semispace. |
| 2398 Address age_mark() { return from_space_.age_mark(); } | 2446 Address age_mark() { return from_space_.age_mark(); } |
| 2399 // Set the age mark in the active semispace. | 2447 // Set the age mark in the active semispace. |
| 2400 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } | 2448 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } |
| 2401 | 2449 |
| 2402 // The start address of the space and a bit mask. Anding an address in the | 2450 // The start address of the space and a bit mask. Anding an address in the |
| 2403 // new space with the mask will result in the start address. | 2451 // new space with the mask will result in the start address. |
| 2404 Address start() { return start_; } | 2452 Address start() { return start_; } |
| 2405 uintptr_t mask() { return address_mask_; } | 2453 uintptr_t mask() { return address_mask_; } |
| 2406 | 2454 |
| 2407 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { | 2455 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { |
| 2408 ASSERT(Contains(addr)); | 2456 ASSERT(Contains(addr)); |
| 2409 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || | 2457 ASSERT(IsAligned(OffsetFrom(addr), kPointerSize) || |
| 2410 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); | 2458 IsAligned(OffsetFrom(addr) - 1, kPointerSize)); |
| 2411 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; | 2459 return static_cast<uint32_t>(addr - start_) >> kPointerSizeLog2; |
| 2412 } | 2460 } |
| 2413 | 2461 |
| 2414 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { | 2462 INLINE(Address MarkbitIndexToAddress(uint32_t index)) { |
| 2415 return reinterpret_cast<Address>(index << kPointerSizeLog2); | 2463 return reinterpret_cast<Address>(index << kPointerSizeLog2); |
| 2416 } | 2464 } |
| 2417 | 2465 |
| 2418 // The allocation top and limit addresses. | 2466 // The allocation top and limit address. |
| 2419 Address* allocation_top_address() { return &allocation_info_.top; } | 2467 Address* allocation_top_address() { |
| 2420 Address* allocation_limit_address() { return &allocation_info_.limit; } | 2468 return allocation_info_.top_address(); |
| 2469 } |
| 2470 |
| 2471 // The allocation limit address. |
| 2472 Address* allocation_limit_address() { |
| 2473 return allocation_info_.limit_address(); |
| 2474 } |
| 2421 | 2475 |
| 2422 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); | 2476 MUST_USE_RESULT INLINE(MaybeObject* AllocateRaw(int size_in_bytes)); |
| 2423 | 2477 |
| 2424 // Reset the allocation pointer to the beginning of the active semispace. | 2478 // Reset the allocation pointer to the beginning of the active semispace. |
| 2425 void ResetAllocationInfo(); | 2479 void ResetAllocationInfo(); |
| 2426 | 2480 |
| 2427 void LowerInlineAllocationLimit(intptr_t step) { | 2481 void LowerInlineAllocationLimit(intptr_t step) { |
| 2428 inline_allocation_limit_step_ = step; | 2482 inline_allocation_limit_step_ = step; |
| 2429 if (step == 0) { | 2483 if (step == 0) { |
| 2430 allocation_info_.limit = to_space_.page_high(); | 2484 allocation_info_.set_limit(to_space_.page_high()); |
| 2431 } else { | 2485 } else { |
| 2432 allocation_info_.limit = Min( | 2486 Address new_limit = Min( |
| 2433 allocation_info_.top + inline_allocation_limit_step_, | 2487 allocation_info_.top() + inline_allocation_limit_step_, |
| 2434 allocation_info_.limit); | 2488 allocation_info_.limit()); |
| 2489 allocation_info_.set_limit(new_limit); |
| 2435 } | 2490 } |
| 2436 top_on_previous_step_ = allocation_info_.top; | 2491 top_on_previous_step_ = allocation_info_.top(); |
| 2437 } | 2492 } |
| 2438 | 2493 |
| 2439 // Get the extent of the inactive semispace (for use as a marking stack, | 2494 // Get the extent of the inactive semispace (for use as a marking stack, |
| 2440 // or to zap it). Notice: space-addresses are not necessarily on the | 2495 // or to zap it). Notice: space-addresses are not necessarily on the |
| 2441 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2496 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
| 2442 Address FromSpacePageLow() { return from_space_.page_low(); } | 2497 Address FromSpacePageLow() { return from_space_.page_low(); } |
| 2443 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2498 Address FromSpacePageHigh() { return from_space_.page_high(); } |
| 2444 Address FromSpaceStart() { return from_space_.space_start(); } | 2499 Address FromSpaceStart() { return from_space_.space_start(); } |
| 2445 Address FromSpaceEnd() { return from_space_.space_end(); } | 2500 Address FromSpaceEnd() { return from_space_.space_end(); } |
| 2446 | 2501 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2460 // semispace). | 2515 // semispace). |
| 2461 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } | 2516 inline bool ToSpaceContains(Object* o) { return to_space_.Contains(o); } |
| 2462 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } | 2517 inline bool FromSpaceContains(Object* o) { return from_space_.Contains(o); } |
| 2463 | 2518 |
| 2464 // Try to switch the active semispace to a new, empty, page. | 2519 // Try to switch the active semispace to a new, empty, page. |
| 2465 // Returns false if this isn't possible or reasonable (i.e., there | 2520 // Returns false if this isn't possible or reasonable (i.e., there |
| 2466 // are no pages, or the current page is already empty), or true | 2521 // are no pages, or the current page is already empty), or true |
| 2467 // if successful. | 2522 // if successful. |
| 2468 bool AddFreshPage(); | 2523 bool AddFreshPage(); |
| 2469 | 2524 |
| 2470 virtual bool ReserveSpace(int bytes); | |
| 2471 | |
| 2472 #ifdef VERIFY_HEAP | 2525 #ifdef VERIFY_HEAP |
| 2473 // Verify the active semispace. | 2526 // Verify the active semispace. |
| 2474 virtual void Verify(); | 2527 virtual void Verify(); |
| 2475 #endif | 2528 #endif |
| 2476 | 2529 |
| 2477 #ifdef DEBUG | 2530 #ifdef DEBUG |
| 2478 // Print the active semispace. | 2531 // Print the active semispace. |
| 2479 virtual void Print() { to_space_.Print(); } | 2532 virtual void Print() { to_space_.Print(); } |
| 2480 #endif | 2533 #endif |
| 2481 | 2534 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2557 | 2610 |
| 2558 class OldSpace : public PagedSpace { | 2611 class OldSpace : public PagedSpace { |
| 2559 public: | 2612 public: |
| 2560 // Creates an old space object with a given maximum capacity. | 2613 // Creates an old space object with a given maximum capacity. |
| 2561 // The constructor does not allocate pages from OS. | 2614 // The constructor does not allocate pages from OS. |
| 2562 OldSpace(Heap* heap, | 2615 OldSpace(Heap* heap, |
| 2563 intptr_t max_capacity, | 2616 intptr_t max_capacity, |
| 2564 AllocationSpace id, | 2617 AllocationSpace id, |
| 2565 Executability executable) | 2618 Executability executable) |
| 2566 : PagedSpace(heap, max_capacity, id, executable) { | 2619 : PagedSpace(heap, max_capacity, id, executable) { |
| 2567 page_extra_ = 0; | |
| 2568 } | |
| 2569 | |
| 2570 // The limit of allocation for a page in this space. | |
| 2571 virtual Address PageAllocationLimit(Page* page) { | |
| 2572 return page->area_end(); | |
| 2573 } | 2620 } |
| 2574 | 2621 |
| 2575 public: | 2622 public: |
| 2576 TRACK_MEMORY("OldSpace") | 2623 TRACK_MEMORY("OldSpace") |
| 2577 }; | 2624 }; |
| 2578 | 2625 |
| 2579 | 2626 |
| 2580 // For contiguous spaces, top should be in the space (or at the end) and limit | 2627 // For contiguous spaces, top should be in the space (or at the end) and limit |
| 2581 // should be the end of the space. | 2628 // should be the end of the space. |
| 2582 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ | 2629 #define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \ |
| 2583 SLOW_ASSERT((space).page_low() <= (info).top \ | 2630 SLOW_ASSERT((space).page_low() <= (info).top() \ |
| 2584 && (info).top <= (space).page_high() \ | 2631 && (info).top() <= (space).page_high() \ |
| 2585 && (info).limit <= (space).page_high()) | 2632 && (info).limit() <= (space).page_high()) |
| 2586 | |
| 2587 | |
| 2588 // ----------------------------------------------------------------------------- | |
| 2589 // Old space for objects of a fixed size | |
| 2590 | |
| 2591 class FixedSpace : public PagedSpace { | |
| 2592 public: | |
| 2593 FixedSpace(Heap* heap, | |
| 2594 intptr_t max_capacity, | |
| 2595 AllocationSpace id, | |
| 2596 int object_size_in_bytes) | |
| 2597 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), | |
| 2598 object_size_in_bytes_(object_size_in_bytes) { | |
| 2599 page_extra_ = Page::kNonCodeObjectAreaSize % object_size_in_bytes; | |
| 2600 } | |
| 2601 | |
| 2602 // The limit of allocation for a page in this space. | |
| 2603 virtual Address PageAllocationLimit(Page* page) { | |
| 2604 return page->area_end() - page_extra_; | |
| 2605 } | |
| 2606 | |
| 2607 int object_size_in_bytes() { return object_size_in_bytes_; } | |
| 2608 | |
| 2609 // Prepares for a mark-compact GC. | |
| 2610 virtual void PrepareForMarkCompact(); | |
| 2611 | |
| 2612 private: | |
| 2613 // The size of objects in this space. | |
| 2614 int object_size_in_bytes_; | |
| 2615 }; | |
| 2616 | 2633 |
| 2617 | 2634 |
| 2618 // ----------------------------------------------------------------------------- | 2635 // ----------------------------------------------------------------------------- |
| 2619 // Old space for all map objects | 2636 // Old space for all map objects |
| 2620 | 2637 |
| 2621 class MapSpace : public FixedSpace { | 2638 class MapSpace : public PagedSpace { |
| 2622 public: | 2639 public: |
| 2623 // Creates a map space object with a maximum capacity. | 2640 // Creates a map space object with a maximum capacity. |
| 2624 MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) | 2641 MapSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) |
| 2625 : FixedSpace(heap, max_capacity, id, Map::kSize), | 2642 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE), |
| 2626 max_map_space_pages_(kMaxMapPageIndex - 1) { | 2643 max_map_space_pages_(kMaxMapPageIndex - 1) { |
| 2627 } | 2644 } |
| 2628 | 2645 |
| 2629 // Given an index, returns the page address. | 2646 // Given an index, returns the page address. |
| 2630 // TODO(1600): this limit is artifical just to keep code compilable | 2647 // TODO(1600): this limit is artifical just to keep code compilable |
| 2631 static const int kMaxMapPageIndex = 1 << 16; | 2648 static const int kMaxMapPageIndex = 1 << 16; |
| 2632 | 2649 |
| 2633 virtual int RoundSizeDownToObjectAlignment(int size) { | 2650 virtual int RoundSizeDownToObjectAlignment(int size) { |
| 2634 if (IsPowerOf2(Map::kSize)) { | 2651 if (IsPowerOf2(Map::kSize)) { |
| 2635 return RoundDown(size, Map::kSize); | 2652 return RoundDown(size, Map::kSize); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2652 const int max_map_space_pages_; | 2669 const int max_map_space_pages_; |
| 2653 | 2670 |
| 2654 public: | 2671 public: |
| 2655 TRACK_MEMORY("MapSpace") | 2672 TRACK_MEMORY("MapSpace") |
| 2656 }; | 2673 }; |
| 2657 | 2674 |
| 2658 | 2675 |
| 2659 // ----------------------------------------------------------------------------- | 2676 // ----------------------------------------------------------------------------- |
| 2660 // Old space for simple property cell objects | 2677 // Old space for simple property cell objects |
| 2661 | 2678 |
| 2662 class CellSpace : public FixedSpace { | 2679 class CellSpace : public PagedSpace { |
| 2663 public: | 2680 public: |
| 2664 // Creates a property cell space object with a maximum capacity. | 2681 // Creates a property cell space object with a maximum capacity. |
| 2665 CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) | 2682 CellSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id) |
| 2666 : FixedSpace(heap, max_capacity, id, Cell::kSize) | 2683 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) { |
| 2667 {} | 2684 } |
| 2668 | 2685 |
| 2669 virtual int RoundSizeDownToObjectAlignment(int size) { | 2686 virtual int RoundSizeDownToObjectAlignment(int size) { |
| 2670 if (IsPowerOf2(Cell::kSize)) { | 2687 if (IsPowerOf2(Cell::kSize)) { |
| 2671 return RoundDown(size, Cell::kSize); | 2688 return RoundDown(size, Cell::kSize); |
| 2672 } else { | 2689 } else { |
| 2673 return (size / Cell::kSize) * Cell::kSize; | 2690 return (size / Cell::kSize) * Cell::kSize; |
| 2674 } | 2691 } |
| 2675 } | 2692 } |
| 2676 | 2693 |
| 2677 protected: | 2694 protected: |
| 2678 virtual void VerifyObject(HeapObject* obj); | 2695 virtual void VerifyObject(HeapObject* obj); |
| 2679 | 2696 |
| 2680 public: | 2697 public: |
| 2681 TRACK_MEMORY("CellSpace") | 2698 TRACK_MEMORY("CellSpace") |
| 2682 }; | 2699 }; |
| 2683 | 2700 |
| 2684 | 2701 |
| 2685 // ----------------------------------------------------------------------------- | 2702 // ----------------------------------------------------------------------------- |
| 2686 // Old space for all global object property cell objects | 2703 // Old space for all global object property cell objects |
| 2687 | 2704 |
| 2688 class PropertyCellSpace : public FixedSpace { | 2705 class PropertyCellSpace : public PagedSpace { |
| 2689 public: | 2706 public: |
| 2690 // Creates a property cell space object with a maximum capacity. | 2707 // Creates a property cell space object with a maximum capacity. |
| 2691 PropertyCellSpace(Heap* heap, intptr_t max_capacity, | 2708 PropertyCellSpace(Heap* heap, intptr_t max_capacity, |
| 2692 AllocationSpace id) | 2709 AllocationSpace id) |
| 2693 : FixedSpace(heap, max_capacity, id, PropertyCell::kSize) | 2710 : PagedSpace(heap, max_capacity, id, NOT_EXECUTABLE) { |
| 2694 {} | 2711 } |
| 2695 | 2712 |
| 2696 virtual int RoundSizeDownToObjectAlignment(int size) { | 2713 virtual int RoundSizeDownToObjectAlignment(int size) { |
| 2697 if (IsPowerOf2(PropertyCell::kSize)) { | 2714 if (IsPowerOf2(PropertyCell::kSize)) { |
| 2698 return RoundDown(size, PropertyCell::kSize); | 2715 return RoundDown(size, PropertyCell::kSize); |
| 2699 } else { | 2716 } else { |
| 2700 return (size / PropertyCell::kSize) * PropertyCell::kSize; | 2717 return (size / PropertyCell::kSize) * PropertyCell::kSize; |
| 2701 } | 2718 } |
| 2702 } | 2719 } |
| 2703 | 2720 |
| 2704 protected: | 2721 protected: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2741 inline intptr_t Available(); | 2758 inline intptr_t Available(); |
| 2742 | 2759 |
| 2743 virtual intptr_t Size() { | 2760 virtual intptr_t Size() { |
| 2744 return size_; | 2761 return size_; |
| 2745 } | 2762 } |
| 2746 | 2763 |
| 2747 virtual intptr_t SizeOfObjects() { | 2764 virtual intptr_t SizeOfObjects() { |
| 2748 return objects_size_; | 2765 return objects_size_; |
| 2749 } | 2766 } |
| 2750 | 2767 |
| 2768 intptr_t MaximumCommittedMemory() { |
| 2769 return maximum_committed_; |
| 2770 } |
| 2771 |
| 2751 intptr_t CommittedMemory() { | 2772 intptr_t CommittedMemory() { |
| 2752 return Size(); | 2773 return Size(); |
| 2753 } | 2774 } |
| 2754 | 2775 |
| 2755 // Approximate amount of physical memory committed for this space. | 2776 // Approximate amount of physical memory committed for this space. |
| 2756 size_t CommittedPhysicalMemory(); | 2777 size_t CommittedPhysicalMemory(); |
| 2757 | 2778 |
| 2758 int PageCount() { | 2779 int PageCount() { |
| 2759 return page_count_; | 2780 return page_count_; |
| 2760 } | 2781 } |
| 2761 | 2782 |
| 2762 // Finds an object for a given address, returns Failure::Exception() | 2783 // Finds an object for a given address, returns Failure::Exception() |
| 2763 // if it is not found. The function iterates through all objects in this | 2784 // if it is not found. The function iterates through all objects in this |
| 2764 // space, may be slow. | 2785 // space, may be slow. |
| 2765 MaybeObject* FindObject(Address a); | 2786 MaybeObject* FindObject(Address a); |
| 2766 | 2787 |
| 2767 // Finds a large object page containing the given address, returns NULL | 2788 // Finds a large object page containing the given address, returns NULL |
| 2768 // if such a page doesn't exist. | 2789 // if such a page doesn't exist. |
| 2769 LargePage* FindPage(Address a); | 2790 LargePage* FindPage(Address a); |
| 2770 | 2791 |
| 2771 // Frees unmarked objects. | 2792 // Frees unmarked objects. |
| 2772 void FreeUnmarkedObjects(); | 2793 void FreeUnmarkedObjects(); |
| 2773 | 2794 |
| 2774 // Checks whether a heap object is in this space; O(1). | 2795 // Checks whether a heap object is in this space; O(1). |
| 2775 bool Contains(HeapObject* obj); | 2796 bool Contains(HeapObject* obj); |
| 2776 | 2797 |
| 2777 // Checks whether the space is empty. | 2798 // Checks whether the space is empty. |
| 2778 bool IsEmpty() { return first_page_ == NULL; } | 2799 bool IsEmpty() { return first_page_ == NULL; } |
| 2779 | 2800 |
| 2780 // See the comments for ReserveSpace in the Space class. This has to be | |
| 2781 // called after ReserveSpace has been called on the paged spaces, since they | |
| 2782 // may use some memory, leaving less for large objects. | |
| 2783 virtual bool ReserveSpace(int bytes); | |
| 2784 | |
| 2785 LargePage* first_page() { return first_page_; } | 2801 LargePage* first_page() { return first_page_; } |
| 2786 | 2802 |
| 2787 #ifdef VERIFY_HEAP | 2803 #ifdef VERIFY_HEAP |
| 2788 virtual void Verify(); | 2804 virtual void Verify(); |
| 2789 #endif | 2805 #endif |
| 2790 | 2806 |
| 2791 #ifdef DEBUG | 2807 #ifdef DEBUG |
| 2792 virtual void Print(); | 2808 virtual void Print(); |
| 2793 void ReportStatistics(); | 2809 void ReportStatistics(); |
| 2794 void CollectCodeStatistics(); | 2810 void CollectCodeStatistics(); |
| 2795 #endif | 2811 #endif |
| 2796 // Checks whether an address is in the object area in this space. It | 2812 // Checks whether an address is in the object area in this space. It |
| 2797 // iterates all objects in the space. May be slow. | 2813 // iterates all objects in the space. May be slow. |
| 2798 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } | 2814 bool SlowContains(Address addr) { return !FindObject(addr)->IsFailure(); } |
| 2799 | 2815 |
| 2800 private: | 2816 private: |
| 2801 intptr_t max_capacity_; | 2817 intptr_t max_capacity_; |
| 2818 intptr_t maximum_committed_; |
| 2802 // The head of the linked list of large object chunks. | 2819 // The head of the linked list of large object chunks. |
| 2803 LargePage* first_page_; | 2820 LargePage* first_page_; |
| 2804 intptr_t size_; // allocated bytes | 2821 intptr_t size_; // allocated bytes |
| 2805 int page_count_; // number of chunks | 2822 int page_count_; // number of chunks |
| 2806 intptr_t objects_size_; // size of objects | 2823 intptr_t objects_size_; // size of objects |
| 2807 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them | 2824 // Map MemoryChunk::kAlignment-aligned chunks to large pages covering them |
| 2808 HashMap chunk_map_; | 2825 HashMap chunk_map_; |
| 2809 | 2826 |
| 2810 friend class LargeObjectIterator; | 2827 friend class LargeObjectIterator; |
| 2811 | 2828 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2903 } | 2920 } |
| 2904 // Must be small, since an iteration is used for lookup. | 2921 // Must be small, since an iteration is used for lookup. |
| 2905 static const int kMaxComments = 64; | 2922 static const int kMaxComments = 64; |
| 2906 }; | 2923 }; |
| 2907 #endif | 2924 #endif |
| 2908 | 2925 |
| 2909 | 2926 |
| 2910 } } // namespace v8::internal | 2927 } } // namespace v8::internal |
| 2911 | 2928 |
| 2912 #endif // V8_SPACES_H_ | 2929 #endif // V8_SPACES_H_ |
| OLD | NEW |