Chromium Code Reviews| 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()); |
| } |