8183127: UpdateRSetDeferred should not enqueue cards for NULL references
Summary: Filter out NULL references during generating cards for an object.
Reviewed-by: mgerdin, ehelin
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Wed Jul 05 20:16:26 2017 -0700
+++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Jul 06 10:42:02 2017 +0200
@@ -40,27 +40,30 @@
G1CollectedHeap* _g1;
DirtyCardQueue *_dcq;
G1SATBCardTableModRefBS* _ct_bs;
- HeapRegion* _from;
public:
UpdateRSetDeferred(DirtyCardQueue* dcq) :
- _g1(G1CollectedHeap::heap()), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq), _from(NULL) {}
+ _g1(G1CollectedHeap::heap()), _ct_bs(_g1->g1_barrier_set()), _dcq(dcq) {}
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop( oop* p) { do_oop_work(p); }
template <class T> void do_oop_work(T* p) {
- assert(_from->is_in_reserved(p), "paranoia");
- assert(!_from->is_survivor(), "Unexpected evac failure in survivor region");
+ assert(_g1->heap_region_containing(p)->is_in_reserved(p), "paranoia");
+ assert(!_g1->heap_region_containing(p)->is_survivor(), "Unexpected evac failure in survivor region");
- if (!_from->is_in_reserved(oopDesc::load_decode_heap_oop(p))) {
- size_t card_index = _ct_bs->index_for(p);
- if (_ct_bs->mark_card_deferred(card_index)) {
- _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
- }
+ T const o = oopDesc::load_heap_oop(p);
+ if (oopDesc::is_null(o)) {
+ return;
+ }
+
+ if (HeapRegion::is_in_same_region(p, oopDesc::decode_heap_oop(o))) {
+ return;
+ }
+ size_t card_index = _ct_bs->index_for(p);
+ if (_ct_bs->mark_card_deferred(card_index)) {
+ _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index));
}
}
-
- void set_region(HeapRegion* from) { _from = from; }
};
class RemoveSelfForwardPtrObjClosure: public ObjectClosure {
@@ -210,7 +213,6 @@
&_update_rset_cl,
during_initial_mark,
_worker_id);
- _update_rset_cl.set_region(hr);
hr->object_iterate(&rspc);
// Need to zap the remainder area of the processed region.
rspc.zap_remainder();