comparison src/share/vm/gc_implementation/shared/markSweep.cpp @ 1836:894b1d7c7e01

6423256: GC stacks should use a better data structure 6942771: SEGV in ParScanThreadState::take_from_overflow_stack Reviewed-by: apetrusenko, ysr, pbk
author jcoomes
date Tue, 28 Sep 2010 15:56:15 -0700
parents c18cbe5936b8
children f95d63e2154a
comparison
equal deleted inserted replaced
1835:4805b9f4779e 1836:894b1d7c7e01
23 */ 23 */
24 24
25 #include "incls/_precompiled.incl" 25 #include "incls/_precompiled.incl"
26 #include "incls/_markSweep.cpp.incl" 26 #include "incls/_markSweep.cpp.incl"
27 27
28 GrowableArray<oop>* MarkSweep::_marking_stack = NULL; 28 Stack<oop> MarkSweep::_marking_stack;
29 GrowableArray<ObjArrayTask>* MarkSweep::_objarray_stack = NULL; 29 Stack<DataLayout*> MarkSweep::_revisit_mdo_stack;
30 GrowableArray<Klass*>* MarkSweep::_revisit_klass_stack = NULL; 30 Stack<Klass*> MarkSweep::_revisit_klass_stack;
31 GrowableArray<DataLayout*>* MarkSweep::_revisit_mdo_stack = NULL; 31 Stack<ObjArrayTask> MarkSweep::_objarray_stack;
32 32
33 GrowableArray<oop>* MarkSweep::_preserved_oop_stack = NULL; 33 Stack<oop> MarkSweep::_preserved_oop_stack;
34 GrowableArray<markOop>* MarkSweep::_preserved_mark_stack= NULL; 34 Stack<markOop> MarkSweep::_preserved_mark_stack;
35 size_t MarkSweep::_preserved_count = 0; 35 size_t MarkSweep::_preserved_count = 0;
36 size_t MarkSweep::_preserved_count_max = 0; 36 size_t MarkSweep::_preserved_count_max = 0;
37 PreservedMark* MarkSweep::_preserved_marks = NULL; 37 PreservedMark* MarkSweep::_preserved_marks = NULL;
38 ReferenceProcessor* MarkSweep::_ref_processor = NULL; 38 ReferenceProcessor* MarkSweep::_ref_processor = NULL;
39 39
56 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL; 56 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL;
57 GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL; 57 GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL;
58 #endif 58 #endif
59 59
60 void MarkSweep::revisit_weak_klass_link(Klass* k) { 60 void MarkSweep::revisit_weak_klass_link(Klass* k) {
61 _revisit_klass_stack->push(k); 61 _revisit_klass_stack.push(k);
62 } 62 }
63 63
64 void MarkSweep::follow_weak_klass_links() { 64 void MarkSweep::follow_weak_klass_links() {
65 // All klasses on the revisit stack are marked at this point. 65 // All klasses on the revisit stack are marked at this point.
66 // Update and follow all subklass, sibling and implementor links. 66 // Update and follow all subklass, sibling and implementor links.
67 if (PrintRevisitStats) { 67 if (PrintRevisitStats) {
68 gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes()); 68 gclog_or_tty->print_cr("#classes in system dictionary = %d",
69 gclog_or_tty->print_cr("Revisit klass stack length = %d", _revisit_klass_stack->length()); 69 SystemDictionary::number_of_classes());
70 } 70 gclog_or_tty->print_cr("Revisit klass stack size = " SIZE_FORMAT,
71 for (int i = 0; i < _revisit_klass_stack->length(); i++) { 71 _revisit_klass_stack.size());
72 _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive); 72 }
73 while (!_revisit_klass_stack.is_empty()) {
74 Klass* const k = _revisit_klass_stack.pop();
75 k->follow_weak_klass_links(&is_alive, &keep_alive);
73 } 76 }
74 follow_stack(); 77 follow_stack();
75 } 78 }
76 79
77 void MarkSweep::revisit_mdo(DataLayout* p) { 80 void MarkSweep::revisit_mdo(DataLayout* p) {
78 _revisit_mdo_stack->push(p); 81 _revisit_mdo_stack.push(p);
79 } 82 }
80 83
81 void MarkSweep::follow_mdo_weak_refs() { 84 void MarkSweep::follow_mdo_weak_refs() {
82 // All strongly reachable oops have been marked at this point; 85 // All strongly reachable oops have been marked at this point;
83 // we can visit and clear any weak references from MDO's which 86 // we can visit and clear any weak references from MDO's which
84 // we memoized during the strong marking phase. 87 // we memoized during the strong marking phase.
85 assert(_marking_stack->is_empty(), "Marking stack should be empty"); 88 assert(_marking_stack.is_empty(), "Marking stack should be empty");
86 if (PrintRevisitStats) { 89 if (PrintRevisitStats) {
87 gclog_or_tty->print_cr("#classes in system dictionary = %d", SystemDictionary::number_of_classes()); 90 gclog_or_tty->print_cr("#classes in system dictionary = %d",
88 gclog_or_tty->print_cr("Revisit MDO stack length = %d", _revisit_mdo_stack->length()); 91 SystemDictionary::number_of_classes());
89 } 92 gclog_or_tty->print_cr("Revisit MDO stack size = " SIZE_FORMAT,
90 for (int i = 0; i < _revisit_mdo_stack->length(); i++) { 93 _revisit_mdo_stack.size());
91 _revisit_mdo_stack->at(i)->follow_weak_refs(&is_alive); 94 }
95 while (!_revisit_mdo_stack.is_empty()) {
96 _revisit_mdo_stack.pop()->follow_weak_refs(&is_alive);
92 } 97 }
93 follow_stack(); 98 follow_stack();
94 } 99 }
95 100
96 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; 101 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
104 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); } 109 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); }
105 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } 110 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
106 111
107 void MarkSweep::follow_stack() { 112 void MarkSweep::follow_stack() {
108 do { 113 do {
109 while (!_marking_stack->is_empty()) { 114 while (!_marking_stack.is_empty()) {
110 oop obj = _marking_stack->pop(); 115 oop obj = _marking_stack.pop();
111 assert (obj->is_gc_marked(), "p must be marked"); 116 assert (obj->is_gc_marked(), "p must be marked");
112 obj->follow_contents(); 117 obj->follow_contents();
113 } 118 }
114 // Process ObjArrays one at a time to avoid marking stack bloat. 119 // Process ObjArrays one at a time to avoid marking stack bloat.
115 if (!_objarray_stack->is_empty()) { 120 if (!_objarray_stack.is_empty()) {
116 ObjArrayTask task = _objarray_stack->pop(); 121 ObjArrayTask task = _objarray_stack.pop();
117 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint(); 122 objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
118 k->oop_follow_contents(task.obj(), task.index()); 123 k->oop_follow_contents(task.obj(), task.index());
119 } 124 }
120 } while (!_marking_stack->is_empty() || !_objarray_stack->is_empty()); 125 } while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
121 } 126 }
122 127
123 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure; 128 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
124 129
125 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); } 130 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
126 131
127 // We preserve the mark which should be replaced at the end and the location that it 132 // We preserve the mark which should be replaced at the end and the location
128 // will go. Note that the object that this markOop belongs to isn't currently at that 133 // that it will go. Note that the object that this markOop belongs to isn't
129 // address but it will be after phase4 134 // currently at that address but it will be after phase4
130 void MarkSweep::preserve_mark(oop obj, markOop mark) { 135 void MarkSweep::preserve_mark(oop obj, markOop mark) {
131 // we try to store preserved marks in the to space of the new generation since this 136 // We try to store preserved marks in the to space of the new generation since
132 // is storage which should be available. Most of the time this should be sufficient 137 // this is storage which should be available. Most of the time this should be
133 // space for the marks we need to preserve but if it isn't we fall back in using 138 // sufficient space for the marks we need to preserve but if it isn't we fall
134 // GrowableArrays to keep track of the overflow. 139 // back to using Stacks to keep track of the overflow.
135 if (_preserved_count < _preserved_count_max) { 140 if (_preserved_count < _preserved_count_max) {
136 _preserved_marks[_preserved_count++].init(obj, mark); 141 _preserved_marks[_preserved_count++].init(obj, mark);
137 } else { 142 } else {
138 if (_preserved_mark_stack == NULL) { 143 _preserved_mark_stack.push(mark);
139 _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); 144 _preserved_oop_stack.push(obj);
140 _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
141 }
142 _preserved_mark_stack->push(mark);
143 _preserved_oop_stack->push(obj);
144 } 145 }
145 } 146 }
146 147
147 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true); 148 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true);
148 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false); 149 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false);
149 150
150 void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); } 151 void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); }
151 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); } 152 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
152 153
153 void MarkSweep::adjust_marks() { 154 void MarkSweep::adjust_marks() {
154 assert(_preserved_oop_stack == NULL || 155 assert( _preserved_oop_stack.size() == _preserved_mark_stack.size(),
155 _preserved_oop_stack->length() == _preserved_mark_stack->length(),
156 "inconsistent preserved oop stacks"); 156 "inconsistent preserved oop stacks");
157 157
158 // adjust the oops we saved earlier 158 // adjust the oops we saved earlier
159 for (size_t i = 0; i < _preserved_count; i++) { 159 for (size_t i = 0; i < _preserved_count; i++) {
160 _preserved_marks[i].adjust_pointer(); 160 _preserved_marks[i].adjust_pointer();
161 } 161 }
162 162
163 // deal with the overflow stack 163 // deal with the overflow stack
164 if (_preserved_oop_stack) { 164 StackIterator<oop> iter(_preserved_oop_stack);
165 for (int i = 0; i < _preserved_oop_stack->length(); i++) { 165 while (!iter.is_empty()) {
166 oop* p = _preserved_oop_stack->adr_at(i); 166 oop* p = iter.next_addr();
167 adjust_pointer(p); 167 adjust_pointer(p);
168 }
169 } 168 }
170 } 169 }
171 170
172 void MarkSweep::restore_marks() { 171 void MarkSweep::restore_marks() {
173 assert(_preserved_oop_stack == NULL || 172 assert(_preserved_oop_stack.size() == _preserved_mark_stack.size(),
174 _preserved_oop_stack->length() == _preserved_mark_stack->length(),
175 "inconsistent preserved oop stacks"); 173 "inconsistent preserved oop stacks");
176 if (PrintGC && Verbose) { 174 if (PrintGC && Verbose) {
177 gclog_or_tty->print_cr("Restoring %d marks", _preserved_count + 175 gclog_or_tty->print_cr("Restoring %d marks",
178 (_preserved_oop_stack ? _preserved_oop_stack->length() : 0)); 176 _preserved_count + _preserved_oop_stack.size());
179 } 177 }
180 178
181 // restore the marks we saved earlier 179 // restore the marks we saved earlier
182 for (size_t i = 0; i < _preserved_count; i++) { 180 for (size_t i = 0; i < _preserved_count; i++) {
183 _preserved_marks[i].restore(); 181 _preserved_marks[i].restore();
184 } 182 }
185 183
186 // deal with the overflow 184 // deal with the overflow
187 if (_preserved_oop_stack) { 185 while (!_preserved_oop_stack.is_empty()) {
188 for (int i = 0; i < _preserved_oop_stack->length(); i++) { 186 oop obj = _preserved_oop_stack.pop();
189 oop obj = _preserved_oop_stack->at(i); 187 markOop mark = _preserved_mark_stack.pop();
190 markOop mark = _preserved_mark_stack->at(i); 188 obj->set_mark(mark);
191 obj->set_mark(mark);
192 }
193 } 189 }
194 } 190 }
195 191
196 #ifdef VALIDATE_MARK_SWEEP 192 #ifdef VALIDATE_MARK_SWEEP
197 193