Mercurial > hg > truffle
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 |