Index: src/global-handles.cc |
diff --git a/src/global-handles.cc b/src/global-handles.cc |
index 25a5a0ba2426589d6070f28d5158bba0c255e1f7..82b4fcd0626228608d3004ff1f6b03b4bfe9d041 100644 |
--- a/src/global-handles.cc |
+++ b/src/global-handles.cc |
@@ -194,6 +194,16 @@ class GlobalHandles::Node { |
bool IsInUse() const { return state() != FREE; } |
+ bool IsPendingPhantomCallback() const { |
+ return state() == PENDING && |
+ (weakness_type() == PHANTOM_WEAK || |
+ weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); |
+ } |
+ |
+ bool IsPendingPhantomResetHandle() const { |
+ return state() == PENDING && weakness_type() == PHANTOM_WEAK_RESET_HANDLE; |
+ } |
+ |
bool IsRetainer() const { |
return state() != FREE && |
!(state() == NEAR_DEATH && weakness_type() != FINALIZER_WEAK); |
@@ -271,6 +281,15 @@ class GlobalHandles::Node { |
weak_callback_ = phantom_callback; |
} |
+ void MakeWeak(Object*** location_addr) { |
+ DCHECK(IsInUse()); |
+ CHECK_NE(object_, reinterpret_cast<Object*>(kGlobalHandleZapValue)); |
+ set_state(WEAK); |
+ set_weakness_type(PHANTOM_WEAK_RESET_HANDLE); |
+ set_parameter(location_addr); |
+ weak_callback_ = nullptr; |
+ } |
+ |
void* ClearWeakness() { |
DCHECK(IsInUse()); |
void* p = parameter(); |
@@ -285,6 +304,7 @@ class GlobalHandles::Node { |
DCHECK(weakness_type() == PHANTOM_WEAK || |
weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); |
DCHECK(state() == PENDING); |
+ DCHECK(weak_callback_ != nullptr); |
void* internal_fields[v8::kInternalFieldsInWeakCallback] = {nullptr, |
nullptr}; |
@@ -309,6 +329,15 @@ class GlobalHandles::Node { |
set_state(NEAR_DEATH); |
} |
+ void ResetPhantomHandle() { |
+ DCHECK(weakness_type() == PHANTOM_WEAK_RESET_HANDLE); |
+ DCHECK(state() == PENDING); |
+ DCHECK(weak_callback_ == nullptr); |
+ Object*** handle = reinterpret_cast<Object***>(parameter()); |
+ *handle = nullptr; |
+ Release(); |
+ } |
+ |
bool PostGarbageCollectionProcessing(Isolate* isolate) { |
// Handles only weak handles (not phantom) that are dying. |
if (state() != Node::PENDING) return false; |
@@ -540,7 +569,6 @@ class GlobalHandles::PendingPhantomCallbacksSecondPassTask |
DISALLOW_COPY_AND_ASSIGN(PendingPhantomCallbacksSecondPassTask); |
}; |
- |
GlobalHandles::GlobalHandles(Isolate* isolate) |
: isolate_(isolate), |
number_of_global_handles_(0), |
@@ -548,9 +576,9 @@ GlobalHandles::GlobalHandles(Isolate* isolate) |
first_used_block_(NULL), |
first_free_(NULL), |
post_gc_processing_count_(0), |
+ number_of_phantom_handle_resets_(0), |
object_group_connections_(kObjectGroupConnectionsCapacity) {} |
- |
GlobalHandles::~GlobalHandles() { |
NodeBlock* block = first_block_; |
while (block != NULL) { |
@@ -601,6 +629,9 @@ void GlobalHandles::MakeWeak(Object** location, void* parameter, |
Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type); |
} |
+void GlobalHandles::MakeWeak(Object*** location_addr) { |
+ Node::FromLocation(*location_addr)->MakeWeak(location_addr); |
+} |
void* GlobalHandles::ClearWeakness(Object** location) { |
return Node::FromLocation(location)->ClearWeakness(); |
@@ -636,8 +667,10 @@ void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { |
Node* node = it.node(); |
if (node->IsWeakRetainer()) { |
// Pending weak phantom handles die immediately. Everything else survives. |
- if (node->state() == Node::PENDING && |
- node->weakness_type() != FINALIZER_WEAK) { |
+ if (node->IsPendingPhantomResetHandle()) { |
+ node->ResetPhantomHandle(); |
+ ++number_of_phantom_handle_resets_; |
+ } else if (node->IsPendingPhantomCallback()) { |
node->CollectPhantomCallbackData(isolate(), |
&pending_phantom_callbacks_); |
} else { |
@@ -697,8 +730,10 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { |
if ((node->is_independent() || node->is_partially_dependent()) && |
node->IsWeakRetainer()) { |
// Pending weak phantom handles die immediately. Everything else survives. |
- if (node->state() == Node::PENDING && |
- node->weakness_type() != FINALIZER_WEAK) { |
+ if (node->IsPendingPhantomResetHandle()) { |
+ node->ResetPhantomHandle(); |
+ ++number_of_phantom_handle_resets_; |
+ } else if (node->IsPendingPhantomCallback()) { |
node->CollectPhantomCallbackData(isolate(), |
&pending_phantom_callbacks_); |
} else { |
@@ -740,8 +775,10 @@ void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) { |
if ((node->is_independent() || !node->is_active()) && |
node->IsWeakRetainer()) { |
// Pending weak phantom handles die immediately. Everything else survives. |
- if (node->state() == Node::PENDING && |
- node->weakness_type() != FINALIZER_WEAK) { |
+ if (node->IsPendingPhantomResetHandle()) { |
+ node->ResetPhantomHandle(); |
+ ++number_of_phantom_handle_resets_; |
+ } else if (node->IsPendingPhantomCallback()) { |
node->CollectPhantomCallbackData(isolate(), |
&pending_phantom_callbacks_); |
} else { |