diff options
Diffstat (limited to 'src/3rdparty/v8/src/global-handles.cc')
-rw-r--r-- | src/3rdparty/v8/src/global-handles.cc | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/3rdparty/v8/src/global-handles.cc b/src/3rdparty/v8/src/global-handles.cc index 9c0ad45..0006f8e 100644 --- a/src/3rdparty/v8/src/global-handles.cc +++ b/src/3rdparty/v8/src/global-handles.cc @@ -69,6 +69,7 @@ class GlobalHandles::Node { class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; index_ = 0; independent_ = false; + partially_dependent_ = false; in_new_space_list_ = false; parameter_or_next_free_.next_free = NULL; callback_ = NULL; @@ -89,6 +90,7 @@ class GlobalHandles::Node { object_ = object; class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; independent_ = false; + partially_dependent_ = false; state_ = NORMAL; parameter_or_next_free_.parameter = NULL; callback_ = NULL; @@ -154,6 +156,15 @@ class GlobalHandles::Node { } bool is_independent() const { return independent_; } + void MarkPartiallyDependent(GlobalHandles* global_handles) { + ASSERT(state_ != FREE); + if (global_handles->isolate()->heap()->InNewSpace(object_)) { + partially_dependent_ = true; + } + } + bool is_partially_dependent() const { return partially_dependent_; } + void clear_partially_dependent() { partially_dependent_ = false; } + // In-new-space-list flag accessors. void set_in_new_space_list(bool v) { in_new_space_list_ = v; } bool is_in_new_space_list() const { return in_new_space_list_; } @@ -260,6 +271,7 @@ class GlobalHandles::Node { State state_ : 4; bool independent_ : 1; + bool partially_dependent_ : 1; bool in_new_space_list_ : 1; // Handle specific callback. @@ -448,6 +460,16 @@ void GlobalHandles::MarkIndependent(Object** location) { } +void GlobalHandles::MarkPartiallyDependent(Object** location) { + Node::FromLocation(location)->MarkPartiallyDependent(this); +} + + +bool GlobalHandles::IsIndependent(Object** location) { + return Node::FromLocation(location)->is_independent(); +} + + bool GlobalHandles::IsNearDeath(Object** location) { return Node::FromLocation(location)->IsNearDeath(); } @@ -462,6 +484,9 @@ void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) { Node::FromLocation(location)->set_wrapper_class_id(class_id); } +uint16_t GlobalHandles::GetWrapperClassId(Object** location) { + return Node::FromLocation(location)->wrapper_class_id(); +} void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { for (NodeIterator it(this); !it.done(); it.Advance()) { @@ -493,8 +518,9 @@ void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) { for (int i = 0; i < new_space_nodes_.length(); ++i) { Node* node = new_space_nodes_[i]; if (node->IsStrongRetainer() || - (node->IsWeakRetainer() && !node->is_independent())) { - v->VisitPointer(node->location()); + (node->IsWeakRetainer() && !node->is_independent() && + !node->is_partially_dependent())) { + v->VisitPointer(node->location()); } } } @@ -505,8 +531,8 @@ void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles( for (int i = 0; i < new_space_nodes_.length(); ++i) { Node* node = new_space_nodes_[i]; ASSERT(node->is_in_new_space_list()); - if (node->is_independent() && node->IsWeak() && - f(isolate_->heap(), node->location())) { + if ((node->is_independent() || node->is_partially_dependent()) && + node->IsWeak() && f(isolate_->heap(), node->location())) { node->MarkPending(); } } @@ -517,7 +543,8 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { for (int i = 0; i < new_space_nodes_.length(); ++i) { Node* node = new_space_nodes_[i]; ASSERT(node->is_in_new_space_list()); - if (node->is_independent() && node->IsWeakRetainer()) { + if ((node->is_independent() || node->is_partially_dependent()) && + node->IsWeakRetainer()) { v->VisitPointer(node->location()); } } @@ -539,7 +566,10 @@ bool GlobalHandles::PostGarbageCollectionProcessing( // Skip dependent handles. Their weak callbacks might expect to be // called between two global garbage collection callbacks which // are not called for minor collections. - if (!node->is_independent()) continue; + if (!node->is_independent() && !node->is_partially_dependent()) { + continue; + } + node->clear_partially_dependent(); if (node->PostGarbageCollectionProcessing(isolate_, this)) { if (initial_post_gc_processing_count != post_gc_processing_count_) { // Weak callback triggered another GC and another round of @@ -555,6 +585,7 @@ bool GlobalHandles::PostGarbageCollectionProcessing( } } else { for (NodeIterator it(this); !it.done(); it.Advance()) { + it.node()->clear_partially_dependent(); if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) { if (initial_post_gc_processing_count != post_gc_processing_count_) { // See the comment above. @@ -602,7 +633,7 @@ void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { for (NodeIterator it(this); !it.done(); it.Advance()) { - if (it.node()->has_wrapper_class_id() && it.node()->IsRetainer()) { + if (it.node()->IsRetainer() && it.node()->has_wrapper_class_id()) { v->VisitEmbedderReference(it.node()->location(), it.node()->wrapper_class_id()); } |