comparison src/share/vm/memory/cardTableRS.cpp @ 2428:5134fa1cfe63

7029036: Card-table verification hangs with all framework collectors, except G1, even before the first GC Summary: When verifying clean card ranges, use memory-range-bounded iteration over oops of objects overlapping that range, thus avoiding the otherwise quadratic worst-case cost of scanning large object arrays. Reviewed-by: jmasa, jwilhelm, tonyp
author ysr
date Thu, 24 Mar 2011 15:47:01 -0700
parents f95d63e2154a
children c69b1043dfb1
comparison
equal deleted inserted replaced
2427:a0de1dfd1933 2428:5134fa1cfe63
316 HeapWord* _begin; 316 HeapWord* _begin;
317 HeapWord* _end; 317 HeapWord* _end;
318 protected: 318 protected:
319 template <class T> void do_oop_work(T* p) { 319 template <class T> void do_oop_work(T* p) {
320 HeapWord* jp = (HeapWord*)p; 320 HeapWord* jp = (HeapWord*)p;
321 if (jp >= _begin && jp < _end) { 321 assert(jp >= _begin && jp < _end,
322 oop obj = oopDesc::load_decode_heap_oop(p); 322 err_msg("Error: jp " PTR_FORMAT " should be within "
323 guarantee(obj == NULL || 323 "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")",
324 (HeapWord*)p < _boundary || 324 _begin, _end));
325 (HeapWord*)obj >= _boundary, 325 oop obj = oopDesc::load_decode_heap_oop(p);
326 "pointer on clean card crosses boundary"); 326 guarantee(obj == NULL || (HeapWord*)obj >= _boundary,
327 } 327 err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
328 } 328 "clean card crosses boundary" PTR_FORMAT,
329 (HeapWord*)obj, jp, _boundary));
330 }
331
329 public: 332 public:
330 VerifyCleanCardClosure(HeapWord* b, HeapWord* begin, HeapWord* end) : 333 VerifyCleanCardClosure(HeapWord* b, HeapWord* begin, HeapWord* end) :
331 _boundary(b), _begin(begin), _end(end) {} 334 _boundary(b), _begin(begin), _end(end) {
335 assert(b <= begin,
336 err_msg("Error: boundary " PTR_FORMAT " should be at or below begin " PTR_FORMAT,
337 b, begin));
338 assert(begin <= end,
339 err_msg("Error: begin " PTR_FORMAT " should be strictly below end " PTR_FORMAT,
340 begin, end));
341 }
342
332 virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); } 343 virtual void do_oop(oop* p) { VerifyCleanCardClosure::do_oop_work(p); }
333 virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); } 344 virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); }
334 }; 345 };
335 346
336 class VerifyCTSpaceClosure: public SpaceClosure { 347 class VerifyCTSpaceClosure: public SpaceClosure {
390 } 401 }
391 } 402 }
392 } 403 }
393 } 404 }
394 // Now traverse objects until end. 405 // Now traverse objects until end.
395 HeapWord* cur = start_block; 406 if (begin < end) {
396 VerifyCleanCardClosure verify_blk(gen_boundary, begin, end); 407 MemRegion mr(begin, end);
397 while (cur < end) { 408 VerifyCleanCardClosure verify_blk(gen_boundary, begin, end);
398 if (s->block_is_obj(cur) && s->obj_is_alive(cur)) { 409 for (HeapWord* cur = start_block; cur < end; cur += s->block_size(cur)) {
399 oop(cur)->oop_iterate(&verify_blk); 410 if (s->block_is_obj(cur) && s->obj_is_alive(cur)) {
411 oop(cur)->oop_iterate(&verify_blk, mr);
412 }
400 } 413 }
401 cur += s->block_size(cur);
402 } 414 }
403 cur_entry = first_dirty; 415 cur_entry = first_dirty;
404 } else { 416 } else {
405 // We'd normally expect that cur_youngergen_and_prev_nonclean_card 417 // We'd normally expect that cur_youngergen_and_prev_nonclean_card
406 // is a transient value, that cannot be in the card table 418 // is a transient value, that cannot be in the card table