8153413: Exceptions::_throw always logs exceptions, penalizing performance
authorcoleenp
Thu, 21 Feb 2019 09:21:21 -0500
changeset 53874 b2fb6f782d84
parent 53873 5cf6623b1283
child 53875 7a6fb8a48434
8153413: Exceptions::_throw always logs exceptions, penalizing performance Summary: construct exception string into Event message directly add if (log_is_enabled) for logging. Reviewed-by: ysuenaga, dholmes
src/hotspot/share/utilities/events.cpp
src/hotspot/share/utilities/events.hpp
src/hotspot/share/utilities/exceptions.cpp
--- a/src/hotspot/share/utilities/events.cpp	Thu Feb 21 15:52:42 2019 +0100
+++ b/src/hotspot/share/utilities/events.cpp	Thu Feb 21 09:21:21 2019 -0500
@@ -36,7 +36,7 @@
 
 EventLog* Events::_logs = NULL;
 StringEventLog* Events::_messages = NULL;
-ExtendedStringEventLog* Events::_exceptions = NULL;
+ExceptionsEventLog* Events::_exceptions = NULL;
 StringEventLog* Events::_redefinitions = NULL;
 UnloadingEventLog* Events::_class_unloading = NULL;
 StringEventLog* Events::_deopt_messages = NULL;
@@ -67,7 +67,7 @@
 void Events::init() {
   if (LogEvents) {
     _messages = new StringEventLog("Events");
-    _exceptions = new ExtendedStringEventLog("Internal exceptions");
+    _exceptions = new ExceptionsEventLog("Internal exceptions");
     _redefinitions = new StringEventLog("Classes redefined");
     _class_unloading = new UnloadingEventLog("Classes unloaded");
     _deopt_messages = new StringEventLog("Deoptimization events");
@@ -112,3 +112,20 @@
   st.print("Unloading class " INTPTR_FORMAT " ", p2i(ik));
   ik->name()->print_value_on(&st);
 }
+
+void ExceptionsEventLog::log(Thread* thread, Handle h_exception, const char* message, const char* file, int line) {
+  if (!should_log()) return;
+
+  double timestamp = fetch_timestamp();
+  MutexLockerEx ml(&_mutex, Mutex::_no_safepoint_check_flag);
+  int index = compute_log_index();
+  _records[index].thread = thread;
+  _records[index].timestamp = timestamp;
+  stringStream st = _records[index].data.stream();
+  st.print("Exception <");
+  h_exception->print_value_on(&st);
+  st.print("%s%s> (" INTPTR_FORMAT ") \n"
+           "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
+           message ? ": " : "", message ? message : "",
+           p2i(h_exception()), file, line, p2i(thread));
+}
--- a/src/hotspot/share/utilities/events.hpp	Thu Feb 21 15:52:42 2019 +0100
+++ b/src/hotspot/share/utilities/events.hpp	Thu Feb 21 09:21:21 2019 -0500
@@ -183,6 +183,14 @@
   void log(Thread* thread, InstanceKlass* ik);
 };
 
+// Event log for exceptions
+class ExceptionsEventLog : public ExtendedStringEventLog {
+ public:
+  ExceptionsEventLog(const char* name, int count = LogEventsBufferEntries) : ExtendedStringEventLog(name, count) {}
+
+  void log(Thread* thread, Handle h_exception, const char* message, const char* file, int line);
+};
+
 
 class Events : AllStatic {
   friend class EventLog;
@@ -195,7 +203,7 @@
 
   // A log for internal exception related messages, like internal
   // throws and implicit exceptions.
-  static ExtendedStringEventLog* _exceptions;
+  static ExceptionsEventLog* _exceptions;
 
   // Deoptization related messages
   static StringEventLog* _deopt_messages;
@@ -216,6 +224,7 @@
 
   // Log exception related message
   static void log_exception(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+  static void log_exception(Thread* thread, Handle h_exception, const char* message, const char* file, int line);
 
   static void log_redefinition(Thread* thread, const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
 
@@ -245,6 +254,12 @@
   }
 }
 
+inline void Events::log_exception(Thread* thread, Handle h_exception, const char* message, const char* file, int line) {
+  if (LogEvents) {
+    _exceptions->log(thread, h_exception, message, file, line);
+  }
+}
+
 inline void Events::log_redefinition(Thread* thread, const char* format, ...) {
   if (LogEvents) {
     va_list ap;
--- a/src/hotspot/share/utilities/exceptions.cpp	Thu Feb 21 15:52:42 2019 +0100
+++ b/src/hotspot/share/utilities/exceptions.cpp	Thu Feb 21 09:21:21 2019 -0500
@@ -131,15 +131,17 @@
 }
 
 void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
-  ResourceMark rm;
+  ResourceMark rm(thread);
   assert(h_exception() != NULL, "exception should not be NULL");
 
   // tracing (do this up front - so it works during boot strapping)
+  // Note, the print_value_string() argument is not called unless logging is enabled!
   log_info(exceptions)("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
                        "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
                        h_exception->print_value_string(),
                        message ? ": " : "", message ? message : "",
                        p2i(h_exception()), file, line, p2i(thread));
+
   // for AbortVMOnException flag
   Exceptions::debug_check_abort(h_exception, message);
 
@@ -162,11 +164,7 @@
   thread->set_pending_exception(h_exception(), file, line);
 
   // vm log
-  if (LogEvents){
-    Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
-                          h_exception->print_value_string(), message ? ": " : "", message ? message : "",
-                          p2i(h_exception()), file, line);
-  }
+  Events::log_exception(thread, h_exception, message, file, line);
 }