33 #include "gc/g1/heapRegionBounds.inline.hpp" |
33 #include "gc/g1/heapRegionBounds.inline.hpp" |
34 #include "gc/g1/heapRegionManager.inline.hpp" |
34 #include "gc/g1/heapRegionManager.inline.hpp" |
35 #include "gc/g1/heapRegionRemSet.hpp" |
35 #include "gc/g1/heapRegionRemSet.hpp" |
36 #include "gc/g1/heapRegionTracer.hpp" |
36 #include "gc/g1/heapRegionTracer.hpp" |
37 #include "gc/shared/genOopClosures.inline.hpp" |
37 #include "gc/shared/genOopClosures.inline.hpp" |
38 #include "gc/shared/space.inline.hpp" |
|
39 #include "logging/log.hpp" |
38 #include "logging/log.hpp" |
40 #include "logging/logStream.hpp" |
39 #include "logging/logStream.hpp" |
41 #include "memory/iterator.inline.hpp" |
40 #include "memory/iterator.inline.hpp" |
42 #include "memory/resourceArea.hpp" |
41 #include "memory/resourceArea.hpp" |
43 #include "oops/access.inline.hpp" |
42 #include "oops/access.inline.hpp" |
44 #include "oops/compressedOops.inline.hpp" |
43 #include "oops/compressedOops.inline.hpp" |
45 #include "oops/oop.inline.hpp" |
44 #include "oops/oop.inline.hpp" |
46 #include "runtime/atomic.hpp" |
45 #include "runtime/atomic.hpp" |
47 #include "runtime/orderAccess.hpp" |
46 #include "runtime/orderAccess.hpp" |
48 #include "utilities/growableArray.hpp" |
|
49 |
47 |
50 int HeapRegion::LogOfHRGrainBytes = 0; |
48 int HeapRegion::LogOfHRGrainBytes = 0; |
51 int HeapRegion::LogOfHRGrainWords = 0; |
49 int HeapRegion::LogOfHRGrainWords = 0; |
52 int HeapRegion::LogCardsPerRegion = 0; |
50 int HeapRegion::LogCardsPerRegion = 0; |
53 size_t HeapRegion::GrainBytes = 0; |
51 size_t HeapRegion::GrainBytes = 0; |
232 } |
230 } |
233 |
231 |
234 HeapRegion::HeapRegion(uint hrm_index, |
232 HeapRegion::HeapRegion(uint hrm_index, |
235 G1BlockOffsetTable* bot, |
233 G1BlockOffsetTable* bot, |
236 MemRegion mr) : |
234 MemRegion mr) : |
237 G1ContiguousSpace(bot), |
235 _bottom(NULL), |
238 _rem_set(NULL), |
236 _end(NULL), |
239 _hrm_index(hrm_index), |
237 _top(NULL), |
240 _type(), |
238 _compaction_top(NULL), |
241 _humongous_start_region(NULL), |
239 _bot_part(bot, this), |
242 _evacuation_failed(false), |
240 _par_alloc_lock(Mutex::leaf, "HeapRegion par alloc lock", true), |
243 _next(NULL), _prev(NULL), |
241 _pre_dummy_top(NULL), |
|
242 _rem_set(NULL), |
|
243 _hrm_index(hrm_index), |
|
244 _type(), |
|
245 _humongous_start_region(NULL), |
|
246 _evacuation_failed(false), |
|
247 _next(NULL), _prev(NULL), |
244 #ifdef ASSERT |
248 #ifdef ASSERT |
245 _containing_set(NULL), |
249 _containing_set(NULL), |
246 #endif |
250 #endif |
247 _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0), |
251 _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0), |
248 _index_in_opt_cset(InvalidCSetIndex), _young_index_in_cset(-1), |
252 _index_in_opt_cset(InvalidCSetIndex), _young_index_in_cset(-1), |
249 _surv_rate_group(NULL), _age_index(-1), |
253 _surv_rate_group(NULL), _age_index(-1), |
250 _prev_top_at_mark_start(NULL), _next_top_at_mark_start(NULL), |
254 _prev_top_at_mark_start(NULL), _next_top_at_mark_start(NULL), |
251 _recorded_rs_length(0), _predicted_elapsed_time_ms(0) |
255 _recorded_rs_length(0), _predicted_elapsed_time_ms(0) |
252 { |
256 { |
253 _rem_set = new HeapRegionRemSet(bot, this); |
257 _rem_set = new HeapRegionRemSet(bot, this); |
254 |
258 |
255 initialize(mr); |
259 initialize(mr); |
256 } |
260 } |
257 |
261 |
258 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
262 void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
259 assert(_rem_set->is_empty(), "Remembered set must be empty"); |
263 assert(_rem_set->is_empty(), "Remembered set must be empty"); |
260 |
264 |
261 G1ContiguousSpace::initialize(mr, clear_space, mangle_space); |
265 assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), |
|
266 "invalid space boundaries"); |
|
267 |
|
268 set_bottom(mr.start()); |
|
269 set_end(mr.end()); |
|
270 if (clear_space) { |
|
271 clear(mangle_space); |
|
272 } |
|
273 |
|
274 set_top(bottom()); |
|
275 set_compaction_top(bottom()); |
|
276 reset_bot(); |
262 |
277 |
263 hr_clear(false /*par*/, false /*clear_space*/); |
278 hr_clear(false /*par*/, false /*clear_space*/); |
264 set_top(bottom()); |
|
265 } |
279 } |
266 |
280 |
267 void HeapRegion::report_region_type_change(G1HeapRegionTraceType::Type to) { |
281 void HeapRegion::report_region_type_change(G1HeapRegionTraceType::Type to) { |
268 HeapRegionTracer::send_region_type_change(_hrm_index, |
282 HeapRegionTracer::send_region_type_change(_hrm_index, |
269 get_trace_type(), |
283 get_trace_type(), |
442 *failures = true; |
456 *failures = true; |
443 } |
457 } |
444 } |
458 } |
445 |
459 |
446 void HeapRegion::print() const { print_on(tty); } |
460 void HeapRegion::print() const { print_on(tty); } |
|
461 |
447 void HeapRegion::print_on(outputStream* st) const { |
462 void HeapRegion::print_on(outputStream* st) const { |
448 st->print("|%4u", this->_hrm_index); |
463 st->print("|%4u", this->_hrm_index); |
449 st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT, |
464 st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT, |
450 p2i(bottom()), p2i(top()), p2i(end())); |
465 p2i(bottom()), p2i(top()), p2i(end())); |
451 st->print("|%3d%%", (int) ((double) used() * 100 / capacity())); |
466 st->print("|%3d%%", (int) ((double) used() * 100 / capacity())); |
634 |
649 |
635 // This closure provides its own oop verification code. |
650 // This closure provides its own oop verification code. |
636 debug_only(virtual bool should_verify_oops() { return false; }) |
651 debug_only(virtual bool should_verify_oops() { return false; }) |
637 }; |
652 }; |
638 |
653 |
639 // This really ought to be commoned up into OffsetTableContigSpace somehow. |
|
640 // We would need a mechanism to make that code skip dead objects. |
|
641 |
|
642 void HeapRegion::verify(VerifyOption vo, |
654 void HeapRegion::verify(VerifyOption vo, |
643 bool* failures) const { |
655 bool* failures) const { |
644 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
656 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
645 *failures = false; |
657 *failures = false; |
646 HeapWord* p = bottom(); |
658 HeapWord* p = bottom(); |
826 bool failures = false; |
838 bool failures = false; |
827 verify_rem_set(VerifyOption_G1UsePrevMarking, &failures); |
839 verify_rem_set(VerifyOption_G1UsePrevMarking, &failures); |
828 guarantee(!failures, "HeapRegion RemSet verification failed"); |
840 guarantee(!failures, "HeapRegion RemSet verification failed"); |
829 } |
841 } |
830 |
842 |
831 void HeapRegion::prepare_for_compaction(CompactPoint* cp) { |
843 void HeapRegion::clear(bool mangle_space) { |
832 // Not used for G1 anymore, but pure virtual in Space. |
|
833 ShouldNotReachHere(); |
|
834 } |
|
835 |
|
836 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go |
|
837 // away eventually. |
|
838 |
|
839 void G1ContiguousSpace::clear(bool mangle_space) { |
|
840 set_top(bottom()); |
844 set_top(bottom()); |
841 CompactibleSpace::clear(mangle_space); |
845 set_compaction_top(bottom()); |
|
846 |
|
847 if (ZapUnusedHeapArea && mangle_space) { |
|
848 mangle_unused_area(); |
|
849 } |
842 reset_bot(); |
850 reset_bot(); |
843 } |
851 } |
|
852 |
844 #ifndef PRODUCT |
853 #ifndef PRODUCT |
845 void G1ContiguousSpace::mangle_unused_area() { |
854 void HeapRegion::mangle_unused_area() { |
846 mangle_unused_area_complete(); |
|
847 } |
|
848 |
|
849 void G1ContiguousSpace::mangle_unused_area_complete() { |
|
850 SpaceMangler::mangle_region(MemRegion(top(), end())); |
855 SpaceMangler::mangle_region(MemRegion(top(), end())); |
851 } |
856 } |
852 #endif |
857 #endif |
853 |
858 |
854 void G1ContiguousSpace::print() const { |
859 HeapWord* HeapRegion::initialize_threshold() { |
855 print_short(); |
|
856 tty->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " |
|
857 INTPTR_FORMAT ", " INTPTR_FORMAT ")", |
|
858 p2i(bottom()), p2i(top()), p2i(_bot_part.threshold()), p2i(end())); |
|
859 } |
|
860 |
|
861 HeapWord* G1ContiguousSpace::initialize_threshold() { |
|
862 return _bot_part.initialize_threshold(); |
860 return _bot_part.initialize_threshold(); |
863 } |
861 } |
864 |
862 |
865 HeapWord* G1ContiguousSpace::cross_threshold(HeapWord* start, |
863 HeapWord* HeapRegion::cross_threshold(HeapWord* start, HeapWord* end) { |
866 HeapWord* end) { |
|
867 _bot_part.alloc_block(start, end); |
864 _bot_part.alloc_block(start, end); |
868 return _bot_part.threshold(); |
865 return _bot_part.threshold(); |
869 } |
866 } |
870 |
867 |
871 void G1ContiguousSpace::safe_object_iterate(ObjectClosure* blk) { |
868 void HeapRegion::object_iterate(ObjectClosure* blk) { |
872 object_iterate(blk); |
|
873 } |
|
874 |
|
875 void G1ContiguousSpace::object_iterate(ObjectClosure* blk) { |
|
876 HeapWord* p = bottom(); |
869 HeapWord* p = bottom(); |
877 while (p < top()) { |
870 while (p < top()) { |
878 if (block_is_obj(p)) { |
871 if (block_is_obj(p)) { |
879 blk->do_object(oop(p)); |
872 blk->do_object(oop(p)); |
880 } |
873 } |
881 p += block_size(p); |
874 p += block_size(p); |
882 } |
875 } |
883 } |
876 } |
884 |
|
885 G1ContiguousSpace::G1ContiguousSpace(G1BlockOffsetTable* bot) : |
|
886 _top(NULL), |
|
887 _bot_part(bot, this), |
|
888 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), |
|
889 _pre_dummy_top(NULL) |
|
890 { |
|
891 } |
|
892 |
|
893 void G1ContiguousSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { |
|
894 CompactibleSpace::initialize(mr, clear_space, mangle_space); |
|
895 _top = bottom(); |
|
896 set_saved_mark_word(NULL); |
|
897 reset_bot(); |
|
898 } |
|