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.

R=hpayer@chromium.org
BUG=v8:2699

Review URL: https://codereview.chromium.org/16286018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14940 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mstarzinger@chromium.org 2013-06-04 17:20:06 +00:00
parent 95cd146359
commit be243df7ca
4 changed files with 34 additions and 27 deletions

View File

@ -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());

View File

@ -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
};

View File

@ -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)));
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);
Map* map = object->map();
MarkBit map_mark = Marking::MarkBitFrom(map);
MarkObject(map, map_mark);
MarkCompactMarkingVisitor::IterateBody(map, object);
}
// 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::ProcessEphemeralMarking(ObjectVisitor* 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.
ProcessEphemeralMarking(&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.
ProcessEphemeralMarking(&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)));

View File

@ -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 ProcessEphemeralMarking(ObjectVisitor* 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