hotspot/src/share/vm/utilities/exceptions.cpp
changeset 31335 60081f497e75
parent 26135 82b516c550f7
child 31337 98b10897ee17
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Mon Jun 08 15:40:28 2015 +0200
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Jun 09 10:26:25 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -154,6 +154,10 @@
     return;
   }
 
+  if (h_exception->is_a(SystemDictionary::OutOfMemoryError_klass())) {
+    count_out_of_memory_exceptions(h_exception);
+  }
+
   assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
 
   // set the pending exception
@@ -228,6 +232,8 @@
     if (StackTraceInThrowable) {
       java_lang_Throwable::fill_in_stack_trace(exception, method());
     }
+    // Increment counter for hs_err file reporting
+    Atomic::inc(&Exceptions::_stack_overflow_errors);
   } else {
     // if prior exception, throw that one instead
     exception = Handle(THREAD, THREAD->pending_exception());
@@ -404,6 +410,44 @@
                                    h_prot, to_utf8_safe);
 }
 
+
+// Exception counting for hs_err file
+volatile int Exceptions::_stack_overflow_errors = 0;
+volatile int Exceptions::_out_of_memory_error_java_heap_errors = 0;
+volatile int Exceptions::_out_of_memory_error_metaspace_errors = 0;
+volatile int Exceptions::_out_of_memory_error_class_metaspace_errors = 0;
+
+void Exceptions::count_out_of_memory_exceptions(Handle exception) {
+  if (exception() == Universe::out_of_memory_error_metaspace()) {
+     Atomic::inc(&_out_of_memory_error_metaspace_errors);
+  } else if (exception() == Universe::out_of_memory_error_class_metaspace()) {
+     Atomic::inc(&_out_of_memory_error_class_metaspace_errors);
+  } else {
+     // everything else reported as java heap OOM
+     Atomic::inc(&_out_of_memory_error_java_heap_errors);
+  }
+}
+
+void print_oom_count(outputStream* st, const char *err, int count) {
+  if (count > 0) {
+    st->print_cr("OutOfMemoryError %s=%d", err, count);
+  }
+}
+
+bool Exceptions::has_exception_counts() {
+  return (_stack_overflow_errors + _out_of_memory_error_java_heap_errors +
+         _out_of_memory_error_metaspace_errors + _out_of_memory_error_class_metaspace_errors) > 0;
+}
+
+void Exceptions::print_exception_counts_on_error(outputStream* st) {
+  print_oom_count(st, "java_heap_errors", _out_of_memory_error_java_heap_errors);
+  print_oom_count(st, "metaspace_errors", _out_of_memory_error_metaspace_errors);
+  print_oom_count(st, "class_metaspace_errors", _out_of_memory_error_class_metaspace_errors);
+  if (_stack_overflow_errors > 0) {
+    st->print_cr("StackOverflowErrors=%d", _stack_overflow_errors);
+  }
+}
+
 // Implementation of ExceptionMark
 
 ExceptionMark::ExceptionMark(Thread*& thread) {