Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Unified Diff: src/global-handles.cc

Issue 7043003: Version 3.3.8 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/global-handles.h ('k') | src/handles.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(&current->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(), &current->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(&current->object_);
+ }
+ }
+}
+
+
void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) {
for (Node* current = head_; current != NULL; current = current->next()) {
if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId &&
« no previous file with comments | « src/global-handles.h ('k') | src/handles.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698