| Index: src/global-handles.cc
|
| diff --git a/src/global-handles.cc b/src/global-handles.cc
|
| index c4e8f131afa8e1d1c590c2f8643f662449ac1e7f..249f40ff140ddfb576436a5db910e61d29268c8a 100644
|
| --- a/src/global-handles.cc
|
| +++ b/src/global-handles.cc
|
| @@ -48,6 +48,7 @@ class GlobalHandles::Node : public Malloced {
|
| // Set the initial value of the handle.
|
| object_ = object;
|
| class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
|
| + independent_ = false;
|
| state_ = NORMAL;
|
| parameter_or_next_free_.parameter = NULL;
|
| callback_ = NULL;
|
| @@ -138,6 +139,13 @@ class GlobalHandles::Node : public Malloced {
|
| set_parameter(NULL);
|
| }
|
|
|
| + void MarkIndependent(GlobalHandles* global_handles) {
|
| + LOG(global_handles->isolate(),
|
| + HandleEvent("GlobalHandle::MarkIndependent", handle().location()));
|
| + ASSERT(state_ != DESTROYED);
|
| + independent_ = true;
|
| + }
|
| +
|
| bool IsNearDeath() {
|
| // Check for PENDING to ensure correct answer when processing callbacks.
|
| return state_ == PENDING || state_ == NEAR_DEATH;
|
| @@ -222,6 +230,8 @@ class GlobalHandles::Node : public Malloced {
|
| };
|
| State state_ : 4; // Need one more bit for MSVC as it treats enums as signed.
|
|
|
| + bool independent_ : 1;
|
| +
|
| private:
|
| // Handle specific callback.
|
| WeakReferenceCallback callback_;
|
| @@ -364,6 +374,11 @@ void GlobalHandles::ClearWeakness(Object** location) {
|
| }
|
|
|
|
|
| +void GlobalHandles::MarkIndependent(Object** location) {
|
| + Node::FromLocation(location)->MarkIndependent(this);
|
| +}
|
| +
|
| +
|
| bool GlobalHandles::IsNearDeath(Object** location) {
|
| return Node::FromLocation(location)->IsNearDeath();
|
| }
|
| @@ -381,8 +396,22 @@ void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) {
|
|
|
| void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
|
| // Traversal of GC roots in the global handle list that are marked as
|
| - // WEAK or PENDING.
|
| + // WEAK, PENDING or NEAR_DEATH.
|
| + for (Node* current = head_; current != NULL; current = current->next()) {
|
| + if (current->state_ == Node::WEAK
|
| + || current->state_ == Node::PENDING
|
| + || current->state_ == Node::NEAR_DEATH) {
|
| + v->VisitPointer(¤t->object_);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +void GlobalHandles::IterateWeakIndependentRoots(ObjectVisitor* v) {
|
| + // Traversal of GC roots in the global handle list that are independent
|
| + // and marked as WEAK, PENDING or NEAR_DEATH.
|
| for (Node* current = head_; current != NULL; current = current->next()) {
|
| + if (!current->independent_) continue;
|
| if (current->state_ == Node::WEAK
|
| || current->state_ == Node::PENDING
|
| || current->state_ == Node::NEAR_DEATH) {
|
| @@ -415,6 +444,19 @@ void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
|
| }
|
|
|
|
|
| +void GlobalHandles::IdentifyWeakIndependentHandles(WeakSlotCallbackWithHeap f) {
|
| + for (Node* current = head_; current != NULL; current = current->next()) {
|
| + if (current->state_ == Node::WEAK && current->independent_) {
|
| + if (f(isolate_->heap(), ¤t->object_)) {
|
| + current->state_ = Node::PENDING;
|
| + LOG(isolate_,
|
| + HandleEvent("GlobalHandle::Pending", current->handle().location()));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| bool GlobalHandles::PostGarbageCollectionProcessing() {
|
| // Process weak global handle callbacks. This must be done after the
|
| // GC is completely done, because the callbacks may invoke arbitrary
|
| @@ -476,6 +518,16 @@ void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
|
| }
|
|
|
|
|
| +void GlobalHandles::IterateStrongAndDependentRoots(ObjectVisitor* v) {
|
| + for (Node* current = head_; current != NULL; current = current->next()) {
|
| + if ((current->independent_ && current->state_ == Node::NORMAL) ||
|
| + (!current->independent_ && current->state_ != Node::DESTROYED)) {
|
| + v->VisitPointer(¤t->object_);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) {
|
| for (Node* current = head_; current != NULL; current = current->next()) {
|
| if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId &&
|
|
|