| Index: src/global-handles.cc
 | 
| diff --git a/src/global-handles.cc b/src/global-handles.cc
 | 
| index c4e8f131afa8e1d1c590c2f8643f662449ac1e7f..250f1276494c532d6f8834cb867ffeeed10b2bc5 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,7 +396,7 @@ 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
 | 
| @@ -392,6 +407,20 @@ void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +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) {
 | 
| +      v->VisitPointer(¤t->object_);
 | 
| +    }
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f,
 | 
|                                       WeakReferenceCallback callback) {
 | 
|    for (Node* current = head_; current != NULL; current = current->next()) {
 | 
| @@ -415,7 +444,21 @@ void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -bool GlobalHandles::PostGarbageCollectionProcessing() {
 | 
| +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(
 | 
| +    GarbageCollector collector) {
 | 
|    // Process weak global handle callbacks. This must be done after the
 | 
|    // GC is completely done, because the callbacks may invoke arbitrary
 | 
|    // API functions.
 | 
| @@ -425,6 +468,14 @@ bool GlobalHandles::PostGarbageCollectionProcessing() {
 | 
|    bool next_gc_likely_to_collect_more = false;
 | 
|    Node** p = &head_;
 | 
|    while (*p != NULL) {
 | 
| +    // 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 (collector == SCAVENGER && !(*p)->independent_) {
 | 
| +      p = (*p)->next_addr();
 | 
| +      continue;
 | 
| +    }
 | 
| +
 | 
|      if ((*p)->PostGarbageCollectionProcessing(isolate_, this)) {
 | 
|        if (initial_post_gc_processing_count != post_gc_processing_count_) {
 | 
|          // Weak callback triggered another GC and another round of
 | 
| @@ -476,6 +527,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 &&
 | 
| 
 |