Index: src/global-handles.cc |
diff --git a/src/global-handles.cc b/src/global-handles.cc |
index c4e8f131afa8e1d1c590c2f8643f662449ac1e7f..3485f3ef3ef92fab794bc7ff5e39aa4143a296c3 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(); |
} |
@@ -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 marked as |
+ // WEAK or PENDING. |
antonm
2011/05/16 14:13:19
comment is wrong.
Vyacheslav Egorov (Chromium)
2011/05/16 14:55:34
Thanks! Will fix.
|
+ 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,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 && |