diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index f5a335f17f375..c41d5d2f05288 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -127,10 +127,8 @@ ResolutionErrorEntry::~ResolutionErrorEntry() { } void ResolutionErrorEntry::set_nest_host_error(const char* message) { - // If a message is already set, free it. - if (nest_host_error() != nullptr) { - FREE_C_HEAP_ARRAY(char, _nest_host_error); - } + assert(_nest_host_error == nullptr, "caller should have checked"); + assert_lock_strong(SystemDictionary_lock); _nest_host_error = message; } diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index e03d198eb9f03..7373841201702 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1859,7 +1859,7 @@ Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool, int which, - const char* message) { + const stringStream& message) { { MutexLocker ml(Thread::current(), SystemDictionary_lock); ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which); @@ -1868,14 +1868,19 @@ void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool, // constant pool index. In this case resolution succeeded but there's an error in this nest host // that we use the table to record. assert(pool->resolved_klass_at(which) != nullptr, "klass should be resolved if there is no entry"); - ResolutionErrorTable::add_entry(pool, which, message); + ResolutionErrorTable::add_entry(pool, which, message.as_string(true /* on C-heap */)); } else { // An existing entry means we had a true resolution failure (LinkageError) with our nest host, but we // still want to add the error message for the higher-level access checks to report. We should // only reach here under the same error condition, so we can ignore the potential race with setting - // the message, and set it again. - assert(entry->nest_host_error() == nullptr || strcmp(entry->nest_host_error(), message) == 0, "should be the same message"); - entry->set_nest_host_error(message); + // the message. + const char* nhe = entry->nest_host_error(); + if (nhe == nullptr) { + entry->set_nest_host_error(message.as_string(true /* on C-heap */)); + } else { + DEBUG_ONLY(const char* msg = message.base();) + assert(strcmp(nhe, msg) == 0, "New message %s, differs from original %s", msg, nhe); + } } } } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 99e13fea61e14..e32e0082f8f49 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -280,7 +280,7 @@ class SystemDictionary : AllStatic { // Record a nest host resolution/validation error static void add_nest_host_error(const constantPoolHandle& pool, int which, - const char* message); + const stringStream& message); static const char* find_nest_host_error(const constantPoolHandle& pool, int which); static void add_to_initiating_loader(JavaThread* current, InstanceKlass* k, diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index e74bc80d893ee..56a80daed6049 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -312,12 +312,11 @@ InstanceKlass* InstanceKlass::nest_host(TRAPS) { ss.print("Nest host resolution of %s with host %s failed: ", this->external_name(), target_host_class); java_lang_Throwable::print(PENDING_EXCEPTION, &ss); - const char* msg = ss.as_string(true /* on C-heap */); constantPoolHandle cph(THREAD, constants()); - SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, ss); CLEAR_PENDING_EXCEPTION; - log_trace(class, nestmates)("%s", msg); + log_trace(class, nestmates)("%s", ss.base()); } else { // A valid nest-host is an instance class in the current package that lists this // class as a nest member. If any of these conditions are not met the class is @@ -356,10 +355,9 @@ InstanceKlass* InstanceKlass::nest_host(TRAPS) { k->external_name(), k->class_loader_data()->loader_name_and_id(), error); - const char* msg = ss.as_string(true /* on C-heap */); constantPoolHandle cph(THREAD, constants()); - SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); - log_trace(class, nestmates)("%s", msg); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, ss); + log_trace(class, nestmates)("%s", ss.base()); } } } else {