From e8be53d0cb38a01a16dacd66d80659b194fee117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20H=C3=BCbner?= Date: Fri, 7 Nov 2025 09:57:00 +0100 Subject: [PATCH 1/2] Print oop without klass asserts. --- src/hotspot/share/classfile/javaClasses.hpp | 1 + src/hotspot/share/classfile/javaClasses.inline.hpp | 7 +++++++ src/hotspot/share/oops/oop.cpp | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 28f8c0a3b8cf3..4fa62e37b1811 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -213,6 +213,7 @@ class java_lang_String : AllStatic { // Tester static inline bool is_instance(oop obj); + static inline bool is_instance_without_asserts(oop obj); // Debugging static void print(oop java_string, outputStream* st, int max_length = MaxStringPrintSize); diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 21ad62f840805..ed526e0f9144a 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -126,6 +126,13 @@ bool java_lang_String::is_instance(oop obj) { return obj != nullptr && obj->klass() == vmClasses::String_klass(); } +// We need to be able to check if this is a string even when we are in an +// erroneous state where the klass is corrupted/can't be read safely. +// This happens when printing an oop during GC error reporting. +bool java_lang_String::is_instance_without_asserts(oop obj) { + return obj != nullptr && obj->klass_without_asserts() == vmClasses::String_klass(); +} + // Accessors oop java_lang_ref_Reference::weak_referent_no_keepalive(oop ref) { diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index f874a39bf3100..ecc409816a40c 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -83,7 +83,7 @@ char* oopDesc::print_value_string() { void oopDesc::print_value_on(outputStream* st) const { oop obj = const_cast(this); - if (java_lang_String::is_instance(obj)) { + if (java_lang_String::is_instance_without_asserts(obj)) { java_lang_String::print(obj, st); print_address_on(st); } else { From b5991b7f23a32a96bfc4a419beb28adb5c5e257e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20H=C3=BCbner?= Date: Fri, 7 Nov 2025 14:54:52 +0100 Subject: [PATCH 2/2] Don't make a new function. --- src/hotspot/share/classfile/javaClasses.hpp | 1 - src/hotspot/share/classfile/javaClasses.inline.hpp | 7 ------- src/hotspot/share/oops/oop.cpp | 5 ++++- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 4fa62e37b1811..28f8c0a3b8cf3 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -213,7 +213,6 @@ class java_lang_String : AllStatic { // Tester static inline bool is_instance(oop obj); - static inline bool is_instance_without_asserts(oop obj); // Debugging static void print(oop java_string, outputStream* st, int max_length = MaxStringPrintSize); diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index ed526e0f9144a..21ad62f840805 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -126,13 +126,6 @@ bool java_lang_String::is_instance(oop obj) { return obj != nullptr && obj->klass() == vmClasses::String_klass(); } -// We need to be able to check if this is a string even when we are in an -// erroneous state where the klass is corrupted/can't be read safely. -// This happens when printing an oop during GC error reporting. -bool java_lang_String::is_instance_without_asserts(oop obj) { - return obj != nullptr && obj->klass_without_asserts() == vmClasses::String_klass(); -} - // Accessors oop java_lang_ref_Reference::weak_referent_no_keepalive(oop ref) { diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index ecc409816a40c..5f453241c3da8 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -83,7 +83,10 @@ char* oopDesc::print_value_string() { void oopDesc::print_value_on(outputStream* st) const { oop obj = const_cast(this); - if (java_lang_String::is_instance_without_asserts(obj)) { + // We can't use java_lang_String::is_instance since that has klass assertions enabled. + // If the klass is garbage we want to just fail the check and continue printing, as + // opposed to aborting the VM entirely. + if (obj != nullptr && obj->klass_without_asserts() == vmClasses::String_klass()) { java_lang_String::print(obj, st); print_address_on(st); } else {