34 size_t MarkSweep::_preserved_count_max = 0; |
34 size_t MarkSweep::_preserved_count_max = 0; |
35 PreservedMark* MarkSweep::_preserved_marks = NULL; |
35 PreservedMark* MarkSweep::_preserved_marks = NULL; |
36 ReferenceProcessor* MarkSweep::_ref_processor = NULL; |
36 ReferenceProcessor* MarkSweep::_ref_processor = NULL; |
37 |
37 |
38 #ifdef VALIDATE_MARK_SWEEP |
38 #ifdef VALIDATE_MARK_SWEEP |
39 GrowableArray<oop*>* MarkSweep::_root_refs_stack = NULL; |
39 GrowableArray<void*>* MarkSweep::_root_refs_stack = NULL; |
40 GrowableArray<oop> * MarkSweep::_live_oops = NULL; |
40 GrowableArray<oop> * MarkSweep::_live_oops = NULL; |
41 GrowableArray<oop> * MarkSweep::_live_oops_moved_to = NULL; |
41 GrowableArray<oop> * MarkSweep::_live_oops_moved_to = NULL; |
42 GrowableArray<size_t>* MarkSweep::_live_oops_size = NULL; |
42 GrowableArray<size_t>* MarkSweep::_live_oops_size = NULL; |
43 size_t MarkSweep::_live_oops_index = 0; |
43 size_t MarkSweep::_live_oops_index = 0; |
44 size_t MarkSweep::_live_oops_index_at_perm = 0; |
44 size_t MarkSweep::_live_oops_index_at_perm = 0; |
45 GrowableArray<oop*>* MarkSweep::_other_refs_stack = NULL; |
45 GrowableArray<void*>* MarkSweep::_other_refs_stack = NULL; |
46 GrowableArray<oop*>* MarkSweep::_adjusted_pointers = NULL; |
46 GrowableArray<void*>* MarkSweep::_adjusted_pointers = NULL; |
47 bool MarkSweep::_pointer_tracking = false; |
47 bool MarkSweep::_pointer_tracking = false; |
48 bool MarkSweep::_root_tracking = true; |
48 bool MarkSweep::_root_tracking = true; |
49 |
49 |
50 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL; |
50 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL; |
51 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL; |
51 GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL; |
52 GrowableArray<size_t> * MarkSweep::_cur_gc_live_oops_size = NULL; |
52 GrowableArray<size_t> * MarkSweep::_cur_gc_live_oops_size = NULL; |
53 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL; |
53 GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL; |
57 |
57 |
58 void MarkSweep::revisit_weak_klass_link(Klass* k) { |
58 void MarkSweep::revisit_weak_klass_link(Klass* k) { |
59 _revisit_klass_stack->push(k); |
59 _revisit_klass_stack->push(k); |
60 } |
60 } |
61 |
61 |
62 |
|
63 void MarkSweep::follow_weak_klass_links() { |
62 void MarkSweep::follow_weak_klass_links() { |
64 // All klasses on the revisit stack are marked at this point. |
63 // All klasses on the revisit stack are marked at this point. |
65 // Update and follow all subklass, sibling and implementor links. |
64 // Update and follow all subklass, sibling and implementor links. |
66 for (int i = 0; i < _revisit_klass_stack->length(); i++) { |
65 for (int i = 0; i < _revisit_klass_stack->length(); i++) { |
67 _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive); |
66 _revisit_klass_stack->at(i)->follow_weak_klass_links(&is_alive,&keep_alive); |
68 } |
67 } |
69 follow_stack(); |
68 follow_stack(); |
70 } |
69 } |
71 |
70 |
72 |
71 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; |
73 void MarkSweep::mark_and_follow(oop* p) { |
72 |
74 assert(Universe::heap()->is_in_reserved(p), |
73 void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); } |
75 "we should only be traversing objects here"); |
74 void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); } |
76 oop m = *p; |
|
77 if (m != NULL && !m->mark()->is_marked()) { |
|
78 mark_object(m); |
|
79 m->follow_contents(); // Follow contents of the marked object |
|
80 } |
|
81 } |
|
82 |
|
83 void MarkSweep::_mark_and_push(oop* p) { |
|
84 // Push marked object, contents will be followed later |
|
85 oop m = *p; |
|
86 mark_object(m); |
|
87 _marking_stack->push(m); |
|
88 } |
|
89 |
75 |
90 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; |
76 MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure; |
91 |
77 |
92 void MarkSweep::follow_root(oop* p) { |
78 void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); } |
93 assert(!Universe::heap()->is_in_reserved(p), |
79 void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); } |
94 "roots shouldn't be things within the heap"); |
|
95 #ifdef VALIDATE_MARK_SWEEP |
|
96 if (ValidateMarkSweep) { |
|
97 guarantee(!_root_refs_stack->contains(p), "should only be in here once"); |
|
98 _root_refs_stack->push(p); |
|
99 } |
|
100 #endif |
|
101 oop m = *p; |
|
102 if (m != NULL && !m->mark()->is_marked()) { |
|
103 mark_object(m); |
|
104 m->follow_contents(); // Follow contents of the marked object |
|
105 } |
|
106 follow_stack(); |
|
107 } |
|
108 |
|
109 MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; |
|
110 |
80 |
111 void MarkSweep::follow_stack() { |
81 void MarkSweep::follow_stack() { |
112 while (!_marking_stack->is_empty()) { |
82 while (!_marking_stack->is_empty()) { |
113 oop obj = _marking_stack->pop(); |
83 oop obj = _marking_stack->pop(); |
114 assert (obj->is_gc_marked(), "p must be marked"); |
84 assert (obj->is_gc_marked(), "p must be marked"); |
116 } |
86 } |
117 } |
87 } |
118 |
88 |
119 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure; |
89 MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure; |
120 |
90 |
|
91 void MarkSweep::FollowStackClosure::do_void() { follow_stack(); } |
121 |
92 |
122 // We preserve the mark which should be replaced at the end and the location that it |
93 // We preserve the mark which should be replaced at the end and the location that it |
123 // will go. Note that the object that this markOop belongs to isn't currently at that |
94 // will go. Note that the object that this markOop belongs to isn't currently at that |
124 // address but it will be after phase4 |
95 // address but it will be after phase4 |
125 void MarkSweep::preserve_mark(oop obj, markOop mark) { |
96 void MarkSweep::preserve_mark(oop obj, markOop mark) { |
140 } |
111 } |
141 |
112 |
142 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true); |
113 MarkSweep::AdjustPointerClosure MarkSweep::adjust_root_pointer_closure(true); |
143 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false); |
114 MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure(false); |
144 |
115 |
|
116 void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); } |
|
117 void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); } |
|
118 |
145 void MarkSweep::adjust_marks() { |
119 void MarkSweep::adjust_marks() { |
146 assert(_preserved_oop_stack == NULL || |
120 assert(_preserved_oop_stack == NULL || |
147 _preserved_oop_stack->length() == _preserved_mark_stack->length(), |
121 _preserved_oop_stack->length() == _preserved_mark_stack->length(), |
148 "inconsistent preserved oop stacks"); |
122 "inconsistent preserved oop stacks"); |
149 |
123 |
199 } else { |
173 } else { |
200 ptrdiff_t index = _root_refs_stack->find(p); |
174 ptrdiff_t index = _root_refs_stack->find(p); |
201 if (index != -1) { |
175 if (index != -1) { |
202 int l = _root_refs_stack->length(); |
176 int l = _root_refs_stack->length(); |
203 if (l > 0 && l - 1 != index) { |
177 if (l > 0 && l - 1 != index) { |
204 oop* last = _root_refs_stack->pop(); |
178 void* last = _root_refs_stack->pop(); |
205 assert(last != p, "should be different"); |
179 assert(last != p, "should be different"); |
206 _root_refs_stack->at_put(index, last); |
180 _root_refs_stack->at_put(index, last); |
207 } else { |
181 } else { |
208 _root_refs_stack->remove(p); |
182 _root_refs_stack->remove(p); |
209 } |
183 } |
210 } |
184 } |
211 } |
185 } |
212 } |
186 } |
213 |
187 |
214 |
188 void MarkSweep::check_adjust_pointer(void* p) { |
215 void MarkSweep::check_adjust_pointer(oop* p) { |
|
216 _adjusted_pointers->push(p); |
189 _adjusted_pointers->push(p); |
217 } |
190 } |
218 |
|
219 |
191 |
220 class AdjusterTracker: public OopClosure { |
192 class AdjusterTracker: public OopClosure { |
221 public: |
193 public: |
222 AdjusterTracker() {}; |
194 AdjusterTracker() {} |
223 void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); } |
195 void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); } |
|
196 void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); } |
224 }; |
197 }; |
225 |
|
226 |
198 |
227 void MarkSweep::track_interior_pointers(oop obj) { |
199 void MarkSweep::track_interior_pointers(oop obj) { |
228 if (ValidateMarkSweep) { |
200 if (ValidateMarkSweep) { |
229 _adjusted_pointers->clear(); |
201 _adjusted_pointers->clear(); |
230 _pointer_tracking = true; |
202 _pointer_tracking = true; |
232 AdjusterTracker checker; |
204 AdjusterTracker checker; |
233 obj->oop_iterate(&checker); |
205 obj->oop_iterate(&checker); |
234 } |
206 } |
235 } |
207 } |
236 |
208 |
237 |
|
238 void MarkSweep::check_interior_pointers() { |
209 void MarkSweep::check_interior_pointers() { |
239 if (ValidateMarkSweep) { |
210 if (ValidateMarkSweep) { |
240 _pointer_tracking = false; |
211 _pointer_tracking = false; |
241 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); |
212 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers"); |
242 } |
213 } |
243 } |
214 } |
244 |
215 |
245 |
|
246 void MarkSweep::reset_live_oop_tracking(bool at_perm) { |
216 void MarkSweep::reset_live_oop_tracking(bool at_perm) { |
247 if (ValidateMarkSweep) { |
217 if (ValidateMarkSweep) { |
248 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); |
218 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops"); |
249 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; |
219 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0; |
250 } |
220 } |
251 } |
221 } |
252 |
|
253 |
222 |
254 void MarkSweep::register_live_oop(oop p, size_t size) { |
223 void MarkSweep::register_live_oop(oop p, size_t size) { |
255 if (ValidateMarkSweep) { |
224 if (ValidateMarkSweep) { |
256 _live_oops->push(p); |
225 _live_oops->push(p); |
257 _live_oops_size->push(size); |
226 _live_oops_size->push(size); |
280 _cur_gc_live_oops->push(q); |
249 _cur_gc_live_oops->push(q); |
281 _cur_gc_live_oops_moved_to->push(compaction_top); |
250 _cur_gc_live_oops_moved_to->push(compaction_top); |
282 _cur_gc_live_oops_size->push(size); |
251 _cur_gc_live_oops_size->push(size); |
283 } |
252 } |
284 } |
253 } |
285 |
|
286 |
254 |
287 void MarkSweep::compaction_complete() { |
255 void MarkSweep::compaction_complete() { |
288 if (RecordMarkSweepCompaction) { |
256 if (RecordMarkSweepCompaction) { |
289 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops; |
257 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops; |
290 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; |
258 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to; |
296 _last_gc_live_oops = _tmp_live_oops; |
264 _last_gc_live_oops = _tmp_live_oops; |
297 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; |
265 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to; |
298 _last_gc_live_oops_size = _tmp_live_oops_size; |
266 _last_gc_live_oops_size = _tmp_live_oops_size; |
299 } |
267 } |
300 } |
268 } |
301 |
|
302 |
269 |
303 void MarkSweep::print_new_location_of_heap_address(HeapWord* q) { |
270 void MarkSweep::print_new_location_of_heap_address(HeapWord* q) { |
304 if (!RecordMarkSweepCompaction) { |
271 if (!RecordMarkSweepCompaction) { |
305 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); |
272 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled"); |
306 return; |
273 return; |
316 size_t sz = _last_gc_live_oops_size->at(i); |
283 size_t sz = _last_gc_live_oops_size->at(i); |
317 if (old_oop <= q && q < (old_oop + sz)) { |
284 if (old_oop <= q && q < (old_oop + sz)) { |
318 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); |
285 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i); |
319 size_t offset = (q - old_oop); |
286 size_t offset = (q - old_oop); |
320 tty->print_cr("Address " PTR_FORMAT, q); |
287 tty->print_cr("Address " PTR_FORMAT, q); |
321 tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset); |
288 tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset); |
322 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); |
289 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset); |
323 return; |
290 return; |
324 } |
291 } |
325 } |
292 } |
326 |
293 |
327 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); |
294 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q); |
328 } |
295 } |
329 #endif //VALIDATE_MARK_SWEEP |
296 #endif //VALIDATE_MARK_SWEEP |
330 |
297 |
331 MarkSweep::IsAliveClosure MarkSweep::is_alive; |
298 MarkSweep::IsAliveClosure MarkSweep::is_alive; |
332 |
299 |
333 void MarkSweep::KeepAliveClosure::do_oop(oop* p) { |
300 void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); } |
334 #ifdef VALIDATE_MARK_SWEEP |
301 bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); } |
335 if (ValidateMarkSweep) { |
|
336 if (!Universe::heap()->is_in_reserved(p)) { |
|
337 _root_refs_stack->push(p); |
|
338 } else { |
|
339 _other_refs_stack->push(p); |
|
340 } |
|
341 } |
|
342 #endif |
|
343 mark_and_push(p); |
|
344 } |
|
345 |
302 |
346 MarkSweep::KeepAliveClosure MarkSweep::keep_alive; |
303 MarkSweep::KeepAliveClosure MarkSweep::keep_alive; |
|
304 |
|
305 void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } |
|
306 void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); } |
347 |
307 |
348 void marksweep_init() { /* empty */ } |
308 void marksweep_init() { /* empty */ } |
349 |
309 |
350 #ifndef PRODUCT |
310 #ifndef PRODUCT |
351 |
311 |