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

Unified Diff: src/global-handles.cc

Issue 1410593005: Adds a scavenge GC pass to collect unmodified references (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Forgot a fix in the last patch Created 5 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
« no previous file with comments | « src/global-handles.h ('k') | src/heap/heap.cc » ('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 650999f394c5cc7c2e5397afff53c74e3c186d20..3608fe81b684df8894e106169d82b71d01340c58 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -54,6 +54,8 @@ class GlobalHandles::Node {
Internals::kNodeIsIndependentShift);
STATIC_ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
Internals::kNodeIsPartiallyDependentShift);
+ STATIC_ASSERT(static_cast<int>(IsActive::kShift) ==
+ Internals::kNodeIsActiveShift);
}
#ifdef ENABLE_HANDLE_ZAPPING
@@ -64,7 +66,11 @@ class GlobalHandles::Node {
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
index_ = 0;
set_independent(false);
- set_partially_dependent(false);
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ set_active(false);
+ } else {
+ set_partially_dependent(false);
+ }
set_in_new_space_list(false);
parameter_or_next_free_.next_free = NULL;
weak_callback_ = NULL;
@@ -86,7 +92,11 @@ class GlobalHandles::Node {
object_ = object;
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
set_independent(false);
- set_partially_dependent(false);
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ set_active(false);
+ } else {
+ set_partially_dependent(false);
+ }
set_state(NORMAL);
parameter_or_next_free_.parameter = NULL;
weak_callback_ = NULL;
@@ -106,7 +116,11 @@ class GlobalHandles::Node {
object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
set_independent(false);
- set_partially_dependent(false);
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ set_active(false);
+ } else {
+ set_partially_dependent(false);
+ }
weak_callback_ = NULL;
DecreaseBlockUses();
}
@@ -140,12 +154,23 @@ class GlobalHandles::Node {
}
bool is_partially_dependent() {
+ CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
return IsPartiallyDependent::decode(flags_);
}
void set_partially_dependent(bool v) {
+ CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
flags_ = IsPartiallyDependent::update(flags_, v);
}
+ bool is_active() {
+ CHECK(FLAG_scavenge_reclaim_unmodified_objects);
+ return IsActive::decode(flags_);
+ }
+ void set_active(bool v) {
+ CHECK(FLAG_scavenge_reclaim_unmodified_objects);
+ flags_ = IsActive::update(flags_, v);
+ }
+
bool is_in_new_space_list() {
return IsInNewSpaceList::decode(flags_);
}
@@ -349,6 +374,8 @@ class GlobalHandles::Node {
// in_new_space_list) and a State.
class NodeState : public BitField<State, 0, 3> {};
class IsIndependent : public BitField<bool, 3, 1> {};
+ // The following two fields are mutually exclusive
+ class IsActive : public BitField<bool, 4, 1> {};
class IsPartiallyDependent : public BitField<bool, 4, 1> {};
class IsInNewSpaceList : public BitField<bool, 5, 1> {};
class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
@@ -646,10 +673,18 @@ void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
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() &&
- !node->is_partially_dependent())) {
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ if (node->IsStrongRetainer() ||
+ (node->IsWeakRetainer() && !node->is_independent() &&
+ node->is_active())) {
+ v->VisitPointer(node->location());
+ }
+ } else {
+ if (node->IsStrongRetainer() ||
+ (node->IsWeakRetainer() && !node->is_independent() &&
+ !node->is_partially_dependent())) {
v->VisitPointer(node->location());
+ }
}
}
}
@@ -687,6 +722,49 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
}
+void GlobalHandles::IdentifyWeakUnmodifiedObjects(
+ WeakSlotCallback is_unmodified) {
+ for (int i = 0; i < new_space_nodes_.length(); ++i) {
+ Node* node = new_space_nodes_[i];
+ if (node->IsWeak() && !is_unmodified(node->location())) {
+ node->set_active(true);
+ }
+ }
+}
+
+
+void GlobalHandles::MarkNewSpaceWeakUnmodifiedObjectsPending(
+ WeakSlotCallbackWithHeap is_unscavenged) {
+ for (int i = 0; i < new_space_nodes_.length(); ++i) {
+ Node* node = new_space_nodes_[i];
+ DCHECK(node->is_in_new_space_list());
+ if ((node->is_independent() || !node->is_active()) && node->IsWeak() &&
+ is_unscavenged(isolate_->heap(), node->location())) {
+ node->MarkPending();
+ }
+ }
+}
+
+
+void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) {
+ for (int i = 0; i < new_space_nodes_.length(); ++i) {
+ Node* node = new_space_nodes_[i];
+ DCHECK(node->is_in_new_space_list());
+ if ((node->is_independent() || !node->is_active()) &&
+ node->IsWeakRetainer()) {
+ // Pending weak phantom handles die immediately. Everything else survives.
+ if (node->state() == Node::PENDING &&
+ node->weakness_type() != NORMAL_WEAK) {
+ node->CollectPhantomCallbackData(isolate(),
+ &pending_phantom_callbacks_);
+ } else {
+ v->VisitPointer(node->location());
+ }
+ }
+ }
+}
+
+
bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
WeakSlotCallbackWithHeap can_skip) {
ComputeObjectGroupsAndImplicitReferences();
@@ -757,13 +835,23 @@ int GlobalHandles::PostScavengeProcessing(
// the freed_nodes.
continue;
}
- // Skip dependent handles. Their weak callbacks might expect to be
+ // Skip dependent or unmodified 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() && !node->is_partially_dependent()) {
- continue;
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ if (!node->is_independent() && (node->is_active())) {
+ node->set_active(false);
+ continue;
+ }
+ node->set_active(false);
+ } else {
+ if (!node->is_independent() && !node->is_partially_dependent()) {
+ continue;
+ }
+ node->clear_partially_dependent();
}
- node->clear_partially_dependent();
+
if (node->PostGarbageCollectionProcessing(isolate_)) {
if (initial_post_gc_processing_count != post_gc_processing_count_) {
// Weak callback triggered another GC and another round of
@@ -790,7 +878,11 @@ int GlobalHandles::PostMarkSweepProcessing(
// the freed_nodes.
continue;
}
- it.node()->clear_partially_dependent();
+ if (FLAG_scavenge_reclaim_unmodified_objects) {
+ it.node()->set_active(false);
+ } else {
+ it.node()->clear_partially_dependent();
+ }
if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
if (initial_post_gc_processing_count != post_gc_processing_count_) {
// See the comment above.
@@ -955,6 +1047,16 @@ void GlobalHandles::IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v) {
}
+void GlobalHandles::IterateWeakRootsInNewSpaceWithClassIds(ObjectVisitor* v) {
+ for (int i = 0; i < new_space_nodes_.length(); ++i) {
+ Node* node = new_space_nodes_[i];
+ if (node->has_wrapper_class_id() && node->IsWeak()) {
+ v->VisitEmbedderReference(node->location(), node->wrapper_class_id());
+ }
+ }
+}
+
+
int GlobalHandles::NumberOfWeakHandles() {
int count = 0;
for (NodeIterator it(this); !it.done(); it.Advance()) {
« no previous file with comments | « src/global-handles.h ('k') | src/heap/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698