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

Unified Diff: src/global-handles.cc

Issue 11085015: Allow collection of DOM objects in minor GC cycles. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Comments addressed Created 8 years, 2 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
Index: src/global-handles.cc
diff --git a/src/global-handles.cc b/src/global-handles.cc
index c09ba4b476b97e8fc524bc4180c8017d72814167..7be48751a0c14eda1ad5b2a38523097b17b4f0cb 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -69,6 +69,7 @@ class GlobalHandles::Node {
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
index_ = 0;
independent_ = false;
+ externally_unreachable_ = false;
in_new_space_list_ = false;
parameter_or_next_free_.next_free = NULL;
callback_ = NULL;
@@ -89,6 +90,7 @@ class GlobalHandles::Node {
object_ = object;
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
independent_ = false;
+ externally_unreachable_ = false;
state_ = NORMAL;
parameter_or_next_free_.parameter = NULL;
callback_ = NULL;
@@ -154,6 +156,14 @@ class GlobalHandles::Node {
}
bool is_independent() const { return independent_; }
+ void MarkExternallyUnreachable(GlobalHandles* global_handles) {
+ ASSERT(state_ != FREE);
+ if (global_handles->isolate()->heap()->InNewSpace(object_))
Michael Starzinger 2012/11/05 10:47:27 Put curly brackets around the body of this if-stat
haraken 2012/11/05 12:42:07 Done.
+ externally_unreachable_ = true;
+ }
+ bool is_externally_unreachable() const { return externally_unreachable_; }
+ bool clear_externally_unreachable() { externally_unreachable_ = false; }
+
// In-new-space-list flag accessors.
void set_in_new_space_list(bool v) { in_new_space_list_ = v; }
bool is_in_new_space_list() const { return in_new_space_list_; }
@@ -260,6 +270,7 @@ class GlobalHandles::Node {
State state_ : 4;
bool independent_ : 1;
+ bool externally_unreachable_ : 1;
bool in_new_space_list_ : 1;
// Handle specific callback.
@@ -448,6 +459,11 @@ void GlobalHandles::MarkIndependent(Object** location) {
}
+void GlobalHandles::MarkExternallyUnreachable(Object** location) {
+ Node::FromLocation(location)->MarkExternallyUnreachable(this);
+}
+
+
bool GlobalHandles::IsIndependent(Object** location) {
return Node::FromLocation(location)->is_independent();
}
@@ -501,8 +517,9 @@ void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
for (int i = 0; i < new_space_nodes_.length(); ++i) {
Node* node = new_space_nodes_[i];
if (node->IsStrongRetainer() ||
- (node->IsWeakRetainer() && !node->is_independent())) {
- v->VisitPointer(node->location());
+ (node->IsWeakRetainer() && !node->is_independent() &&
+ !node->is_externally_unreachable())) {
+ v->VisitPointer(node->location());
}
}
}
@@ -513,8 +530,8 @@ void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles(
for (int i = 0; i < new_space_nodes_.length(); ++i) {
Node* node = new_space_nodes_[i];
ASSERT(node->is_in_new_space_list());
- if (node->is_independent() && node->IsWeak() &&
- f(isolate_->heap(), node->location())) {
+ if ((node->is_independent() || node->is_externally_unreachable()) &&
+ node->IsWeak() && f(isolate_->heap(), node->location())) {
node->MarkPending();
}
}
@@ -525,7 +542,8 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
for (int i = 0; i < new_space_nodes_.length(); ++i) {
Node* node = new_space_nodes_[i];
ASSERT(node->is_in_new_space_list());
- if (node->is_independent() && node->IsWeakRetainer()) {
+ if ((node->is_independent() || node->is_externally_unreachable()) &&
+ node->IsWeakRetainer()) {
v->VisitPointer(node->location());
}
}
@@ -547,7 +565,10 @@ bool GlobalHandles::PostGarbageCollectionProcessing(
// 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 (!node->is_independent()) continue;
+ if (!node->is_independent() && !node->is_externally_unreachable()) {
+ continue;
+ }
+ node->clear_externally_unreachable();
if (node->PostGarbageCollectionProcessing(isolate_, this)) {
if (initial_post_gc_processing_count != post_gc_processing_count_) {
// Weak callback triggered another GC and another round of
@@ -563,6 +584,7 @@ bool GlobalHandles::PostGarbageCollectionProcessing(
}
} else {
for (NodeIterator it(this); !it.done(); it.Advance()) {
+ it.node()->clear_externally_unreachable();
if (it.node()->PostGarbageCollectionProcessing(isolate_, this)) {
if (initial_post_gc_processing_count != post_gc_processing_count_) {
// See the comment above.

Powered by Google App Engine
This is Rietveld 408576698