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

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

Issue 2486173002: [api] Remove marking persistents as partially dependent (Closed)
Patch Set: Addressed comments Created 4 years, 1 month 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/gc-tracer.h » ('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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 Node() { 45 Node() {
46 DCHECK(offsetof(Node, class_id_) == Internals::kNodeClassIdOffset); 46 DCHECK(offsetof(Node, class_id_) == Internals::kNodeClassIdOffset);
47 DCHECK(offsetof(Node, flags_) == Internals::kNodeFlagsOffset); 47 DCHECK(offsetof(Node, flags_) == Internals::kNodeFlagsOffset);
48 STATIC_ASSERT(static_cast<int>(NodeState::kMask) == 48 STATIC_ASSERT(static_cast<int>(NodeState::kMask) ==
49 Internals::kNodeStateMask); 49 Internals::kNodeStateMask);
50 STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue); 50 STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue);
51 STATIC_ASSERT(PENDING == Internals::kNodeStateIsPendingValue); 51 STATIC_ASSERT(PENDING == Internals::kNodeStateIsPendingValue);
52 STATIC_ASSERT(NEAR_DEATH == Internals::kNodeStateIsNearDeathValue); 52 STATIC_ASSERT(NEAR_DEATH == Internals::kNodeStateIsNearDeathValue);
53 STATIC_ASSERT(static_cast<int>(IsIndependent::kShift) == 53 STATIC_ASSERT(static_cast<int>(IsIndependent::kShift) ==
54 Internals::kNodeIsIndependentShift); 54 Internals::kNodeIsIndependentShift);
55 STATIC_ASSERT(static_cast<int>(IsPartiallyDependent::kShift) ==
56 Internals::kNodeIsPartiallyDependentShift);
57 STATIC_ASSERT(static_cast<int>(IsActive::kShift) == 55 STATIC_ASSERT(static_cast<int>(IsActive::kShift) ==
58 Internals::kNodeIsActiveShift); 56 Internals::kNodeIsActiveShift);
59 } 57 }
60 58
61 #ifdef ENABLE_HANDLE_ZAPPING 59 #ifdef ENABLE_HANDLE_ZAPPING
62 ~Node() { 60 ~Node() {
63 // 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.
64 // Zap the values for eager trapping. 62 // Zap the values for eager trapping.
65 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 63 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
66 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 64 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
67 index_ = 0; 65 index_ = 0;
68 set_independent(false); 66 set_independent(false);
69 if (FLAG_scavenge_reclaim_unmodified_objects) { 67 set_active(false);
70 set_active(false);
71 } else {
72 set_partially_dependent(false);
73 }
74 set_in_new_space_list(false); 68 set_in_new_space_list(false);
75 parameter_or_next_free_.next_free = NULL; 69 parameter_or_next_free_.next_free = NULL;
76 weak_callback_ = NULL; 70 weak_callback_ = NULL;
77 } 71 }
78 #endif 72 #endif
79 73
80 void Initialize(int index, Node** first_free) { 74 void Initialize(int index, Node** first_free) {
81 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 75 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
82 index_ = static_cast<uint8_t>(index); 76 index_ = static_cast<uint8_t>(index);
83 DCHECK(static_cast<int>(index_) == index); 77 DCHECK(static_cast<int>(index_) == index);
84 set_state(FREE); 78 set_state(FREE);
85 set_in_new_space_list(false); 79 set_in_new_space_list(false);
86 parameter_or_next_free_.next_free = *first_free; 80 parameter_or_next_free_.next_free = *first_free;
87 *first_free = this; 81 *first_free = this;
88 } 82 }
89 83
90 void Acquire(Object* object) { 84 void Acquire(Object* object) {
91 DCHECK(state() == FREE); 85 DCHECK(state() == FREE);
92 object_ = object; 86 object_ = object;
93 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 87 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
94 set_independent(false); 88 set_independent(false);
95 if (FLAG_scavenge_reclaim_unmodified_objects) { 89 set_active(false);
96 set_active(false);
97 } else {
98 set_partially_dependent(false);
99 }
100 set_state(NORMAL); 90 set_state(NORMAL);
101 parameter_or_next_free_.parameter = NULL; 91 parameter_or_next_free_.parameter = NULL;
102 weak_callback_ = NULL; 92 weak_callback_ = NULL;
103 IncreaseBlockUses(); 93 IncreaseBlockUses();
104 } 94 }
105 95
106 void Zap() { 96 void Zap() {
107 DCHECK(IsInUse()); 97 DCHECK(IsInUse());
108 // Zap the values for eager trapping. 98 // Zap the values for eager trapping.
109 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 99 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
110 } 100 }
111 101
112 void Release() { 102 void Release() {
113 DCHECK(IsInUse()); 103 DCHECK(IsInUse());
114 set_state(FREE); 104 set_state(FREE);
115 // Zap the values for eager trapping. 105 // Zap the values for eager trapping.
116 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 106 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
117 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 107 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
118 set_independent(false); 108 set_independent(false);
119 if (FLAG_scavenge_reclaim_unmodified_objects) { 109 set_active(false);
120 set_active(false);
121 } else {
122 set_partially_dependent(false);
123 }
124 weak_callback_ = NULL; 110 weak_callback_ = NULL;
125 DecreaseBlockUses(); 111 DecreaseBlockUses();
126 } 112 }
127 113
128 // Object slot accessors. 114 // Object slot accessors.
129 Object* object() const { return object_; } 115 Object* object() const { return object_; }
130 Object** location() { return &object_; } 116 Object** location() { return &object_; }
131 Handle<Object> handle() { return Handle<Object>(location()); } 117 Handle<Object> handle() { return Handle<Object>(location()); }
132 118
133 // Wrapper class ID accessors. 119 // Wrapper class ID accessors.
(...skipping 12 matching lines...) Expand all
146 flags_ = NodeState::update(flags_, state); 132 flags_ = NodeState::update(flags_, state);
147 } 133 }
148 134
149 bool is_independent() { 135 bool is_independent() {
150 return IsIndependent::decode(flags_); 136 return IsIndependent::decode(flags_);
151 } 137 }
152 void set_independent(bool v) { 138 void set_independent(bool v) {
153 flags_ = IsIndependent::update(flags_, v); 139 flags_ = IsIndependent::update(flags_, v);
154 } 140 }
155 141
156 bool is_partially_dependent() {
157 CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
158 return IsPartiallyDependent::decode(flags_);
159 }
160 void set_partially_dependent(bool v) {
161 CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
162 flags_ = IsPartiallyDependent::update(flags_, v);
163 }
164
165 bool is_active() { 142 bool is_active() {
166 CHECK(FLAG_scavenge_reclaim_unmodified_objects);
167 return IsActive::decode(flags_); 143 return IsActive::decode(flags_);
168 } 144 }
169 void set_active(bool v) { 145 void set_active(bool v) {
170 CHECK(FLAG_scavenge_reclaim_unmodified_objects);
171 flags_ = IsActive::update(flags_, v); 146 flags_ = IsActive::update(flags_, v);
172 } 147 }
173 148
174 bool is_in_new_space_list() { 149 bool is_in_new_space_list() {
175 return IsInNewSpaceList::decode(flags_); 150 return IsInNewSpaceList::decode(flags_);
176 } 151 }
177 void set_in_new_space_list(bool v) { 152 void set_in_new_space_list(bool v) {
178 flags_ = IsInNewSpaceList::update(flags_, v); 153 flags_ = IsInNewSpaceList::update(flags_, v);
179 } 154 }
180 155
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 DCHECK(state() == WEAK); 195 DCHECK(state() == WEAK);
221 set_state(PENDING); 196 set_state(PENDING);
222 } 197 }
223 198
224 // Independent flag accessors. 199 // Independent flag accessors.
225 void MarkIndependent() { 200 void MarkIndependent() {
226 DCHECK(IsInUse()); 201 DCHECK(IsInUse());
227 set_independent(true); 202 set_independent(true);
228 } 203 }
229 204
230 void MarkPartiallyDependent() {
231 DCHECK(IsInUse());
232 if (GetGlobalHandles()->isolate()->heap()->InNewSpace(object_)) {
233 set_partially_dependent(true);
234 }
235 }
236 void clear_partially_dependent() { set_partially_dependent(false); }
237
238 // Callback accessor. 205 // Callback accessor.
239 // TODO(svenpanne) Re-enable or nuke later. 206 // TODO(svenpanne) Re-enable or nuke later.
240 // WeakReferenceCallback callback() { return callback_; } 207 // WeakReferenceCallback callback() { return callback_; }
241 208
242 // Callback parameter accessors. 209 // Callback parameter accessors.
243 void set_parameter(void* parameter) { 210 void set_parameter(void* parameter) {
244 DCHECK(IsInUse()); 211 DCHECK(IsInUse());
245 parameter_or_next_free_.parameter = parameter; 212 parameter_or_next_free_.parameter = parameter;
246 } 213 }
247 void* parameter() const { 214 void* parameter() const {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 358
392 // Index in the containing handle block. 359 // Index in the containing handle block.
393 uint8_t index_; 360 uint8_t index_;
394 361
395 // This stores three flags (independent, partially_dependent and 362 // This stores three flags (independent, partially_dependent and
396 // in_new_space_list) and a State. 363 // in_new_space_list) and a State.
397 class NodeState : public BitField<State, 0, 3> {}; 364 class NodeState : public BitField<State, 0, 3> {};
398 class IsIndependent : public BitField<bool, 3, 1> {}; 365 class IsIndependent : public BitField<bool, 3, 1> {};
399 // The following two fields are mutually exclusive 366 // The following two fields are mutually exclusive
400 class IsActive : public BitField<bool, 4, 1> {}; 367 class IsActive : public BitField<bool, 4, 1> {};
401 class IsPartiallyDependent : public BitField<bool, 4, 1> {};
402 class IsInNewSpaceList : public BitField<bool, 5, 1> {}; 368 class IsInNewSpaceList : public BitField<bool, 5, 1> {};
403 class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {}; 369 class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
404 370
405 uint8_t flags_; 371 uint8_t flags_;
406 372
407 // Handle specific callback - might be a weak reference in disguise. 373 // Handle specific callback - might be a weak reference in disguise.
408 WeakCallbackInfo<void>::Callback weak_callback_; 374 WeakCallbackInfo<void>::Callback weak_callback_;
409 375
410 // Provided data for callback. In FREE state, this is used for 376 // Provided data for callback. In FREE state, this is used for
411 // the free list link. 377 // the free list link.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 601
636 void* GlobalHandles::ClearWeakness(Object** location) { 602 void* GlobalHandles::ClearWeakness(Object** location) {
637 return Node::FromLocation(location)->ClearWeakness(); 603 return Node::FromLocation(location)->ClearWeakness();
638 } 604 }
639 605
640 606
641 void GlobalHandles::MarkIndependent(Object** location) { 607 void GlobalHandles::MarkIndependent(Object** location) {
642 Node::FromLocation(location)->MarkIndependent(); 608 Node::FromLocation(location)->MarkIndependent();
643 } 609 }
644 610
645
646 void GlobalHandles::MarkPartiallyDependent(Object** location) {
647 Node::FromLocation(location)->MarkPartiallyDependent();
648 }
649
650
651 bool GlobalHandles::IsIndependent(Object** location) { 611 bool GlobalHandles::IsIndependent(Object** location) {
652 return Node::FromLocation(location)->is_independent(); 612 return Node::FromLocation(location)->is_independent();
653 } 613 }
654 614
655 615
656 bool GlobalHandles::IsNearDeath(Object** location) { 616 bool GlobalHandles::IsNearDeath(Object** location) {
657 return Node::FromLocation(location)->IsNearDeath(); 617 return Node::FromLocation(location)->IsNearDeath();
658 } 618 }
659 619
660 620
(...skipping 26 matching lines...) Expand all
687 if (it.node()->IsWeak() && f(it.node()->location())) { 647 if (it.node()->IsWeak() && f(it.node()->location())) {
688 it.node()->MarkPending(); 648 it.node()->MarkPending();
689 } 649 }
690 } 650 }
691 } 651 }
692 652
693 653
694 void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) { 654 void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
695 for (int i = 0; i < new_space_nodes_.length(); ++i) { 655 for (int i = 0; i < new_space_nodes_.length(); ++i) {
696 Node* node = new_space_nodes_[i]; 656 Node* node = new_space_nodes_[i];
697 if (FLAG_scavenge_reclaim_unmodified_objects) { 657 if (node->IsStrongRetainer() ||
698 if (node->IsStrongRetainer() || 658 (node->IsWeakRetainer() && !node->is_independent() &&
699 (node->IsWeakRetainer() && !node->is_independent() && 659 node->is_active())) {
700 node->is_active())) { 660 v->VisitPointer(node->location());
701 v->VisitPointer(node->location());
702 }
703 } else {
704 if (node->IsStrongRetainer() ||
705 (node->IsWeakRetainer() && !node->is_independent() &&
706 !node->is_partially_dependent())) {
707 v->VisitPointer(node->location());
708 }
709 } 661 }
710 } 662 }
711 } 663 }
712 664
713 665
714 void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles( 666 void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles(
715 WeakSlotCallbackWithHeap f) { 667 WeakSlotCallbackWithHeap f) {
716 for (int i = 0; i < new_space_nodes_.length(); ++i) { 668 for (int i = 0; i < new_space_nodes_.length(); ++i) {
717 Node* node = new_space_nodes_[i]; 669 Node* node = new_space_nodes_[i];
718 DCHECK(node->is_in_new_space_list()); 670 DCHECK(node->is_in_new_space_list());
719 if ((node->is_independent() || node->is_partially_dependent()) && 671 if (node->is_independent() && node->IsWeak() &&
720 node->IsWeak() && f(isolate_->heap(), node->location())) { 672 f(isolate_->heap(), node->location())) {
721 node->MarkPending(); 673 node->MarkPending();
722 } 674 }
723 } 675 }
724 } 676 }
725 677
726 678
727 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { 679 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
728 for (int i = 0; i < new_space_nodes_.length(); ++i) { 680 for (int i = 0; i < new_space_nodes_.length(); ++i) {
729 Node* node = new_space_nodes_[i]; 681 Node* node = new_space_nodes_[i];
730 DCHECK(node->is_in_new_space_list()); 682 DCHECK(node->is_in_new_space_list());
731 if ((node->is_independent() || node->is_partially_dependent()) && 683 if (node->is_independent() && node->IsWeakRetainer()) {
732 node->IsWeakRetainer()) {
733 // Pending weak phantom handles die immediately. Everything else survives. 684 // Pending weak phantom handles die immediately. Everything else survives.
734 if (node->IsPendingPhantomResetHandle()) { 685 if (node->IsPendingPhantomResetHandle()) {
735 node->ResetPhantomHandle(); 686 node->ResetPhantomHandle();
736 ++number_of_phantom_handle_resets_; 687 ++number_of_phantom_handle_resets_;
737 } else if (node->IsPendingPhantomCallback()) { 688 } else if (node->IsPendingPhantomCallback()) {
738 node->CollectPhantomCallbackData(isolate(), 689 node->CollectPhantomCallbackData(isolate(),
739 &pending_phantom_callbacks_); 690 &pending_phantom_callbacks_);
740 } else { 691 } else {
741 v->VisitPointer(node->location()); 692 v->VisitPointer(node->location());
742 } 693 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 DCHECK(node->is_in_new_space_list()); 912 DCHECK(node->is_in_new_space_list());
962 if (!node->IsRetainer()) { 913 if (!node->IsRetainer()) {
963 // Free nodes do not have weak callbacks. Do not use them to compute 914 // Free nodes do not have weak callbacks. Do not use them to compute
964 // the freed_nodes. 915 // the freed_nodes.
965 continue; 916 continue;
966 } 917 }
967 // Skip dependent or unmodified handles. Their weak callbacks might expect 918 // Skip dependent or unmodified handles. Their weak callbacks might expect
968 // to be 919 // to be
969 // called between two global garbage collection callbacks which 920 // called between two global garbage collection callbacks which
970 // are not called for minor collections. 921 // are not called for minor collections.
971 if (FLAG_scavenge_reclaim_unmodified_objects) {
972 if (!node->is_independent() && (node->is_active())) { 922 if (!node->is_independent() && (node->is_active())) {
973 node->set_active(false); 923 node->set_active(false);
974 continue; 924 continue;
975 } 925 }
976 node->set_active(false); 926 node->set_active(false);
977 } else {
978 if (!node->is_independent() && !node->is_partially_dependent()) {
979 continue;
980 }
981 node->clear_partially_dependent();
982 }
983 927
984 if (node->PostGarbageCollectionProcessing(isolate_)) { 928 if (node->PostGarbageCollectionProcessing(isolate_)) {
985 if (initial_post_gc_processing_count != post_gc_processing_count_) { 929 if (initial_post_gc_processing_count != post_gc_processing_count_) {
986 // Weak callback triggered another GC and another round of 930 // Weak callback triggered another GC and another round of
987 // PostGarbageCollection processing. The current node might 931 // PostGarbageCollection processing. The current node might
988 // have been deleted in that round, so we need to bail out (or 932 // have been deleted in that round, so we need to bail out (or
989 // restart the processing). 933 // restart the processing).
990 return freed_nodes; 934 return freed_nodes;
991 } 935 }
992 } 936 }
993 if (!node->IsRetainer()) { 937 if (!node->IsRetainer()) {
994 freed_nodes++; 938 freed_nodes++;
995 } 939 }
996 } 940 }
997 return freed_nodes; 941 return freed_nodes;
998 } 942 }
999 943
1000 944
1001 int GlobalHandles::PostMarkSweepProcessing( 945 int GlobalHandles::PostMarkSweepProcessing(
1002 const int initial_post_gc_processing_count) { 946 const int initial_post_gc_processing_count) {
1003 int freed_nodes = 0; 947 int freed_nodes = 0;
1004 for (NodeIterator it(this); !it.done(); it.Advance()) { 948 for (NodeIterator it(this); !it.done(); it.Advance()) {
1005 if (!it.node()->IsRetainer()) { 949 if (!it.node()->IsRetainer()) {
1006 // Free nodes do not have weak callbacks. Do not use them to compute 950 // Free nodes do not have weak callbacks. Do not use them to compute
1007 // the freed_nodes. 951 // the freed_nodes.
1008 continue; 952 continue;
1009 } 953 }
1010 if (FLAG_scavenge_reclaim_unmodified_objects) { 954 it.node()->set_active(false);
1011 it.node()->set_active(false);
1012 } else {
1013 it.node()->clear_partially_dependent();
1014 }
1015 if (it.node()->PostGarbageCollectionProcessing(isolate_)) { 955 if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
1016 if (initial_post_gc_processing_count != post_gc_processing_count_) { 956 if (initial_post_gc_processing_count != post_gc_processing_count_) {
1017 // See the comment above. 957 // See the comment above.
1018 return freed_nodes; 958 return freed_nodes;
1019 } 959 }
1020 } 960 }
1021 if (!it.node()->IsRetainer()) { 961 if (!it.node()->IsRetainer()) {
1022 freed_nodes++; 962 freed_nodes++;
1023 } 963 }
1024 } 964 }
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 blocks_[block][offset] = object; 1451 blocks_[block][offset] = object;
1512 if (isolate->heap()->InNewSpace(object)) { 1452 if (isolate->heap()->InNewSpace(object)) {
1513 new_space_indices_.Add(size_); 1453 new_space_indices_.Add(size_);
1514 } 1454 }
1515 *index = size_++; 1455 *index = size_++;
1516 } 1456 }
1517 1457
1518 1458
1519 } // namespace internal 1459 } // namespace internal
1520 } // namespace v8 1460 } // namespace v8
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | src/heap/gc-tracer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698