OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 | 779 |
780 return true; | 780 return true; |
781 } | 781 } |
782 | 782 |
783 | 783 |
784 #ifdef DEBUG | 784 #ifdef DEBUG |
785 void PagedSpace::Print() { } | 785 void PagedSpace::Print() { } |
786 #endif | 786 #endif |
787 | 787 |
788 | 788 |
| 789 #ifdef DEBUG |
| 790 // We do not assume that the PageIterator works, because it depends on the |
| 791 // invariants we are checking during verification. |
| 792 void PagedSpace::Verify(ObjectVisitor* visitor) { |
| 793 // The allocation pointer should be valid, and it should be in a page in the |
| 794 // space. |
| 795 ASSERT(allocation_info_.VerifyPagedAllocation()); |
| 796 Page* top_page = Page::FromAllocationTop(allocation_info_.top); |
| 797 ASSERT(MemoryAllocator::IsPageInSpace(top_page, this)); |
| 798 |
| 799 // Loop over all the pages. |
| 800 bool above_allocation_top = false; |
| 801 Page* current_page = first_page_; |
| 802 while (current_page->is_valid()) { |
| 803 if (above_allocation_top) { |
| 804 // We don't care what's above the allocation top. |
| 805 } else { |
| 806 // Unless this is the last page in the space containing allocated |
| 807 // objects, the allocation top should be at a constant offset from the |
| 808 // object area end. |
| 809 Address top = current_page->AllocationTop(); |
| 810 if (current_page == top_page) { |
| 811 ASSERT(top == allocation_info_.top); |
| 812 // The next page will be above the allocation top. |
| 813 above_allocation_top = true; |
| 814 } else { |
| 815 ASSERT(top == current_page->ObjectAreaEnd() - page_extra_); |
| 816 } |
| 817 |
| 818 // It should be packed with objects from the bottom to the top. |
| 819 Address current = current_page->ObjectAreaStart(); |
| 820 while (current < top) { |
| 821 HeapObject* object = HeapObject::FromAddress(current); |
| 822 |
| 823 // The first word should be a map, and we expect all map pointers to |
| 824 // be in map space. |
| 825 Map* map = object->map(); |
| 826 ASSERT(map->IsMap()); |
| 827 ASSERT(Heap::map_space()->Contains(map)); |
| 828 |
| 829 // Perform space-specific object verification. |
| 830 VerifyObject(object); |
| 831 |
| 832 // The object itself should look OK. |
| 833 object->Verify(); |
| 834 |
| 835 // All the interior pointers should be contained in the heap and |
| 836 // have their remembered set bits set if required as determined |
| 837 // by the visitor. |
| 838 int size = object->Size(); |
| 839 if (object->IsCode()) { |
| 840 Code::cast(object)->ConvertICTargetsFromAddressToObject(); |
| 841 object->IterateBody(map->instance_type(), size, visitor); |
| 842 Code::cast(object)->ConvertICTargetsFromObjectToAddress(); |
| 843 } else { |
| 844 object->IterateBody(map->instance_type(), size, visitor); |
| 845 } |
| 846 |
| 847 current += size; |
| 848 } |
| 849 |
| 850 // The allocation pointer should not be in the middle of an object. |
| 851 ASSERT(current == top); |
| 852 } |
| 853 |
| 854 current_page = current_page->next_page(); |
| 855 } |
| 856 } |
| 857 #endif |
| 858 |
| 859 |
789 // ----------------------------------------------------------------------------- | 860 // ----------------------------------------------------------------------------- |
790 // NewSpace implementation | 861 // NewSpace implementation |
791 | 862 |
792 | 863 |
793 bool NewSpace::Setup(Address start, int size) { | 864 bool NewSpace::Setup(Address start, int size) { |
794 // Setup new space based on the preallocated memory block defined by | 865 // Setup new space based on the preallocated memory block defined by |
795 // start and size. The provided space is divided into two semi-spaces. | 866 // start and size. The provided space is divided into two semi-spaces. |
796 // To support fast containment testing in the new space, the size of | 867 // To support fast containment testing in the new space, the size of |
797 // this chunk must be a power of two and it must be aligned to its size. | 868 // this chunk must be a power of two and it must be aligned to its size. |
798 int initial_semispace_capacity = Heap::InitialSemiSpaceSize(); | 869 int initial_semispace_capacity = Heap::InitialSemiSpaceSize(); |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 if (free_size > 0) { | 1679 if (free_size > 0) { |
1609 int wasted_bytes = free_list_.Free(allocation_info_.top, free_size); | 1680 int wasted_bytes = free_list_.Free(allocation_info_.top, free_size); |
1610 accounting_stats_.WasteBytes(wasted_bytes); | 1681 accounting_stats_.WasteBytes(wasted_bytes); |
1611 } | 1682 } |
1612 SetAllocationInfo(&allocation_info_, current_page->next_page()); | 1683 SetAllocationInfo(&allocation_info_, current_page->next_page()); |
1613 return AllocateLinearly(&allocation_info_, size_in_bytes); | 1684 return AllocateLinearly(&allocation_info_, size_in_bytes); |
1614 } | 1685 } |
1615 | 1686 |
1616 | 1687 |
1617 #ifdef DEBUG | 1688 #ifdef DEBUG |
1618 // We do not assume that the PageIterator works, because it depends on the | |
1619 // invariants we are checking during verification. | |
1620 void OldSpace::Verify() { | |
1621 // The allocation pointer should be valid, and it should be in a page in the | |
1622 // space. | |
1623 ASSERT(allocation_info_.VerifyPagedAllocation()); | |
1624 Page* top_page = Page::FromAllocationTop(allocation_info_.top); | |
1625 ASSERT(MemoryAllocator::IsPageInSpace(top_page, this)); | |
1626 | |
1627 // Loop over all the pages. | |
1628 bool above_allocation_top = false; | |
1629 Page* current_page = first_page_; | |
1630 while (current_page->is_valid()) { | |
1631 if (above_allocation_top) { | |
1632 // We don't care what's above the allocation top. | |
1633 } else { | |
1634 // Unless this is the last page in the space containing allocated | |
1635 // objects, the allocation top should be at the object area end. | |
1636 Address top = current_page->AllocationTop(); | |
1637 if (current_page == top_page) { | |
1638 ASSERT(top == allocation_info_.top); | |
1639 // The next page will be above the allocation top. | |
1640 above_allocation_top = true; | |
1641 } else { | |
1642 ASSERT(top == current_page->ObjectAreaEnd()); | |
1643 } | |
1644 | |
1645 // It should be packed with objects from the bottom to the top. | |
1646 Address current = current_page->ObjectAreaStart(); | |
1647 while (current < top) { | |
1648 HeapObject* object = HeapObject::FromAddress(current); | |
1649 | |
1650 // The first word should be a map, and we expect all map pointers to | |
1651 // be in map space. | |
1652 Map* map = object->map(); | |
1653 ASSERT(map->IsMap()); | |
1654 ASSERT(Heap::map_space()->Contains(map)); | |
1655 | |
1656 // The object should not be a map. | |
1657 ASSERT(!object->IsMap()); | |
1658 | |
1659 // The object itself should look OK. | |
1660 object->Verify(); | |
1661 | |
1662 // All the interior pointers should be contained in the heap and have | |
1663 // their remembered set bits set if they point to new space. Code | |
1664 // objects do not have remembered set bits that we care about. | |
1665 VerifyPointersAndRSetVisitor rset_visitor; | |
1666 VerifyPointersVisitor no_rset_visitor; | |
1667 int size = object->Size(); | |
1668 if (object->IsCode()) { | |
1669 Code::cast(object)->ConvertICTargetsFromAddressToObject(); | |
1670 object->IterateBody(map->instance_type(), size, &no_rset_visitor); | |
1671 Code::cast(object)->ConvertICTargetsFromObjectToAddress(); | |
1672 } else { | |
1673 object->IterateBody(map->instance_type(), size, &rset_visitor); | |
1674 } | |
1675 | |
1676 current += size; | |
1677 } | |
1678 | |
1679 // The allocation pointer should not be in the middle of an object. | |
1680 ASSERT(current == top); | |
1681 } | |
1682 | |
1683 current_page = current_page->next_page(); | |
1684 } | |
1685 } | |
1686 | |
1687 | |
1688 struct CommentStatistic { | 1689 struct CommentStatistic { |
1689 const char* comment; | 1690 const char* comment; |
1690 int size; | 1691 int size; |
1691 int count; | 1692 int count; |
1692 void Clear() { | 1693 void Clear() { |
1693 comment = NULL; | 1694 comment = NULL; |
1694 size = 0; | 1695 size = 0; |
1695 count = 0; | 1696 count = 0; |
1696 } | 1697 } |
1697 }; | 1698 }; |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2079 ASSERT(current_page->next_page()->is_valid()); | 2080 ASSERT(current_page->next_page()->is_valid()); |
2080 ASSERT(current_page->ObjectAreaEnd() - allocation_info_.top == page_extra_); | 2081 ASSERT(current_page->ObjectAreaEnd() - allocation_info_.top == page_extra_); |
2081 ASSERT_EQ(object_size_in_bytes_, size_in_bytes); | 2082 ASSERT_EQ(object_size_in_bytes_, size_in_bytes); |
2082 accounting_stats_.WasteBytes(page_extra_); | 2083 accounting_stats_.WasteBytes(page_extra_); |
2083 SetAllocationInfo(&allocation_info_, current_page->next_page()); | 2084 SetAllocationInfo(&allocation_info_, current_page->next_page()); |
2084 return AllocateLinearly(&allocation_info_, size_in_bytes); | 2085 return AllocateLinearly(&allocation_info_, size_in_bytes); |
2085 } | 2086 } |
2086 | 2087 |
2087 | 2088 |
2088 #ifdef DEBUG | 2089 #ifdef DEBUG |
2089 // We do not assume that the PageIterator works, because it depends on the | |
2090 // invariants we are checking during verification. | |
2091 void FixedSpace::Verify() { | |
2092 // The allocation pointer should be valid, and it should be in a page in the | |
2093 // space. | |
2094 ASSERT(allocation_info_.VerifyPagedAllocation()); | |
2095 Page* top_page = Page::FromAllocationTop(allocation_info_.top); | |
2096 ASSERT(MemoryAllocator::IsPageInSpace(top_page, this)); | |
2097 | |
2098 // Loop over all the pages. | |
2099 bool above_allocation_top = false; | |
2100 Page* current_page = first_page_; | |
2101 while (current_page->is_valid()) { | |
2102 if (above_allocation_top) { | |
2103 // We don't care what's above the allocation top. | |
2104 } else { | |
2105 // Unless this is the last page in the space containing allocated | |
2106 // objects, the allocation top should be at a constant offset from the | |
2107 // object area end. | |
2108 Address top = current_page->AllocationTop(); | |
2109 if (current_page == top_page) { | |
2110 ASSERT(top == allocation_info_.top); | |
2111 // The next page will be above the allocation top. | |
2112 above_allocation_top = true; | |
2113 } else { | |
2114 ASSERT(top == current_page->ObjectAreaEnd() - page_extra_); | |
2115 } | |
2116 | |
2117 // It should be packed with objects from the bottom to the top. | |
2118 Address current = current_page->ObjectAreaStart(); | |
2119 while (current < top) { | |
2120 HeapObject* object = HeapObject::FromAddress(current); | |
2121 | |
2122 // The first word should be a map, and we expect all map pointers to | |
2123 // be in map space. | |
2124 Map* map = object->map(); | |
2125 ASSERT(map->IsMap()); | |
2126 ASSERT(Heap::map_space()->Contains(map)); | |
2127 | |
2128 // Verify the object in the space. | |
2129 VerifyObject(object); | |
2130 | |
2131 // The object itself should look OK. | |
2132 object->Verify(); | |
2133 | |
2134 // All the interior pointers should be contained in the heap and | |
2135 // have their remembered set bits set if they point to new space. | |
2136 VerifyPointersAndRSetVisitor visitor; | |
2137 int size = object->Size(); | |
2138 object->IterateBody(map->instance_type(), size, &visitor); | |
2139 | |
2140 current += size; | |
2141 } | |
2142 | |
2143 // The allocation pointer should not be in the middle of an object. | |
2144 ASSERT(current == top); | |
2145 } | |
2146 | |
2147 current_page = current_page->next_page(); | |
2148 } | |
2149 } | |
2150 | |
2151 | |
2152 void FixedSpace::ReportStatistics() { | 2090 void FixedSpace::ReportStatistics() { |
2153 int pct = Available() * 100 / Capacity(); | 2091 int pct = Available() * 100 / Capacity(); |
2154 PrintF(" capacity: %d, waste: %d, available: %d, %%%d\n", | 2092 PrintF(" capacity: %d, waste: %d, available: %d, %%%d\n", |
2155 Capacity(), Waste(), Available(), pct); | 2093 Capacity(), Waste(), Available(), pct); |
2156 | 2094 |
2157 // Report remembered set statistics. | 2095 // Report remembered set statistics. |
2158 int rset_marked_pointers = 0; | 2096 int rset_marked_pointers = 0; |
2159 int cross_gen_pointers = 0; | 2097 int cross_gen_pointers = 0; |
2160 | 2098 |
2161 PageIterator page_it(this, PageIterator::PAGES_IN_USE); | 2099 PageIterator page_it(this, PageIterator::PAGES_IN_USE); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 reinterpret_cast<Object**>(object->address() | 2591 reinterpret_cast<Object**>(object->address() |
2654 + Page::kObjectAreaSize), | 2592 + Page::kObjectAreaSize), |
2655 allocation_top); | 2593 allocation_top); |
2656 PrintF("\n"); | 2594 PrintF("\n"); |
2657 } | 2595 } |
2658 } | 2596 } |
2659 } | 2597 } |
2660 #endif // DEBUG | 2598 #endif // DEBUG |
2661 | 2599 |
2662 } } // namespace v8::internal | 2600 } } // namespace v8::internal |
OLD | NEW |