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:
parent
95cd146359
commit
be243df7ca
@ -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());
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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)));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user