34 #include "gc/g1/heapRegionRemSet.hpp"
35 #include "gc/g1/heapRegionTracer.hpp"
36 #include "gc/shared/genOopClosures.inline.hpp"
37 #include "gc/shared/space.inline.hpp"
38 #include "logging/log.hpp"
39 #include "memory/iterator.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "oops/oop.inline.hpp"
42 #include "runtime/atomic.hpp"
43 #include "runtime/orderAccess.inline.hpp"
44
45 int HeapRegion::LogOfHRGrainBytes = 0;
46 int HeapRegion::LogOfHRGrainWords = 0;
47 size_t HeapRegion::GrainBytes = 0;
48 size_t HeapRegion::GrainWords = 0;
49 size_t HeapRegion::CardsPerRegion = 0;
50
51 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1,
52 HeapRegion* hr,
53 G1ParPushHeapRSClosure* cl,
54 CardTableModRefBS::PrecisionStyle precision) :
55 DirtyCardToOopClosure(hr, cl, precision, NULL),
56 _hr(hr), _rs_scan(cl), _g1(g1) { }
57
58 void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
59 HeapWord* bottom,
60 HeapWord* top) {
61 G1CollectedHeap* g1h = _g1;
62 size_t oop_size;
63 HeapWord* cur = bottom;
64
65 // Start filtering what we add to the remembered set. If the object is
66 // not considered dead, either because it is marked (in the mark bitmap)
67 // or it was allocated after marking finished, then we add it. Otherwise
68 // we can safely ignore the object.
69 if (!g1h->is_obj_dead(oop(cur))) {
70 oop_size = oop(cur)->oop_iterate_size(_rs_scan, mr);
71 } else {
72 oop_size = _hr->block_size(cur);
73 }
74
131 region_size_log = log2_long((jlong) region_size);
132
133 // Now, set up the globals.
134 guarantee(LogOfHRGrainBytes == 0, "we should only set it once");
135 LogOfHRGrainBytes = region_size_log;
136
137 guarantee(LogOfHRGrainWords == 0, "we should only set it once");
138 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize;
139
140 guarantee(GrainBytes == 0, "we should only set it once");
141 // The cast to int is safe, given that we've bounded region_size by
142 // MIN_REGION_SIZE and MAX_REGION_SIZE.
143 GrainBytes = region_size;
144 log_info(gc, heap)("Heap region size: " SIZE_FORMAT "M", GrainBytes / M);
145
146 guarantee(GrainWords == 0, "we should only set it once");
147 GrainWords = GrainBytes >> LogHeapWordSize;
148 guarantee((size_t) 1 << LogOfHRGrainWords == GrainWords, "sanity");
149
150 guarantee(CardsPerRegion == 0, "we should only set it once");
151 CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift;
152
153 if (G1HeapRegionSize != GrainBytes) {
154 FLAG_SET_ERGO(size_t, G1HeapRegionSize, GrainBytes);
155 }
156 }
157
158 void HeapRegion::reset_after_compaction() {
159 G1ContiguousSpace::reset_after_compaction();
160 // After a compaction the mark bitmap is invalid, so we must
161 // treat all objects as being inside the unmarked area.
162 zero_marked_bytes();
163 init_top_at_mark_start();
164 }
165
166 void HeapRegion::hr_clear(bool keep_remset, bool clear_space, bool locked) {
167 assert(_humongous_start_region == NULL,
168 "we should have already filtered out humongous regions");
169 assert(!in_collection_set(),
170 "Should not clear heap region %u in the collection set", hrm_index());
171
178 if (!keep_remset) {
179 if (locked) {
180 rem_set()->clear_locked();
181 } else {
182 rem_set()->clear();
183 }
184 }
185
186 zero_marked_bytes();
187
188 init_top_at_mark_start();
189 _gc_time_stamp = G1CollectedHeap::heap()->get_gc_time_stamp();
190 if (clear_space) clear(SpaceDecorator::Mangle);
191 }
192
193 void HeapRegion::par_clear() {
194 assert(used() == 0, "the region should have been already cleared");
195 assert(capacity() == HeapRegion::GrainBytes, "should be back to normal");
196 HeapRegionRemSet* hrrs = rem_set();
197 hrrs->clear();
198 CardTableModRefBS* ct_bs =
199 barrier_set_cast<CardTableModRefBS>(G1CollectedHeap::heap()->barrier_set());
200 ct_bs->clear(MemRegion(bottom(), end()));
201 }
202
203 void HeapRegion::calc_gc_efficiency() {
204 // GC efficiency is the ratio of how much space would be
205 // reclaimed over how long we predict it would take to reclaim it.
206 G1CollectedHeap* g1h = G1CollectedHeap::heap();
207 G1Policy* g1p = g1h->g1_policy();
208
209 // Retrieve a prediction of the elapsed time for this region for
210 // a mixed gc because the region will only be evacuated during a
211 // mixed gc.
212 double region_elapsed_time_ms =
213 g1p->predict_region_elapsed_time_ms(this, false /* for_young_gc */);
214 _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
215 }
216
217 void HeapRegion::set_free() {
218 report_region_type_change(G1HeapRegionTraceType::Free);
219 _type.set_free();
220 }
601 void HeapRegion::print_on(outputStream* st) const {
602 st->print("|%4u", this->_hrm_index);
603 st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT,
604 p2i(bottom()), p2i(top()), p2i(end()));
605 st->print("|%3d%%", (int) ((double) used() * 100 / capacity()));
606 st->print("|%2s", get_short_type_str());
607 if (in_collection_set()) {
608 st->print("|CS");
609 } else {
610 st->print("| ");
611 }
612 st->print("|TS%3u", _gc_time_stamp);
613 st->print("|AC%3u", allocation_context());
614 st->print_cr("|TAMS " PTR_FORMAT ", " PTR_FORMAT "|",
615 p2i(prev_top_at_mark_start()), p2i(next_top_at_mark_start()));
616 }
617
618 class G1VerificationClosure : public OopClosure {
619 protected:
620 G1CollectedHeap* _g1h;
621 CardTableModRefBS* _bs;
622 oop _containing_obj;
623 bool _failures;
624 int _n_failures;
625 VerifyOption _vo;
626 public:
627 // _vo == UsePrevMarking -> use "prev" marking information,
628 // _vo == UseNextMarking -> use "next" marking information,
629 // _vo == UseMarkWord -> use mark word from object header.
630 G1VerificationClosure(G1CollectedHeap* g1h, VerifyOption vo) :
631 _g1h(g1h), _bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())),
632 _containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo) {
633 }
634
635 void set_containing_obj(oop obj) {
636 _containing_obj = obj;
637 }
638
639 bool failures() { return _failures; }
640 int n_failures() { return _n_failures; }
641
642 void print_object(outputStream* out, oop obj) {
643 #ifdef PRODUCT
644 Klass* k = obj->klass();
645 const char* class_name = k->external_name();
646 out->print_cr("class name %s", class_name);
647 #else // PRODUCT
648 obj->print_on(out);
649 #endif // PRODUCT
650 }
651 };
712
713 template <class T>
714 void do_oop_work(T* p) {
715 assert(_containing_obj != NULL, "Precondition");
716 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
717 "Precondition");
718 verify_remembered_set(p);
719 }
720
721 template <class T>
722 void verify_remembered_set(T* p) {
723 T heap_oop = oopDesc::load_heap_oop(p);
724 Log(gc, verify) log;
725 if (!oopDesc::is_null(heap_oop)) {
726 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
727 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
728 HeapRegion* to = _g1h->heap_region_containing(obj);
729 if (from != NULL && to != NULL &&
730 from != to &&
731 !to->is_pinned()) {
732 jbyte cv_obj = *_bs->byte_for_const(_containing_obj);
733 jbyte cv_field = *_bs->byte_for_const(p);
734 const jbyte dirty = CardTableModRefBS::dirty_card_val();
735
736 bool is_bad = !(from->is_young()
737 || to->rem_set()->contains_reference(p)
738 || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
739 (_containing_obj->is_objArray() ?
740 cv_field == dirty
741 : cv_obj == dirty || cv_field == dirty));
742 if (is_bad) {
743 MutexLockerEx x(ParGCRareEvent_lock,
744 Mutex::_no_safepoint_check_flag);
745
746 if (!_failures) {
747 log.error("----------");
748 }
749 log.error("Missing rem set entry:");
750 log.error("Field " PTR_FORMAT " of obj " PTR_FORMAT ", in region " HR_FORMAT,
751 p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
752 ResourceMark rm;
753 _containing_obj->print_on(log.error_stream());
754 log.error("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
1062 blk->do_object(oop(p));
1063 }
1064 p += block_size(p);
1065 }
1066 }
1067
1068 G1ContiguousSpace::G1ContiguousSpace(G1BlockOffsetTable* bot) :
1069 _bot_part(bot, this),
1070 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true),
1071 _gc_time_stamp(0)
1072 {
1073 }
1074
1075 void G1ContiguousSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
1076 CompactibleSpace::initialize(mr, clear_space, mangle_space);
1077 _top = bottom();
1078 _scan_top = bottom();
1079 set_saved_mark_word(NULL);
1080 reset_bot();
1081 }
1082
|
34 #include "gc/g1/heapRegionRemSet.hpp"
35 #include "gc/g1/heapRegionTracer.hpp"
36 #include "gc/shared/genOopClosures.inline.hpp"
37 #include "gc/shared/space.inline.hpp"
38 #include "logging/log.hpp"
39 #include "memory/iterator.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "oops/oop.inline.hpp"
42 #include "runtime/atomic.hpp"
43 #include "runtime/orderAccess.inline.hpp"
44
45 int HeapRegion::LogOfHRGrainBytes = 0;
46 int HeapRegion::LogOfHRGrainWords = 0;
47 size_t HeapRegion::GrainBytes = 0;
48 size_t HeapRegion::GrainWords = 0;
49 size_t HeapRegion::CardsPerRegion = 0;
50
51 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1,
52 HeapRegion* hr,
53 G1ParPushHeapRSClosure* cl,
54 CardTable::PrecisionStyle precision) :
55 DirtyCardToOopClosure(hr, cl, precision, NULL),
56 _hr(hr), _rs_scan(cl), _g1(g1) { }
57
58 void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
59 HeapWord* bottom,
60 HeapWord* top) {
61 G1CollectedHeap* g1h = _g1;
62 size_t oop_size;
63 HeapWord* cur = bottom;
64
65 // Start filtering what we add to the remembered set. If the object is
66 // not considered dead, either because it is marked (in the mark bitmap)
67 // or it was allocated after marking finished, then we add it. Otherwise
68 // we can safely ignore the object.
69 if (!g1h->is_obj_dead(oop(cur))) {
70 oop_size = oop(cur)->oop_iterate_size(_rs_scan, mr);
71 } else {
72 oop_size = _hr->block_size(cur);
73 }
74
131 region_size_log = log2_long((jlong) region_size);
132
133 // Now, set up the globals.
134 guarantee(LogOfHRGrainBytes == 0, "we should only set it once");
135 LogOfHRGrainBytes = region_size_log;
136
137 guarantee(LogOfHRGrainWords == 0, "we should only set it once");
138 LogOfHRGrainWords = LogOfHRGrainBytes - LogHeapWordSize;
139
140 guarantee(GrainBytes == 0, "we should only set it once");
141 // The cast to int is safe, given that we've bounded region_size by
142 // MIN_REGION_SIZE and MAX_REGION_SIZE.
143 GrainBytes = region_size;
144 log_info(gc, heap)("Heap region size: " SIZE_FORMAT "M", GrainBytes / M);
145
146 guarantee(GrainWords == 0, "we should only set it once");
147 GrainWords = GrainBytes >> LogHeapWordSize;
148 guarantee((size_t) 1 << LogOfHRGrainWords == GrainWords, "sanity");
149
150 guarantee(CardsPerRegion == 0, "we should only set it once");
151 CardsPerRegion = GrainBytes >> G1CardTable::card_shift;
152
153 if (G1HeapRegionSize != GrainBytes) {
154 FLAG_SET_ERGO(size_t, G1HeapRegionSize, GrainBytes);
155 }
156 }
157
158 void HeapRegion::reset_after_compaction() {
159 G1ContiguousSpace::reset_after_compaction();
160 // After a compaction the mark bitmap is invalid, so we must
161 // treat all objects as being inside the unmarked area.
162 zero_marked_bytes();
163 init_top_at_mark_start();
164 }
165
166 void HeapRegion::hr_clear(bool keep_remset, bool clear_space, bool locked) {
167 assert(_humongous_start_region == NULL,
168 "we should have already filtered out humongous regions");
169 assert(!in_collection_set(),
170 "Should not clear heap region %u in the collection set", hrm_index());
171
178 if (!keep_remset) {
179 if (locked) {
180 rem_set()->clear_locked();
181 } else {
182 rem_set()->clear();
183 }
184 }
185
186 zero_marked_bytes();
187
188 init_top_at_mark_start();
189 _gc_time_stamp = G1CollectedHeap::heap()->get_gc_time_stamp();
190 if (clear_space) clear(SpaceDecorator::Mangle);
191 }
192
193 void HeapRegion::par_clear() {
194 assert(used() == 0, "the region should have been already cleared");
195 assert(capacity() == HeapRegion::GrainBytes, "should be back to normal");
196 HeapRegionRemSet* hrrs = rem_set();
197 hrrs->clear();
198 G1CardTable* ct = G1CollectedHeap::heap()->g1_card_table();
199 ct->clear(MemRegion(bottom(), end()));
200 }
201
202 void HeapRegion::calc_gc_efficiency() {
203 // GC efficiency is the ratio of how much space would be
204 // reclaimed over how long we predict it would take to reclaim it.
205 G1CollectedHeap* g1h = G1CollectedHeap::heap();
206 G1Policy* g1p = g1h->g1_policy();
207
208 // Retrieve a prediction of the elapsed time for this region for
209 // a mixed gc because the region will only be evacuated during a
210 // mixed gc.
211 double region_elapsed_time_ms =
212 g1p->predict_region_elapsed_time_ms(this, false /* for_young_gc */);
213 _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
214 }
215
216 void HeapRegion::set_free() {
217 report_region_type_change(G1HeapRegionTraceType::Free);
218 _type.set_free();
219 }
600 void HeapRegion::print_on(outputStream* st) const {
601 st->print("|%4u", this->_hrm_index);
602 st->print("|" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT,
603 p2i(bottom()), p2i(top()), p2i(end()));
604 st->print("|%3d%%", (int) ((double) used() * 100 / capacity()));
605 st->print("|%2s", get_short_type_str());
606 if (in_collection_set()) {
607 st->print("|CS");
608 } else {
609 st->print("| ");
610 }
611 st->print("|TS%3u", _gc_time_stamp);
612 st->print("|AC%3u", allocation_context());
613 st->print_cr("|TAMS " PTR_FORMAT ", " PTR_FORMAT "|",
614 p2i(prev_top_at_mark_start()), p2i(next_top_at_mark_start()));
615 }
616
617 class G1VerificationClosure : public OopClosure {
618 protected:
619 G1CollectedHeap* _g1h;
620 G1CardTable *_ct;
621 oop _containing_obj;
622 bool _failures;
623 int _n_failures;
624 VerifyOption _vo;
625 public:
626 // _vo == UsePrevMarking -> use "prev" marking information,
627 // _vo == UseNextMarking -> use "next" marking information,
628 // _vo == UseMarkWord -> use mark word from object header.
629 G1VerificationClosure(G1CollectedHeap* g1h, VerifyOption vo) :
630 _g1h(g1h), _ct(g1h->g1_card_table()),
631 _containing_obj(NULL), _failures(false), _n_failures(0), _vo(vo) {
632 }
633
634 void set_containing_obj(oop obj) {
635 _containing_obj = obj;
636 }
637
638 bool failures() { return _failures; }
639 int n_failures() { return _n_failures; }
640
641 void print_object(outputStream* out, oop obj) {
642 #ifdef PRODUCT
643 Klass* k = obj->klass();
644 const char* class_name = k->external_name();
645 out->print_cr("class name %s", class_name);
646 #else // PRODUCT
647 obj->print_on(out);
648 #endif // PRODUCT
649 }
650 };
711
712 template <class T>
713 void do_oop_work(T* p) {
714 assert(_containing_obj != NULL, "Precondition");
715 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
716 "Precondition");
717 verify_remembered_set(p);
718 }
719
720 template <class T>
721 void verify_remembered_set(T* p) {
722 T heap_oop = oopDesc::load_heap_oop(p);
723 Log(gc, verify) log;
724 if (!oopDesc::is_null(heap_oop)) {
725 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
726 HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p);
727 HeapRegion* to = _g1h->heap_region_containing(obj);
728 if (from != NULL && to != NULL &&
729 from != to &&
730 !to->is_pinned()) {
731 jbyte cv_obj = *_ct->byte_for_const(_containing_obj);
732 jbyte cv_field = *_ct->byte_for_const(p);
733 const jbyte dirty = G1CardTable::dirty_card_val();
734
735 bool is_bad = !(from->is_young()
736 || to->rem_set()->contains_reference(p)
737 || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed
738 (_containing_obj->is_objArray() ?
739 cv_field == dirty
740 : cv_obj == dirty || cv_field == dirty));
741 if (is_bad) {
742 MutexLockerEx x(ParGCRareEvent_lock,
743 Mutex::_no_safepoint_check_flag);
744
745 if (!_failures) {
746 log.error("----------");
747 }
748 log.error("Missing rem set entry:");
749 log.error("Field " PTR_FORMAT " of obj " PTR_FORMAT ", in region " HR_FORMAT,
750 p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
751 ResourceMark rm;
752 _containing_obj->print_on(log.error_stream());
753 log.error("points to obj " PTR_FORMAT " in region " HR_FORMAT, p2i(obj), HR_FORMAT_PARAMS(to));
1061 blk->do_object(oop(p));
1062 }
1063 p += block_size(p);
1064 }
1065 }
1066
1067 G1ContiguousSpace::G1ContiguousSpace(G1BlockOffsetTable* bot) :
1068 _bot_part(bot, this),
1069 _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true),
1070 _gc_time_stamp(0)
1071 {
1072 }
1073
1074 void G1ContiguousSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) {
1075 CompactibleSpace::initialize(mr, clear_space, mangle_space);
1076 _top = bottom();
1077 _scan_top = bottom();
1078 set_saved_mark_word(NULL);
1079 reset_bot();
1080 }
|