Chromium Code Reviews| Index: src/global-handles.cc | 
| diff --git a/src/global-handles.cc b/src/global-handles.cc | 
| index 650999f394c5cc7c2e5397afff53c74e3c186d20..6aedfc1a6214c0144383303d241171bfdb410b8f 100644 | 
| --- a/src/global-handles.cc | 
| +++ b/src/global-handles.cc | 
| @@ -64,7 +64,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_unmodified(false); | 
| + } else { | 
| + set_partially_dependent(false); | 
| + } | 
| set_in_new_space_list(false); | 
| parameter_or_next_free_.next_free = NULL; | 
| weak_callback_ = NULL; | 
| @@ -77,6 +81,9 @@ class GlobalHandles::Node { | 
| set_state(FREE); | 
| set_weakness_type(NORMAL_WEAK); | 
| set_in_new_space_list(false); | 
| + if (FLAG_scavenge_reclaim_unmodified_objects) { | 
| + set_unmodified(false); | 
| + } | 
| parameter_or_next_free_.next_free = *first_free; | 
| *first_free = this; | 
| } | 
| @@ -86,7 +93,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_unmodified(false); | 
| + } else { | 
| + set_partially_dependent(false); | 
| + } | 
| set_state(NORMAL); | 
| parameter_or_next_free_.parameter = NULL; | 
| weak_callback_ = NULL; | 
| @@ -106,7 +117,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_unmodified(false); | 
| + } else { | 
| + set_partially_dependent(false); | 
| + } | 
| weak_callback_ = NULL; | 
| DecreaseBlockUses(); | 
| } | 
| @@ -140,12 +155,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_unmodified() { | 
| + CHECK(FLAG_scavenge_reclaim_unmodified_objects); | 
| + return IsUnModified::decode(flags_); | 
| + } | 
| + void set_unmodified(bool v) { | 
| + CHECK(FLAG_scavenge_reclaim_unmodified_objects); | 
| + flags_ = IsUnModified::update(flags_, v); | 
| + } | 
| + | 
| bool is_in_new_space_list() { | 
| return IsInNewSpaceList::decode(flags_); | 
| } | 
| @@ -349,6 +375,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 IsUnModified : 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,15 +674,22 @@ 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_unmodified())) { | 
| v->VisitPointer(node->location()); | 
| + } | 
| + } else { | 
| + if (node->IsStrongRetainer() || | 
| + (node->IsWeakRetainer() && !node->is_independent() && | 
| + !node->is_partially_dependent())) { | 
| + v->VisitPointer(node->location()); | 
| + } | 
| } | 
| } | 
| } | 
| - | 
| 
 
rmcilroy
2015/10/02 18:09:46
Add back missing newline (2 newlines between funct
 
 | 
| void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles( | 
| WeakSlotCallbackWithHeap f) { | 
| for (int i = 0; i < new_space_nodes_.length(); ++i) { | 
| @@ -687,6 +722,51 @@ 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()) { | 
| + if (is_unmodified(node->location())) { | 
| 
 
rmcilroy
2015/10/02 18:09:46
Nit - do both checks in the if above, I.e. - if (n
 
mythria
2015/10/05 10:55:34
Done.
 
 | 
| + node->set_unmodified(true); | 
| + } | 
| + } | 
| + } | 
| +} | 
| + | 
| + | 
| +void GlobalHandles::MarkNewSpaceWeakUnModifiedObjectsPending( | 
| 
 
rmcilroy
2015/10/02 18:09:46
Nit - replace UnModified with Unmodified (througho
 
mythria
2015/10/05 10:55:34
Done.
 
 | 
| + 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_unmodified()) && 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_unmodified()) && | 
| + 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(); | 
| @@ -760,10 +840,18 @@ int GlobalHandles::PostScavengeProcessing( | 
| // Skip dependent handles. Their weak callbacks might expect to be | 
| 
 
rmcilroy
2015/10/02 18:09:46
Nit, update comment (dependent or unmodified handl
 
mythria
2015/10/05 10:55:34
Done.
 
 | 
| // 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_unmodified()) { | 
| + continue; | 
| + } | 
| + node->set_unmodified(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_unmodified(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. |