Mercurial > hg > graal-jvmci-8
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 |