| Index: src/global-handles.cc
|
| diff --git a/src/global-handles.cc b/src/global-handles.cc
|
| index c09ba4b476b97e8fc524bc4180c8017d72814167..59af2381dc5249c7d9678293c6e2ef63527c1007 100644
|
| --- a/src/global-handles.cc
|
| +++ b/src/global-handles.cc
|
| @@ -154,6 +154,14 @@ class GlobalHandles::Node {
|
| }
|
| bool is_independent() const { return independent_; }
|
|
|
| + void MarkExternallyUnreachable(GlobalHandles* global_handles) {
|
| + ASSERT(state_ != FREE);
|
| + if (global_handles->isolate()->heap()->InNewSpace(object_))
|
| + externally_unreachable_ = true;
|
| + }
|
| + bool is_externally_unreachable() const { return externally_unreachable_; }
|
| + bool clear_externally_unreachable() { externally_unreachable_ = 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 +268,7 @@ class GlobalHandles::Node {
|
| State state_ : 4;
|
|
|
| bool independent_ : 1;
|
| + bool externally_unreachable_ : 1;
|
| bool in_new_space_list_ : 1;
|
|
|
| // Handle specific callback.
|
| @@ -448,6 +457,11 @@ void GlobalHandles::MarkIndependent(Object** location) {
|
| }
|
|
|
|
|
| +void GlobalHandles::MarkExternallyUnreachable(Object** location) {
|
| + Node::FromLocation(location)->MarkExternallyUnreachable(this);
|
| +}
|
| +
|
| +
|
| bool GlobalHandles::IsIndependent(Object** location) {
|
| return Node::FromLocation(location)->is_independent();
|
| }
|
| @@ -501,8 +515,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_externally_unreachable())) {
|
| + v->VisitPointer(node->location());
|
| }
|
| }
|
| }
|
| @@ -513,8 +528,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_externally_unreachable()) &&
|
| + node->IsWeak() && f(isolate_->heap(), node->location())) {
|
| node->MarkPending();
|
| }
|
| }
|
| @@ -525,7 +540,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_externally_unreachable()) &&
|
| + node->IsWeakRetainer()) {
|
| v->VisitPointer(node->location());
|
| }
|
| }
|
| @@ -547,7 +563,8 @@ 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_externally_unreachable()) continue;
|
| + node->clear_externally_unreachable();
|
| 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 +580,7 @@ bool GlobalHandles::PostGarbageCollectionProcessing(
|
| }
|
| } else {
|
| for (NodeIterator it(this); !it.done(); it.Advance()) {
|
| + it.node()->clear_externally_unreachable();
|
| if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) {
|
| if (initial_post_gc_processing_count != post_gc_processing_count_) {
|
| // See the comment above.
|
|
|