Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/heapRegion.cpp @ 4137:04b9a2566eec
Merge with hsx23/hotspot.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 21:40:27 +0100 |
parents | be4ca325525a 53074c2c4600 |
children | 33df1aeaebbf |
comparison
equal
deleted
inserted
replaced
3737:9dc19b7d89a3 | 4137:04b9a2566eec |
---|---|
31 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | 31 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" |
32 #include "memory/genOopClosures.inline.hpp" | 32 #include "memory/genOopClosures.inline.hpp" |
33 #include "memory/iterator.hpp" | 33 #include "memory/iterator.hpp" |
34 #include "oops/oop.inline.hpp" | 34 #include "oops/oop.inline.hpp" |
35 | 35 |
36 int HeapRegion::LogOfHRGrainBytes = 0; | 36 int HeapRegion::LogOfHRGrainBytes = 0; |
37 int HeapRegion::LogOfHRGrainWords = 0; | 37 int HeapRegion::LogOfHRGrainWords = 0; |
38 int HeapRegion::GrainBytes = 0; | 38 size_t HeapRegion::GrainBytes = 0; |
39 int HeapRegion::GrainWords = 0; | 39 size_t HeapRegion::GrainWords = 0; |
40 int HeapRegion::CardsPerRegion = 0; | 40 size_t HeapRegion::CardsPerRegion = 0; |
41 | 41 |
42 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, | 42 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, |
43 HeapRegion* hr, OopClosure* cl, | 43 HeapRegion* hr, OopClosure* cl, |
44 CardTableModRefBS::PrecisionStyle precision, | 44 CardTableModRefBS::PrecisionStyle precision, |
45 FilterKind fk) : | 45 FilterKind fk) : |
46 ContiguousSpaceDCTOC(hr, cl, precision, NULL), | 46 ContiguousSpaceDCTOC(hr, cl, precision, NULL), |
47 _hr(hr), _fk(fk), _g1(g1) | 47 _hr(hr), _fk(fk), _g1(g1) |
48 {} | 48 { } |
49 | 49 |
50 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, | 50 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, |
51 OopClosure* oc) : | 51 OopClosure* oc) : |
52 _r_bottom(r->bottom()), _r_end(r->end()), | 52 _r_bottom(r->bottom()), _r_end(r->end()), |
53 _oc(oc), _out_of_region(0) | 53 _oc(oc), _out_of_region(0) |
58 G1CollectedHeap* _g1h; | 58 G1CollectedHeap* _g1h; |
59 CardTableModRefBS* _bs; | 59 CardTableModRefBS* _bs; |
60 oop _containing_obj; | 60 oop _containing_obj; |
61 bool _failures; | 61 bool _failures; |
62 int _n_failures; | 62 int _n_failures; |
63 bool _use_prev_marking; | 63 VerifyOption _vo; |
64 public: | 64 public: |
65 // use_prev_marking == true -> use "prev" marking information, | 65 // _vo == UsePrevMarking -> use "prev" marking information, |
66 // use_prev_marking == false -> use "next" marking information | 66 // _vo == UseNextMarking -> use "next" marking information, |
67 VerifyLiveClosure(G1CollectedHeap* g1h, bool use_prev_marking) : | 67 // _vo == UseMarkWord -> use mark word from object header. |
68 VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : | |
68 _g1h(g1h), _bs(NULL), _containing_obj(NULL), | 69 _g1h(g1h), _bs(NULL), _containing_obj(NULL), |
69 _failures(false), _n_failures(0), _use_prev_marking(use_prev_marking) | 70 _failures(false), _n_failures(0), _vo(vo) |
70 { | 71 { |
71 BarrierSet* bs = _g1h->barrier_set(); | 72 BarrierSet* bs = _g1h->barrier_set(); |
72 if (bs->is_a(BarrierSet::CardTableModRef)) | 73 if (bs->is_a(BarrierSet::CardTableModRef)) |
73 _bs = (CardTableModRefBS*)bs; | 74 _bs = (CardTableModRefBS*)bs; |
74 } | 75 } |
93 #endif // PRODUCT | 94 #endif // PRODUCT |
94 } | 95 } |
95 | 96 |
96 template <class T> void do_oop_work(T* p) { | 97 template <class T> void do_oop_work(T* p) { |
97 assert(_containing_obj != NULL, "Precondition"); | 98 assert(_containing_obj != NULL, "Precondition"); |
98 assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), | 99 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), |
99 "Precondition"); | 100 "Precondition"); |
100 T heap_oop = oopDesc::load_heap_oop(p); | 101 T heap_oop = oopDesc::load_heap_oop(p); |
101 if (!oopDesc::is_null(heap_oop)) { | 102 if (!oopDesc::is_null(heap_oop)) { |
102 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | 103 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
103 bool failed = false; | 104 bool failed = false; |
104 if (!_g1h->is_in_closed_subset(obj) || | 105 if (!_g1h->is_in_closed_subset(obj) || |
105 _g1h->is_obj_dead_cond(obj, _use_prev_marking)) { | 106 _g1h->is_obj_dead_cond(obj, _vo)) { |
106 if (!_failures) { | 107 if (!_failures) { |
107 gclog_or_tty->print_cr(""); | 108 gclog_or_tty->print_cr(""); |
108 gclog_or_tty->print_cr("----------"); | 109 gclog_or_tty->print_cr("----------"); |
109 } | 110 } |
110 if (!_g1h->is_in_closed_subset(obj)) { | 111 if (!_g1h->is_in_closed_subset(obj)) { |
157 if (!_failures) { | 158 if (!_failures) { |
158 gclog_or_tty->print_cr(""); | 159 gclog_or_tty->print_cr(""); |
159 gclog_or_tty->print_cr("----------"); | 160 gclog_or_tty->print_cr("----------"); |
160 } | 161 } |
161 gclog_or_tty->print_cr("Missing rem set entry:"); | 162 gclog_or_tty->print_cr("Missing rem set entry:"); |
162 gclog_or_tty->print_cr("Field "PTR_FORMAT | 163 gclog_or_tty->print_cr("Field "PTR_FORMAT" " |
163 " of obj "PTR_FORMAT | 164 "of obj "PTR_FORMAT", " |
164 ", in region %d ["PTR_FORMAT | 165 "in region "HR_FORMAT, |
165 ", "PTR_FORMAT"),", | 166 p, (void*) _containing_obj, |
166 p, (void*) _containing_obj, | 167 HR_FORMAT_PARAMS(from)); |
167 from->hrs_index(), | |
168 from->bottom(), | |
169 from->end()); | |
170 _containing_obj->print_on(gclog_or_tty); | 168 _containing_obj->print_on(gclog_or_tty); |
171 gclog_or_tty->print_cr("points to obj "PTR_FORMAT | 169 gclog_or_tty->print_cr("points to obj "PTR_FORMAT" " |
172 " in region %d ["PTR_FORMAT | 170 "in region "HR_FORMAT, |
173 ", "PTR_FORMAT").", | 171 (void*) obj, |
174 (void*) obj, to->hrs_index(), | 172 HR_FORMAT_PARAMS(to)); |
175 to->bottom(), to->end()); | |
176 obj->print_on(gclog_or_tty); | 173 obj->print_on(gclog_or_tty); |
177 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", | 174 gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", |
178 cv_obj, cv_field); | 175 cv_obj, cv_field); |
179 gclog_or_tty->print_cr("----------"); | 176 gclog_or_tty->print_cr("----------"); |
180 _failures = true; | 177 _failures = true; |
211 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, | 208 void HeapRegionDCTOC::walk_mem_region_with_cl(MemRegion mr, |
212 HeapWord* bottom, | 209 HeapWord* bottom, |
213 HeapWord* top, | 210 HeapWord* top, |
214 OopClosure* cl) { | 211 OopClosure* cl) { |
215 G1CollectedHeap* g1h = _g1; | 212 G1CollectedHeap* g1h = _g1; |
216 | |
217 int oop_size; | 213 int oop_size; |
218 | 214 OopClosure* cl2 = NULL; |
219 OopClosure* cl2 = cl; | 215 |
220 FilterIntoCSClosure intoCSFilt(this, g1h, cl); | 216 FilterIntoCSClosure intoCSFilt(this, g1h, cl); |
221 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); | 217 FilterOutOfRegionClosure outOfRegionFilt(_hr, cl); |
218 | |
222 switch (_fk) { | 219 switch (_fk) { |
220 case NoFilterKind: cl2 = cl; break; | |
223 case IntoCSFilterKind: cl2 = &intoCSFilt; break; | 221 case IntoCSFilterKind: cl2 = &intoCSFilt; break; |
224 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; | 222 case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; |
223 default: ShouldNotReachHere(); | |
225 } | 224 } |
226 | 225 |
227 // Start filtering what we add to the remembered set. If the object is | 226 // Start filtering what we add to the remembered set. If the object is |
228 // not considered dead, either because it is marked (in the mark bitmap) | 227 // not considered dead, either because it is marked (in the mark bitmap) |
229 // or it was allocated after marking finished, then we add it. Otherwise | 228 // or it was allocated after marking finished, then we add it. Otherwise |
240 // We replicate the loop below for several kinds of possible filters. | 239 // We replicate the loop below for several kinds of possible filters. |
241 switch (_fk) { | 240 switch (_fk) { |
242 case NoFilterKind: | 241 case NoFilterKind: |
243 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); | 242 bottom = walk_mem_region_loop(cl, g1h, _hr, bottom, top); |
244 break; | 243 break; |
244 | |
245 case IntoCSFilterKind: { | 245 case IntoCSFilterKind: { |
246 FilterIntoCSClosure filt(this, g1h, cl); | 246 FilterIntoCSClosure filt(this, g1h, cl); |
247 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | 247 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); |
248 break; | 248 break; |
249 } | 249 } |
250 | |
250 case OutOfRegionFilterKind: { | 251 case OutOfRegionFilterKind: { |
251 FilterOutOfRegionClosure filt(_hr, cl); | 252 FilterOutOfRegionClosure filt(_hr, cl); |
252 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); | 253 bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); |
253 break; | 254 break; |
254 } | 255 } |
256 | |
255 default: | 257 default: |
256 ShouldNotReachHere(); | 258 ShouldNotReachHere(); |
257 } | 259 } |
258 | 260 |
259 // Last object. Need to do dead-obj filtering here too. | 261 // Last object. Need to do dead-obj filtering here too. |
318 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; | 320 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize; |
319 | 321 |
320 guarantee(GrainBytes == 0, "we should only set it once"); | 322 guarantee(GrainBytes == 0, "we should only set it once"); |
321 // The cast to int is safe, given that we've bounded region_size by | 323 // The cast to int is safe, given that we've bounded region_size by |
322 // MIN_REGION_SIZE and MAX_REGION_SIZE. | 324 // MIN_REGION_SIZE and MAX_REGION_SIZE. |
323 GrainBytes = (int) region_size; | 325 GrainBytes = (size_t)region_size; |
324 | 326 |
325 guarantee(GrainWords == 0, "we should only set it once"); | 327 guarantee(GrainWords == 0, "we should only set it once"); |
326 GrainWords = GrainBytes >> LogHeapWordSize; | 328 GrainWords = GrainBytes >> LogHeapWordSize; |
327 guarantee(1 << LogOfHRGrainWords == GrainWords, "sanity"); | 329 guarantee((size_t)(1 << LogOfHRGrainWords) == GrainWords, "sanity"); |
328 | 330 |
329 guarantee(CardsPerRegion == 0, "we should only set it once"); | 331 guarantee(CardsPerRegion == 0, "we should only set it once"); |
330 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; | 332 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift; |
331 } | 333 } |
332 | 334 |
334 G1OffsetTableContigSpace::reset_after_compaction(); | 336 G1OffsetTableContigSpace::reset_after_compaction(); |
335 // After a compaction the mark bitmap is invalid, so we must | 337 // After a compaction the mark bitmap is invalid, so we must |
336 // treat all objects as being inside the unmarked area. | 338 // treat all objects as being inside the unmarked area. |
337 zero_marked_bytes(); | 339 zero_marked_bytes(); |
338 init_top_at_mark_start(); | 340 init_top_at_mark_start(); |
339 } | |
340 | |
341 DirtyCardToOopClosure* | |
342 HeapRegion::new_dcto_closure(OopClosure* cl, | |
343 CardTableModRefBS::PrecisionStyle precision, | |
344 HeapRegionDCTOC::FilterKind fk) { | |
345 return new HeapRegionDCTOC(G1CollectedHeap::heap(), | |
346 this, cl, precision, fk); | |
347 } | 341 } |
348 | 342 |
349 void HeapRegion::hr_clear(bool par, bool clear_space) { | 343 void HeapRegion::hr_clear(bool par, bool clear_space) { |
350 assert(_humongous_type == NotHumongous, | 344 assert(_humongous_type == NotHumongous, |
351 "we should have already filtered out humongous regions"); | 345 "we should have already filtered out humongous regions"); |
353 "we should have already filtered out humongous regions"); | 347 "we should have already filtered out humongous regions"); |
354 assert(_end == _orig_end, | 348 assert(_end == _orig_end, |
355 "we should have already filtered out humongous regions"); | 349 "we should have already filtered out humongous regions"); |
356 | 350 |
357 _in_collection_set = false; | 351 _in_collection_set = false; |
358 _is_gc_alloc_region = false; | |
359 | 352 |
360 set_young_index_in_cset(-1); | 353 set_young_index_in_cset(-1); |
361 uninstall_surv_rate_group(); | 354 uninstall_surv_rate_group(); |
362 set_young_type(NotYoung); | 355 set_young_type(NotYoung); |
363 reset_pre_dummy_top(); | 356 reset_pre_dummy_top(); |
376 if (clear_space) clear(SpaceDecorator::Mangle); | 369 if (clear_space) clear(SpaceDecorator::Mangle); |
377 } | 370 } |
378 | 371 |
379 void HeapRegion::par_clear() { | 372 void HeapRegion::par_clear() { |
380 assert(used() == 0, "the region should have been already cleared"); | 373 assert(used() == 0, "the region should have been already cleared"); |
381 assert(capacity() == (size_t) HeapRegion::GrainBytes, | 374 assert(capacity() == HeapRegion::GrainBytes, "should be back to normal"); |
382 "should be back to normal"); | |
383 HeapRegionRemSet* hrrs = rem_set(); | 375 HeapRegionRemSet* hrrs = rem_set(); |
384 hrrs->clear(); | 376 hrrs->clear(); |
385 CardTableModRefBS* ct_bs = | 377 CardTableModRefBS* ct_bs = |
386 (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); | 378 (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); |
387 ct_bs->clear(MemRegion(bottom(), end())); | 379 ct_bs->clear(MemRegion(bottom(), end())); |
433 } else { | 425 } else { |
434 // continues humongous | 426 // continues humongous |
435 assert(end() == _orig_end, "sanity"); | 427 assert(end() == _orig_end, "sanity"); |
436 } | 428 } |
437 | 429 |
438 assert(capacity() == (size_t) HeapRegion::GrainBytes, "pre-condition"); | 430 assert(capacity() == HeapRegion::GrainBytes, "pre-condition"); |
439 _humongous_type = NotHumongous; | 431 _humongous_type = NotHumongous; |
440 _humongous_start_region = NULL; | 432 _humongous_start_region = NULL; |
441 } | 433 } |
442 | 434 |
443 bool HeapRegion::claimHeapRegion(jint claimValue) { | 435 bool HeapRegion::claimHeapRegion(jint claimValue) { |
482 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | 474 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
483 #endif // _MSC_VER | 475 #endif // _MSC_VER |
484 | 476 |
485 | 477 |
486 HeapRegion:: | 478 HeapRegion:: |
487 HeapRegion(G1BlockOffsetSharedArray* sharedOffsetArray, | 479 HeapRegion(size_t hrs_index, G1BlockOffsetSharedArray* sharedOffsetArray, |
488 MemRegion mr, bool is_zeroed) | 480 MemRegion mr, bool is_zeroed) |
489 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), | 481 : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), |
490 _next_fk(HeapRegionDCTOC::NoFilterKind), | 482 _hrs_index(hrs_index), |
491 _hrs_index(-1), | |
492 _humongous_type(NotHumongous), _humongous_start_region(NULL), | 483 _humongous_type(NotHumongous), _humongous_start_region(NULL), |
493 _in_collection_set(false), _is_gc_alloc_region(false), | 484 _in_collection_set(false), |
494 _next_in_special_set(NULL), _orig_end(NULL), | 485 _next_in_special_set(NULL), _orig_end(NULL), |
495 _claimed(InitialClaimValue), _evacuation_failed(false), | 486 _claimed(InitialClaimValue), _evacuation_failed(false), |
496 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), | 487 _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1), |
488 _gc_efficiency(0.0), | |
497 _young_type(NotYoung), _next_young_region(NULL), | 489 _young_type(NotYoung), _next_young_region(NULL), |
498 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), | 490 _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false), |
499 #ifdef ASSERT | 491 #ifdef ASSERT |
500 _containing_set(NULL), | 492 _containing_set(NULL), |
501 #endif // ASSERT | 493 #endif // ASSERT |
718 } else { | 710 } else { |
719 st->print(" "); | 711 st->print(" "); |
720 } | 712 } |
721 if (in_collection_set()) | 713 if (in_collection_set()) |
722 st->print(" CS"); | 714 st->print(" CS"); |
723 else if (is_gc_alloc_region()) | |
724 st->print(" A "); | |
725 else | 715 else |
726 st->print(" "); | 716 st->print(" "); |
727 if (is_young()) | 717 if (is_young()) |
728 st->print(is_survivor() ? " SU" : " Y "); | 718 st->print(is_survivor() ? " SU" : " Y "); |
729 else | 719 else |
730 st->print(" "); | 720 st->print(" "); |
731 if (is_empty()) | 721 if (is_empty()) |
732 st->print(" F"); | 722 st->print(" F"); |
733 else | 723 else |
734 st->print(" "); | 724 st->print(" "); |
735 st->print(" %5d", _gc_time_stamp); | 725 st->print(" TS %5d", _gc_time_stamp); |
736 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, | 726 st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT, |
737 prev_top_at_mark_start(), next_top_at_mark_start()); | 727 prev_top_at_mark_start(), next_top_at_mark_start()); |
738 G1OffsetTableContigSpace::print_on(st); | 728 G1OffsetTableContigSpace::print_on(st); |
739 } | 729 } |
740 | 730 |
741 void HeapRegion::verify(bool allow_dirty) const { | 731 void HeapRegion::verify(bool allow_dirty) const { |
742 bool dummy = false; | 732 bool dummy = false; |
743 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); | 733 verify(allow_dirty, VerifyOption_G1UsePrevMarking, /* failures */ &dummy); |
744 } | 734 } |
745 | 735 |
746 // This really ought to be commoned up into OffsetTableContigSpace somehow. | 736 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
747 // We would need a mechanism to make that code skip dead objects. | 737 // We would need a mechanism to make that code skip dead objects. |
748 | 738 |
749 void HeapRegion::verify(bool allow_dirty, | 739 void HeapRegion::verify(bool allow_dirty, |
750 bool use_prev_marking, | 740 VerifyOption vo, |
751 bool* failures) const { | 741 bool* failures) const { |
752 G1CollectedHeap* g1 = G1CollectedHeap::heap(); | 742 G1CollectedHeap* g1 = G1CollectedHeap::heap(); |
753 *failures = false; | 743 *failures = false; |
754 HeapWord* p = bottom(); | 744 HeapWord* p = bottom(); |
755 HeapWord* prev_p = NULL; | 745 HeapWord* prev_p = NULL; |
756 VerifyLiveClosure vl_cl(g1, use_prev_marking); | 746 VerifyLiveClosure vl_cl(g1, vo); |
757 bool is_humongous = isHumongous(); | 747 bool is_humongous = isHumongous(); |
758 bool do_bot_verify = !is_young(); | 748 bool do_bot_verify = !is_young(); |
759 size_t object_num = 0; | 749 size_t object_num = 0; |
760 while (p < top()) { | 750 while (p < top()) { |
761 oop obj = oop(p); | 751 oop obj = oop(p); |
776 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) { | 766 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) { |
777 *failures = true; | 767 *failures = true; |
778 return; | 768 return; |
779 } | 769 } |
780 | 770 |
781 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) { | 771 if (!g1->is_obj_dead_cond(obj, this, vo)) { |
782 if (obj->is_oop()) { | 772 if (obj->is_oop()) { |
783 klassOop klass = obj->klass(); | 773 klassOop klass = obj->klass(); |
784 if (!klass->is_perm()) { | 774 if (!klass->is_perm()) { |
785 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " | 775 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " |
786 "not in perm", klass, obj); | 776 "not in perm", klass, obj); |