Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/shared/markSweep.cpp @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | a61af66fc99e |
children | d1605aabd0a1 |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
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 |
185 } | 159 } |
186 } | 160 } |
187 | 161 |
188 #ifdef VALIDATE_MARK_SWEEP | 162 #ifdef VALIDATE_MARK_SWEEP |
189 | 163 |
190 void MarkSweep::track_adjusted_pointer(oop* p, oop newobj, bool isroot) { | 164 void MarkSweep::track_adjusted_pointer(void* p, bool isroot) { |
191 if (!ValidateMarkSweep) | 165 if (!ValidateMarkSweep) |
192 return; | 166 return; |
193 | 167 |
194 if (!isroot) { | 168 if (!isroot) { |
195 if (_pointer_tracking) { | 169 if (_pointer_tracking) { |
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 |