Chromium Code Reviews

Unified Diff: src/mark-compact.cc

Issue 6250076: Start using store buffers. Handle store buffer overflow situation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 6554)
+++ src/mark-compact.cc (working copy)
@@ -101,9 +101,9 @@
if (FLAG_collect_maps) ClearNonLiveTransitions();
+ SweepSpaces();
SweepLargeObjectSpace();
Vyacheslav Egorov (Chromium) 2011/02/02 13:15:47 You can now move SweepLargeObjectSpace into SweepS
Erik Corry 2011/02/03 13:21:17 Done.
- SweepSpaces();
PcToCodeCache::FlushPcToCodeCache();
Finish();
@@ -416,7 +416,8 @@
// Since we don't have the object's start, it is impossible to update the
// page dirty marks. Therefore, we only replace the string with its left
- // substring when page dirty marks do not change.
+ // substring when page dirty marks do not change. TODO(gc): Seems like we
Vyacheslav Egorov (Chromium) 2011/02/02 13:15:47 move todo to the new line
Erik Corry 2011/02/03 13:21:17 Done.
+ // could relax this restriction with store buffers.
Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first();
if (!Heap::InNewSpace(object) && Heap::InNewSpace(first)) return object;
@@ -1430,9 +1431,7 @@
void MarkCompactCollector::SweepLargeObjectSpace() {
#ifdef DEBUG
- ASSERT(state_ == MARK_LIVE_OBJECTS);
- state_ =
- compacting_collection_ ? ENCODE_FORWARDING_ADDRESSES : SWEEP_SPACES;
+ ASSERT(state_ == SWEEP_SPACES);
#endif
// Deallocate unmarked objects and clear marked bits for marked objects.
Heap::lo_space()->FreeUnmarkedObjects();
@@ -1509,14 +1508,18 @@
// We scavange new space simultaneously with sweeping. This is done in two
// passes.
+//
// The first pass migrates all alive objects from one semispace to another or
-// promotes them to old space. Forwading address is written directly into
-// first word of object without any encoding. If object is dead we are writing
+// promotes them to old space. Forwarding address is written directly into
+// first word of object without any encoding. If object is dead we write
// NULL as a forwarding address.
-// The second pass updates pointers to new space in all spaces. It is possible
-// to encounter pointers to dead objects during traversal of dirty regions we
-// should clear them to avoid encountering them during next dirty regions
-// iteration.
+//
+// The second pass updates pointers to new space in all spaces. It is possible
+// to encounter pointers to dead new space objects during traversal of pointers
+// to new space. We should clear them to avoid encountering them during next
+// pointer iteration. This is an issue if the store buffer overflows and we
+// have to scan the entire old space, including dead objects, looking for
+// pointers to new space.
static void MigrateObject(Address dst,
Address src,
int size,
@@ -1526,7 +1529,6 @@
} else {
Heap::CopyBlock(dst, src, size);
}
-
Memory::Address_at(src) = dst;
}
@@ -1581,23 +1583,27 @@
};
-// Visitor for updating pointers from live objects in old spaces to new space.
-// It can encounter pointers to dead objects in new space when traversing map
-// space (see comment for MigrateObject).
-static void UpdatePointerToNewGen(HeapObject** p) {
- if (!(*p)->IsHeapObject()) return;
+static void UpdatePointerToNewGen(HeapObject** p, HeapObject* object) {
+ ASSERT(Heap::InFromSpace(object));
+ ASSERT(*p == object);
- Address old_addr = (*p)->address();
- ASSERT(Heap::InFromSpace(*p));
+ Address old_addr = object->address();
Address new_addr = Memory::Address_at(old_addr);
- if (new_addr == NULL) {
- // We encountered pointer to a dead object. Clear it so we will
- // not visit it again during next iteration of dirty regions.
- *p = NULL;
+ // The new space sweep will overwrite the map word of dead objects
+ // with NULL. In this case we do not need to transfer this entry to
+ // the store buffer which we are rebuilding.
+ if (new_addr != NULL) {
+ *p = HeapObject::FromAddress(new_addr);
+ if (Heap::InNewSpace(new_addr)) {
+ StoreBuffer::EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(p));
+ }
} else {
- *p = HeapObject::FromAddress(new_addr);
+ // We have to zap this pointer, because the store buffer may overflow later,
+ // and then we have to scan the entire heap and we don't want to find
+ // spurious newspace pointers in the old space.
+ *p = HeapObject::FromAddress(NULL); // Fake heap object not in new space.
}
}
@@ -1685,6 +1691,7 @@
false);
} else {
size = object->Size();
+ // Mark dead objects in the new space with null in their map field.
Memory::Address_at(current) = NULL;
}
}
@@ -1704,14 +1711,11 @@
// Update roots.
Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
- // Update pointers in old spaces.
- Heap::IterateDirtyRegions(Heap::old_pointer_space(),
- &Heap::IteratePointersInDirtyRegion,
- &UpdatePointerToNewGen,
- Heap::WATERMARK_SHOULD_BE_VALID);
+ {
+ StoreBufferRebuildScope scope;
+ StoreBuffer::IteratePointersToNewSpace(&UpdatePointerToNewGen);
+ }
- Heap::lo_space()->IterateDirtyRegions(&UpdatePointerToNewGen);
-
// Update pointers from cells.
HeapObjectIterator cell_iterator(Heap::cell_space());
for (HeapObject* cell = cell_iterator.next();
@@ -2029,8 +2033,9 @@
void MarkCompactCollector::SweepSpaces() {
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
-
- ASSERT(state_ == SWEEP_SPACES);
+#ifdef DEBUG
+ state_ = SWEEP_SPACES;
+#endif
ASSERT(!IsCompacting());
// Noncompacting collections simply sweep the spaces to clear the mark
// bits and free the nonlive blocks (for old and map spaces). We sweep
@@ -2051,11 +2056,6 @@
// TODO(gc): Implement specialized sweeper for map space.
SweepSpace(Heap::map_space(), PRECISE);
- Heap::IterateDirtyRegions(Heap::map_space(),
- &Heap::IteratePointersInDirtyMapsRegion,
- &UpdatePointerToNewGen,
- Heap::WATERMARK_SHOULD_BE_VALID);
-
ASSERT(live_map_objects_size_ <= Heap::map_space()->Size());
}

Powered by Google App Engine