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

Side by Side Diff: src/global-handles.cc

Issue 1388133002: Revert of Changed scavenge GC to collect unmodified references (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « src/global-handles.h ('k') | src/heap/heap.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/global-handles.h" 5 #include "src/global-handles.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/v8.h" 8 #include "src/v8.h"
9 #include "src/vm-state-inl.h" 9 #include "src/vm-state-inl.h"
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 } 57 }
58 58
59 #ifdef ENABLE_HANDLE_ZAPPING 59 #ifdef ENABLE_HANDLE_ZAPPING
60 ~Node() { 60 ~Node() {
61 // TODO(1428): if it's a weak handle we should have invoked its callback. 61 // TODO(1428): if it's a weak handle we should have invoked its callback.
62 // Zap the values for eager trapping. 62 // Zap the values for eager trapping.
63 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 63 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
64 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 64 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
65 index_ = 0; 65 index_ = 0;
66 set_independent(false); 66 set_independent(false);
67 if (FLAG_scavenge_reclaim_unmodified_objects) { 67 set_partially_dependent(false);
68 set_unmodified(false);
69 } else {
70 set_partially_dependent(false);
71 }
72 set_in_new_space_list(false); 68 set_in_new_space_list(false);
73 parameter_or_next_free_.next_free = NULL; 69 parameter_or_next_free_.next_free = NULL;
74 weak_callback_ = NULL; 70 weak_callback_ = NULL;
75 } 71 }
76 #endif 72 #endif
77 73
78 void Initialize(int index, Node** first_free) { 74 void Initialize(int index, Node** first_free) {
79 index_ = static_cast<uint8_t>(index); 75 index_ = static_cast<uint8_t>(index);
80 DCHECK(static_cast<int>(index_) == index); 76 DCHECK(static_cast<int>(index_) == index);
81 set_state(FREE); 77 set_state(FREE);
82 set_weakness_type(NORMAL_WEAK); 78 set_weakness_type(NORMAL_WEAK);
83 set_in_new_space_list(false); 79 set_in_new_space_list(false);
84 if (FLAG_scavenge_reclaim_unmodified_objects) {
85 set_unmodified(false);
86 }
87 parameter_or_next_free_.next_free = *first_free; 80 parameter_or_next_free_.next_free = *first_free;
88 *first_free = this; 81 *first_free = this;
89 } 82 }
90 83
91 void Acquire(Object* object) { 84 void Acquire(Object* object) {
92 DCHECK(state() == FREE); 85 DCHECK(state() == FREE);
93 object_ = object; 86 object_ = object;
94 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 87 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
95 set_independent(false); 88 set_independent(false);
96 if (FLAG_scavenge_reclaim_unmodified_objects) { 89 set_partially_dependent(false);
97 set_unmodified(false);
98 } else {
99 set_partially_dependent(false);
100 }
101 set_state(NORMAL); 90 set_state(NORMAL);
102 parameter_or_next_free_.parameter = NULL; 91 parameter_or_next_free_.parameter = NULL;
103 weak_callback_ = NULL; 92 weak_callback_ = NULL;
104 IncreaseBlockUses(); 93 IncreaseBlockUses();
105 } 94 }
106 95
107 void Zap() { 96 void Zap() {
108 DCHECK(IsInUse()); 97 DCHECK(IsInUse());
109 // Zap the values for eager trapping. 98 // Zap the values for eager trapping.
110 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 99 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
111 } 100 }
112 101
113 void Release() { 102 void Release() {
114 DCHECK(IsInUse()); 103 DCHECK(IsInUse());
115 set_state(FREE); 104 set_state(FREE);
116 // Zap the values for eager trapping. 105 // Zap the values for eager trapping.
117 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 106 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
118 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 107 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
119 set_independent(false); 108 set_independent(false);
120 if (FLAG_scavenge_reclaim_unmodified_objects) { 109 set_partially_dependent(false);
121 set_unmodified(false);
122 } else {
123 set_partially_dependent(false);
124 }
125 weak_callback_ = NULL; 110 weak_callback_ = NULL;
126 DecreaseBlockUses(); 111 DecreaseBlockUses();
127 } 112 }
128 113
129 // Object slot accessors. 114 // Object slot accessors.
130 Object* object() const { return object_; } 115 Object* object() const { return object_; }
131 Object** location() { return &object_; } 116 Object** location() { return &object_; }
132 Handle<Object> handle() { return Handle<Object>(location()); } 117 Handle<Object> handle() { return Handle<Object>(location()); }
133 118
134 // Wrapper class ID accessors. 119 // Wrapper class ID accessors.
(...skipping 13 matching lines...) Expand all
148 } 133 }
149 134
150 bool is_independent() { 135 bool is_independent() {
151 return IsIndependent::decode(flags_); 136 return IsIndependent::decode(flags_);
152 } 137 }
153 void set_independent(bool v) { 138 void set_independent(bool v) {
154 flags_ = IsIndependent::update(flags_, v); 139 flags_ = IsIndependent::update(flags_, v);
155 } 140 }
156 141
157 bool is_partially_dependent() { 142 bool is_partially_dependent() {
158 CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
159 return IsPartiallyDependent::decode(flags_); 143 return IsPartiallyDependent::decode(flags_);
160 } 144 }
161 void set_partially_dependent(bool v) { 145 void set_partially_dependent(bool v) {
162 CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
163 flags_ = IsPartiallyDependent::update(flags_, v); 146 flags_ = IsPartiallyDependent::update(flags_, v);
164 } 147 }
165 148
166 bool is_unmodified() {
167 CHECK(FLAG_scavenge_reclaim_unmodified_objects);
168 return IsUnmodified::decode(flags_);
169 }
170 void set_unmodified(bool v) {
171 CHECK(FLAG_scavenge_reclaim_unmodified_objects);
172 flags_ = IsUnmodified::update(flags_, v);
173 }
174
175 bool is_in_new_space_list() { 149 bool is_in_new_space_list() {
176 return IsInNewSpaceList::decode(flags_); 150 return IsInNewSpaceList::decode(flags_);
177 } 151 }
178 void set_in_new_space_list(bool v) { 152 void set_in_new_space_list(bool v) {
179 flags_ = IsInNewSpaceList::update(flags_, v); 153 flags_ = IsInNewSpaceList::update(flags_, v);
180 } 154 }
181 155
182 WeaknessType weakness_type() const { 156 WeaknessType weakness_type() const {
183 return NodeWeaknessType::decode(flags_); 157 return NodeWeaknessType::decode(flags_);
184 } 158 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // Wrapper class ID. 342 // Wrapper class ID.
369 uint16_t class_id_; 343 uint16_t class_id_;
370 344
371 // Index in the containing handle block. 345 // Index in the containing handle block.
372 uint8_t index_; 346 uint8_t index_;
373 347
374 // This stores three flags (independent, partially_dependent and 348 // This stores three flags (independent, partially_dependent and
375 // in_new_space_list) and a State. 349 // in_new_space_list) and a State.
376 class NodeState : public BitField<State, 0, 3> {}; 350 class NodeState : public BitField<State, 0, 3> {};
377 class IsIndependent : public BitField<bool, 3, 1> {}; 351 class IsIndependent : public BitField<bool, 3, 1> {};
378 // The following two fields are mutually exclusive
379 class IsUnmodified : public BitField<bool, 4, 1> {};
380 class IsPartiallyDependent : public BitField<bool, 4, 1> {}; 352 class IsPartiallyDependent : public BitField<bool, 4, 1> {};
381 class IsInNewSpaceList : public BitField<bool, 5, 1> {}; 353 class IsInNewSpaceList : public BitField<bool, 5, 1> {};
382 class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {}; 354 class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
383 355
384 uint8_t flags_; 356 uint8_t flags_;
385 357
386 // Handle specific callback - might be a weak reference in disguise. 358 // Handle specific callback - might be a weak reference in disguise.
387 WeakCallback weak_callback_; 359 WeakCallback weak_callback_;
388 360
389 // Provided data for callback. In FREE state, this is used for 361 // Provided data for callback. In FREE state, this is used for
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 if (it.node()->IsWeak() && f(it.node()->location())) { 639 if (it.node()->IsWeak() && f(it.node()->location())) {
668 it.node()->MarkPending(); 640 it.node()->MarkPending();
669 } 641 }
670 } 642 }
671 } 643 }
672 644
673 645
674 void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) { 646 void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
675 for (int i = 0; i < new_space_nodes_.length(); ++i) { 647 for (int i = 0; i < new_space_nodes_.length(); ++i) {
676 Node* node = new_space_nodes_[i]; 648 Node* node = new_space_nodes_[i];
677 if (FLAG_scavenge_reclaim_unmodified_objects) { 649 if (node->IsStrongRetainer() ||
678 if (node->IsStrongRetainer() || 650 (node->IsWeakRetainer() && !node->is_independent() &&
679 (node->IsWeakRetainer() && !node->is_independent() && 651 !node->is_partially_dependent())) {
680 !node->is_unmodified())) {
681 v->VisitPointer(node->location()); 652 v->VisitPointer(node->location());
682 }
683 } else {
684 if (node->IsStrongRetainer() ||
685 (node->IsWeakRetainer() && !node->is_independent() &&
686 !node->is_partially_dependent())) {
687 v->VisitPointer(node->location());
688 }
689 } 653 }
690 } 654 }
691 } 655 }
692 656
693 657
694 void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles( 658 void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles(
695 WeakSlotCallbackWithHeap f) { 659 WeakSlotCallbackWithHeap f) {
696 for (int i = 0; i < new_space_nodes_.length(); ++i) { 660 for (int i = 0; i < new_space_nodes_.length(); ++i) {
697 Node* node = new_space_nodes_[i]; 661 Node* node = new_space_nodes_[i];
698 DCHECK(node->is_in_new_space_list()); 662 DCHECK(node->is_in_new_space_list());
(...skipping 17 matching lines...) Expand all
716 node->CollectPhantomCallbackData(isolate(), 680 node->CollectPhantomCallbackData(isolate(),
717 &pending_phantom_callbacks_); 681 &pending_phantom_callbacks_);
718 } else { 682 } else {
719 v->VisitPointer(node->location()); 683 v->VisitPointer(node->location());
720 } 684 }
721 } 685 }
722 } 686 }
723 } 687 }
724 688
725 689
726 void GlobalHandles::IdentifyWeakUnmodifiedObjects(
727 WeakSlotCallback is_unmodified) {
728 for (int i = 0; i < new_space_nodes_.length(); ++i) {
729 Node* node = new_space_nodes_[i];
730 if (node->IsWeak() && is_unmodified(node->location())) {
731 node->set_unmodified(true);
732 }
733 }
734 }
735
736
737 void GlobalHandles::MarkNewSpaceWeakUnmodifiedObjectsPending(
738 WeakSlotCallbackWithHeap is_unscavenged) {
739 for (int i = 0; i < new_space_nodes_.length(); ++i) {
740 Node* node = new_space_nodes_[i];
741 DCHECK(node->is_in_new_space_list());
742 if ((node->is_independent() || node->is_unmodified()) && node->IsWeak() &&
743 is_unscavenged(isolate_->heap(), node->location())) {
744 node->MarkPending();
745 }
746 }
747 }
748
749
750 void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) {
751 for (int i = 0; i < new_space_nodes_.length(); ++i) {
752 Node* node = new_space_nodes_[i];
753 DCHECK(node->is_in_new_space_list());
754 if ((node->is_independent() || node->is_unmodified()) &&
755 node->IsWeakRetainer()) {
756 // Pending weak phantom handles die immediately. Everything else survives.
757 if (node->state() == Node::PENDING &&
758 node->weakness_type() != NORMAL_WEAK) {
759 node->CollectPhantomCallbackData(isolate(),
760 &pending_phantom_callbacks_);
761 } else {
762 v->VisitPointer(node->location());
763 }
764 }
765 }
766 }
767
768
769 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 690 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
770 WeakSlotCallbackWithHeap can_skip) { 691 WeakSlotCallbackWithHeap can_skip) {
771 ComputeObjectGroupsAndImplicitReferences(); 692 ComputeObjectGroupsAndImplicitReferences();
772 int last = 0; 693 int last = 0;
773 bool any_group_was_visited = false; 694 bool any_group_was_visited = false;
774 for (int i = 0; i < object_groups_.length(); i++) { 695 for (int i = 0; i < object_groups_.length(); i++) {
775 ObjectGroup* entry = object_groups_.at(i); 696 ObjectGroup* entry = object_groups_.at(i);
776 DCHECK(entry != NULL); 697 DCHECK(entry != NULL);
777 698
778 Object*** objects = entry->objects; 699 Object*** objects = entry->objects;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 const int initial_post_gc_processing_count) { 750 const int initial_post_gc_processing_count) {
830 int freed_nodes = 0; 751 int freed_nodes = 0;
831 for (int i = 0; i < new_space_nodes_.length(); ++i) { 752 for (int i = 0; i < new_space_nodes_.length(); ++i) {
832 Node* node = new_space_nodes_[i]; 753 Node* node = new_space_nodes_[i];
833 DCHECK(node->is_in_new_space_list()); 754 DCHECK(node->is_in_new_space_list());
834 if (!node->IsRetainer()) { 755 if (!node->IsRetainer()) {
835 // Free nodes do not have weak callbacks. Do not use them to compute 756 // Free nodes do not have weak callbacks. Do not use them to compute
836 // the freed_nodes. 757 // the freed_nodes.
837 continue; 758 continue;
838 } 759 }
839 // Skip dependent or unmodified handles. Their weak callbacks might expect 760 // Skip dependent handles. Their weak callbacks might expect to be
840 // to be
841 // called between two global garbage collection callbacks which 761 // called between two global garbage collection callbacks which
842 // are not called for minor collections. 762 // are not called for minor collections.
843 if (FLAG_scavenge_reclaim_unmodified_objects) { 763 if (!node->is_independent() && !node->is_partially_dependent()) {
844 if (!node->is_independent() && !node->is_unmodified()) { 764 continue;
845 continue;
846 }
847 node->set_unmodified(false);
848 } else {
849 if (!node->is_independent() && !node->is_partially_dependent()) {
850 continue;
851 }
852 node->clear_partially_dependent();
853 } 765 }
854 766 node->clear_partially_dependent();
855 if (node->PostGarbageCollectionProcessing(isolate_)) { 767 if (node->PostGarbageCollectionProcessing(isolate_)) {
856 if (initial_post_gc_processing_count != post_gc_processing_count_) { 768 if (initial_post_gc_processing_count != post_gc_processing_count_) {
857 // Weak callback triggered another GC and another round of 769 // Weak callback triggered another GC and another round of
858 // PostGarbageCollection processing. The current node might 770 // PostGarbageCollection processing. The current node might
859 // have been deleted in that round, so we need to bail out (or 771 // have been deleted in that round, so we need to bail out (or
860 // restart the processing). 772 // restart the processing).
861 return freed_nodes; 773 return freed_nodes;
862 } 774 }
863 } 775 }
864 if (!node->IsRetainer()) { 776 if (!node->IsRetainer()) {
865 freed_nodes++; 777 freed_nodes++;
866 } 778 }
867 } 779 }
868 return freed_nodes; 780 return freed_nodes;
869 } 781 }
870 782
871 783
872 int GlobalHandles::PostMarkSweepProcessing( 784 int GlobalHandles::PostMarkSweepProcessing(
873 const int initial_post_gc_processing_count) { 785 const int initial_post_gc_processing_count) {
874 int freed_nodes = 0; 786 int freed_nodes = 0;
875 for (NodeIterator it(this); !it.done(); it.Advance()) { 787 for (NodeIterator it(this); !it.done(); it.Advance()) {
876 if (!it.node()->IsRetainer()) { 788 if (!it.node()->IsRetainer()) {
877 // Free nodes do not have weak callbacks. Do not use them to compute 789 // Free nodes do not have weak callbacks. Do not use them to compute
878 // the freed_nodes. 790 // the freed_nodes.
879 continue; 791 continue;
880 } 792 }
881 if (FLAG_scavenge_reclaim_unmodified_objects) { 793 it.node()->clear_partially_dependent();
882 it.node()->set_unmodified(false);
883 } else {
884 it.node()->clear_partially_dependent();
885 }
886 if (it.node()->PostGarbageCollectionProcessing(isolate_)) { 794 if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
887 if (initial_post_gc_processing_count != post_gc_processing_count_) { 795 if (initial_post_gc_processing_count != post_gc_processing_count_) {
888 // See the comment above. 796 // See the comment above.
889 return freed_nodes; 797 return freed_nodes;
890 } 798 }
891 } 799 }
892 if (!it.node()->IsRetainer()) { 800 if (!it.node()->IsRetainer()) {
893 freed_nodes++; 801 freed_nodes++;
894 } 802 }
895 } 803 }
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 blocks_[block][offset] = object; 1274 blocks_[block][offset] = object;
1367 if (isolate->heap()->InNewSpace(object)) { 1275 if (isolate->heap()->InNewSpace(object)) {
1368 new_space_indices_.Add(size_); 1276 new_space_indices_.Add(size_);
1369 } 1277 }
1370 *index = size_++; 1278 *index = size_++;
1371 } 1279 }
1372 1280
1373 1281
1374 } // namespace internal 1282 } // namespace internal
1375 } // namespace v8 1283 } // namespace v8
OLDNEW
« 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