Skip to content

Commit 0aeebee

Browse files
author
Thomas Schatzl
committed
8301988: VerifyLiveClosure::verify_liveness asserts on bad pointers outside heap
Reviewed-by: dholmes, ayang
1 parent 4815566 commit 0aeebee

File tree

6 files changed

+52
-43
lines changed

6 files changed

+52
-43
lines changed

src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ inline bool G1CollectedHeap::requires_barriers(stackChunkOop obj) const {
239239
}
240240

241241
inline bool G1CollectedHeap::is_obj_filler(const oop obj) {
242-
Klass* k = obj->klass();
242+
Klass* k = obj->klass_raw();
243243
return k == Universe::fillerArrayKlassObj() || k == vmClasses::FillerObject_klass();
244244
}
245245

src/hotspot/share/gc/g1/heapRegion.cpp

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -494,61 +494,54 @@ class G1VerificationClosure : public BasicOopIterateClosure {
494494
};
495495

496496
class VerifyLiveClosure : public G1VerificationClosure {
497-
public:
498-
VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : G1VerificationClosure(g1h, vo) {}
499-
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
500-
virtual void do_oop(oop* p) { do_oop_work(p); }
501497

502498
template <class T>
503499
void do_oop_work(T* p) {
504500
assert(_containing_obj != NULL, "Precondition");
505501
assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
506502
"Precondition");
507-
verify_liveness(p);
508-
}
509503

510-
template <class T>
511-
void verify_liveness(T* p) {
512504
T heap_oop = RawAccess<>::oop_load(p);
513-
Log(gc, verify) log;
514-
if (!CompressedOops::is_null(heap_oop)) {
515-
oop obj = CompressedOops::decode_not_null(heap_oop);
516-
bool failed = false;
517-
bool is_in_heap = _g1h->is_in(obj);
518-
if (!is_in_heap || _g1h->is_obj_dead_cond(obj, _vo)) {
519-
MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
505+
if (CompressedOops::is_null(heap_oop)) {
506+
return;
507+
}
520508

521-
if (!_failures) {
522-
log.error("----------");
523-
}
524-
ResourceMark rm;
525-
if (!is_in_heap) {
526-
HeapRegion* from = _g1h->heap_region_containing(p);
527-
log.error("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region " HR_FORMAT,
528-
p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
529-
LogStream ls(log.error());
530-
print_object(&ls, _containing_obj);
531-
HeapRegion* const to = _g1h->heap_region_containing(obj);
532-
log.error("points to obj " PTR_FORMAT " in region " HR_FORMAT " remset %s",
533-
p2i(obj), HR_FORMAT_PARAMS(to), to->rem_set()->get_state_str());
534-
} else {
535-
HeapRegion* from = _g1h->heap_region_containing(p);
536-
HeapRegion* to = _g1h->heap_region_containing(obj);
537-
log.error("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region " HR_FORMAT,
538-
p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
539-
LogStream ls(log.error());
540-
print_object(&ls, _containing_obj);
541-
log.error("points to dead obj " PTR_FORMAT " in region " HR_FORMAT,
542-
p2i(obj), HR_FORMAT_PARAMS(to));
543-
print_object(&ls, obj);
544-
}
509+
oop obj = CompressedOops::decode_raw_not_null(heap_oop);
510+
bool is_in_heap = _g1h->is_in(obj);
511+
if (!is_in_heap || _g1h->is_obj_dead_cond(obj, _vo)) {
512+
MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
513+
514+
Log(gc, verify) log;
515+
if (!_failures) {
545516
log.error("----------");
546-
_failures = true;
547-
failed = true;
548-
_n_failures++;
549517
}
518+
ResourceMark rm;
519+
520+
HeapRegion* from = _g1h->heap_region_containing(p);
521+
log.error("Field " PTR_FORMAT " of live obj " PTR_FORMAT " in region " HR_FORMAT,
522+
p2i(p), p2i(_containing_obj), HR_FORMAT_PARAMS(from));
523+
LogStream ls(log.error());
524+
print_object(&ls, _containing_obj);
525+
526+
if (!is_in_heap) {
527+
log.error("points to address " PTR_FORMAT " outside of heap", p2i(obj));
528+
} else {
529+
HeapRegion* to = _g1h->heap_region_containing(obj);
530+
log.error("points to dead obj " PTR_FORMAT " in region " HR_FORMAT " remset %s",
531+
p2i(obj), HR_FORMAT_PARAMS(to), to->rem_set()->get_state_str());
532+
print_object(&ls, obj);
533+
}
534+
log.error("----------");
535+
_failures = true;
536+
_n_failures++;
550537
}
551538
}
539+
540+
public:
541+
VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) : G1VerificationClosure(g1h, vo) {}
542+
543+
virtual void do_oop(narrowOop* p) { do_oop_work(p); }
544+
virtual void do_oop(oop* p) { do_oop_work(p); }
552545
};
553546

554547
class VerifyRemSetClosure : public G1VerificationClosure {

src/hotspot/share/oops/compressedOops.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class CompressedOops : public AllStatic {
127127
static inline narrowOop encode(oop v);
128128

129129
// No conversions needed for these overloads
130+
static inline oop decode_raw_not_null(oop v);
130131
static inline oop decode_not_null(oop v);
131132
static inline oop decode(oop v);
132133
static inline narrowOop encode_not_null(narrowOop v);

src/hotspot/share/oops/compressedOops.inline.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ inline narrowOop CompressedOops::encode(oop v) {
7878
return is_null(v) ? narrowOop::null : encode_not_null(v);
7979
}
8080

81+
inline oop CompressedOops::decode_raw_not_null(oop v) {
82+
assert(v != nullptr, "object is null");
83+
return v;
84+
}
85+
8186
inline oop CompressedOops::decode_not_null(oop v) {
8287
assert(Universe::is_in_heap(v), "object not in heap " PTR_FORMAT, p2i(v));
8388
return v;

src/hotspot/share/oops/oop.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ class oopDesc {
8585
inline Klass* klass() const;
8686
inline Klass* klass_or_null() const;
8787
inline Klass* klass_or_null_acquire() const;
88+
// Get the raw value without any checks.
89+
inline Klass* klass_raw() const;
8890

8991
void set_narrow_klass(narrowKlass nk) NOT_CDS_JAVA_HEAP_RETURN;
9092
inline void set_klass(Klass* k);

src/hotspot/share/oops/oop.inline.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ Klass* oopDesc::klass_or_null_acquire() const {
107107
}
108108
}
109109

110+
Klass* oopDesc::klass_raw() const {
111+
if (UseCompressedClassPointers) {
112+
return CompressedKlassPointers::decode_raw(_metadata._compressed_klass);
113+
} else {
114+
return _metadata._klass;
115+
}
116+
}
117+
110118
void oopDesc::set_klass(Klass* k) {
111119
assert(Universe::is_bootstrapping() || (k != NULL && k->is_klass()), "incorrect Klass");
112120
if (UseCompressedClassPointers) {

0 commit comments

Comments
 (0)