Skip to content

8361342: Shenandoah: Evacuation may assert on invalid mirror object after JDK-8340297 #26187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,15 @@ void ShenandoahAsserts::assert_correct(void* interior_loc, oop obj, const char*
// We want to check class loading/unloading did not corrupt them.

if (Universe::is_fully_initialized() && (obj_klass == vmClasses::Class_klass())) {
Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset());
// During class redefinition the old Klass gets reclaimed and the old mirror oop's Klass reference
// nulled out (hence the "klass != nullptr" condition below). However, the mirror oop may have been
// forwarded if we are in the mids of an evacuation. In that case, the forwardee's Klass reference
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/mids/midst

// is nulled out. The old, forwarded, still still carries the old invalid Klass pointer. It will be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/still still/still

// eventually collected.
// This checking code may encounter the old copy of the mirror, and its referee Klass pointer may
// already be reclaimed and therefore be invalid. We must therefore check the forwardee's Klass
// reference.
const Metadata* klass = fwd->metadata_field(java_lang_Class::klass_offset());
if (klass != nullptr && !Metaspace::contains(klass)) {
print_failure(_safe_all, obj, interior_loc, nullptr, "Shenandoah assert_correct failed",
"Instance class mirror should point to Metaspace",
Expand Down
10 changes: 9 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,15 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure {
// We want to check class loading/unloading did not corrupt them.

if (obj_klass == vmClasses::Class_klass()) {
Metadata* klass = obj->metadata_field(java_lang_Class::klass_offset());
// During class redefinition the old Klass gets reclaimed and the old mirror oop's Klass reference
// nulled out (hence the "klass != nullptr" condition below). However, the mirror oop may have been
// forwarded if we are in the mids of an evacuation. In that case, the forwardee's Klass reference
// is nulled out. The old, forwarded, still still carries the old invalid Klass pointer. It will be
// eventually collected.
// This checking code may encounter the old copy of the mirror, and its referee Klass pointer may
// already be reclaimed and therefore be invalid. We must therefore check the forwardee's Klass
// reference.
Metadata* klass = fwd->metadata_field(java_lang_Class::klass_offset());
check(ShenandoahAsserts::_safe_oop, obj,
klass == nullptr || Metaspace::contains(klass),
"Instance class mirror should point to Metaspace");
Expand Down