Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: src/mark-compact.cc

Issue 3260001: Force relinking of paged space if first attempt to recommit from space fails. (Closed)
Patch Set: Virtualizing block deallocation Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 // Update pointers from external string table. 1620 // Update pointers from external string table.
1621 Heap::UpdateNewSpaceReferencesInExternalStringTable( 1621 Heap::UpdateNewSpaceReferencesInExternalStringTable(
1622 &UpdateNewSpaceReferenceInExternalStringTableEntry); 1622 &UpdateNewSpaceReferenceInExternalStringTableEntry);
1623 1623
1624 // All pointers were updated. Update auxiliary allocation info. 1624 // All pointers were updated. Update auxiliary allocation info.
1625 Heap::IncrementYoungSurvivorsCounter(survivors_size); 1625 Heap::IncrementYoungSurvivorsCounter(survivors_size);
1626 space->set_age_mark(space->top()); 1626 space->set_age_mark(space->top());
1627 } 1627 }
1628 1628
1629 1629
1630 static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { 1630 static void SweepSpace(PagedSpace* space) {
1631 PageIterator it(space, PageIterator::PAGES_IN_USE); 1631 PageIterator it(space, PageIterator::PAGES_IN_USE);
1632 1632
1633 // During sweeping of paged space we are trying to find longest sequences 1633 // During sweeping of paged space we are trying to find longest sequences
1634 // of pages without live objects and free them (instead of putting them on 1634 // of pages without live objects and free them (instead of putting them on
1635 // the free list). 1635 // the free list).
1636 1636
1637 // Page preceding current. 1637 // Page preceding current.
1638 Page* prev = Page::FromAddress(NULL); 1638 Page* prev = Page::FromAddress(NULL);
1639 1639
1640 // First empty page in a sequence. 1640 // First empty page in a sequence.
(...skipping 20 matching lines...) Expand all
1661 1661
1662 for (Address current = p->ObjectAreaStart(); 1662 for (Address current = p->ObjectAreaStart();
1663 current < p->AllocationTop(); 1663 current < p->AllocationTop();
1664 current += object->Size()) { 1664 current += object->Size()) {
1665 object = HeapObject::FromAddress(current); 1665 object = HeapObject::FromAddress(current);
1666 if (object->IsMarked()) { 1666 if (object->IsMarked()) {
1667 object->ClearMark(); 1667 object->ClearMark();
1668 MarkCompactCollector::tracer()->decrement_marked_count(); 1668 MarkCompactCollector::tracer()->decrement_marked_count();
1669 1669
1670 if (!is_previous_alive) { // Transition from free to live. 1670 if (!is_previous_alive) { // Transition from free to live.
1671 dealloc(free_start, 1671 space->DeallocateBlock(free_start,
1672 static_cast<int>(current - free_start), 1672 static_cast<int>(current - free_start),
1673 true, 1673 true);
1674 false);
1675 is_previous_alive = true; 1674 is_previous_alive = true;
1676 } 1675 }
1677 } else { 1676 } else {
1678 MarkCompactCollector::ReportDeleteIfNeeded(object); 1677 MarkCompactCollector::ReportDeleteIfNeeded(object);
1679 if (is_previous_alive) { // Transition from live to free. 1678 if (is_previous_alive) { // Transition from live to free.
1680 free_start = current; 1679 free_start = current;
1681 is_previous_alive = false; 1680 is_previous_alive = false;
1682 } 1681 }
1683 } 1682 }
1684 // The object is now unmarked for the call to Size() at the top of the 1683 // The object is now unmarked for the call to Size() at the top of the
1685 // loop. 1684 // loop.
1686 } 1685 }
1687 1686
1688 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop()) 1687 bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop())
1689 || (!is_previous_alive && free_start == p->ObjectAreaStart()); 1688 || (!is_previous_alive && free_start == p->ObjectAreaStart());
1690 1689
1691 if (page_is_empty) { 1690 if (page_is_empty) {
1692 // This page is empty. Check whether we are in the middle of 1691 // This page is empty. Check whether we are in the middle of
1693 // sequence of empty pages and start one if not. 1692 // sequence of empty pages and start one if not.
1694 if (!first_empty_page->is_valid()) { 1693 if (!first_empty_page->is_valid()) {
1695 first_empty_page = p; 1694 first_empty_page = p;
1696 prec_first_empty_page = prev; 1695 prec_first_empty_page = prev;
1697 } 1696 }
1698 1697
1699 if (!is_previous_alive) { 1698 if (!is_previous_alive) {
1700 // There are dead objects on this page. Update space accounting stats 1699 // There are dead objects on this page. Update space accounting stats
1701 // without putting anything into free list. 1700 // without putting anything into free list.
1702 int size_in_bytes = static_cast<int>(p->AllocationTop() - free_start); 1701 int size_in_bytes = static_cast<int>(p->AllocationTop() - free_start);
1703 if (size_in_bytes > 0) { 1702 if (size_in_bytes > 0) {
1704 dealloc(free_start, size_in_bytes, false, true); 1703 space->DeallocateBlock(free_start, size_in_bytes, false);
1705 } 1704 }
1706 } 1705 }
1707 } else { 1706 } else {
1708 // This page is not empty. Sequence of empty pages ended on the previous 1707 // This page is not empty. Sequence of empty pages ended on the previous
1709 // one. 1708 // one.
1710 if (first_empty_page->is_valid()) { 1709 if (first_empty_page->is_valid()) {
1711 space->FreePages(prec_first_empty_page, prev); 1710 space->FreePages(prec_first_empty_page, prev);
1712 prec_first_empty_page = first_empty_page = Page::FromAddress(NULL); 1711 prec_first_empty_page = first_empty_page = Page::FromAddress(NULL);
1713 } 1712 }
1714 1713
1715 // If there is a free ending area on one of the previous pages we have 1714 // If there is a free ending area on one of the previous pages we have
1716 // deallocate that area and put it on the free list. 1715 // deallocate that area and put it on the free list.
1717 if (last_free_size > 0) { 1716 if (last_free_size > 0) {
1718 Page::FromAddress(last_free_start)-> 1717 Page::FromAddress(last_free_start)->
1719 SetAllocationWatermark(last_free_start); 1718 SetAllocationWatermark(last_free_start);
1720 dealloc(last_free_start, last_free_size, true, true); 1719 space->DeallocateBlock(last_free_start, last_free_size, true);
1721 last_free_start = NULL; 1720 last_free_start = NULL;
1722 last_free_size = 0; 1721 last_free_size = 0;
1723 } 1722 }
1724 1723
1725 // If the last region of this page was not live we remember it. 1724 // If the last region of this page was not live we remember it.
1726 if (!is_previous_alive) { 1725 if (!is_previous_alive) {
1727 ASSERT(last_free_size == 0); 1726 ASSERT(last_free_size == 0);
1728 last_free_size = static_cast<int>(p->AllocationTop() - free_start); 1727 last_free_size = static_cast<int>(p->AllocationTop() - free_start);
1729 last_free_start = free_start; 1728 last_free_start = free_start;
1730 } 1729 }
(...skipping 10 matching lines...) Expand all
1741 // to the beginning of first empty page. 1740 // to the beginning of first empty page.
1742 ASSERT(prev == space->AllocationTopPage()); 1741 ASSERT(prev == space->AllocationTopPage());
1743 1742
1744 new_allocation_top = first_empty_page->ObjectAreaStart(); 1743 new_allocation_top = first_empty_page->ObjectAreaStart();
1745 } 1744 }
1746 1745
1747 if (last_free_size > 0) { 1746 if (last_free_size > 0) {
1748 // There was a free ending area on the previous page. 1747 // There was a free ending area on the previous page.
1749 // Deallocate it without putting it into freelist and move allocation 1748 // Deallocate it without putting it into freelist and move allocation
1750 // top to the beginning of this free area. 1749 // top to the beginning of this free area.
1751 dealloc(last_free_start, last_free_size, false, true); 1750 space->DeallocateBlock(last_free_start, last_free_size, false);
1752 new_allocation_top = last_free_start; 1751 new_allocation_top = last_free_start;
1753 } 1752 }
1754 1753
1755 if (new_allocation_top != NULL) { 1754 if (new_allocation_top != NULL) {
1756 #ifdef DEBUG 1755 #ifdef DEBUG
1757 Page* new_allocation_top_page = Page::FromAllocationTop(new_allocation_top); 1756 Page* new_allocation_top_page = Page::FromAllocationTop(new_allocation_top);
1758 if (!first_empty_page->is_valid()) { 1757 if (!first_empty_page->is_valid()) {
1759 ASSERT(new_allocation_top_page == space->AllocationTopPage()); 1758 ASSERT(new_allocation_top_page == space->AllocationTopPage());
1760 } else if (last_free_size > 0) { 1759 } else if (last_free_size > 0) {
1761 ASSERT(new_allocation_top_page == prec_first_empty_page); 1760 ASSERT(new_allocation_top_page == prec_first_empty_page);
1762 } else { 1761 } else {
1763 ASSERT(new_allocation_top_page == first_empty_page); 1762 ASSERT(new_allocation_top_page == first_empty_page);
1764 } 1763 }
1765 #endif 1764 #endif
1766 1765
1767 space->SetTop(new_allocation_top); 1766 space->SetTop(new_allocation_top);
1768 } 1767 }
1769 } 1768 }
1770 1769
1771 1770
1772 void MarkCompactCollector::DeallocateOldPointerBlock(Address start,
1773 int size_in_bytes,
1774 bool add_to_freelist,
1775 bool last_on_page) {
1776 Heap::old_pointer_space()->Free(start, size_in_bytes, add_to_freelist);
1777 }
1778
1779
1780 void MarkCompactCollector::DeallocateOldDataBlock(Address start,
1781 int size_in_bytes,
1782 bool add_to_freelist,
1783 bool last_on_page) {
1784 Heap::old_data_space()->Free(start, size_in_bytes, add_to_freelist);
1785 }
1786
1787
1788 void MarkCompactCollector::DeallocateCodeBlock(Address start,
1789 int size_in_bytes,
1790 bool add_to_freelist,
1791 bool last_on_page) {
1792 Heap::code_space()->Free(start, size_in_bytes, add_to_freelist);
1793 }
1794
1795
1796 void MarkCompactCollector::DeallocateMapBlock(Address start,
1797 int size_in_bytes,
1798 bool add_to_freelist,
1799 bool last_on_page) {
1800 // Objects in map space are assumed to have size Map::kSize and a
1801 // valid map in their first word. Thus, we break the free block up into
1802 // chunks and free them separately.
1803 ASSERT(size_in_bytes % Map::kSize == 0);
1804 Address end = start + size_in_bytes;
1805 for (Address a = start; a < end; a += Map::kSize) {
1806 Heap::map_space()->Free(a, add_to_freelist);
1807 }
1808 }
1809
1810
1811 void MarkCompactCollector::DeallocateCellBlock(Address start,
1812 int size_in_bytes,
1813 bool add_to_freelist,
1814 bool last_on_page) {
1815 // Free-list elements in cell space are assumed to have a fixed size.
1816 // We break the free block into chunks and add them to the free list
1817 // individually.
1818 int size = Heap::cell_space()->object_size_in_bytes();
1819 ASSERT(size_in_bytes % size == 0);
1820 Address end = start + size_in_bytes;
1821 for (Address a = start; a < end; a += size) {
1822 Heap::cell_space()->Free(a, add_to_freelist);
1823 }
1824 }
1825
1826
1827 void MarkCompactCollector::EncodeForwardingAddresses() { 1771 void MarkCompactCollector::EncodeForwardingAddresses() {
1828 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); 1772 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
1829 // Objects in the active semispace of the young generation may be 1773 // Objects in the active semispace of the young generation may be
1830 // relocated to the inactive semispace (if not promoted). Set the 1774 // relocated to the inactive semispace (if not promoted). Set the
1831 // relocation info to the beginning of the inactive semispace. 1775 // relocation info to the beginning of the inactive semispace.
1832 Heap::new_space()->MCResetRelocationInfo(); 1776 Heap::new_space()->MCResetRelocationInfo();
1833 1777
1834 // Compute the forwarding pointers in each space. 1778 // Compute the forwarding pointers in each space.
1835 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace, 1779 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace,
1836 ReportDeleteIfNeeded>( 1780 ReportDeleteIfNeeded>(
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 void MarkCompactCollector::SweepSpaces() { 2025 void MarkCompactCollector::SweepSpaces() {
2082 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 2026 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
2083 2027
2084 ASSERT(state_ == SWEEP_SPACES); 2028 ASSERT(state_ == SWEEP_SPACES);
2085 ASSERT(!IsCompacting()); 2029 ASSERT(!IsCompacting());
2086 // Noncompacting collections simply sweep the spaces to clear the mark 2030 // Noncompacting collections simply sweep the spaces to clear the mark
2087 // bits and free the nonlive blocks (for old and map spaces). We sweep 2031 // bits and free the nonlive blocks (for old and map spaces). We sweep
2088 // the map space last because freeing non-live maps overwrites them and 2032 // the map space last because freeing non-live maps overwrites them and
2089 // the other spaces rely on possibly non-live maps to get the sizes for 2033 // the other spaces rely on possibly non-live maps to get the sizes for
2090 // non-live objects. 2034 // non-live objects.
2091 SweepSpace(Heap::old_pointer_space(), &DeallocateOldPointerBlock); 2035 SweepSpace(Heap::old_pointer_space());
2092 SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock); 2036 SweepSpace(Heap::old_data_space());
2093 SweepSpace(Heap::code_space(), &DeallocateCodeBlock); 2037 SweepSpace(Heap::code_space());
2094 SweepSpace(Heap::cell_space(), &DeallocateCellBlock); 2038 SweepSpace(Heap::cell_space());
2095 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); 2039 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
2096 SweepNewSpace(Heap::new_space()); 2040 SweepNewSpace(Heap::new_space());
2097 } 2041 }
2098 SweepSpace(Heap::map_space(), &DeallocateMapBlock); 2042 SweepSpace(Heap::map_space());
2099 2043
2100 Heap::IterateDirtyRegions(Heap::map_space(), 2044 Heap::IterateDirtyRegions(Heap::map_space(),
2101 &Heap::IteratePointersInDirtyMapsRegion, 2045 &Heap::IteratePointersInDirtyMapsRegion,
2102 &UpdatePointerToNewGen, 2046 &UpdatePointerToNewGen,
2103 Heap::WATERMARK_SHOULD_BE_VALID); 2047 Heap::WATERMARK_SHOULD_BE_VALID);
2104 2048
2105 int live_maps_size = Heap::map_space()->Size(); 2049 int live_maps_size = Heap::map_space()->Size();
2106 int live_maps = live_maps_size / Map::kSize; 2050 int live_maps = live_maps_size / Map::kSize;
2107 ASSERT(live_map_objects_size_ == live_maps_size); 2051 ASSERT(live_map_objects_size_ == live_maps_size);
2108 2052
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 } 2608 }
2665 2609
2666 2610
2667 void MarkCompactCollector::Initialize() { 2611 void MarkCompactCollector::Initialize() {
2668 StaticPointersToNewGenUpdatingVisitor::Initialize(); 2612 StaticPointersToNewGenUpdatingVisitor::Initialize();
2669 StaticMarkingVisitor::Initialize(); 2613 StaticMarkingVisitor::Initialize();
2670 } 2614 }
2671 2615
2672 2616
2673 } } // namespace v8::internal 2617 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698