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

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

Issue 7124006: Two-page newspace. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Address review comments. Created 9 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/heap-inl.h ('k') | src/runtime.cc » ('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 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 } 107 }
108 } 108 }
109 109
110 110
111 static void VerifyMarking(Page* p) { 111 static void VerifyMarking(Page* p) {
112 VerifyMarking(p->ObjectAreaStart(), p->ObjectAreaEnd()); 112 VerifyMarking(p->ObjectAreaStart(), p->ObjectAreaEnd());
113 } 113 }
114 114
115 115
116 static void VerifyMarking(NewSpace* space) { 116 static void VerifyMarking(NewSpace* space) {
117 VerifyMarking(space->bottom(), space->top()); 117 Address end = space->top();
118 NewSpacePageIterator it(space->bottom(), end);
119 // The bottom position is at the start of its page. Allows us to use
120 // page->body() as start of range on all pages.
121 ASSERT_EQ(space->bottom(),
122 NewSpacePage::FromAddress(space->bottom())->body());
123 while (it.has_next()) {
124 NewSpacePage* page = it.next();
125 Address limit = it.has_next() ? page->body_limit() : end;
126 VerifyMarking(page->body(), limit);
127 }
118 } 128 }
119 129
120 130
121 static void VerifyMarking(PagedSpace* space) { 131 static void VerifyMarking(PagedSpace* space) {
122 PageIterator it(space); 132 PageIterator it(space);
123 133
124 while (it.has_next()) { 134 while (it.has_next()) {
125 VerifyMarking(it.next()); 135 VerifyMarking(it.next());
126 } 136 }
127 } 137 }
(...skipping 1562 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 incremental_marking->marking_deque()->ClearOverflowed(); 1700 incremental_marking->marking_deque()->ClearOverflowed();
1691 } else { 1701 } else {
1692 // Abort any pending incremental activities e.g. incremental sweeping. 1702 // Abort any pending incremental activities e.g. incremental sweeping.
1693 incremental_marking->Abort(); 1703 incremental_marking->Abort();
1694 } 1704 }
1695 1705
1696 #ifdef DEBUG 1706 #ifdef DEBUG
1697 ASSERT(state_ == PREPARE_GC); 1707 ASSERT(state_ == PREPARE_GC);
1698 state_ = MARK_LIVE_OBJECTS; 1708 state_ = MARK_LIVE_OBJECTS;
1699 #endif 1709 #endif
1700 // The to space contains live objects, the from space is used as a marking 1710 // The to space contains live objects, a page in from space is used as a
1701 // stack. 1711 // marking stack.
1702 Address marking_deque_start = heap()->new_space()->FromSpaceLow(); 1712 Address marking_deque_start = heap()->new_space()->FromSpacePageLow();
1703 Address marking_deque_end = heap()->new_space()->FromSpaceHigh(); 1713 Address marking_deque_end = heap()->new_space()->FromSpaceHigh();
1704 if (FLAG_force_marking_deque_overflows) { 1714 if (FLAG_force_marking_deque_overflows) {
1705 marking_deque_end = marking_deque_start + 64 * kPointerSize; 1715 marking_deque_end = marking_deque_start + 64 * kPointerSize;
1706 } 1716 }
1707 marking_deque_.Initialize(marking_deque_start, 1717 marking_deque_.Initialize(marking_deque_start,
1708 marking_deque_end); 1718 marking_deque_end);
1709 ASSERT(!marking_deque_.overflowed()); 1719 ASSERT(!marking_deque_.overflowed());
1710 1720
1711 if (incremental_marking_overflowed) { 1721 if (incremental_marking_overflowed) {
1712 // There are overflowed objects left in the heap after incremental marking. 1722 // There are overflowed objects left in the heap after incremental marking.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 // to new space. We should clear them to avoid encountering them during next 1930 // to new space. We should clear them to avoid encountering them during next
1921 // pointer iteration. This is an issue if the store buffer overflows and we 1931 // pointer iteration. This is an issue if the store buffer overflows and we
1922 // have to scan the entire old space, including dead objects, looking for 1932 // have to scan the entire old space, including dead objects, looking for
1923 // pointers to new space. 1933 // pointers to new space.
1924 static void MigrateObject(Heap* heap, 1934 static void MigrateObject(Heap* heap,
1925 Address dst, 1935 Address dst,
1926 Address src, 1936 Address src,
1927 int size, 1937 int size,
1928 bool to_old_space) { 1938 bool to_old_space) {
1929 if (to_old_space) { 1939 if (to_old_space) {
1930 HEAP->CopyBlockToOldSpaceAndUpdateWriteBarrier(dst, src, size); 1940 heap->CopyBlockToOldSpaceAndUpdateWriteBarrier(dst, src, size);
1931 } else { 1941 } else {
1932 heap->CopyBlock(dst, src, size); 1942 heap->CopyBlock(dst, src, size);
1933 } 1943 }
1934 Memory::Address_at(src) = dst; 1944 Memory::Address_at(src) = dst;
1935 } 1945 }
1936 1946
1937 1947
1938 class StaticPointersToNewGenUpdatingVisitor : public 1948 class StaticPointersToNewGenUpdatingVisitor : public
1939 StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> { 1949 StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> {
1940 public: 1950 public:
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2057 } 2067 }
2058 } 2068 }
2059 2069
2060 return false; 2070 return false;
2061 } 2071 }
2062 2072
2063 2073
2064 void MarkCompactCollector::SweepNewSpace(NewSpace* space) { 2074 void MarkCompactCollector::SweepNewSpace(NewSpace* space) {
2065 heap_->CheckNewSpaceExpansionCriteria(); 2075 heap_->CheckNewSpaceExpansionCriteria();
2066 2076
2077 // Store allocation range before flipping semispaces.
2067 Address from_bottom = space->bottom(); 2078 Address from_bottom = space->bottom();
2068 Address from_top = space->top(); 2079 Address from_top = space->top();
2069 2080
2070 // Flip the semispaces. After flipping, to space is empty, from space has 2081 // Flip the semispaces. After flipping, to space is empty, from space has
2071 // live objects. 2082 // live objects.
2072 space->Flip(); 2083 space->Flip();
2073 space->ResetAllocationInfo(); 2084 space->ResetAllocationInfo();
2074 2085
2075 int size = 0;
2076 int survivors_size = 0; 2086 int survivors_size = 0;
2077 2087
2078 // First pass: traverse all objects in inactive semispace, remove marks, 2088 // First pass: traverse all objects in inactive semispace, remove marks,
2079 // migrate live objects and write forwarding addresses. This stage puts 2089 // migrate live objects and write forwarding addresses. This stage puts
2080 // new entries in the store buffer and may cause some pages to be marked 2090 // new entries in the store buffer and may cause some pages to be marked
2081 // scan-on-scavenge. 2091 // scan-on-scavenge.
2082 for (Address current = from_bottom; current < from_top; current += size) { 2092 SemiSpaceIterator from_it(from_bottom, from_top);
2083 HeapObject* object = HeapObject::FromAddress(current); 2093 for (HeapObject* object = from_it.Next();
2084 2094 object != NULL;
2095 object = from_it.Next()) {
2085 MarkBit mark_bit = Marking::MarkBitFrom(object); 2096 MarkBit mark_bit = Marking::MarkBitFrom(object);
2086 if (mark_bit.Get()) { 2097 if (mark_bit.Get()) {
2087 mark_bit.Clear(); 2098 mark_bit.Clear();
2088 heap_->mark_compact_collector()->tracer()->decrement_marked_count(); 2099 heap_->mark_compact_collector()->tracer()->decrement_marked_count();
2089 2100
2090 size = object->Size(); 2101 int size = object->Size();
2091 survivors_size += size; 2102 survivors_size += size;
2092 2103
2093 // Aggressively promote young survivors to the old space. 2104 // Aggressively promote young survivors to the old space.
2094 if (TryPromoteObject(heap_, object, size)) { 2105 if (TryPromoteObject(heap_, object, size)) {
2095 continue; 2106 continue;
2096 } 2107 }
2097 2108
2098 // Promotion failed. Just migrate object to another semispace. 2109 // Promotion failed. Just migrate object to another semispace.
2099 // Allocation cannot fail at this point: semispaces are of equal size. 2110 MaybeObject* allocation = space->AllocateRaw(size);
2100 Object* target = space->AllocateRaw(size)->ToObjectUnchecked(); 2111 if (allocation->IsFailure()) {
2101 2112 if (!space->AddFreshPage()) {
2113 // Shouldn't happen. We are sweeping linearly, and to-space
2114 // has the same number of pages as from-space, so there is
2115 // always room.
2116 UNREACHABLE();
2117 }
2118 allocation = space->AllocateRaw(size);
2119 ASSERT(!allocation->IsFailure());
2120 }
2121 Object* target = allocation->ToObjectUnchecked();
2102 MigrateObject(heap_, 2122 MigrateObject(heap_,
2103 HeapObject::cast(target)->address(), 2123 HeapObject::cast(target)->address(),
2104 current, 2124 object->address(),
2105 size, 2125 size,
2106 false); 2126 false);
2107 } else { 2127 } else {
2108 // Process the dead object before we write a NULL into its header. 2128 // Process the dead object before we write a NULL into its header.
2109 LiveObjectList::ProcessNonLive(object); 2129 LiveObjectList::ProcessNonLive(object);
2110 2130
2111 size = object->Size();
2112 // Mark dead objects in the new space with null in their map field. 2131 // Mark dead objects in the new space with null in their map field.
2113 Memory::Address_at(current) = NULL; 2132 Memory::Address_at(object->address()) = NULL;
2114 } 2133 }
2115 } 2134 }
2116 2135
2117 // Second pass: find pointers to new space and update them. 2136 // Second pass: find pointers to new space and update them.
2118 PointersToNewGenUpdatingVisitor updating_visitor(heap_); 2137 PointersToNewGenUpdatingVisitor updating_visitor(heap_);
2119 2138
2120 // Update pointers in to space. 2139 // Update pointers in to space.
2121 Address current = space->bottom(); 2140 SemiSpaceIterator to_it(space->bottom(), space->top());
2122 while (current < space->top()) { 2141 for (HeapObject* object = to_it.Next();
2123 HeapObject* object = HeapObject::FromAddress(current); 2142 object != NULL;
2124 current += 2143 object = to_it.Next()) {
2125 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), 2144 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(),
2126 object); 2145 object);
2127 } 2146 }
2128 2147
2129 // Update roots. 2148 // Update roots.
2130 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); 2149 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
2131 LiveObjectList::IterateElements(&updating_visitor); 2150 LiveObjectList::IterateElements(&updating_visitor);
2132 2151
2133 { 2152 {
2134 StoreBufferRebuildScope scope(heap_, 2153 StoreBufferRebuildScope scope(heap_,
2135 heap_->store_buffer(), 2154 heap_->store_buffer(),
2136 &Heap::ScavengeStoreBufferCallback); 2155 &Heap::ScavengeStoreBufferCallback);
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 live_objects_size += size; 2732 live_objects_size += size;
2714 } 2733 }
2715 } 2734 }
2716 return live_objects_size; 2735 return live_objects_size;
2717 } 2736 }
2718 2737
2719 2738
2720 int MarkCompactCollector::IterateLiveObjects( 2739 int MarkCompactCollector::IterateLiveObjects(
2721 NewSpace* space, LiveObjectCallback size_f) { 2740 NewSpace* space, LiveObjectCallback size_f) {
2722 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); 2741 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
2723 return IterateLiveObjectsInRange(space->bottom(), space->top(), size_f); 2742 int accumulator = 0;
2743 Address end = space->top();
2744 NewSpacePageIterator it(space->bottom(), end);
2745 // The bottom is at the start of its page.
2746 ASSERT_EQ(space->bottom(),
2747 NewSpacePage::FromAddress(space->bottom())->body());
2748 while (it.has_next()) {
2749 NewSpacePage* page = it.next();
2750 Address start = page->body();
2751 Address limit = it.has_next() ? page->body_limit() : end;
2752 accumulator += IterateLiveObjectsInRange(start, limit, size_f);
2753 }
2754 return accumulator;
2724 } 2755 }
2725 2756
2726 2757
2727 int MarkCompactCollector::IterateLiveObjects( 2758 int MarkCompactCollector::IterateLiveObjects(
2728 PagedSpace* space, LiveObjectCallback size_f) { 2759 PagedSpace* space, LiveObjectCallback size_f) {
2729 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS); 2760 ASSERT(MARK_LIVE_OBJECTS < state_ && state_ <= RELOCATE_OBJECTS);
2730 // TODO(gc): Do a mark-sweep first with precise sweeping. 2761 // TODO(gc): Do a mark-sweep first with precise sweeping.
2731 int total = 0; 2762 int total = 0;
2732 PageIterator it(space); 2763 PageIterator it(space);
2733 while (it.has_next()) { 2764 while (it.has_next()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2770 } 2801 }
2771 2802
2772 2803
2773 void MarkCompactCollector::Initialize() { 2804 void MarkCompactCollector::Initialize() {
2774 StaticPointersToNewGenUpdatingVisitor::Initialize(); 2805 StaticPointersToNewGenUpdatingVisitor::Initialize();
2775 StaticMarkingVisitor::Initialize(); 2806 StaticMarkingVisitor::Initialize();
2776 } 2807 }
2777 2808
2778 2809
2779 } } // namespace v8::internal 2810 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-inl.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698