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

Unified Diff: src/mark-compact.cc

Issue 6542047: Basic implementation of incremental marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 10 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
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 5db1b36e02f1ba121062206f9e5b207fdb13637e..e08ff90e36c8e857b723700f3e0512c05dcab4e1 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -90,6 +90,61 @@ void Marking::TearDown() {
}
+#ifdef DEBUG
+class VerifyMarkingVisitor: public ObjectVisitor {
+ public:
+ void VisitPointers(Object** start, Object** end) {
+ for (Object** current = start; current < end; current++) {
+ if ((*current)->IsHeapObject()) {
+ HeapObject* object = HeapObject::cast(*current);
+ ASSERT(Marking::IsMarked(object));
+ }
+ }
+ }
+};
+
Erik Corry 2011/02/22 12:27:19 2 blank lines here and several places.
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
+static void VerifyMarking(Address bottom, Address top) {
+ VerifyMarkingVisitor visitor;
+ HeapObject* object;
+
+ for (Address current = bottom;
+ current < top;
+ current += object->Size()) {
+ object = HeapObject::FromAddress(current);
+ if (Marking::IsMarked(object)) object->Iterate(&visitor);
+ }
+
+}
+
+static void VerifyMarking(Page* p) {
+ VerifyMarking(p->ObjectAreaStart(), p->AllocationTop());
+}
+
+static void VerifyMarking(NewSpace* space) {
+ VerifyMarking(space->bottom(), space->top());
+}
+
+static void VerifyMarking(PagedSpace* space) {
+ PageIterator it(space, PageIterator::PAGES_IN_USE);
+
+ while (it.has_next()) {
+ VerifyMarking(it.next());
+ }
+}
+
+static void VerifyMarking() {
+ VerifyMarking(Heap::old_pointer_space());
+ VerifyMarking(Heap::old_data_space());
+ VerifyMarking(Heap::code_space());
+ VerifyMarking(Heap::cell_space());
+ VerifyMarking(Heap::map_space());
+ VerifyMarking(Heap::new_space());
+
+ VerifyMarkingVisitor visitor;
+ Heap::IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
+}
+#endif
+
void MarkCompactCollector::CollectGarbage() {
// Make sure that Prepare() has been called. The individual steps below will
// update the state as they proceed.
@@ -97,11 +152,23 @@ void MarkCompactCollector::CollectGarbage() {
// Prepare has selected whether to compact the old generation or not.
// Tell the tracer.
- if (IsCompacting()) tracer_->set_is_compacting();
+ // if (IsCompacting()) tracer_->set_is_compacting();
Erik Corry 2011/02/22 12:27:19 Commented code.
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
- MarkLiveObjects();
+ if (IncrementalMarking::state() == IncrementalMarking::STOPPED) {
+ MarkLiveObjects();
+ } else {
+ {
+ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
+ IncrementalMarking::Finalize();
+ ASSERT(IncrementalMarking::state() == IncrementalMarking::STOPPED);
+ }
+ MarkLiveObjects();
+ }
- if (FLAG_collect_maps) ClearNonLiveTransitions();
+#ifdef DEBUG
+ VerifyMarking();
+#endif
+ // if (FLAG_collect_maps) ClearNonLiveTransitions();
SweepSpaces();
@@ -154,11 +221,37 @@ static void ClearMarkbits() {
}
+void Marking::TransferMark(Address old_start, Address new_start) {
+ if (IncrementalMarking::state() == IncrementalMarking::MARKING) {
+ if (IncrementalMarking::IsBlack(HeapObject::FromAddress(old_start))) {
+ IncrementalMarking::MarkBlack(HeapObject::FromAddress(new_start));
+ } else if (IncrementalMarking::IsGrey(HeapObject::FromAddress(old_start))) {
+ IncrementalMarking::WhiteToGrey(HeapObject::FromAddress(new_start));
+ // TODO(gc): if we shift huge array in the loop we might end up pushing
+ // to much to marking stack. maybe we should check one or two elements
+ // on top of it to see whether they are equal to old_start.
Erik Corry 2011/02/22 12:27:19 Or perhaps we should compact the marking stack by
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 We will think about it.
+ }
+ } else {
+ if (Heap::InNewSpace(old_start) ||
+ Page::FromAddress(old_start)->IsFlagSet(Page::IS_CONTINUOUS) ||
+ !IsMarked(old_start)) {
+ return;
+ }
+ SetMark(new_start);
+ }
+}
+
+
void MarkCompactCollector::Prepare(GCTracer* tracer) {
FLAG_flush_code = false;
FLAG_always_compact = false;
FLAG_never_compact = true;
+ // Disable collection of maps if incremental marking is enabled.
+ // TODO(gc) improve maps collection algorithm to work with incremental
+ // marking.
+ if (FLAG_incremental_marking) FLAG_collect_maps = false;
+
// Rather than passing the tracer around we stash it in a static member
// variable.
tracer_ = tracer;
@@ -174,8 +267,9 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
compact_on_next_gc_ = false;
if (FLAG_never_compact) compacting_collection_ = false;
- if (!Heap::map_space()->MapPointersEncodable())
- compacting_collection_ = false;
+ if (!Heap::map_space()->MapPointersEncodable()) {
+ compacting_collection_ = false;
+ }
if (FLAG_collect_maps) CreateBackPointers();
#ifdef ENABLE_GDB_JIT_INTERFACE
if (FLAG_gdbjit) {
@@ -190,17 +284,20 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) {
space->PrepareForMarkCompact(compacting_collection_);
}
- Address new_space_top = Heap::new_space()->top();
- Address new_space_bottom = Heap::new_space()->bottom();
+ if (IncrementalMarking::state() == IncrementalMarking::STOPPED) {
+ Address new_space_top = Heap::new_space()->top();
+ Address new_space_bottom = Heap::new_space()->bottom();
- Marking::ClearRange(new_space_bottom,
- static_cast<int>(new_space_top - new_space_bottom));
-
- ClearMarkbits();
+ Marking::ClearRange(new_space_bottom,
+ static_cast<int>(new_space_top - new_space_bottom));
+ ClearMarkbits();
#ifdef DEBUG
- VerifyMarkbitsAreClean();
+ VerifyMarkbitsAreClean();
+#endif
+ }
+#ifdef DEBUG
live_bytes_ = 0;
live_young_objects_size_ = 0;
live_old_pointer_objects_size_ = 0;
@@ -545,7 +642,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
Object* old_cell = cell;
VisitPointer(&cell);
if (cell != old_cell) {
- rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell));
+ rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), NULL);
}
}
@@ -792,6 +889,8 @@ class StaticMarkingVisitor : public StaticVisitorBase {
static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) {
+ UNREACHABLE();
Erik Corry 2011/02/22 12:27:19 TODO?
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
+#if 0
Erik Corry 2011/02/22 12:27:19 Commented code.
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
// The function must have a valid context and not be a builtin.
bool flush_code_candidate = false;
@@ -826,6 +925,7 @@ class StaticMarkingVisitor : public StaticVisitorBase {
VisitJSFunctionFields(map,
reinterpret_cast<JSFunction*>(object),
flush_code_candidate);
+#endif
}
@@ -1072,13 +1172,14 @@ void MarkCompactCollector::ProcessNewlyMarkedObject(HeapObject* object) {
if (FLAG_cleanup_caches_in_maps_at_gc) {
map->ClearCodeCache();
}
- if (FLAG_collect_maps &&
+ /*if (FLAG_collect_maps &&
Erik Corry 2011/02/22 12:27:19 Commented code. TODO?
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
map->instance_type() <= JS_FUNCTION_TYPE) {
+ UNREACHABLE();
MarkMapContents(map);
- } else {
+ } else {*/
marking_stack.Push(map);
- }
+ /*}*/
} else {
marking_stack.Push(object);
}
@@ -1388,6 +1489,11 @@ void MarkCompactCollector::MarkLiveObjects() {
// weak roots.
ProcessObjectGroups();
+ AfterMarking();
+}
+
+
+void MarkCompactCollector::AfterMarking() {
// Prune the symbol table removing all symbols only pointed to by the
// symbol table. Cannot use symbol_table() here because the symbol
// table is marked.
@@ -1406,7 +1512,7 @@ void MarkCompactCollector::MarkLiveObjects() {
GlobalHandles::RemoveObjectGroups();
// Flush code from collected candidates.
- FlushCode::ProcessCandidates();
+ // FlushCode::ProcessCandidates();
Erik Corry 2011/02/22 12:27:19 Commented code and missing TODO'
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
}
@@ -1566,7 +1672,7 @@ class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VisitPointer(&target);
- rinfo->set_target_address(Code::cast(target)->instruction_start());
+ rinfo->set_target_address(Code::cast(target)->instruction_start(), NULL);
}
void VisitDebugTarget(RelocInfo* rinfo) {
@@ -1896,6 +2002,9 @@ static void SweepPrecisely(PagedSpace* space,
is_previous_alive = true;
}
} else {
+ ASSERT((current + kPointerSize) >= p->AllocationTop() ||
+ object->Size() == 4 ||
Erik Corry 2011/02/22 12:27:19 kPointerSize?
Vyacheslav Egorov (Chromium) 2011/02/23 14:31:46 Done.
+ IncrementalMarking::IsWhite(object));
MarkCompactCollector::ReportDeleteIfNeeded(object);
if (is_previous_alive) { // Transition from live to free.
free_start = current;
@@ -2038,17 +2147,24 @@ void MarkCompactCollector::SweepSpaces() {
#ifdef DEBUG
state_ = SWEEP_SPACES;
#endif
+
+#ifndef DEBUG
+ SweeperType fast_sweeper = CONSERVATIVE;
+#else
+ SweeperType fast_sweeper = PRECISE;
+#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
// the map space last because freeing non-live maps overwrites them and
// the other spaces rely on possibly non-live maps to get the sizes for
// non-live objects.
- SweepSpace(Heap::old_pointer_space(), CONSERVATIVE);
- SweepSpace(Heap::old_data_space(), CONSERVATIVE);
+ SweepSpace(Heap::old_pointer_space(), fast_sweeper);
+ SweepSpace(Heap::old_data_space(), fast_sweeper);
SweepSpace(Heap::code_space(), PRECISE);
// TODO(gc): implement specialized sweeper for cell space.
- SweepSpace(Heap::cell_space(), CONSERVATIVE);
+ SweepSpace(Heap::cell_space(), fast_sweeper);
{ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
SweepNewSpace(Heap::new_space());
}

Powered by Google App Engine
This is Rietveld 408576698