| 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 |