Reviewers: Hannes Payer,
Description:
Prevent excessive processing of weak maps while marking.
This makes sure processing of Harmony weak maps is only triggerd twice
during a mark-compact collection. Note that the processing itself still
is a fix-point iteration with quadratic worst-case time.
[email protected]
BUG=v8:2699
Please review this at https://codereview.chromium.org/16286018/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/heap.h
M src/heap.cc
M src/mark-compact.h
M src/mark-compact.cc
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index
ba5b6903984c205a04417d7be075ac1e6f7ac860..625fde3ade5979b0db011b8b7088b1922d9e2388
100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -7512,6 +7512,8 @@ GCTracer::~GCTracer() {
PrintF("intracompaction_ptrs=%.1f ",
scopes_[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
PrintF("misc_compaction=%.1f ",
scopes_[Scope::MC_UPDATE_MISC_POINTERS]);
+ PrintF("weakmap_process=%.1f ", scopes_[Scope::MC_WEAKMAP_PROCESS]);
+ PrintF("weakmap_clear=%.1f ", scopes_[Scope::MC_WEAKMAP_CLEAR]);
PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_object_size_);
PrintF("total_size_after=%" V8_PTR_PREFIX "d ",
heap_->SizeOfObjects());
Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index
5a93981b218d67e913b99f5a3cca73185f8d99fc..394a02ad2c7c9fc2c8d7631bc0eddf27d511f8e8
100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2711,6 +2711,8 @@ class GCTracer BASE_EMBEDDED {
MC_UPDATE_POINTERS_TO_EVACUATED,
MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
MC_UPDATE_MISC_POINTERS,
+ MC_WEAKMAP_PROCESS,
+ MC_WEAKMAP_CLEAR,
MC_FLUSH_CODE,
kNumberOfScopes
};
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
40015010d11dc32f8bb74fc8f4245e7ea2c004df..72d09d32e69fd3e4f83fe959d77490cf0dffe05c
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2074,22 +2074,16 @@ void MarkCompactCollector::MarkImplicitRefGroups() {
// marking stack have been marked, or are overflowed in the heap.
void MarkCompactCollector::EmptyMarkingDeque() {
while (!marking_deque_.IsEmpty()) {
- while (!marking_deque_.IsEmpty()) {
- HeapObject* object = marking_deque_.Pop();
- ASSERT(object->IsHeapObject());
- ASSERT(heap()->Contains(object));
- ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
-
- Map* map = object->map();
- MarkBit map_mark = Marking::MarkBitFrom(map);
- MarkObject(map, map_mark);
+ HeapObject* object = marking_deque_.Pop();
+ ASSERT(object->IsHeapObject());
+ ASSERT(heap()->Contains(object));
+ ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
- MarkCompactMarkingVisitor::IterateBody(map, object);
- }
+ Map* map = object->map();
+ MarkBit map_mark = Marking::MarkBitFrom(map);
+ MarkObject(map, map_mark);
- // Process encountered weak maps, mark objects only reachable by those
- // weak maps and repeat until fix-point is reached.
- ProcessWeakMaps();
+ MarkCompactMarkingVisitor::IterateBody(map, object);
}
}
@@ -2154,13 +2148,16 @@ void MarkCompactCollector::ProcessMarkingDeque() {
}
-void MarkCompactCollector::ProcessExternalMarking(RootMarkingVisitor*
visitor) {
+// Mark all objects reachable (transitively) from objects on the marking
+// stack including references only considered in the atomic marking pause.
+void MarkCompactCollector::ProcessAtomicMarking(RootMarkingVisitor*
visitor) {
bool work_to_do = true;
ASSERT(marking_deque_.IsEmpty());
while (work_to_do) {
isolate()->global_handles()->IterateObjectGroups(
visitor, &IsUnmarkedHeapObjectWithHeap);
MarkImplicitRefGroups();
+ ProcessWeakMaps();
work_to_do = !marking_deque_.IsEmpty();
ProcessMarkingDeque();
}
@@ -2237,12 +2234,12 @@ void MarkCompactCollector::MarkLiveObjects() {
// The objects reachable from the roots are marked, yet unreachable
// objects are unmarked. Mark objects reachable due to host
- // application specific logic.
- ProcessExternalMarking(&root_visitor);
+ // application specific logic or through Harmony weak maps.
+ ProcessAtomicMarking(&root_visitor);
- // The objects reachable from the roots or object groups are marked,
- // yet unreachable objects are unmarked. Mark objects reachable
- // only from weak global handles.
+ // The objects reachable from the roots, weak maps or object groups
+ // are marked, yet unreachable objects are unmarked. Mark objects
+ // reachable only from weak global handles.
//
// First we identify nonlive weak handles and mark them as pending
// destruction.
@@ -2255,9 +2252,9 @@ void MarkCompactCollector::MarkLiveObjects() {
EmptyMarkingDeque();
}
- // Repeat host application specific marking to mark unmarked objects
- // reachable from the weak roots.
- ProcessExternalMarking(&root_visitor);
+ // Repeat host application specific and Harmony weak maps marking to
+ // mark unmarked objects reachable from the weak roots.
+ ProcessAtomicMarking(&root_visitor);
AfterMarking();
}
@@ -2529,6 +2526,7 @@ void
MarkCompactCollector::ClearNonLiveDependentCode(Map* map) {
void MarkCompactCollector::ProcessWeakMaps() {
+ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_PROCESS);
Object* weak_map_obj = encountered_weak_maps();
while (weak_map_obj != Smi::FromInt(0)) {
ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
@@ -2554,6 +2552,7 @@ void MarkCompactCollector::ProcessWeakMaps() {
void MarkCompactCollector::ClearWeakMaps() {
+ GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_CLEAR);
Object* weak_map_obj = encountered_weak_maps();
while (weak_map_obj != Smi::FromInt(0)) {
ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
Index: src/mark-compact.h
diff --git a/src/mark-compact.h b/src/mark-compact.h
index
0f20440062710bbc0e9108a7e1092476ac04cdbe..4abd1e38368a332f520b24a15bb48b2abaed7e95
100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -841,14 +841,18 @@ class MarkCompactCollector {
// is marked.
void MarkImplicitRefGroups();
- // Mark all objects which are reachable due to host application
- // logic like object groups or implicit references' groups.
- void ProcessExternalMarking(RootMarkingVisitor* visitor);
-
// Mark objects reachable (transitively) from objects in the marking
stack
// or overflowed in the heap.
void ProcessMarkingDeque();
+ // Mark objects reachable (transitively) from objects in the marking
stack
+ // or overflowed in the heap. This respects references only considered
in
+ // the final atomic marking pause including the following:
+ // - Processing of objects reachable through Harmony WeakMaps.
+ // - Objects reachable due to host application logic like object
groups
+ // or implicit references' groups.
+ void ProcessAtomicMarking(RootMarkingVisitor* visitor);
+
// Mark objects reachable (transitively) from objects in the marking
// stack. This function empties the marking stack, but may leave
// overflowed objects in the heap, in which case the marking stack's
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.