8328698: oopDesc::klass_raw() decodes without a null check
Reviewed-by: ayang, tschatzl
This commit is contained in:
parent
d1aad71209
commit
6f087cbcd5
@ -248,7 +248,7 @@ inline bool G1CollectedHeap::requires_barriers(stackChunkOop obj) const {
|
||||
}
|
||||
|
||||
inline bool G1CollectedHeap::is_obj_filler(const oop obj) {
|
||||
Klass* k = obj->klass_raw();
|
||||
Klass* k = obj->klass_without_asserts();
|
||||
return k == Universe::fillerArrayKlass() || k == vmClasses::FillerObject_klass();
|
||||
}
|
||||
|
||||
|
@ -433,25 +433,33 @@ void HeapRegion::print_on(outputStream* st) const {
|
||||
}
|
||||
|
||||
static bool is_oop_safe(oop obj) {
|
||||
if (!oopDesc::is_oop(obj)) {
|
||||
log_error(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
|
||||
// Make a few sanity checks of the class before calling the full-fledged
|
||||
// is_oop check (which also performs its own klass verification).
|
||||
Klass* klass = obj->klass_without_asserts();
|
||||
|
||||
if (klass == nullptr) {
|
||||
log_error(gc, verify)("Object " PTR_FORMAT " has a null klass", p2i(obj));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now examine the Klass a little more closely.
|
||||
Klass* klass = obj->klass_raw();
|
||||
|
||||
bool is_metaspace_object = Metaspace::contains(klass);
|
||||
if (!is_metaspace_object) {
|
||||
if (!Metaspace::contains(klass)) {
|
||||
log_error(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
|
||||
"not metadata", p2i(klass), p2i(obj));
|
||||
"is not in metaspace", p2i(klass), p2i(obj));
|
||||
return false;
|
||||
} else if (!klass->is_klass()) {
|
||||
}
|
||||
|
||||
if (!klass->is_klass()) {
|
||||
log_error(gc, verify)("klass " PTR_FORMAT " of object " PTR_FORMAT " "
|
||||
"not a klass", p2i(klass), p2i(obj));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, perform the more in-depth verification of the object.
|
||||
if (!oopDesc::is_oop(obj)) {
|
||||
log_error(gc, verify)(PTR_FORMAT " not an oop", p2i(obj));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ bool CollectedHeap::is_oop(oop object) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Metaspace::contains(object->klass_raw())) {
|
||||
if (!Metaspace::contains(object->klass_without_asserts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "memory/universe.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
|
||||
bool LocationPrinter::is_valid_obj(void* obj) {
|
||||
if (!is_object_aligned(obj)) {
|
||||
@ -45,6 +46,6 @@ bool LocationPrinter::is_valid_obj(void* obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Klass* k = (Klass*)oopDesc::load_klass_raw((oopDesc*)obj);
|
||||
Klass* k = ((oopDesc*)obj)->klass_without_asserts();
|
||||
return Klass::is_valid(k);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlas
|
||||
// For UseCompressedClassPointers.
|
||||
class CompressedKlassPointers : public AllStatic {
|
||||
friend class VMStructs;
|
||||
friend class ArchiveBuilder;
|
||||
|
||||
static address _base;
|
||||
static int _shift;
|
||||
@ -64,6 +65,11 @@ class CompressedKlassPointers : public AllStatic {
|
||||
|
||||
DEBUG_ONLY(static void assert_is_valid_encoding(address addr, size_t len, address base, int shift);)
|
||||
|
||||
static inline Klass* decode_not_null_without_asserts(narrowKlass v, address base, int shift);
|
||||
static inline Klass* decode_not_null(narrowKlass v, address base, int shift);
|
||||
|
||||
static inline narrowKlass encode_not_null(Klass* v, address base, int shift);
|
||||
|
||||
public:
|
||||
|
||||
// Reserve a range of memory that is to contain Klass strucutures which are referenced by narrow Klass IDs.
|
||||
@ -92,15 +98,15 @@ public:
|
||||
static bool is_null(Klass* v) { return v == nullptr; }
|
||||
static bool is_null(narrowKlass v) { return v == 0; }
|
||||
|
||||
static inline Klass* decode_raw(narrowKlass v, address base, int shift);
|
||||
static inline Klass* decode_raw(narrowKlass v);
|
||||
static inline Klass* decode_not_null(narrowKlass v);
|
||||
static inline Klass* decode_not_null(narrowKlass v, address base, int shift);
|
||||
static inline Klass* decode(narrowKlass v);
|
||||
static inline narrowKlass encode_not_null(Klass* v);
|
||||
static inline narrowKlass encode_not_null(Klass* v, address base, int shift);
|
||||
static inline narrowKlass encode(Klass* v);
|
||||
// Versions without asserts
|
||||
static inline Klass* decode_not_null_without_asserts(narrowKlass v);
|
||||
static inline Klass* decode_without_asserts(narrowKlass v);
|
||||
|
||||
static inline Klass* decode_not_null(narrowKlass v);
|
||||
static inline Klass* decode(narrowKlass v);
|
||||
|
||||
static inline narrowKlass encode_not_null(Klass* v);
|
||||
static inline narrowKlass encode(Klass* v);
|
||||
};
|
||||
|
||||
#endif // SHARE_OOPS_COMPRESSEDKLASS_HPP
|
||||
|
@ -36,33 +36,17 @@ static inline bool check_alignment(Klass* v) {
|
||||
return (intptr_t)v % KlassAlignmentInBytes == 0;
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v) {
|
||||
return decode_raw(v, base(), shift());
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_raw(narrowKlass v, address narrow_base, int shift) {
|
||||
inline Klass* CompressedKlassPointers::decode_not_null_without_asserts(narrowKlass v, address narrow_base, int shift) {
|
||||
return (Klass*)((uintptr_t)narrow_base +((uintptr_t)v << shift));
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v) {
|
||||
return decode_not_null(v, base(), shift());
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v, address narrow_base, int shift) {
|
||||
assert(!is_null(v), "narrow klass value can never be zero");
|
||||
Klass* result = decode_raw(v, narrow_base, shift);
|
||||
Klass* result = decode_not_null_without_asserts(v, narrow_base, shift);
|
||||
assert(check_alignment(result), "address not aligned: " PTR_FORMAT, p2i(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode(narrowKlass v) {
|
||||
return is_null(v) ? nullptr : decode_not_null(v);
|
||||
}
|
||||
|
||||
inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v) {
|
||||
return encode_not_null(v, base(), shift());
|
||||
}
|
||||
|
||||
inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v, address narrow_base, int shift) {
|
||||
assert(!is_null(v), "klass value can never be zero");
|
||||
assert(check_alignment(v), "Address not aligned");
|
||||
@ -74,6 +58,26 @@ inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v, address na
|
||||
return (narrowKlass)result;
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_not_null_without_asserts(narrowKlass v) {
|
||||
return decode_not_null_without_asserts(v, base(), shift());
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_without_asserts(narrowKlass v) {
|
||||
return is_null(v) ? nullptr : decode_not_null_without_asserts(v);
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode_not_null(narrowKlass v) {
|
||||
return decode_not_null(v, base(), shift());
|
||||
}
|
||||
|
||||
inline Klass* CompressedKlassPointers::decode(narrowKlass v) {
|
||||
return is_null(v) ? nullptr : decode_not_null(v);
|
||||
}
|
||||
|
||||
inline narrowKlass CompressedKlassPointers::encode_not_null(Klass* v) {
|
||||
return encode_not_null(v, base(), shift());
|
||||
}
|
||||
|
||||
inline narrowKlass CompressedKlassPointers::encode(Klass* v) {
|
||||
return is_null(v) ? (narrowKlass)0 : encode_not_null(v);
|
||||
}
|
||||
|
@ -165,16 +165,6 @@ void oopDesc::set_narrow_klass(narrowKlass nk) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void* oopDesc::load_klass_raw(oop obj) {
|
||||
if (UseCompressedClassPointers) {
|
||||
narrowKlass narrow_klass = obj->_metadata._compressed_klass;
|
||||
if (narrow_klass == 0) return nullptr;
|
||||
return (void*)CompressedKlassPointers::decode_raw(narrow_klass);
|
||||
} else {
|
||||
return obj->_metadata._klass;
|
||||
}
|
||||
}
|
||||
|
||||
void* oopDesc::load_oop_raw(oop obj, int offset) {
|
||||
uintptr_t addr = (uintptr_t)(void*)obj + (uint)offset;
|
||||
if (UseCompressedOops) {
|
||||
|
@ -85,8 +85,8 @@ class oopDesc {
|
||||
inline Klass* klass() const;
|
||||
inline Klass* klass_or_null() const;
|
||||
inline Klass* klass_or_null_acquire() const;
|
||||
// Get the raw value without any checks.
|
||||
inline Klass* klass_raw() const;
|
||||
// Get the klass without running any asserts.
|
||||
inline Klass* klass_without_asserts() const;
|
||||
|
||||
void set_narrow_klass(narrowKlass nk) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
inline void set_klass(Klass* k);
|
||||
@ -316,7 +316,6 @@ class oopDesc {
|
||||
}
|
||||
|
||||
// for error reporting
|
||||
static void* load_klass_raw(oop obj);
|
||||
static void* load_oop_raw(oop obj, int offset);
|
||||
|
||||
DEBUG_ONLY(bool size_might_change();)
|
||||
|
@ -111,9 +111,9 @@ Klass* oopDesc::klass_or_null_acquire() const {
|
||||
}
|
||||
}
|
||||
|
||||
Klass* oopDesc::klass_raw() const {
|
||||
Klass* oopDesc::klass_without_asserts() const {
|
||||
if (UseCompressedClassPointers) {
|
||||
return CompressedKlassPointers::decode_raw(_metadata._compressed_klass);
|
||||
return CompressedKlassPointers::decode_without_asserts(_metadata._compressed_klass);
|
||||
} else {
|
||||
return _metadata._klass;
|
||||
}
|
||||
|
@ -1256,7 +1256,7 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedClassPointers && ((uintptr_t)addr &~ (uintptr_t)max_juint) == 0) {
|
||||
narrowKlass narrow_klass = (narrowKlass)(uintptr_t)addr;
|
||||
Klass* k = CompressedKlassPointers::decode_raw(narrow_klass);
|
||||
Klass* k = CompressedKlassPointers::decode_without_asserts(narrow_klass);
|
||||
|
||||
if (Klass::is_valid(k)) {
|
||||
st->print_cr(UINT32_FORMAT " is a compressed pointer to class: " INTPTR_FORMAT, narrow_klass, p2i((HeapWord*)k));
|
||||
|
Loading…
x
Reference in New Issue
Block a user