From 93b3c7e0be8d09e98811d49716400bedc3360301 Mon Sep 17 00:00:00 2001 From: Ulan Degenbaev Date: Mon, 11 Feb 2019 16:17:20 +0100 Subject: [PATCH] [heap] Handle young large objects in global handles Bug: chromium:852420 Change-Id: I9c86353734055ef08ab5b2d3c55bf5dd0a870335 Reviewed-on: https://chromium-review.googlesource.com/c/1463520 Commit-Queue: Ulan Degenbaev Reviewed-by: Michael Lippautz Cr-Commit-Position: refs/heads/master@{#59511} --- src/api.cc | 4 +- src/global-handles.cc | 123 ++++++++++++++++++--------------------- src/global-handles.h | 39 ++++++------- src/heap/heap.cc | 6 +- src/heap/mark-compact.cc | 9 ++- src/heap/scavenger.cc | 9 ++- 6 files changed, 90 insertions(+), 100 deletions(-) diff --git a/src/api.cc b/src/api.cc index f913eee3aa..aca952e11a 100644 --- a/src/api.cc +++ b/src/api.cc @@ -8851,14 +8851,14 @@ void Isolate::VisitHandlesForPartialDependence( PersistentHandleVisitor* visitor) { i::Isolate* isolate = reinterpret_cast(this); i::DisallowHeapAllocation no_allocation; - isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(visitor); + isolate->global_handles()->IterateAllYoungRootsWithClassIds(visitor); } void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { i::Isolate* isolate = reinterpret_cast(this); i::DisallowHeapAllocation no_allocation; - isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(visitor); + isolate->global_handles()->IterateYoungWeakRootsWithClassIds(visitor); } void Isolate::SetAllowAtomicsWait(bool allow) { diff --git a/src/global-handles.cc b/src/global-handles.cc index 857cccc729..1452718aa5 100644 --- a/src/global-handles.cc +++ b/src/global-handles.cc @@ -383,7 +383,7 @@ class GlobalHandles::Node final : public NodeBase { Internals::kNodeIsIndependentShift); STATIC_ASSERT(static_cast(IsActive::kShift) == Internals::kNodeIsActiveShift); - set_in_new_space_list(false); + set_in_young_list(false); } void Zap() { @@ -416,12 +416,8 @@ class GlobalHandles::Node final : public NodeBase { flags_ = IsActive::update(flags_, v); } - bool is_in_new_space_list() { - return IsInNewSpaceList::decode(flags_); - } - void set_in_new_space_list(bool v) { - flags_ = IsInNewSpaceList::update(flags_, v); - } + bool is_in_young_list() const { return IsInYoungList::decode(flags_); } + void set_in_young_list(bool v) { flags_ = IsInYoungList::update(flags_, v); } WeaknessType weakness_type() const { return NodeWeaknessType::decode(flags_); @@ -614,14 +610,14 @@ class GlobalHandles::Node final : public NodeBase { } // This stores three flags (independent, partially_dependent and - // in_new_space_list) and a State. + // in_young_list) and a State. class NodeState : public BitField8 {}; class IsIndependent : public BitField8 {}; // The following two fields are mutually exclusive class IsActive : public BitField8 {}; - class IsInNewSpaceList : public BitField8 {}; + class IsInYoungList : public BitField8 {}; class NodeWeaknessType - : public BitField8 {}; + : public BitField8 {}; // Handle specific callback - might be a weak reference in disguise. WeakCallbackInfo::Callback weak_callback_; @@ -634,7 +630,7 @@ class GlobalHandles::Node final : public NodeBase { class GlobalHandles::TracedNode final : public NodeBase { public: - TracedNode() { set_in_new_space_list(false); } + TracedNode() { set_in_young_list(false); } enum State { FREE = 0, NORMAL, NEAR_DEATH }; @@ -647,10 +643,8 @@ class GlobalHandles::TracedNode final bool IsRetainer() const { return state() == NORMAL; } bool IsPhantomResetHandle() const { return callback_ == nullptr; } - bool is_in_new_space_list() const { return IsInNewSpaceList::decode(flags_); } - void set_in_new_space_list(bool v) { - flags_ = IsInNewSpaceList::update(flags_, v); - } + bool is_in_young_list() const { return IsInYoungList::decode(flags_); } + void set_in_young_list(bool v) { flags_ = IsInYoungList::update(flags_, v); } bool is_root() const { return IsRoot::decode(flags_); } void set_root(bool v) { flags_ = IsRoot::update(flags_, v); } @@ -691,8 +685,8 @@ class GlobalHandles::TracedNode final protected: class NodeState : public BitField8 {}; - class IsInNewSpaceList : public BitField8 {}; - class IsRoot : public BitField8 {}; + class IsInYoungList : public BitField8 {}; + class IsRoot : public BitField8 {}; void ClearImplFields() { set_root(true); @@ -720,9 +714,9 @@ GlobalHandles::~GlobalHandles() { regular_nodes_.reset(nullptr); } Handle GlobalHandles::Create(Object value) { GlobalHandles::Node* result = regular_nodes_->Acquire(value); - if (Heap::InNewSpace(value) && !result->is_in_new_space_list()) { - new_space_nodes_.push_back(result); - result->set_in_new_space_list(true); + if (Heap::InYoungGeneration(value) && !result->is_in_young_list()) { + young_nodes_.push_back(result); + result->set_in_young_list(true); } return result->handle(); } @@ -733,9 +727,9 @@ Handle GlobalHandles::Create(Address value) { Handle GlobalHandles::CreateTraced(Object value, Address* slot) { GlobalHandles::TracedNode* result = traced_nodes_->Acquire(value); - if (Heap::InNewSpace(value) && !result->is_in_new_space_list()) { - traced_new_space_nodes_.push_back(result); - result->set_in_new_space_list(true); + if (Heap::InYoungGeneration(value) && !result->is_in_young_list()) { + traced_young_nodes_.push_back(result); + result->set_in_young_list(true); } result->set_parameter(slot); return result->handle(); @@ -888,7 +882,7 @@ void GlobalHandles::IterateWeakRootsIdentifyFinalizers( void GlobalHandles::IdentifyWeakUnmodifiedObjects( WeakSlotCallback is_unmodified) { - for (Node* node : new_space_nodes_) { + for (Node* node : young_nodes_) { if (node->IsWeak() && !is_unmodified(node->location())) { node->set_active(true); } @@ -896,7 +890,7 @@ void GlobalHandles::IdentifyWeakUnmodifiedObjects( LocalEmbedderHeapTracer* const tracer = isolate()->heap()->local_embedder_heap_tracer(); - for (TracedNode* node : traced_new_space_nodes_) { + for (TracedNode* node : traced_young_nodes_) { if (node->IsInUse()) { DCHECK(node->is_root()); if (is_unmodified(node->location())) { @@ -908,8 +902,8 @@ void GlobalHandles::IdentifyWeakUnmodifiedObjects( } } -void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(RootVisitor* v) { - for (Node* node : new_space_nodes_) { +void GlobalHandles::IterateYoungStrongAndDependentRoots(RootVisitor* v) { + for (Node* node : young_nodes_) { if (node->IsStrongRetainer() || (node->IsWeakRetainer() && !node->is_independent() && node->is_active())) { @@ -917,17 +911,17 @@ void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(RootVisitor* v) { node->location()); } } - for (TracedNode* node : traced_new_space_nodes_) { + for (TracedNode* node : traced_young_nodes_) { if (node->IsInUse() && node->is_root()) { v->VisitRootPointer(Root::kGlobalHandles, nullptr, node->location()); } } } -void GlobalHandles::MarkNewSpaceWeakUnmodifiedObjectsPending( +void GlobalHandles::MarkYoungWeakUnmodifiedObjectsPending( WeakSlotCallbackWithHeap is_dead) { - for (Node* node : new_space_nodes_) { - DCHECK(node->is_in_new_space_list()); + for (Node* node : young_nodes_) { + DCHECK(node->is_in_young_list()); if ((node->is_independent() || !node->is_active()) && node->IsWeak() && is_dead(isolate_->heap(), node->location())) { if (!node->IsPhantomCallback() && !node->IsPhantomResetHandle()) { @@ -937,10 +931,10 @@ void GlobalHandles::MarkNewSpaceWeakUnmodifiedObjectsPending( } } -void GlobalHandles::IterateNewSpaceWeakUnmodifiedRootsForFinalizers( +void GlobalHandles::IterateYoungWeakUnmodifiedRootsForFinalizers( RootVisitor* v) { - for (Node* node : new_space_nodes_) { - DCHECK(node->is_in_new_space_list()); + for (Node* node : young_nodes_) { + DCHECK(node->is_in_young_list()); if ((node->is_independent() || !node->is_active()) && node->IsWeakRetainer() && (node->state() == Node::PENDING)) { DCHECK(!node->IsPhantomCallback()); @@ -952,10 +946,10 @@ void GlobalHandles::IterateNewSpaceWeakUnmodifiedRootsForFinalizers( } } -void GlobalHandles::IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles( +void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles( RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle) { - for (Node* node : new_space_nodes_) { - DCHECK(node->is_in_new_space_list()); + for (Node* node : young_nodes_) { + DCHECK(node->is_in_young_list()); if ((node->is_independent() || !node->is_active()) && node->IsWeakRetainer() && (node->state() != Node::PENDING)) { if (should_reset_handle(isolate_->heap(), node->location())) { @@ -977,7 +971,7 @@ void GlobalHandles::IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles( } } } - for (TracedNode* node : traced_new_space_nodes_) { + for (TracedNode* node : traced_young_nodes_) { if (!node->IsInUse()) continue; DCHECK_IMPLIES(node->is_root(), @@ -1019,7 +1013,7 @@ void GlobalHandles::InvokeSecondPassPhantomCallbacks() { size_t GlobalHandles::PostScavengeProcessing(unsigned post_processing_count) { size_t freed_nodes = 0; - for (Node* node : new_space_nodes_) { + for (Node* node : young_nodes_) { // Filter free nodes. if (!node->IsRetainer()) continue; @@ -1060,21 +1054,21 @@ size_t GlobalHandles::PostMarkSweepProcessing(unsigned post_processing_count) { } template -void GlobalHandles::UpdateAndCompactListOfNewSpaceNode( +void GlobalHandles::UpdateAndCompactListOfYoungNode( std::vector* node_list) { size_t last = 0; for (T* node : *node_list) { - DCHECK(node->is_in_new_space_list()); + DCHECK(node->is_in_young_list()); if (node->IsInUse()) { - if (Heap::InNewSpace(node->object())) { + if (Heap::InYoungGeneration(node->object())) { (*node_list)[last++] = node; isolate_->heap()->IncrementNodesCopiedInNewSpace(); } else { - node->set_in_new_space_list(false); + node->set_in_young_list(false); isolate_->heap()->IncrementNodesPromoted(); } } else { - node->set_in_new_space_list(false); + node->set_in_young_list(false); isolate_->heap()->IncrementNodesDiedInNewSpace(); } } @@ -1083,9 +1077,9 @@ void GlobalHandles::UpdateAndCompactListOfNewSpaceNode( node_list->shrink_to_fit(); } -void GlobalHandles::UpdateListOfNewSpaceNodes() { - UpdateAndCompactListOfNewSpaceNode(&new_space_nodes_); - UpdateAndCompactListOfNewSpaceNode(&traced_new_space_nodes_); +void GlobalHandles::UpdateListOfYoungNodes() { + UpdateAndCompactListOfYoungNode(&young_nodes_); + UpdateAndCompactListOfYoungNode(&traced_young_nodes_); } template @@ -1177,7 +1171,7 @@ size_t GlobalHandles::PostGarbageCollectionProcessing( : PostMarkSweepProcessing(post_processing_count); if (InRecursiveGC(post_processing_count)) return freed_nodes; - UpdateListOfNewSpaceNodes(); + UpdateListOfYoungNodes(); return freed_nodes; } @@ -1220,14 +1214,14 @@ void GlobalHandles::IterateAllRoots(RootVisitor* v) { } DISABLE_CFI_PERF -void GlobalHandles::IterateAllNewSpaceRoots(RootVisitor* v) { - for (Node* node : new_space_nodes_) { +void GlobalHandles::IterateAllYoungRoots(RootVisitor* v) { + for (Node* node : young_nodes_) { if (node->IsRetainer()) { v->VisitRootPointer(Root::kGlobalHandles, node->label(), node->location()); } } - for (TracedNode* node : traced_new_space_nodes_) { + for (TracedNode* node : traced_young_nodes_) { if (node->IsRetainer()) { v->VisitRootPointer(Root::kGlobalHandles, nullptr, node->location()); } @@ -1266,20 +1260,19 @@ void GlobalHandles::IterateTracedNodes( } DISABLE_CFI_PERF -void GlobalHandles::IterateAllRootsInNewSpaceWithClassIds( +void GlobalHandles::IterateAllYoungRootsWithClassIds( v8::PersistentHandleVisitor* visitor) { - for (Node* node : new_space_nodes_) { + for (Node* node : young_nodes_) { if (node->IsRetainer() && node->has_wrapper_class_id()) { ApplyPersistentHandleVisitor(visitor, node); } } } - DISABLE_CFI_PERF -void GlobalHandles::IterateWeakRootsInNewSpaceWithClassIds( +void GlobalHandles::IterateYoungWeakRootsWithClassIds( v8::PersistentHandleVisitor* visitor) { - for (Node* node : new_space_nodes_) { + for (Node* node : young_nodes_) { if (node->has_wrapper_class_id() && node->IsWeak()) { ApplyPersistentHandleVisitor(visitor, node); } @@ -1359,8 +1352,8 @@ void EternalHandles::IterateAllRoots(RootVisitor* visitor) { } } -void EternalHandles::IterateNewSpaceRoots(RootVisitor* visitor) { - for (int index : new_space_indices_) { +void EternalHandles::IterateYoungRoots(RootVisitor* visitor) { + for (int index : young_node_indices_) { visitor->VisitRootPointer(Root::kEternalHandles, nullptr, FullObjectSlot(GetLocation(index))); } @@ -1368,13 +1361,13 @@ void EternalHandles::IterateNewSpaceRoots(RootVisitor* visitor) { void EternalHandles::PostGarbageCollectionProcessing() { size_t last = 0; - for (int index : new_space_indices_) { - if (Heap::InNewSpace(Object(*GetLocation(index)))) { - new_space_indices_[last++] = index; + for (int index : young_node_indices_) { + if (Heap::InYoungGeneration(Object(*GetLocation(index)))) { + young_node_indices_[last++] = index; } } - DCHECK_LE(last, new_space_indices_.size()); - new_space_indices_.resize(last); + DCHECK_LE(last, young_node_indices_.size()); + young_node_indices_.resize(last); } void EternalHandles::Create(Isolate* isolate, Object object, int* index) { @@ -1392,8 +1385,8 @@ void EternalHandles::Create(Isolate* isolate, Object object, int* index) { } DCHECK_EQ(the_hole->ptr(), blocks_[block][offset]); blocks_[block][offset] = object->ptr(); - if (Heap::InNewSpace(object)) { - new_space_indices_.push_back(size_); + if (Heap::InYoungGeneration(object)) { + young_node_indices_.push_back(size_); } *index = size_++; } diff --git a/src/global-handles.h b/src/global-handles.h index 3ad56d79d0..3604af1d28 100644 --- a/src/global-handles.h +++ b/src/global-handles.h @@ -120,18 +120,18 @@ class GlobalHandles final { void IterateStrongRoots(RootVisitor* v); void IterateWeakRoots(RootVisitor* v); void IterateAllRoots(RootVisitor* v); - void IterateAllNewSpaceRoots(RootVisitor* v); + void IterateAllYoungRoots(RootVisitor* v); // Iterates over all handles that have embedder-assigned class ID. void IterateAllRootsWithClassIds(v8::PersistentHandleVisitor* v); // Iterates over all handles in the new space that have embedder-assigned // class ID. - void IterateAllRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v); + void IterateAllYoungRootsWithClassIds(v8::PersistentHandleVisitor* v); // Iterate over all handles in the new space that are weak, unmodified // and have class IDs - void IterateWeakRootsInNewSpaceWithClassIds(v8::PersistentHandleVisitor* v); + void IterateYoungWeakRootsWithClassIds(v8::PersistentHandleVisitor* v); // Iterates over all traces handles represented by TracedGlobal. void IterateTracedNodes( @@ -149,22 +149,21 @@ class GlobalHandles final { void IterateWeakRootsForPhantomHandles( WeakSlotCallbackWithHeap should_reset_handle); - // Note: The following *NewSpace* methods are used for the Scavenger to - // identify and process handles in new space. The set of new space handles is - // complete but the methods may encounter handles that are already in old - // space. + // Note: The following *Young* methods are used for the Scavenger to + // identify and process handles in the young generation. The set of young + // handles is complete but the methods may encounter handles that are + // already in old space. // Iterates over strong and dependent handles. See the note above. - void IterateNewSpaceStrongAndDependentRoots(RootVisitor* v); + void IterateYoungStrongAndDependentRoots(RootVisitor* v); // Marks weak unmodified handles satisfying |is_dead| as pending. - void MarkNewSpaceWeakUnmodifiedObjectsPending( - WeakSlotCallbackWithHeap is_dead); + void MarkYoungWeakUnmodifiedObjectsPending(WeakSlotCallbackWithHeap is_dead); // Iterates over weak independent or unmodified handles. // See the note above. - void IterateNewSpaceWeakUnmodifiedRootsForFinalizers(RootVisitor* v); - void IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles( + void IterateYoungWeakUnmodifiedRootsForFinalizers(RootVisitor* v); + void IterateYoungWeakUnmodifiedRootsForPhantomHandles( RootVisitor* v, WeakSlotCallbackWithHeap should_reset_handle); // Identify unmodified objects that are in weak state and marks them @@ -209,8 +208,8 @@ class GlobalHandles final { std::vector>* pending); template - void UpdateAndCompactListOfNewSpaceNode(std::vector* node_list); - void UpdateListOfNewSpaceNodes(); + void UpdateAndCompactListOfYoungNode(std::vector* node_list); + void UpdateListOfYoungNodes(); void ApplyPersistentHandleVisitor(v8::PersistentHandleVisitor* visitor, Node* node); @@ -218,12 +217,12 @@ class GlobalHandles final { Isolate* const isolate_; std::unique_ptr> regular_nodes_; - // Contains all nodes holding new space objects. Note: when the list + // Contains all nodes holding young objects. Note: when the list // is accessed, some of the objects may have been promoted already. - std::vector new_space_nodes_; + std::vector young_nodes_; std::unique_ptr> traced_nodes_; - std::vector traced_new_space_nodes_; + std::vector traced_young_nodes_; // Field always containing the number of handles to global objects. size_t handles_count_ = 0; @@ -282,8 +281,8 @@ class EternalHandles final { // Iterates over all handles. void IterateAllRoots(RootVisitor* visitor); - // Iterates over all handles which might be in new space. - void IterateNewSpaceRoots(RootVisitor* visitor); + // Iterates over all handles which might be in the young generation. + void IterateYoungRoots(RootVisitor* visitor); // Rebuilds new space list. void PostGarbageCollectionProcessing(); @@ -304,7 +303,7 @@ class EternalHandles final { int size_ = 0; std::vector blocks_; - std::vector new_space_indices_; + std::vector young_node_indices_; DISALLOW_COPY_AND_ASSIGN(EternalHandles); }; diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 18bd839edb..bff16fd90d 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -3910,10 +3910,10 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) { break; case VISIT_ALL_IN_SCAVENGE: case VISIT_ALL_IN_MINOR_MC_MARK: - isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v); + isolate_->global_handles()->IterateYoungStrongAndDependentRoots(v); break; case VISIT_ALL_IN_MINOR_MC_UPDATE: - isolate_->global_handles()->IterateAllNewSpaceRoots(v); + isolate_->global_handles()->IterateAllYoungRoots(v); break; case VISIT_ALL_IN_SWEEP_NEWSPACE: case VISIT_ALL: @@ -3926,7 +3926,7 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) { // serializer. Values referenced by eternal handles need to be added manually. if (mode != VISIT_FOR_SERIALIZATION) { if (isMinorGC) { - isolate_->eternal_handles()->IterateNewSpaceRoots(v); + isolate_->eternal_handles()->IterateYoungRoots(v); } else { isolate_->eternal_handles()->IterateAllRoots(v); } diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 1a6d03184e..1b69e87baa 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -4577,14 +4577,13 @@ void MinorMarkCompactCollector::MarkLiveObjects() { { TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES); - isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( + isolate()->global_handles()->MarkYoungWeakUnmodifiedObjectsPending( &IsUnmarkedObjectForYoungGeneration); + isolate()->global_handles()->IterateYoungWeakUnmodifiedRootsForFinalizers( + &root_visitor); isolate() ->global_handles() - ->IterateNewSpaceWeakUnmodifiedRootsForFinalizers(&root_visitor); - isolate() - ->global_handles() - ->IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles( + ->IterateYoungWeakUnmodifiedRootsForPhantomHandles( &root_visitor, &IsUnmarkedObjectForYoungGeneration); ProcessMarkingWorklist(); } diff --git a/src/heap/scavenger.cc b/src/heap/scavenger.cc index 4e072db669..f6e275e3f8 100644 --- a/src/heap/scavenger.cc +++ b/src/heap/scavenger.cc @@ -230,17 +230,16 @@ void ScavengerCollector::CollectGarbage() { // Scavenge weak global handles. TRACE_GC(heap_->tracer(), GCTracer::Scope::SCAVENGER_SCAVENGE_WEAK_GLOBAL_HANDLES_PROCESS); - isolate_->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending( + isolate_->global_handles()->MarkYoungWeakUnmodifiedObjectsPending( &IsUnscavengedHeapObject); - isolate_->global_handles() - ->IterateNewSpaceWeakUnmodifiedRootsForFinalizers( - &root_scavenge_visitor); + isolate_->global_handles()->IterateYoungWeakUnmodifiedRootsForFinalizers( + &root_scavenge_visitor); scavengers[kMainThreadId]->Process(); DCHECK(copied_list.IsEmpty()); DCHECK(promotion_list.IsEmpty()); isolate_->global_handles() - ->IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles( + ->IterateYoungWeakUnmodifiedRootsForPhantomHandles( &root_scavenge_visitor, &IsUnscavengedHeapObject); }