| 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 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 // ie, its contents will be destroyed. The start address should be word | 1340 // ie, its contents will be destroyed. The start address should be word |
| 1341 // aligned, and the size should be a non-zero multiple of the word size. | 1341 // aligned, and the size should be a non-zero multiple of the word size. |
| 1342 int Free(Address start, int size_in_bytes); | 1342 int Free(Address start, int size_in_bytes); |
| 1343 | 1343 |
| 1344 // Allocate a block of size 'size_in_bytes' from the free list. The block | 1344 // Allocate a block of size 'size_in_bytes' from the free list. The block |
| 1345 // is unitialized. A failure is returned if no block is available. The | 1345 // is unitialized. A failure is returned if no block is available. The |
| 1346 // number of bytes lost to fragmentation is returned in the output parameter | 1346 // number of bytes lost to fragmentation is returned in the output parameter |
| 1347 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. | 1347 // 'wasted_bytes'. The size should be a non-zero multiple of the word size. |
| 1348 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); | 1348 MUST_USE_RESULT HeapObject* Allocate(int size_in_bytes); |
| 1349 | 1349 |
| 1350 void MarkNodes(); | |
| 1351 | |
| 1352 #ifdef DEBUG | 1350 #ifdef DEBUG |
| 1353 void Zap(); | 1351 void Zap(); |
| 1354 static intptr_t SumFreeList(FreeListNode* node); | 1352 static intptr_t SumFreeList(FreeListNode* node); |
| 1355 static int FreeListLength(FreeListNode* cur); | 1353 static int FreeListLength(FreeListNode* cur); |
| 1356 intptr_t SumFreeLists(); | 1354 intptr_t SumFreeLists(); |
| 1357 bool IsVeryLong(); | 1355 bool IsVeryLong(); |
| 1358 #endif | 1356 #endif |
| 1359 | 1357 |
| 1360 void CountFreeListItems(Page* p, intptr_t* sizes); | 1358 struct SizeStats { |
| 1359 intptr_t Total() { |
| 1360 return small_size_ + medium_size_ + large_size_ + huge_size_; |
| 1361 } |
| 1362 |
| 1363 intptr_t small_size_; |
| 1364 intptr_t medium_size_; |
| 1365 intptr_t large_size_; |
| 1366 intptr_t huge_size_; |
| 1367 }; |
| 1368 |
| 1369 void CountFreeListItems(Page* p, SizeStats* sizes); |
| 1370 |
| 1371 intptr_t EvictFreeListItems(Page* p); |
| 1361 | 1372 |
| 1362 private: | 1373 private: |
| 1363 // The size range of blocks, in bytes. | 1374 // The size range of blocks, in bytes. |
| 1364 static const int kMinBlockSize = 3 * kPointerSize; | 1375 static const int kMinBlockSize = 3 * kPointerSize; |
| 1365 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; | 1376 static const int kMaxBlockSize = Page::kMaxHeapObjectSize; |
| 1366 | 1377 |
| 1367 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); | 1378 FreeListNode* PickNodeFromList(FreeListNode** list, int* node_size); |
| 1368 | 1379 |
| 1369 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); | 1380 FreeListNode* FindNodeFor(int size_in_bytes, int* node_size); |
| 1370 | 1381 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 void set_was_swept_conservatively(bool b) { was_swept_conservatively_ = b; } | 1545 void set_was_swept_conservatively(bool b) { was_swept_conservatively_ = b; } |
| 1535 | 1546 |
| 1536 // Evacuation candidates are swept by evacuator. Needs to return a valid | 1547 // Evacuation candidates are swept by evacuator. Needs to return a valid |
| 1537 // result before _and_ after evacuation has finished. | 1548 // result before _and_ after evacuation has finished. |
| 1538 static bool ShouldBeSweptLazily(Page* p) { | 1549 static bool ShouldBeSweptLazily(Page* p) { |
| 1539 return !p->IsEvacuationCandidate() && | 1550 return !p->IsEvacuationCandidate() && |
| 1540 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && | 1551 !p->IsFlagSet(Page::RESCAN_ON_EVACUATION) && |
| 1541 !p->WasSweptPrecisely(); | 1552 !p->WasSweptPrecisely(); |
| 1542 } | 1553 } |
| 1543 | 1554 |
| 1544 void SetPagesToSweep(Page* first, Page* last) { | 1555 void SetPagesToSweep(Page* first) { |
| 1545 first_unswept_page_ = first; | 1556 first_unswept_page_ = first; |
| 1546 last_unswept_page_ = last; | |
| 1547 } | 1557 } |
| 1548 | 1558 |
| 1549 bool AdvanceSweeper(intptr_t bytes_to_sweep); | 1559 bool AdvanceSweeper(intptr_t bytes_to_sweep); |
| 1550 | 1560 |
| 1551 bool IsSweepingComplete() { | 1561 bool IsSweepingComplete() { |
| 1552 return !first_unswept_page_->is_valid(); | 1562 return !first_unswept_page_->is_valid(); |
| 1553 } | 1563 } |
| 1554 | 1564 |
| 1555 Page* FirstPage() { return anchor_.next_page(); } | 1565 Page* FirstPage() { return anchor_.next_page(); } |
| 1556 Page* LastPage() { return anchor_.prev_page(); } | 1566 Page* LastPage() { return anchor_.prev_page(); } |
| 1557 | 1567 |
| 1558 bool IsFragmented(Page* p) { | 1568 bool IsFragmented(Page* p) { |
| 1559 intptr_t sizes[4]; | 1569 FreeList::SizeStats sizes; |
| 1560 free_list_.CountFreeListItems(p, sizes); | 1570 free_list_.CountFreeListItems(p, &sizes); |
| 1561 | 1571 |
| 1562 intptr_t ratio; | 1572 intptr_t ratio; |
| 1563 intptr_t ratio_threshold; | 1573 intptr_t ratio_threshold; |
| 1564 if (identity() == CODE_SPACE) { | 1574 if (identity() == CODE_SPACE) { |
| 1565 ratio = (sizes[1] * 10 + sizes[2] * 2) * 100 / Page::kObjectAreaSize; | 1575 ratio = (sizes.medium_size_ * 10 + sizes.large_size_ * 2) * 100 / |
| 1576 Page::kObjectAreaSize; |
| 1566 ratio_threshold = 10; | 1577 ratio_threshold = 10; |
| 1567 } else { | 1578 } else { |
| 1568 ratio = (sizes[0] * 5 + sizes[1]) * 100 / Page::kObjectAreaSize; | 1579 ratio = (sizes.small_size_ * 5 + sizes.medium_size_) * 100 / |
| 1580 Page::kObjectAreaSize; |
| 1569 ratio_threshold = 15; | 1581 ratio_threshold = 15; |
| 1570 } | 1582 } |
| 1571 | 1583 |
| 1572 if (FLAG_trace_fragmentation) { | 1584 if (FLAG_trace_fragmentation) { |
| 1573 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", | 1585 PrintF("%p [%d]: %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %d (%.2f%%) %s\n", |
| 1574 reinterpret_cast<void*>(p), | 1586 reinterpret_cast<void*>(p), |
| 1575 identity(), | 1587 identity(), |
| 1576 static_cast<int>(sizes[0]), | 1588 static_cast<int>(sizes.small_size_), |
| 1577 static_cast<double>(sizes[0] * 100) / Page::kObjectAreaSize, | 1589 static_cast<double>(sizes.small_size_ * 100) / |
| 1578 static_cast<int>(sizes[1]), | 1590 Page::kObjectAreaSize, |
| 1579 static_cast<double>(sizes[1] * 100) / Page::kObjectAreaSize, | 1591 static_cast<int>(sizes.medium_size_), |
| 1580 static_cast<int>(sizes[2]), | 1592 static_cast<double>(sizes.medium_size_ * 100) / |
| 1581 static_cast<double>(sizes[2] * 100) / Page::kObjectAreaSize, | 1593 Page::kObjectAreaSize, |
| 1582 static_cast<int>(sizes[3]), | 1594 static_cast<int>(sizes.large_size_), |
| 1583 static_cast<double>(sizes[3] * 100) / Page::kObjectAreaSize, | 1595 static_cast<double>(sizes.large_size_ * 100) / |
| 1596 Page::kObjectAreaSize, |
| 1597 static_cast<int>(sizes.huge_size_), |
| 1598 static_cast<double>(sizes.huge_size_ * 100) / |
| 1599 Page::kObjectAreaSize, |
| 1584 (ratio > ratio_threshold) ? "[fragmented]" : ""); | 1600 (ratio > ratio_threshold) ? "[fragmented]" : ""); |
| 1585 } | 1601 } |
| 1586 | 1602 |
| 1587 return (ratio > ratio_threshold) || | 1603 return (ratio > ratio_threshold) || |
| 1588 (FLAG_always_compact && sizes[3] != Page::kObjectAreaSize); | 1604 (FLAG_always_compact && sizes.Total() != Page::kObjectAreaSize); |
| 1589 } | 1605 } |
| 1590 | 1606 |
| 1591 void EvictEvacuationCandidatesFromFreeLists(); | 1607 void EvictEvacuationCandidatesFromFreeLists(); |
| 1592 | 1608 |
| 1593 bool CanExpand(); | 1609 bool CanExpand(); |
| 1594 | 1610 |
| 1595 protected: | 1611 protected: |
| 1596 // Maximum capacity of this space. | 1612 // Maximum capacity of this space. |
| 1597 intptr_t max_capacity_; | 1613 intptr_t max_capacity_; |
| 1598 | 1614 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1610 | 1626 |
| 1611 // Bytes of each page that cannot be allocated. Possibly non-zero | 1627 // Bytes of each page that cannot be allocated. Possibly non-zero |
| 1612 // for pages in spaces with only fixed-size objects. Always zero | 1628 // for pages in spaces with only fixed-size objects. Always zero |
| 1613 // for pages in spaces with variable sized objects (those pages are | 1629 // for pages in spaces with variable sized objects (those pages are |
| 1614 // padded with free-list nodes). | 1630 // padded with free-list nodes). |
| 1615 int page_extra_; | 1631 int page_extra_; |
| 1616 | 1632 |
| 1617 bool was_swept_conservatively_; | 1633 bool was_swept_conservatively_; |
| 1618 | 1634 |
| 1619 Page* first_unswept_page_; | 1635 Page* first_unswept_page_; |
| 1620 Page* last_unswept_page_; | |
| 1621 | 1636 |
| 1622 // Expands the space by allocating a fixed number of pages. Returns false if | 1637 // Expands the space by allocating a fixed number of pages. Returns false if |
| 1623 // it cannot allocate requested number of pages from OS. | 1638 // it cannot allocate requested number of pages from OS. |
| 1624 bool Expand(); | 1639 bool Expand(); |
| 1625 | 1640 |
| 1626 // Generic fast case allocation function that tries linear allocation at the | 1641 // Generic fast case allocation function that tries linear allocation at the |
| 1627 // address denoted by top in allocation_info_. | 1642 // address denoted by top in allocation_info_. |
| 1628 inline HeapObject* AllocateLinearly(int size_in_bytes); | 1643 inline HeapObject* AllocateLinearly(int size_in_bytes); |
| 1629 | 1644 |
| 1630 // Slow path of AllocateRaw. This function is space-dependent. | 1645 // Slow path of AllocateRaw. This function is space-dependent. |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2327 // The limit of allocation for a page in this space. | 2342 // The limit of allocation for a page in this space. |
| 2328 virtual Address PageAllocationLimit(Page* page) { | 2343 virtual Address PageAllocationLimit(Page* page) { |
| 2329 return page->ObjectAreaEnd() - page_extra_; | 2344 return page->ObjectAreaEnd() - page_extra_; |
| 2330 } | 2345 } |
| 2331 | 2346 |
| 2332 int object_size_in_bytes() { return object_size_in_bytes_; } | 2347 int object_size_in_bytes() { return object_size_in_bytes_; } |
| 2333 | 2348 |
| 2334 // Prepares for a mark-compact GC. | 2349 // Prepares for a mark-compact GC. |
| 2335 virtual void PrepareForMarkCompact(); | 2350 virtual void PrepareForMarkCompact(); |
| 2336 | 2351 |
| 2337 void MarkFreeListNodes() { free_list_.MarkNodes(); } | |
| 2338 | |
| 2339 protected: | 2352 protected: |
| 2340 void ResetFreeList() { | 2353 void ResetFreeList() { |
| 2341 free_list_.Reset(); | 2354 free_list_.Reset(); |
| 2342 } | 2355 } |
| 2343 | 2356 |
| 2344 private: | 2357 private: |
| 2345 // The size of objects in this space. | 2358 // The size of objects in this space. |
| 2346 int object_size_in_bytes_; | 2359 int object_size_in_bytes_; |
| 2347 | 2360 |
| 2348 // The name of this space. | 2361 // The name of this space. |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2606 } | 2619 } |
| 2607 // Must be small, since an iteration is used for lookup. | 2620 // Must be small, since an iteration is used for lookup. |
| 2608 static const int kMaxComments = 64; | 2621 static const int kMaxComments = 64; |
| 2609 }; | 2622 }; |
| 2610 #endif | 2623 #endif |
| 2611 | 2624 |
| 2612 | 2625 |
| 2613 } } // namespace v8::internal | 2626 } } // namespace v8::internal |
| 2614 | 2627 |
| 2615 #endif // V8_SPACES_H_ | 2628 #endif // V8_SPACES_H_ |
| OLD | NEW |