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

Unified Diff: src/mark-compact.cc

Issue 1622016: Reverting r4318 (merge of scavenge into sweeping pass of MSC garbage collecto... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mark-compact.h ('k') | src/utils.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 4369)
+++ src/mark-compact.cc (working copy)
@@ -53,13 +53,13 @@
// Counters used for debugging the marking phase of mark-compact or mark-sweep
// collection.
int MarkCompactCollector::live_bytes_ = 0;
-int MarkCompactCollector::live_young_objects_size_ = 0;
-int MarkCompactCollector::live_old_data_objects_size_ = 0;
-int MarkCompactCollector::live_old_pointer_objects_size_ = 0;
-int MarkCompactCollector::live_code_objects_size_ = 0;
-int MarkCompactCollector::live_map_objects_size_ = 0;
-int MarkCompactCollector::live_cell_objects_size_ = 0;
-int MarkCompactCollector::live_lo_objects_size_ = 0;
+int MarkCompactCollector::live_young_objects_ = 0;
+int MarkCompactCollector::live_old_data_objects_ = 0;
+int MarkCompactCollector::live_old_pointer_objects_ = 0;
+int MarkCompactCollector::live_code_objects_ = 0;
+int MarkCompactCollector::live_map_objects_ = 0;
+int MarkCompactCollector::live_cell_objects_ = 0;
+int MarkCompactCollector::live_lo_objects_ = 0;
#endif
void MarkCompactCollector::CollectGarbage() {
@@ -136,13 +136,13 @@
#ifdef DEBUG
live_bytes_ = 0;
- live_young_objects_size_ = 0;
- live_old_pointer_objects_size_ = 0;
- live_old_data_objects_size_ = 0;
- live_code_objects_size_ = 0;
- live_map_objects_size_ = 0;
- live_cell_objects_size_ = 0;
- live_lo_objects_size_ = 0;
+ live_young_objects_ = 0;
+ live_old_pointer_objects_ = 0;
+ live_old_data_objects_ = 0;
+ live_code_objects_ = 0;
+ live_map_objects_ = 0;
+ live_cell_objects_ = 0;
+ live_lo_objects_ = 0;
#endif
}
@@ -742,21 +742,21 @@
void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
live_bytes_ += obj->Size();
if (Heap::new_space()->Contains(obj)) {
- live_young_objects_size_ += obj->Size();
+ live_young_objects_++;
} else if (Heap::map_space()->Contains(obj)) {
ASSERT(obj->IsMap());
- live_map_objects_size_ += obj->Size();
+ live_map_objects_++;
} else if (Heap::cell_space()->Contains(obj)) {
ASSERT(obj->IsJSGlobalPropertyCell());
- live_cell_objects_size_ += obj->Size();
+ live_cell_objects_++;
} else if (Heap::old_pointer_space()->Contains(obj)) {
- live_old_pointer_objects_size_ += obj->Size();
+ live_old_pointer_objects_++;
} else if (Heap::old_data_space()->Contains(obj)) {
- live_old_data_objects_size_ += obj->Size();
+ live_old_data_objects_++;
} else if (Heap::code_space()->Contains(obj)) {
- live_code_objects_size_ += obj->Size();
+ live_code_objects_++;
} else if (Heap::lo_space()->Contains(obj)) {
- live_lo_objects_size_ += obj->Size();
+ live_lo_objects_++;
} else {
UNREACHABLE();
}
@@ -1068,210 +1068,31 @@
}
-// 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
-// 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 remembered set for
-// map space because remembered set bits corresponding to dead maps are cleared
-// later during map space sweeping.
-static void MigrateObject(Address dst, Address src, int size) {
- Heap::CopyBlock(reinterpret_cast<Object**>(dst),
- reinterpret_cast<Object**>(src),
- size);
-
- Memory::Address_at(src) = dst;
-}
-
-
-// Visitor for updating pointers from live objects in old spaces to new space.
-// It does not expect to encounter pointers to dead objects.
-class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
- public:
- void VisitPointer(Object** p) {
- UpdatePointer(p);
- }
-
- void VisitPointers(Object** start, Object** end) {
- for (Object** p = start; p < end; p++) UpdatePointer(p);
- }
-
- void VisitCodeTarget(RelocInfo* rinfo) {
- ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
- Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
- VisitPointer(&target);
- rinfo->set_target_address(Code::cast(target)->instruction_start());
- }
-
- void VisitDebugTarget(RelocInfo* rinfo) {
- ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) &&
- rinfo->IsPatchedReturnSequence());
- Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
- VisitPointer(&target);
- rinfo->set_call_address(Code::cast(target)->instruction_start());
- }
-
- private:
- void UpdatePointer(Object** p) {
- if (!(*p)->IsHeapObject()) return;
-
- HeapObject* obj = HeapObject::cast(*p);
- Address old_addr = obj->address();
-
- if (Heap::new_space()->Contains(obj)) {
- ASSERT(Heap::InFromSpace(*p));
- *p = HeapObject::FromAddress(Memory::Address_at(old_addr));
- }
- }
-};
-
-// 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;
-
- Address old_addr = (*p)->address();
- ASSERT(Heap::InFromSpace(*p));
-
- Address new_addr = Memory::Address_at(old_addr);
-
- // Object pointed by *p is dead. Update is not required.
- if (new_addr == NULL) return;
-
- *p = HeapObject::FromAddress(new_addr);
-}
-
-
-static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Object **p) {
- Address old_addr = HeapObject::cast(*p)->address();
- Address new_addr = Memory::Address_at(old_addr);
- return String::cast(HeapObject::FromAddress(new_addr));
-}
-
-
-static bool TryPromoteObject(HeapObject* object, int object_size) {
- Object* result;
-
- if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
- result = Heap::lo_space()->AllocateRawFixedArray(object_size);
- if (!result->IsFailure()) {
- HeapObject* target = HeapObject::cast(result);
- MigrateObject(target->address(), object->address(), object_size);
- Heap::UpdateRSet(target);
- return true;
- }
- } else {
- OldSpace* target_space = Heap::TargetSpace(object);
-
- ASSERT(target_space == Heap::old_pointer_space() ||
- target_space == Heap::old_data_space());
- result = target_space->AllocateRaw(object_size);
- if (!result->IsFailure()) {
- HeapObject* target = HeapObject::cast(result);
- MigrateObject(target->address(), object->address(), object_size);
- if (target_space == Heap::old_pointer_space()) {
- Heap::UpdateRSet(target);
- }
- return true;
- }
- }
-
- return false;
-}
-
-
-static void SweepNewSpace(NewSpace* space) {
- Heap::CheckNewSpaceExpansionCriteria();
-
- Address from_bottom = space->bottom();
- Address from_top = space->top();
-
- // Flip the semispaces. After flipping, to space is empty, from space has
- // live objects.
- space->Flip();
- space->ResetAllocationInfo();
-
- int size = 0;
- int survivors_size = 0;
-
- // First pass: traverse all objects in inactive semispace, remove marks,
- // migrate live objects and write forwarding addresses.
- for (Address current = from_bottom; current < from_top; current += size) {
- HeapObject* object = HeapObject::FromAddress(current);
-
- if (object->IsMarked()) {
- object->ClearMark();
- MarkCompactCollector::tracer()->decrement_marked_count();
-
- size = object->Size();
- survivors_size += size;
-
- if (Heap::ShouldBePromoted(current, size) &&
- TryPromoteObject(object, size)) {
- continue;
- }
-
- // Promotion either failed or not required.
- // Copy the content of the object.
- Object* target = space->AllocateRaw(size);
-
- // Allocation cannot fail at this point: semispaces are of equal size.
- ASSERT(!target->IsFailure());
-
- MigrateObject(HeapObject::cast(target)->address(), current, size);
- } else {
- size = object->Size();
- Memory::Address_at(current) = NULL;
- }
- }
-
- // Second pass: find pointers to new space and update them.
- PointersToNewGenUpdatingVisitor updating_visitor;
-
- // Update pointers in to space.
+static void SweepSpace(NewSpace* space) {
HeapObject* object;
for (Address current = space->bottom();
current < space->top();
current += object->Size()) {
object = HeapObject::FromAddress(current);
-
- object->IterateBody(object->map()->instance_type(),
- object->Size(),
- &updating_visitor);
- }
-
- // Update roots.
- Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
-
- // Update pointers in old spaces.
- Heap::IterateRSet(Heap::old_pointer_space(), &UpdatePointerToNewGen);
- Heap::IterateRSet(Heap::map_space(), &UpdatePointerToNewGen);
- Heap::lo_space()->IterateRSet(&UpdatePointerToNewGen);
-
- // Update pointers from cells.
- HeapObjectIterator cell_iterator(Heap::cell_space());
- for (HeapObject* cell = cell_iterator.next();
- cell != NULL;
- cell = cell_iterator.next()) {
- if (cell->IsJSGlobalPropertyCell()) {
- Address value_address =
- reinterpret_cast<Address>(cell) +
- (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
- updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
+ if (object->IsMarked()) {
+ object->ClearMark();
+ MarkCompactCollector::tracer()->decrement_marked_count();
+ } else {
+ // We give non-live objects a map that will correctly give their size,
+ // since their existing map might not be live after the collection.
+ int size = object->Size();
+ if (size >= ByteArray::kHeaderSize) {
+ object->set_map(Heap::raw_unchecked_byte_array_map());
+ ByteArray::cast(object)->set_length(ByteArray::LengthFor(size));
+ } else {
+ ASSERT(size == kPointerSize);
+ object->set_map(Heap::raw_unchecked_one_pointer_filler_map());
+ }
+ ASSERT(object->Size() == size);
}
+ // The object is now unmarked for the call to Size() at the top of the
+ // loop.
}
-
- // Update pointers from external string table.
- Heap::UpdateNewSpaceReferencesInExternalStringTable(
- &UpdateNewSpaceReferenceInExternalStringTableEntry);
-
- // All pointers were updated. Update auxiliary allocation info.
- Heap::IncrementYoungSurvivorsCounter(survivors_size);
- space->set_age_mark(space->top());
}
@@ -1561,12 +1382,10 @@
ASSERT(FreeListNode::IsFreeListNode(vacant_map));
ASSERT(map_to_evacuate->IsMap());
- ASSERT(Map::kSize % 4 == 0);
-
- Heap::CopyBlock(reinterpret_cast<Object**>(vacant_map->address()),
- reinterpret_cast<Object**>(map_to_evacuate->address()),
- Map::kSize);
-
+ memcpy(
+ reinterpret_cast<void*>(vacant_map->address()),
+ reinterpret_cast<void*>(map_to_evacuate->address()),
+ Map::kSize);
ASSERT(vacant_map->IsMap()); // Due to memcpy above.
MapWord forwarding_map_word = MapWord::FromMap(vacant_map);
@@ -1646,11 +1465,10 @@
SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
SweepSpace(Heap::cell_space(), &DeallocateCellBlock);
- SweepNewSpace(Heap::new_space());
+ SweepSpace(Heap::new_space());
SweepSpace(Heap::map_space(), &DeallocateMapBlock);
- int live_maps_size = Heap::map_space()->Size();
- int live_maps = live_maps_size / Map::kSize;
- ASSERT(live_map_objects_size_ == live_maps_size);
+ int live_maps = Heap::map_space()->Size() / Map::kSize;
+ ASSERT(live_map_objects_ == live_maps);
if (Heap::map_space()->NeedsCompaction(live_maps)) {
MapCompact map_compact(live_maps);
@@ -1682,7 +1500,7 @@
Address start,
Address end,
HeapObjectCallback size_func) {
- int live_objects_size = 0;
+ int live_objects = 0;
Address current = start;
while (current < end) {
uint32_t encoded_map = Memory::uint32_at(current);
@@ -1691,12 +1509,11 @@
} else if (encoded_map == kMultiFreeEncoding) {
current += Memory::int_at(current + kIntSize);
} else {
- int size = size_func(HeapObject::FromAddress(current));
- current += size;
- live_objects_size += size;
+ live_objects++;
+ current += size_func(HeapObject::FromAddress(current));
}
}
- return live_objects_size;
+ return live_objects;
}
@@ -1822,36 +1639,36 @@
Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
GlobalHandles::IterateWeakRoots(&updating_visitor);
- int live_maps_size = IterateLiveObjects(Heap::map_space(),
+ int live_maps = IterateLiveObjects(Heap::map_space(),
+ &UpdatePointersInOldObject);
+ int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
+ &UpdatePointersInOldObject);
+ int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
&UpdatePointersInOldObject);
- int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
- &UpdatePointersInOldObject);
- int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
- &UpdatePointersInOldObject);
- int live_codes_size = IterateLiveObjects(Heap::code_space(),
- &UpdatePointersInOldObject);
- int live_cells_size = IterateLiveObjects(Heap::cell_space(),
- &UpdatePointersInOldObject);
- int live_news_size = IterateLiveObjects(Heap::new_space(),
- &UpdatePointersInNewObject);
+ int live_codes = IterateLiveObjects(Heap::code_space(),
+ &UpdatePointersInOldObject);
+ int live_cells = IterateLiveObjects(Heap::cell_space(),
+ &UpdatePointersInOldObject);
+ int live_news = IterateLiveObjects(Heap::new_space(),
+ &UpdatePointersInNewObject);
// Large objects do not move, the map word can be updated directly.
LargeObjectIterator it(Heap::lo_space());
for (HeapObject* obj = it.next(); obj != NULL; obj = it.next())
UpdatePointersInNewObject(obj);
- USE(live_maps_size);
- USE(live_pointer_olds_size);
- USE(live_data_olds_size);
- USE(live_codes_size);
- USE(live_cells_size);
- USE(live_news_size);
- ASSERT(live_maps_size == live_map_objects_size_);
- ASSERT(live_data_olds_size == live_old_data_objects_size_);
- ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
- ASSERT(live_codes_size == live_code_objects_size_);
- ASSERT(live_cells_size == live_cell_objects_size_);
- ASSERT(live_news_size == live_young_objects_size_);
+ USE(live_maps);
+ USE(live_pointer_olds);
+ USE(live_data_olds);
+ USE(live_codes);
+ USE(live_cells);
+ USE(live_news);
+ ASSERT(live_maps == live_map_objects_);
+ ASSERT(live_data_olds == live_old_data_objects_);
+ ASSERT(live_pointer_olds == live_old_pointer_objects_);
+ ASSERT(live_codes == live_code_objects_);
+ ASSERT(live_cells == live_cell_objects_);
+ ASSERT(live_news == live_young_objects_);
}
@@ -1966,31 +1783,27 @@
#endif
// Relocates objects, always relocate map objects first. Relocating
// objects in other space relies on map objects to get object size.
- int live_maps_size = IterateLiveObjects(Heap::map_space(),
- &RelocateMapObject);
- int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
- &RelocateOldPointerObject);
- int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
- &RelocateOldDataObject);
- int live_codes_size = IterateLiveObjects(Heap::code_space(),
- &RelocateCodeObject);
- int live_cells_size = IterateLiveObjects(Heap::cell_space(),
- &RelocateCellObject);
- int live_news_size = IterateLiveObjects(Heap::new_space(),
- &RelocateNewObject);
+ int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject);
+ int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
+ &RelocateOldPointerObject);
+ int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
+ &RelocateOldDataObject);
+ int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
+ int live_cells = IterateLiveObjects(Heap::cell_space(), &RelocateCellObject);
+ int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);
- USE(live_maps_size);
- USE(live_pointer_olds_size);
- USE(live_data_olds_size);
- USE(live_codes_size);
- USE(live_cells_size);
- USE(live_news_size);
- ASSERT(live_maps_size == live_map_objects_size_);
- ASSERT(live_data_olds_size == live_old_data_objects_size_);
- ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
- ASSERT(live_codes_size == live_code_objects_size_);
- ASSERT(live_cells_size == live_cell_objects_size_);
- ASSERT(live_news_size == live_young_objects_size_);
+ USE(live_maps);
+ USE(live_data_olds);
+ USE(live_pointer_olds);
+ USE(live_codes);
+ USE(live_cells);
+ USE(live_news);
+ ASSERT(live_maps == live_map_objects_);
+ ASSERT(live_data_olds == live_old_data_objects_);
+ ASSERT(live_pointer_olds == live_old_pointer_objects_);
+ ASSERT(live_codes == live_code_objects_);
+ ASSERT(live_cells == live_cell_objects_);
+ ASSERT(live_news == live_young_objects_);
// Flip from and to spaces
Heap::new_space()->Flip();
@@ -2008,9 +1821,6 @@
PagedSpaces spaces;
for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
space->MCCommitRelocationInfo();
-
- Heap::CheckNewSpaceExpansionCriteria();
- Heap::IncrementYoungSurvivorsCounter(live_news_size);
}
@@ -2030,10 +1840,7 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- // Move contents.
- Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
- reinterpret_cast<Object**>(old_addr),
- Map::kSize);
+ memmove(new_addr, old_addr, Map::kSize); // copy contents
}
#ifdef DEBUG
@@ -2089,10 +1896,7 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- // Move contents.
- Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
- reinterpret_cast<Object**>(old_addr),
- obj_size);
+ memmove(new_addr, old_addr, obj_size); // Copy contents
}
ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
@@ -2136,10 +1940,7 @@
Address old_addr = obj->address();
if (new_addr != old_addr) {
- // Move contents.
- Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
- reinterpret_cast<Object**>(old_addr),
- obj_size);
+ memmove(new_addr, old_addr, obj_size); // Copy contents.
}
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
@@ -2175,9 +1976,9 @@
#endif
// New and old addresses cannot overlap.
- Heap::CopyBlock(reinterpret_cast<Object**>(new_addr),
- reinterpret_cast<Object**>(old_addr),
- obj_size);
+ memcpy(reinterpret_cast<void*>(new_addr),
+ reinterpret_cast<void*>(old_addr),
+ obj_size);
#ifdef DEBUG
if (FLAG_gc_verbose) {
« no previous file with comments | « src/mark-compact.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698