diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index d5c31932e31..bf817989dc1 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -2076,18 +2076,17 @@ oop java_lang_Throwable::message(oop throwable) { return throwable->obj_field(_detailMessage_offset); } -oop java_lang_Throwable::cause(oop throwable) { - return throwable->obj_field(_cause_offset); +const char* java_lang_Throwable::message_as_utf8(oop throwable) { + oop msg = java_lang_Throwable::message(throwable); + const char* msg_utf8 = nullptr; + if (msg != nullptr) { + msg_utf8 = java_lang_String::as_utf8_string(msg); + } + return msg_utf8; } -// Return Symbol for detailed_message or NULL -Symbol* java_lang_Throwable::detail_message(oop throwable) { - PreserveExceptionMark pm(Thread::current()); - oop detailed_message = java_lang_Throwable::message(throwable); - if (detailed_message != NULL) { - return java_lang_String::as_symbol(detailed_message); - } - return NULL; +oop java_lang_Throwable::cause(oop throwable) { + return throwable->obj_field(_cause_offset); } void java_lang_Throwable::set_message(oop throwable, oop value) { @@ -2739,15 +2738,19 @@ Handle java_lang_Throwable::create_initialization_error(JavaThread* current, Han assert(throwable.not_null(), "shouldn't be"); // Now create the message from the original exception and thread name. - Symbol* message = java_lang_Throwable::detail_message(throwable()); ResourceMark rm(current); stringStream st; + const char *message = nullptr; + oop detailed_message = java_lang_Throwable::message(throwable()); + if (detailed_message != nullptr) { + message = java_lang_String::as_utf8_string(detailed_message); + } st.print("Exception %s%s ", throwable()->klass()->name()->as_klass_external_name(), message == nullptr ? "" : ":"); - if (message == NULL) { + if (message == nullptr) { st.print("[in thread \"%s\"]", current->name()); } else { - st.print("%s [in thread \"%s\"]", message->as_C_string(), current->name()); + st.print("%s [in thread \"%s\"]", message, current->name()); } Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError(); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 4a3d37e50dc..f1883878141 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -549,12 +549,14 @@ class java_lang_Throwable: AllStatic { static void set_backtrace(oop throwable, oop value); static int depth(oop throwable); static void set_depth(oop throwable, int value); - static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); } // Message + static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); } static oop message(oop throwable); - static oop cause(oop throwable); + static const char* message_as_utf8(oop throwable); static void set_message(oop throwable, oop value); - static Symbol* detail_message(oop throwable); + + static oop cause(oop throwable); + static void print_stack_element(outputStream *st, Method* method, int bci); static void compute_offsets(); diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index 24a5bcab3a8..4e647871d2a 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -36,8 +36,8 @@ // create new error entry void ResolutionErrorTable::add_entry(int index, unsigned int hash, const constantPoolHandle& pool, int cp_index, - Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg) + Symbol* error, const char* message, + Symbol* cause, const char* cause_msg) { assert_locked_or_safepoint(SystemDictionary_lock); assert(!pool.is_null() && error != NULL, "adding NULL obj"); @@ -95,11 +95,8 @@ void ResolutionErrorEntry::set_error(Symbol* e) { } } -void ResolutionErrorEntry::set_message(Symbol* c) { - _message = c; - if (_message != NULL) { - _message->increment_refcount(); - } +void ResolutionErrorEntry::set_message(const char* c) { + _message = c != nullptr ? os::strdup(c) : nullptr; } void ResolutionErrorEntry::set_cause(Symbol* c) { @@ -109,13 +106,11 @@ void ResolutionErrorEntry::set_cause(Symbol* c) { } } -void ResolutionErrorEntry::set_cause_msg(Symbol* c) { - _cause_msg = c; - if (_cause_msg != NULL) { - _cause_msg->increment_refcount(); - } +void ResolutionErrorEntry::set_cause_msg(const char* c) { + _cause_msg = c != nullptr ? os::strdup(c) : nullptr; } +// The incoming nest host error message is already in the C-Heap. void ResolutionErrorEntry::set_nest_host_error(const char* message) { _nest_host_error = message; } @@ -126,13 +121,13 @@ void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) { entry->error()->decrement_refcount(); } if (entry->message() != NULL) { - entry->message()->decrement_refcount(); + FREE_C_HEAP_ARRAY(char, entry->message()); } if (entry->cause() != NULL) { entry->cause()->decrement_refcount(); } if (entry->cause_msg() != NULL) { - entry->cause_msg()->decrement_refcount(); + FREE_C_HEAP_ARRAY(char, entry->cause_msg()); } if (entry->nest_host_error() != NULL) { FREE_C_HEAP_ARRAY(char, entry->nest_host_error()); diff --git a/src/hotspot/share/classfile/resolutionErrors.hpp b/src/hotspot/share/classfile/resolutionErrors.hpp index 8a9c9951ba1..31a56385860 100644 --- a/src/hotspot/share/classfile/resolutionErrors.hpp +++ b/src/hotspot/share/classfile/resolutionErrors.hpp @@ -61,11 +61,11 @@ class ResolutionErrorTable : public Hashtable { } void add_entry(int index, unsigned int hash, - const constantPoolHandle& pool, int which, Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg); + const constantPoolHandle& pool, int cp_index, Symbol* error, const char* error_msg, + Symbol* cause, const char* cause_msg); void add_entry(int index, unsigned int hash, - const constantPoolHandle& pool, int which, const char* message); + const constantPoolHandle& pool, int cp_index, const char* message); // find error given the constant pool and constant pool index ResolutionErrorEntry* find_entry(int index, unsigned int hash, @@ -96,9 +96,9 @@ class ResolutionErrorEntry : public HashtableEntry { private: int _cp_index; Symbol* _error; - Symbol* _message; + const char* _message; Symbol* _cause; - Symbol* _cause_msg; + const char* _cause_msg; const char* _nest_host_error; public: @@ -110,16 +110,19 @@ class ResolutionErrorEntry : public HashtableEntry { Symbol* error() const { return _error; } void set_error(Symbol* e); - Symbol* message() const { return _message; } - void set_message(Symbol* c); + const char* message() const { return _message; } + // The incoming message is copied to the C-Heap. + void set_message(const char* c); Symbol* cause() const { return _cause; } void set_cause(Symbol* c); - Symbol* cause_msg() const { return _cause_msg; } - void set_cause_msg(Symbol* c); + const char* cause_msg() const { return _cause_msg; } + // The incoming cause_msg is copied to the C-Heap. + void set_cause_msg(const char* c); const char* nest_host_error() const { return _nest_host_error; } + // The incoming nest host error message is already in the C-Heap. void set_nest_host_error(const char* message); ResolutionErrorEntry* next() const { diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 3d476eba09b..96fbf375bca 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1846,8 +1846,8 @@ bool SystemDictionary::add_loader_constraint(Symbol* class_name, // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which, - Symbol* error, Symbol* message, - Symbol* cause, Symbol* cause_msg) { + Symbol* error, const char* message, + Symbol* cause, const char* cause_msg) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { @@ -1866,7 +1866,7 @@ void SystemDictionary::delete_resolution_error(ConstantPool* pool) { // Lookup resolution error table. Returns error if found, otherwise NULL. Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which, - Symbol** message, Symbol** cause, Symbol** cause_msg) { + const char** message, Symbol** cause, const char** cause_msg) { unsigned int hash = resolution_errors()->compute_hash(pool, which); int index = resolution_errors()->hash_to_index(hash); { diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index f4d40685ddc..a075e4de38b 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -281,10 +281,10 @@ class SystemDictionary : AllStatic { // Record the error when the first attempt to resolve a reference from a constant // pool entry to a class fails. static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error, - Symbol* message, Symbol* cause = NULL, Symbol* cause_msg = NULL); + const char* message, Symbol* cause = NULL, const char* cause_msg = NULL); static void delete_resolution_error(ConstantPool* pool); static Symbol* find_resolution_error(const constantPoolHandle& pool, int which, - Symbol** message, Symbol** cause, Symbol** cause_msg); + const char** message, Symbol** cause, const char** cause_msg); // Record a nest host resolution/validation error diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index a97f2fe8d02..53e166c0c69 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -767,13 +767,16 @@ void ConstantPool::resolve_string_constants_impl(const constantPoolHandle& this_ } } -static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { +static const char* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { + // Note: caller needs ResourceMark + // Dig out the detailed message to reuse if possible - Symbol* message = java_lang_Throwable::detail_message(pending_exception); - if (message != NULL) { - return message; + const char* msg = java_lang_Throwable::message_as_utf8(pending_exception); + if (msg != nullptr) { + return msg; } + Symbol* message = nullptr; // Return specific message for the tag switch (tag.value()) { case JVM_CONSTANT_UnresolvedClass: @@ -796,49 +799,48 @@ static Symbol* exception_message(const constantPoolHandle& this_cp, int which, c ShouldNotReachHere(); } - return message; + return message != nullptr ? message->as_C_string() : nullptr; } -static void add_resolution_error(const constantPoolHandle& this_cp, int which, +static void add_resolution_error(JavaThread* current, const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) { + ResourceMark rm(current); Symbol* error = pending_exception->klass()->name(); oop cause = java_lang_Throwable::cause(pending_exception); // Also dig out the exception cause, if present. Symbol* cause_sym = NULL; - Symbol* cause_msg = NULL; + const char* cause_msg = nullptr; if (cause != NULL && cause != pending_exception) { cause_sym = cause->klass()->name(); - cause_msg = java_lang_Throwable::detail_message(cause); + cause_msg = java_lang_Throwable::message_as_utf8(cause); } - Symbol* message = exception_message(this_cp, which, tag, pending_exception); + const char* message = exception_message(this_cp, which, tag, pending_exception); SystemDictionary::add_resolution_error(this_cp, which, error, message, cause_sym, cause_msg); } void ConstantPool::throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS) { ResourceMark rm(THREAD); - Symbol* message = NULL; + const char* message = NULL; Symbol* cause = NULL; - Symbol* cause_msg = NULL; + const char* cause_msg = NULL; Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message, &cause, &cause_msg); assert(error != NULL, "checking"); - const char* cause_str = cause_msg != NULL ? cause_msg->as_C_string() : NULL; CLEAR_PENDING_EXCEPTION; if (message != NULL) { - char* msg = message->as_C_string(); if (cause != NULL) { - Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str); - THROW_MSG_CAUSE(error, msg, h_cause); + Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg); + THROW_MSG_CAUSE(error, message, h_cause); } else { - THROW_MSG(error, msg); + THROW_MSG(error, message); } } else { if (cause != NULL) { - Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str); + Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg); THROW_CAUSE(error, h_cause); } else { THROW(error); @@ -860,7 +862,7 @@ void ConstantPool::save_and_throw_exception(const constantPoolHandle& this_cp, i // and OutOfMemoryError, etc, or if the thread was hit by stop() // Needs clarification to section 5.4.3 of the VM spec (see 6308271) } else if (this_cp->tag_at(which).value() != error_tag) { - add_resolution_error(this_cp, which, tag, PENDING_EXCEPTION); + add_resolution_error(THREAD, this_cp, which, tag, PENDING_EXCEPTION); // CAS in the tag. If a thread beat us to registering this error that's fine. // If another thread resolved the reference, this is a race condition. This // thread may have had a security manager or something temporary. diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 40ca7d7efc6..9fdf69e057d 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -497,9 +497,9 @@ bool ConstantPoolCacheEntry::save_and_throw_indy_exc( CLEAR_PENDING_EXCEPTION; return false; } - + ResourceMark rm(THREAD); Symbol* error = PENDING_EXCEPTION->klass()->name(); - Symbol* message = java_lang_Throwable::detail_message(PENDING_EXCEPTION); + const char* message = java_lang_Throwable::message_as_utf8(PENDING_EXCEPTION); SystemDictionary::add_resolution_error(cpool, index, error, message); set_indy_resolution_failed(); diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index bd95b8306be..d65f5bcfafd 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -563,11 +563,11 @@ void Exceptions::debug_check_abort_helper(Handle exception, const char* message) // for logging exceptions void Exceptions::log_exception(Handle exception, const char* message) { ResourceMark rm; - Symbol* detail_message = java_lang_Throwable::detail_message(exception()); - if (detail_message != NULL) { + const char* detail_message = java_lang_Throwable::message_as_utf8(exception()); + if (detail_message != nullptr) { log_info(exceptions)("Exception <%s: %s>\n thrown in %s", exception->print_value_string(), - detail_message->as_C_string(), + detail_message, message); } else { log_info(exceptions)("Exception <%s>\n thrown in %s",