Chromium Code Reviews| Index: src/global-handles.cc |
| diff --git a/src/global-handles.cc b/src/global-handles.cc |
| index c09ba4b476b97e8fc524bc4180c8017d72814167..4629f988c50aa2137b14e272f81197f261fd0fd6 100644 |
| --- a/src/global-handles.cc |
| +++ b/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_; } |
| + bool clear_partially_dependent() { partially_dependent_ = false; } |
|
Michael Starzinger
2012/11/06 17:33:16
Had to change the return type of this method to vo
|
| + |
| // 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,11 @@ 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(); |
| } |
| @@ -501,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()); |
| } |
| } |
| } |
| @@ -513,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(); |
| } |
| } |
| @@ -525,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()); |
| } |
| } |
| @@ -547,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 |
| @@ -563,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. |