Clean up the mark-sweep/compact collector by removing outdated
verification code and updating outdated comments. Review URL: http://codereview.chromium.org/18502 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1131 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
031e72ce99
commit
6b2a2c1fff
@ -35,16 +35,7 @@
|
||||
|
||||
namespace v8 { namespace internal {
|
||||
|
||||
#ifdef DEBUG
|
||||
// The verification code used between phases of the m-c collector does not
|
||||
// currently work.
|
||||
//
|
||||
// TODO(1240833): Fix the heap verification code and turn this into a real
|
||||
// flag.
|
||||
static const bool FLAG_verify_global_gc = false;
|
||||
#endif // DEBUG
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// MarkCompactCollector
|
||||
|
||||
bool MarkCompactCollector::compacting_collection_ = false;
|
||||
@ -177,7 +168,7 @@ void MarkCompactCollector::Finish() {
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 1: tracing and marking live objects.
|
||||
// before: all objects are in normal state.
|
||||
// after: a live object's map pointer is marked as '00'.
|
||||
@ -729,10 +720,6 @@ void MarkCompactCollector::MarkLiveObjects() {
|
||||
symbol_table->IterateElements(&v);
|
||||
symbol_table->ElementsRemoved(v.PointersRemoved());
|
||||
|
||||
#ifdef DEBUG
|
||||
if (FLAG_verify_global_gc) VerifyHeapAfterMarkingPhase();
|
||||
#endif
|
||||
|
||||
// Remove object groups after marking phase.
|
||||
GlobalHandles::RemoveObjectGroups();
|
||||
}
|
||||
@ -765,46 +752,6 @@ void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MarkCompactCollector::VerifyHeapAfterMarkingPhase() {
|
||||
Heap::new_space()->Verify();
|
||||
Heap::old_pointer_space()->Verify();
|
||||
Heap::old_data_space()->Verify();
|
||||
Heap::code_space()->Verify();
|
||||
Heap::map_space()->Verify();
|
||||
|
||||
int live_objects;
|
||||
|
||||
#define CHECK_LIVE_OBJECTS(it, expected) \
|
||||
live_objects = 0; \
|
||||
while (it.has_next()) { \
|
||||
HeapObject* obj = HeapObject::cast(it.next()); \
|
||||
if (obj->IsMarked()) live_objects++; \
|
||||
} \
|
||||
ASSERT(live_objects == expected);
|
||||
|
||||
SemiSpaceIterator new_it(Heap::new_space(), &CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(new_it, live_young_objects_);
|
||||
|
||||
HeapObjectIterator old_pointer_it(Heap::old_pointer_space(),
|
||||
&CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(old_pointer_it, live_old_pointer_objects_);
|
||||
|
||||
HeapObjectIterator old_data_it(Heap::old_data_space(), &CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(old_data_it, live_old_data_objects_);
|
||||
|
||||
HeapObjectIterator code_it(Heap::code_space(), &CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(code_it, live_code_objects_);
|
||||
|
||||
HeapObjectIterator map_it(Heap::map_space(), &CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(map_it, live_map_objects_);
|
||||
|
||||
LargeObjectIterator lo_it(Heap::lo_space(), &CountMarkedCallback);
|
||||
CHECK_LIVE_OBJECTS(lo_it, live_lo_objects_);
|
||||
|
||||
#undef CHECK_LIVE_OBJECTS
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
@ -1325,54 +1272,7 @@ int MarkCompactCollector::IterateLiveObjects(PagedSpace* space,
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static int VerifyMapObject(HeapObject* obj) {
|
||||
InstanceType type = reinterpret_cast<Map*>(obj)->instance_type();
|
||||
ASSERT(FIRST_TYPE <= type && type <= LAST_TYPE);
|
||||
return Map::kSize;
|
||||
}
|
||||
|
||||
|
||||
void MarkCompactCollector::VerifyHeapAfterEncodingForwardingAddresses() {
|
||||
AllSpaces spaces;
|
||||
while (Space* space = spaces.next()) space->Verify();
|
||||
|
||||
ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
|
||||
int live_maps = IterateLiveObjects(Heap::map_space(), &VerifyMapObject);
|
||||
ASSERT(live_maps == live_map_objects_);
|
||||
|
||||
// Verify page headers in paged spaces.
|
||||
PagedSpaces paged_spaces;
|
||||
while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
|
||||
}
|
||||
|
||||
|
||||
void MarkCompactCollector::VerifyPageHeaders(PagedSpace* space) {
|
||||
PageIterator mc_it(space, PageIterator::PAGES_USED_BY_MC);
|
||||
while (mc_it.has_next()) {
|
||||
Page* p = mc_it.next();
|
||||
Address mc_alloc_top = p->mc_relocation_top;
|
||||
ASSERT(p->ObjectAreaStart() <= mc_alloc_top &&
|
||||
mc_alloc_top <= p->ObjectAreaEnd());
|
||||
}
|
||||
|
||||
int page_count = 0;
|
||||
PageIterator it(space, PageIterator::PAGES_IN_USE);
|
||||
while (it.has_next()) {
|
||||
Page* p = it.next();
|
||||
ASSERT(p->mc_page_index == page_count);
|
||||
page_count++;
|
||||
|
||||
// first_forwarded could be 'deadbeed' if no live objects in this page
|
||||
Address first_forwarded = p->mc_first_forwarded;
|
||||
ASSERT(first_forwarded == kZapValue ||
|
||||
space->Contains(first_forwarded));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 3: Update pointers
|
||||
|
||||
// Helper class for updating pointers in HeapObjects.
|
||||
@ -1494,8 +1394,6 @@ void MarkCompactCollector::UpdatePointers() {
|
||||
ASSERT(live_pointer_olds == live_old_pointer_objects_);
|
||||
ASSERT(live_codes == live_code_objects_);
|
||||
ASSERT(live_news == live_young_objects_);
|
||||
|
||||
if (FLAG_verify_global_gc) VerifyHeapAfterUpdatingPointers();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1601,19 +1499,7 @@ Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void MarkCompactCollector::VerifyHeapAfterUpdatingPointers() {
|
||||
ASSERT(state_ == UPDATE_POINTERS);
|
||||
|
||||
AllSpaces spaces;
|
||||
while (Space* space = spaces.next()) space->Verify();
|
||||
PagedSpaces paged_spaces;
|
||||
while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 4: Relocate objects
|
||||
|
||||
void MarkCompactCollector::RelocateObjects() {
|
||||
@ -1664,10 +1550,6 @@ void MarkCompactCollector::RelocateObjects() {
|
||||
#endif
|
||||
PagedSpaces spaces;
|
||||
while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo();
|
||||
|
||||
#ifdef DEBUG
|
||||
if (FLAG_verify_global_gc) VerifyHeapAfterRelocatingObjects();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1804,18 +1686,6 @@ int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
class VerifyCopyingVisitor: public ObjectVisitor {
|
||||
public:
|
||||
void VisitPointers(Object** start, Object** end) {
|
||||
for (Object** p = start; p < end; p++) {
|
||||
MarkCompactCollector::VerifyCopyingObjects(p);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
|
||||
int obj_size = obj->Size();
|
||||
|
||||
@ -1845,44 +1715,13 @@ int MarkCompactCollector::RelocateNewObject(HeapObject* obj) {
|
||||
if (FLAG_gc_verbose) {
|
||||
PrintF("relocate %p -> %p\n", old_addr, new_addr);
|
||||
}
|
||||
if (FLAG_verify_global_gc) {
|
||||
VerifyCopyingVisitor v;
|
||||
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
|
||||
copied_to->Iterate(&v);
|
||||
}
|
||||
#endif
|
||||
|
||||
return obj_size;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void MarkCompactCollector::VerifyHeapAfterRelocatingObjects() {
|
||||
ASSERT(state_ == RELOCATE_OBJECTS);
|
||||
|
||||
Heap::new_space()->Verify();
|
||||
PagedSpaces spaces;
|
||||
while (PagedSpace* space = spaces.next()) {
|
||||
space->Verify();
|
||||
PageIterator it(space, PageIterator::PAGES_IN_USE);
|
||||
while (it.has_next()) {
|
||||
Page* p = it.next();
|
||||
ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void MarkCompactCollector::VerifyCopyingObjects(Object** p) {
|
||||
if (!(*p)->IsHeapObject()) return;
|
||||
ASSERT(!Heap::InToSpace(*p));
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Phase 5: rebuild remembered sets
|
||||
|
||||
void MarkCompactCollector::RebuildRSets() {
|
||||
|
@ -44,12 +44,12 @@ class RootMarkingVisitor;
|
||||
class MarkingVisitor;
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -------------------------------------------------------------------------
|
||||
// Mark-Compact collector
|
||||
//
|
||||
// All methods are static.
|
||||
|
||||
class MarkCompactCollector : public AllStatic {
|
||||
class MarkCompactCollector: public AllStatic {
|
||||
public:
|
||||
// Type of functions to compute forwarding addresses of objects in
|
||||
// compacted spaces. Given an object and its size, return a (non-failure)
|
||||
@ -127,21 +127,18 @@ class MarkCompactCollector : public AllStatic {
|
||||
// choosing spaces to compact.
|
||||
static void Prepare();
|
||||
|
||||
// Finishes GC, performs heap verification.
|
||||
// Finishes GC, performs heap verification if enabled.
|
||||
static void Finish();
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Phase 1: functions related to marking phase.
|
||||
// before: Heap is in normal state, collector is 'IDLE'.
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 1: Marking live objects.
|
||||
//
|
||||
// The first word of a page in old spaces has the end of
|
||||
// allocation address of the page.
|
||||
// Before: The heap has been prepared for garbage collection by
|
||||
// MarkCompactCollector::Prepare() and is otherwise in its
|
||||
// normal state.
|
||||
//
|
||||
// The word at Chunk::high_ address has the address of the
|
||||
// first page in the next chunk. (The address is tagged to
|
||||
// distinguish it from end-of-allocation address).
|
||||
//
|
||||
// after: live objects are marked.
|
||||
// After: Live objects are marked and non-live objects are unmarked.
|
||||
|
||||
|
||||
friend class RootMarkingVisitor;
|
||||
friend class MarkingVisitor;
|
||||
@ -206,7 +203,6 @@ class MarkCompactCollector : public AllStatic {
|
||||
|
||||
#ifdef DEBUG
|
||||
static void UpdateLiveObjectCount(HeapObject* obj);
|
||||
static void VerifyHeapAfterMarkingPhase();
|
||||
#endif
|
||||
|
||||
// We sweep the large object space in the same way whether we are
|
||||
@ -216,30 +212,50 @@ class MarkCompactCollector : public AllStatic {
|
||||
// Test whether a (possibly marked) object is a Map.
|
||||
static inline bool SafeIsMap(HeapObject* object);
|
||||
|
||||
// Map transitions from a live map to a dead map must be killed.
|
||||
// Map transitions from a live map to a dead map must be killed.
|
||||
// We replace them with a null descriptor, with the same key.
|
||||
static void ClearNonLiveTransitions();
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Phase 2: functions related to computing and encoding forwarding pointers
|
||||
// before: live objects' map pointers are marked as '00'
|
||||
// after: Map pointers of live old and map objects have encoded
|
||||
// forwarding pointers and map pointers
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 2: Sweeping to clear mark bits and free non-live objects for
|
||||
// a non-compacting collection, or else computing and encoding
|
||||
// forwarding addresses for a compacting collection.
|
||||
//
|
||||
// The 3rd word of a page has the page top offset after compaction.
|
||||
// Before: Live objects are marked and non-live objects are unmarked.
|
||||
//
|
||||
// The 4th word of a page in the map space has the map index
|
||||
// of this page in the map table. This word is not used in
|
||||
// the old space.
|
||||
// After: (Non-compacting collection.) Live objects are unmarked,
|
||||
// non-live regions have been added to their space's free
|
||||
// list.
|
||||
//
|
||||
// The 5th and 6th words of a page have the start and end
|
||||
// addresses of the first free region in the page.
|
||||
// After: (Compacting collection.) The forwarding address of live
|
||||
// objects in the paged spaces is encoded in their map word
|
||||
// along with their (non-forwarded) map pointer.
|
||||
//
|
||||
// The 7th word of a page in old spaces has the forwarding address
|
||||
// of the first live object in the page.
|
||||
// The forwarding address of live objects in the new space is
|
||||
// written to their map word's offset in the inactive
|
||||
// semispace.
|
||||
//
|
||||
// Live young objects have their forwarding pointers in
|
||||
// the from space at the same offset to the beginning of the space.
|
||||
// Bookkeeping data is written to the remembered-set are of
|
||||
// eached paged-space page that contains live objects after
|
||||
// compaction:
|
||||
//
|
||||
// The 3rd word of the page (first word of the remembered
|
||||
// set) contains the relocation top address, the address of
|
||||
// the first word after the end of the last live object in
|
||||
// the page after compaction.
|
||||
//
|
||||
// The 4th word contains the zero-based index of the page in
|
||||
// its space. This word is only used for map space pages, in
|
||||
// order to encode the map addresses in 21 bits to free 11
|
||||
// bits per map word for the forwarding address.
|
||||
//
|
||||
// The 5th word contains the (nonencoded) forwarding address
|
||||
// of the first live object in the page.
|
||||
//
|
||||
// In both the new space and the paged spaces, a linked list
|
||||
// of live regions is constructructed (linked through
|
||||
// pointers in the non-live region immediately following each
|
||||
// live region) to speed further passes of the collector.
|
||||
|
||||
// Encodes forwarding addresses of objects in compactable parts of the
|
||||
// heap.
|
||||
@ -272,19 +288,21 @@ class MarkCompactCollector : public AllStatic {
|
||||
static void DeallocateCodeBlock(Address start, int size_in_bytes);
|
||||
static void DeallocateMapBlock(Address start, int size_in_bytes);
|
||||
|
||||
// Phase 2: If we are not compacting the heap, we simply sweep the spaces
|
||||
// except for the large object space, clearing mark bits and adding
|
||||
// unmarked regions to each space's free list.
|
||||
// If we are not compacting the heap, we simply sweep the spaces except
|
||||
// for the large object space, clearing mark bits and adding unmarked
|
||||
// regions to each space's free list.
|
||||
static void SweepSpaces();
|
||||
|
||||
#ifdef DEBUG
|
||||
static void VerifyHeapAfterEncodingForwardingAddresses();
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Phase 3: function related to updating pointers and decode map pointers
|
||||
// before: see after phase 2
|
||||
// after: all pointers are updated to forwarding addresses.
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 3: Updating pointers in live objects.
|
||||
//
|
||||
// Before: Same as after phase 2 (compacting collection).
|
||||
//
|
||||
// After: All pointers in live objects, including encoded map
|
||||
// pointers, are updated to point to their target's new
|
||||
// location. The remembered set area of each paged-space
|
||||
// page containing live objects still contains bookkeeping
|
||||
// information.
|
||||
|
||||
friend class UpdatingVisitor; // helper for updating visited objects
|
||||
|
||||
@ -302,14 +320,17 @@ class MarkCompactCollector : public AllStatic {
|
||||
// Calculates the forwarding address of an object in an old space.
|
||||
static Address GetForwardingAddressInOldSpace(HeapObject* obj);
|
||||
|
||||
#ifdef DEBUG
|
||||
static void VerifyHeapAfterUpdatingPointers();
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Phase 4: functions related to relocating objects
|
||||
// before: see after phase 3
|
||||
// after: heap is in a normal state, except remembered set is not built
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 4: Relocating objects.
|
||||
//
|
||||
// Before: Pointers to live objects are updated to point to their
|
||||
// target's new location. The remembered set area of each
|
||||
// paged-space page containing live objects still contains
|
||||
// bookkeeping information.
|
||||
//
|
||||
// After: Objects have been moved to their new addresses. The
|
||||
// remembered set area of each paged-space page containing
|
||||
// live objects still contains bookkeeping information.
|
||||
|
||||
// Relocates objects in all spaces.
|
||||
static void RelocateObjects();
|
||||
@ -334,18 +355,19 @@ class MarkCompactCollector : public AllStatic {
|
||||
// Copy a new object.
|
||||
static int RelocateNewObject(HeapObject* obj);
|
||||
|
||||
#ifdef DEBUG
|
||||
static void VerifyHeapAfterRelocatingObjects();
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Phase 5: functions related to rebuilding remembered sets
|
||||
// -----------------------------------------------------------------------
|
||||
// Phase 5: Rebuilding remembered sets.
|
||||
//
|
||||
// Before: The heap is in a normal state except that remembered sets
|
||||
// in the paged spaces are not correct.
|
||||
//
|
||||
// After: The heap is in a normal state.
|
||||
|
||||
// Rebuild remembered set in old and map spaces.
|
||||
static void RebuildRSets();
|
||||
|
||||
#ifdef DEBUG
|
||||
// ---------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
// Debugging variables, functions and classes
|
||||
// Counters used for debugging the marking phase of mark-compact or
|
||||
// mark-sweep collection.
|
||||
@ -371,12 +393,6 @@ class MarkCompactCollector : public AllStatic {
|
||||
// Number of live bytes in this collection.
|
||||
static int live_bytes_;
|
||||
|
||||
static void VerifyPageHeaders(PagedSpace* space);
|
||||
|
||||
// Verification functions when relocating objects.
|
||||
friend class VerifyCopyingVisitor;
|
||||
static void VerifyCopyingObjects(Object** p);
|
||||
|
||||
friend class MarkObjectVisitor;
|
||||
static void VisitObject(HeapObject* obj);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user