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 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 | 621 |
622 // ----------------------------------------------------------------------------- | 622 // ----------------------------------------------------------------------------- |
623 // PagedSpace implementation | 623 // PagedSpace implementation |
624 | 624 |
625 PagedSpace::PagedSpace(Heap* heap, | 625 PagedSpace::PagedSpace(Heap* heap, |
626 intptr_t max_capacity, | 626 intptr_t max_capacity, |
627 AllocationSpace id, | 627 AllocationSpace id, |
628 Executability executable) | 628 Executability executable) |
629 : Space(heap, id, executable), | 629 : Space(heap, id, executable), |
630 free_list_(this), | 630 free_list_(this), |
631 was_swept_conservatively_(false) { | 631 was_swept_conservatively_(false), |
| 632 first_unswept_page_(Page::FromAddress(NULL)), |
| 633 last_unswept_page_(Page::FromAddress(NULL)) { |
632 max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) | 634 max_capacity_ = (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) |
633 * Page::kObjectAreaSize; | 635 * Page::kObjectAreaSize; |
634 accounting_stats_.Clear(); | 636 accounting_stats_.Clear(); |
635 | 637 |
636 allocation_info_.top = NULL; | 638 allocation_info_.top = NULL; |
637 allocation_info_.limit = NULL; | 639 allocation_info_.limit = NULL; |
638 | 640 |
639 anchor_.InitializeAsAnchor(this); | 641 anchor_.InitializeAsAnchor(this); |
640 } | 642 } |
641 | 643 |
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1557 | 1559 |
1558 ASSERT(new_node_size - size_in_bytes >= 0); // New linear size. | 1560 ASSERT(new_node_size - size_in_bytes >= 0); // New linear size. |
1559 | 1561 |
1560 const int kThreshold = IncrementalMarking::kAllocatedThreshold; | 1562 const int kThreshold = IncrementalMarking::kAllocatedThreshold; |
1561 | 1563 |
1562 // Memory in the linear allocation area is counted as allocated. We may free | 1564 // Memory in the linear allocation area is counted as allocated. We may free |
1563 // a little of this again immediately - see below. | 1565 // a little of this again immediately - see below. |
1564 owner_->Allocate(new_node_size); | 1566 owner_->Allocate(new_node_size); |
1565 | 1567 |
1566 if (new_node_size - size_in_bytes > kThreshold && | 1568 if (new_node_size - size_in_bytes > kThreshold && |
1567 HEAP->incremental_marking()->IsMarking() && | 1569 HEAP->incremental_marking()->IsMarkingIncomplete() && |
1568 FLAG_incremental_marking_steps) { | 1570 FLAG_incremental_marking_steps) { |
1569 // We don't want to give too large linear areas to the allocator while | 1571 // We don't want to give too large linear areas to the allocator while |
1570 // incremental marking is going on, because we won't check again whether | 1572 // incremental marking is going on, because we won't check again whether |
1571 // we want to do another increment until the linear area is used up. | 1573 // we want to do another increment until the linear area is used up. |
1572 owner_->Free(new_node->address() + size_in_bytes + kThreshold, | 1574 owner_->Free(new_node->address() + size_in_bytes + kThreshold, |
1573 new_node_size - size_in_bytes - kThreshold); | 1575 new_node_size - size_in_bytes - kThreshold); |
1574 owner_->SetTop(new_node->address() + size_in_bytes, | 1576 owner_->SetTop(new_node->address() + size_in_bytes, |
1575 new_node->address() + size_in_bytes + kThreshold); | 1577 new_node->address() + size_in_bytes + kThreshold); |
1576 } else { | 1578 } else { |
1577 // Normally we give the rest of the node to the allocator as its new | 1579 // Normally we give the rest of the node to the allocator as its new |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1634 | 1636 |
1635 | 1637 |
1636 // ----------------------------------------------------------------------------- | 1638 // ----------------------------------------------------------------------------- |
1637 // OldSpace implementation | 1639 // OldSpace implementation |
1638 | 1640 |
1639 void OldSpace::PrepareForMarkCompact(bool will_compact) { | 1641 void OldSpace::PrepareForMarkCompact(bool will_compact) { |
1640 ASSERT(!will_compact); | 1642 ASSERT(!will_compact); |
1641 // Call prepare of the super class. | 1643 // Call prepare of the super class. |
1642 PagedSpace::PrepareForMarkCompact(will_compact); | 1644 PagedSpace::PrepareForMarkCompact(will_compact); |
1643 | 1645 |
| 1646 first_unswept_page_ = last_unswept_page_ = Page::FromAddress(NULL); |
| 1647 |
1644 // Clear the free list before a full GC---it will be rebuilt afterward. | 1648 // Clear the free list before a full GC---it will be rebuilt afterward. |
| 1649 // TODO(gc): can we avoid resetting free list? |
1645 free_list_.Reset(); | 1650 free_list_.Reset(); |
1646 } | 1651 } |
1647 | 1652 |
1648 | 1653 |
1649 bool NewSpace::ReserveSpace(int bytes) { | 1654 bool NewSpace::ReserveSpace(int bytes) { |
1650 // We can't reliably unpack a partial snapshot that needs more new space | 1655 // We can't reliably unpack a partial snapshot that needs more new space |
1651 // space than the minimum NewSpace size. | 1656 // space than the minimum NewSpace size. |
1652 ASSERT(bytes <= InitialCapacity()); | 1657 ASSERT(bytes <= InitialCapacity()); |
1653 Address limit = allocation_info_.limit; | 1658 Address limit = allocation_info_.limit; |
1654 Address top = allocation_info_.top; | 1659 Address top = allocation_info_.top; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1691 } | 1696 } |
1692 | 1697 |
1693 | 1698 |
1694 // You have to call this last, since the implementation from PagedSpace | 1699 // You have to call this last, since the implementation from PagedSpace |
1695 // doesn't know that memory was 'promised' to large object space. | 1700 // doesn't know that memory was 'promised' to large object space. |
1696 bool LargeObjectSpace::ReserveSpace(int bytes) { | 1701 bool LargeObjectSpace::ReserveSpace(int bytes) { |
1697 return heap()->OldGenerationSpaceAvailable() >= bytes; | 1702 return heap()->OldGenerationSpaceAvailable() >= bytes; |
1698 } | 1703 } |
1699 | 1704 |
1700 | 1705 |
| 1706 bool PagedSpace::AdvanceSweeper(intptr_t bytes_to_sweep) { |
| 1707 if (IsSweepingComplete()) return true; |
| 1708 |
| 1709 int freed_bytes = 0; |
| 1710 Page* last = last_unswept_page_->next_page(); |
| 1711 Page* p = first_unswept_page_; |
| 1712 do { |
| 1713 freed_bytes += MarkCompactCollector::SweepConservatively(this, p); |
| 1714 p = p->next_page(); |
| 1715 } while (p != last && freed_bytes < bytes_to_sweep); |
| 1716 |
| 1717 if (p == last) { |
| 1718 last_unswept_page_ = first_unswept_page_ = Page::FromAddress(NULL); |
| 1719 } else { |
| 1720 first_unswept_page_ = p; |
| 1721 } |
| 1722 |
| 1723 heap()->LowerOldGenLimits(freed_bytes); |
| 1724 |
| 1725 return IsSweepingComplete(); |
| 1726 } |
| 1727 |
| 1728 |
1701 HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) { | 1729 HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) { |
1702 // Allocation in this space has failed. | 1730 // Allocation in this space has failed. |
1703 | 1731 |
1704 // Free list allocation failed and there is no next page. Fail if we have | 1732 // Free list allocation failed and there is no next page. Fail if we have |
1705 // hit the old generation size limit that should cause a garbage | 1733 // hit the old generation size limit that should cause a garbage |
1706 // collection. | 1734 // collection. |
1707 if (!heap()->always_allocate() && | 1735 if (!heap()->always_allocate() && |
1708 heap()->OldGenerationAllocationLimitReached()) { | 1736 heap()->OldGenerationAllocationLimitReached()) { |
1709 return NULL; | 1737 return NULL; |
1710 } | 1738 } |
1711 | 1739 |
| 1740 // If there are unswept pages advance lazy sweeper. |
| 1741 if (first_unswept_page_->is_valid()) { |
| 1742 AdvanceSweeper(size_in_bytes); |
| 1743 |
| 1744 // Retry the free list allocation. |
| 1745 HeapObject* object = free_list_.Allocate(size_in_bytes); |
| 1746 if (object != NULL) return object; |
| 1747 |
| 1748 if (!IsSweepingComplete()) { |
| 1749 AdvanceSweeper(kMaxInt); |
| 1750 |
| 1751 // Retry the free list allocation. |
| 1752 object = free_list_.Allocate(size_in_bytes); |
| 1753 if (object != NULL) return object; |
| 1754 } |
| 1755 } |
| 1756 |
1712 // Try to expand the space and allocate in the new next page. | 1757 // Try to expand the space and allocate in the new next page. |
1713 if (Expand()) { | 1758 if (Expand()) { |
1714 return free_list_.Allocate(size_in_bytes); | 1759 return free_list_.Allocate(size_in_bytes); |
1715 } | 1760 } |
1716 | 1761 |
1717 // Finally, fail. | 1762 // Finally, fail. |
1718 return NULL; | 1763 return NULL; |
1719 } | 1764 } |
1720 | 1765 |
1721 | 1766 |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { | 2261 for (HeapObject* obj = obj_it.next(); obj != NULL; obj = obj_it.next()) { |
2217 if (obj->IsCode()) { | 2262 if (obj->IsCode()) { |
2218 Code* code = Code::cast(obj); | 2263 Code* code = Code::cast(obj); |
2219 isolate->code_kind_statistics()[code->kind()] += code->Size(); | 2264 isolate->code_kind_statistics()[code->kind()] += code->Size(); |
2220 } | 2265 } |
2221 } | 2266 } |
2222 } | 2267 } |
2223 #endif // DEBUG | 2268 #endif // DEBUG |
2224 | 2269 |
2225 } } // namespace v8::internal | 2270 } } // namespace v8::internal |
OLD | NEW |