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 // 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 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1279 | 1279 |
| 1280 static inline bool IsFreeListNode(HeapObject* object); | 1280 static inline bool IsFreeListNode(HeapObject* object); |
| 1281 | 1281 |
| 1282 // Set the size in bytes, which can be read with HeapObject::Size(). This | 1282 // Set the size in bytes, which can be read with HeapObject::Size(). This |
| 1283 // function also writes a map to the first word of the block so that it | 1283 // function also writes a map to the first word of the block so that it |
| 1284 // looks like a heap object to the garbage collector and heap iteration | 1284 // looks like a heap object to the garbage collector and heap iteration |
| 1285 // functions. | 1285 // functions. |
| 1286 void set_size(Heap* heap, int size_in_bytes); | 1286 void set_size(Heap* heap, int size_in_bytes); |
| 1287 | 1287 |
| 1288 // Accessors for the next field. | 1288 // Accessors for the next field. |
| 1289 inline FreeListNode* next(); | 1289 FreeListNode* next(); |
| 1290 inline FreeListNode** next_address(); | 1290 inline FreeListNode** next_address(); |
| 1291 inline void set_next(FreeListNode* next); | 1291 inline void set_next(FreeListNode* next); |
| 1292 | 1292 |
| 1293 inline void Zap(); | 1293 inline void Zap(); |
| 1294 | 1294 |
| 1295 private: | 1295 private: |
| 1296 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); | 1296 static const int kNextOffset = POINTER_SIZE_ALIGN(FreeSpace::kHeaderSize); |
| 1297 | 1297 |
| 1298 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); | 1298 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListNode); |
| 1299 }; | 1299 }; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1344 // is unitialized. A failure is returned if no block is available. The | 1344 // is unitialized. A failure is returned if no block is available. The |
| 1345 // number of bytes lost to fragmentation is returned in the output parameter | 1345 // number of bytes lost to fragmentation is returned in the output parameter |
| 1346 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. | 1346 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. |
| 1347 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); | 1347 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); |
| 1348 | 1348 |
| 1349 void MarkNodes(); | 1349 void MarkNodes(); |
| 1350 | 1350 |
| 1351 #ifdef DEBUG | 1351 #ifdef DEBUG |
| 1352 void Zap(); | 1352 void Zap(); |
| 1353 static intptr_t SumFreeList(FreeListNode* node); | 1353 static intptr_t SumFreeList(FreeListNode* node); |
| 1354 static int FreeListLength(FreeListNode* cur); | |
| 1355 intptr_t SumFreeLists(); | 1354 intptr_t SumFreeLists(); |
| 1356 bool IsVeryLong(); | |
| 1357 #endif | 1355 #endif |
| 1358 | 1356 |
| 1357 static int FreeListLength(FreeListNode* cur); | |
| 1358 bool IsVeryLong(); | |
| 1359 void CountFreeListItems(Page* p, intptr_t* sizes); | 1359 void CountFreeListItems(Page* p, intptr_t* sizes); |
| 1360 | 1360 |
| 1361 FreeListNode* get_chain(int i) { | |
|
Vyacheslav Egorov (Chromium)
2011/09/28 15:21:11
make enum!
| |
| 1362 switch (i) { | |
| 1363 case 0: return small_list_; | |
| 1364 case 1: return medium_list_; | |
| 1365 case 2: return large_list_; | |
| 1366 case 3: return huge_list_; | |
| 1367 } | |
| 1368 UNREACHABLE(); | |
| 1369 return NULL; | |
| 1370 } | |
| 1371 static const int kNumberOfChains = 4; | |
| 1372 | |
| 1361 private: | 1373 private: |
| 1362 // The size range of blocks, in bytes. | 1374 // The size range of blocks, in bytes. |
| 1363 static const int kMinBlockSize = 3 * kPointerSize; | 1375 static const int kMinBlockSize = 3 * kPointerSize; |
| 1364 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 1376 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; |
| 1365 | 1377 |
| 1366 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); | 1378 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); |
| 1367 | 1379 |
| 1368 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1380 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
| 1369 | 1381 |
| 1370 PagedSpace* owner_; | 1382 PagedSpace* owner_; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1479 // If add_to_freelist is false then just accounting stats are updated and | 1491 // If add_to_freelist is false then just accounting stats are updated and |
| 1480 // no attempt to add area to free list is made. | 1492 // no attempt to add area to free list is made. |
| 1481 int Free(Address start, int size_in_bytes) { | 1493 int Free(Address start, int size_in_bytes) { |
| 1482 int wasted = free_list_.Free(start, size_in_bytes); | 1494 int wasted = free_list_.Free(start, size_in_bytes); |
| 1483 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); | 1495 accounting_stats_.DeallocateBytes(size_in_bytes - wasted); |
| 1484 return size_in_bytes - wasted; | 1496 return size_in_bytes - wasted; |
| 1485 } | 1497 } |
| 1486 | 1498 |
| 1487 int FreeOrUnmapPage(Page* page, Address start, int size_in_bytes); | 1499 int FreeOrUnmapPage(Page* page, Address start, int size_in_bytes); |
| 1488 | 1500 |
| 1501 void VisualizeTopChange(Address top); | |
| 1502 | |
| 1489 // Set space allocation info. | 1503 // Set space allocation info. |
| 1490 void SetTop(Address top, Address limit) { | 1504 inline void SetTop(Address top, Address limit); |
| 1491 ASSERT(top == limit || | |
| 1492 Page::FromAddress(top) == Page::FromAddress(limit - 1)); | |
| 1493 allocation_info_.top = top; | |
| 1494 allocation_info_.limit = limit; | |
| 1495 } | |
| 1496 | 1505 |
| 1497 void Allocate(int bytes) { | 1506 void Allocate(int bytes) { |
| 1498 accounting_stats_.AllocateBytes(bytes); | 1507 accounting_stats_.AllocateBytes(bytes); |
| 1499 } | 1508 } |
| 1500 | 1509 |
| 1501 void IncreaseCapacity(int size) { | 1510 void IncreaseCapacity(int size) { |
| 1502 accounting_stats_.ExpandSpace(size); | 1511 accounting_stats_.ExpandSpace(size); |
| 1503 } | 1512 } |
| 1504 | 1513 |
| 1505 // Releases half of unused pages. | 1514 // Releases half of unused pages. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1583 } | 1592 } |
| 1584 | 1593 |
| 1585 return (ratio > ratio_threshold) || | 1594 return (ratio > ratio_threshold) || |
| 1586 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); | 1595 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); |
| 1587 } | 1596 } |
| 1588 | 1597 |
| 1589 void EvictEvacuationCandidatesFromFreeLists(); | 1598 void EvictEvacuationCandidatesFromFreeLists(); |
| 1590 | 1599 |
| 1591 bool CanExpand(); | 1600 bool CanExpand(); |
| 1592 | 1601 |
| 1602 FreeList* free_list() { return &free_list_; } | |
| 1603 | |
| 1593 protected: | 1604 protected: |
| 1594 // Maximum capacity of this space. | 1605 // Maximum capacity of this space. |
| 1595 intptr_t max_capacity_; | 1606 intptr_t max_capacity_; |
| 1596 | 1607 |
| 1597 // Accounting information for this space. | 1608 // Accounting information for this space. |
| 1598 AllocationStats accounting_stats_; | 1609 AllocationStats accounting_stats_; |
| 1599 | 1610 |
| 1600 // The dummy page that anchors the double linked list of pages. | 1611 // The dummy page that anchors the double linked list of pages. |
| 1601 Page anchor_; | 1612 Page anchor_; |
| 1602 | 1613 |
| 1603 // The space's free list. | 1614 // The space's free list. |
| 1604 FreeList free_list_; | 1615 FreeList free_list_; |
| 1605 | 1616 |
| 1606 // Normal allocation information. | 1617 // Normal allocation information. |
| 1607 AllocationInfo allocation_info_; | 1618 AllocationInfo allocation_info_; |
| 1608 | 1619 |
| 1620 Address last_visualized_top_; | |
| 1621 | |
| 1609 // Bytes of each page that cannot be allocated. Possibly non-zero | 1622 // Bytes of each page that cannot be allocated. Possibly non-zero |
| 1610 // for pages in spaces with only fixed-size objects. Always zero | 1623 // for pages in spaces with only fixed-size objects. Always zero |
| 1611 // for pages in spaces with variable sized objects (those pages are | 1624 // for pages in spaces with variable sized objects (those pages are |
| 1612 // padded with free-list nodes). | 1625 // padded with free-list nodes). |
| 1613 int page_extra_; | 1626 int page_extra_; |
| 1614 | 1627 |
| 1615 bool was_swept_conservatively_; | 1628 bool was_swept_conservatively_; |
| 1616 | 1629 |
| 1617 Page* first_unswept_page_; | 1630 Page* first_unswept_page_; |
| 1618 Page* last_unswept_page_; | 1631 Page* last_unswept_page_; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1710 return reinterpret_cast<SemiSpace*>(owner()); | 1723 return reinterpret_cast<SemiSpace*>(owner()); |
| 1711 } | 1724 } |
| 1712 | 1725 |
| 1713 bool is_anchor() { return !this->InNewSpace(); } | 1726 bool is_anchor() { return !this->InNewSpace(); } |
| 1714 | 1727 |
| 1715 static bool IsAtStart(Address addr) { | 1728 static bool IsAtStart(Address addr) { |
| 1716 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) | 1729 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) |
| 1717 == kObjectStartOffset; | 1730 == kObjectStartOffset; |
| 1718 } | 1731 } |
| 1719 | 1732 |
| 1733 Address ObjectAreaStart() { | |
| 1734 return address() + kObjectStartOffset; | |
| 1735 } | |
| 1736 | |
| 1737 Address ObjectAreaEnd() { | |
| 1738 return address() + Page::kPageSize; | |
| 1739 } | |
| 1740 | |
| 1720 static bool IsAtEnd(Address addr) { | 1741 static bool IsAtEnd(Address addr) { |
| 1721 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; | 1742 return (reinterpret_cast<intptr_t>(addr) & Page::kPageAlignmentMask) == 0; |
| 1722 } | 1743 } |
| 1723 | 1744 |
| 1724 Address address() { | 1745 Address address() { |
| 1725 return reinterpret_cast<Address>(this); | 1746 return reinterpret_cast<Address>(this); |
| 1726 } | 1747 } |
| 1727 | 1748 |
| 1728 // Finds the NewSpacePage containg the given address. | 1749 // Finds the NewSpacePage containg the given address. |
| 1729 static inline NewSpacePage* FromAddress(Address address_in_page) { | 1750 static inline NewSpacePage* FromAddress(Address address_in_page) { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2018 // forwards most functions to the appropriate semispace. | 2039 // forwards most functions to the appropriate semispace. |
| 2019 | 2040 |
| 2020 class NewSpace : public Space { | 2041 class NewSpace : public Space { |
| 2021 public: | 2042 public: |
| 2022 // Constructor. | 2043 // Constructor. |
| 2023 explicit NewSpace(Heap* heap) | 2044 explicit NewSpace(Heap* heap) |
| 2024 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2045 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
| 2025 to_space_(heap, kToSpace), | 2046 to_space_(heap, kToSpace), |
| 2026 from_space_(heap, kFromSpace), | 2047 from_space_(heap, kFromSpace), |
| 2027 reservation_(), | 2048 reservation_(), |
| 2028 inline_allocation_limit_step_(0) {} | 2049 inline_allocation_limit_step_(0), |
| 2050 last_visualized_top_(NULL) {} | |
| 2029 | 2051 |
| 2030 // Sets up the new space using the given chunk. | 2052 // Sets up the new space using the given chunk. |
| 2031 bool Setup(int reserved_semispace_size_, int max_semispace_size); | 2053 bool Setup(int reserved_semispace_size_, int max_semispace_size); |
| 2032 | 2054 |
| 2033 // Tears down the space. Heap memory was not allocated by the space, so it | 2055 // Tears down the space. Heap memory was not allocated by the space, so it |
| 2034 // is not deallocated here. | 2056 // is not deallocated here. |
| 2035 void TearDown(); | 2057 void TearDown(); |
| 2036 | 2058 |
| 2037 // True if the space has been set up but not torn down. | 2059 // True if the space has been set up but not torn down. |
| 2038 bool HasBeenSetup() { | 2060 bool HasBeenSetup() { |
| 2039 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup(); | 2061 return to_space_.HasBeenSetup() && from_space_.HasBeenSetup(); |
| 2040 } | 2062 } |
| 2041 | 2063 |
| 2042 // Flip the pair of spaces. | 2064 // Flip the pair of spaces. |
| 2043 void Flip(); | 2065 void Flip(); |
| 2044 | 2066 |
| 2067 void VisualizeTop(); | |
| 2068 void VisualizeUnallocation(SemiSpace* semispace); | |
| 2069 | |
| 2045 // Grow the capacity of the semispaces. Assumes that they are not at | 2070 // Grow the capacity of the semispaces. Assumes that they are not at |
| 2046 // their maximum capacity. | 2071 // their maximum capacity. |
| 2047 void Grow(); | 2072 void Grow(); |
| 2048 | 2073 |
| 2049 // Shrink the capacity of the semispaces. | 2074 // Shrink the capacity of the semispaces. |
| 2050 void Shrink(); | 2075 void Shrink(); |
| 2051 | 2076 |
| 2052 // True if the address or object lies in the address range of either | 2077 // True if the address or object lies in the address range of either |
| 2053 // semispace (not necessarily below the allocation pointer). | 2078 // semispace (not necessarily below the allocation pointer). |
| 2054 bool Contains(Address a) { | 2079 bool Contains(Address a) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2111 // Return the address of the allocation pointer in the active semispace. | 2136 // Return the address of the allocation pointer in the active semispace. |
| 2112 Address top() { | 2137 Address top() { |
| 2113 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); | 2138 ASSERT(to_space_.current_page()->ContainsLimit(allocation_info_.top)); |
| 2114 return allocation_info_.top; | 2139 return allocation_info_.top; |
| 2115 } | 2140 } |
| 2116 // Return the address of the first object in the active semispace. | 2141 // Return the address of the first object in the active semispace. |
| 2117 Address bottom() { return to_space_.space_start(); } | 2142 Address bottom() { return to_space_.space_start(); } |
| 2118 | 2143 |
| 2119 // Get the age mark of the inactive semispace. | 2144 // Get the age mark of the inactive semispace. |
| 2120 Address age_mark() { return from_space_.age_mark(); } | 2145 Address age_mark() { return from_space_.age_mark(); } |
| 2146 // Get the age mark of the active semispace. | |
| 2147 Address to_space_age_mark() { return to_space_.age_mark(); } | |
| 2121 // Set the age mark in the active semispace. | 2148 // Set the age mark in the active semispace. |
| 2122 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } | 2149 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } |
| 2123 | 2150 |
| 2124 // The start address of the space and a bit mask. Anding an address in the | 2151 // The start address of the space and a bit mask. Anding an address in the |
| 2125 // new space with the mask will result in the start address. | 2152 // new space with the mask will result in the start address. |
| 2126 Address start() { return start_; } | 2153 Address start() { return start_; } |
| 2127 uintptr_t mask() { return address_mask_; } | 2154 uintptr_t mask() { return address_mask_; } |
| 2128 | 2155 |
| 2129 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { | 2156 INLINE(uint32_t AddressToMarkbitIndex(Address addr)) { |
| 2130 ASSERT(Contains(addr)); | 2157 ASSERT(Contains(addr)); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2262 // to be lower than actual limit and then will gradually increase it | 2289 // to be lower than actual limit and then will gradually increase it |
| 2263 // in steps to guarantee that we do incremental marking steps even | 2290 // in steps to guarantee that we do incremental marking steps even |
| 2264 // when all allocation is performed from inlined generated code. | 2291 // when all allocation is performed from inlined generated code. |
| 2265 intptr_t inline_allocation_limit_step_; | 2292 intptr_t inline_allocation_limit_step_; |
| 2266 | 2293 |
| 2267 Address top_on_previous_step_; | 2294 Address top_on_previous_step_; |
| 2268 | 2295 |
| 2269 HistogramInfo* allocated_histogram_; | 2296 HistogramInfo* allocated_histogram_; |
| 2270 HistogramInfo* promoted_histogram_; | 2297 HistogramInfo* promoted_histogram_; |
| 2271 | 2298 |
| 2299 Address last_visualized_top_; | |
| 2300 | |
| 2272 // Implementation of AllocateRaw. | 2301 // Implementation of AllocateRaw. |
| 2273 MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(int size_in_bytes); | 2302 MUST_USE_RESULT inline MaybeObject* AllocateRawInternal(int size_in_bytes); |
| 2274 | 2303 |
| 2275 friend class SemiSpaceIterator; | 2304 friend class SemiSpaceIterator; |
| 2276 | 2305 |
| 2277 public: | 2306 public: |
| 2278 TRACK_MEMORY("NewSpace") | 2307 TRACK_MEMORY("NewSpace") |
| 2279 }; | 2308 }; |
| 2280 | 2309 |
| 2281 | 2310 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2609 } | 2638 } |
| 2610 // Must be small, since an iteration is used for lookup. | 2639 // Must be small, since an iteration is used for lookup. |
| 2611 static const int kMaxComments = 64; | 2640 static const int kMaxComments = 64; |
| 2612 }; | 2641 }; |
| 2613 #endif | 2642 #endif |
| 2614 | 2643 |
| 2615 | 2644 |
| 2616 } } // namespace v8::internal | 2645 } } // namespace v8::internal |
| 2617 | 2646 |
| 2618 #endif // V8_SPACES_H_ | 2647 #endif // V8_SPACES_H_ |
| OLD | NEW |