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