changeset 6999:679e6584c177

added ScopedDebugValue to add values of interest to hs_err crash logs
author Doug Simon <doug.simon@oracle.com>
date Wed, 21 Nov 2012 19:23:43 +0100
parents 49f0841607b7
children bf2ea3ed3bce
files src/share/vm/code/nmethod.cpp src/share/vm/code/nmethod.hpp src/share/vm/oops/method.cpp src/share/vm/oops/method.hpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/thread.hpp src/share/vm/utilities/debug.cpp src/share/vm/utilities/debug.hpp src/share/vm/utilities/vmError.cpp
diffstat 9 files changed, 153 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/code/nmethod.cpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/code/nmethod.cpp	Wed Nov 21 19:23:43 2012 +0100
@@ -42,6 +42,7 @@
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
+#include "utilities/debug.hpp"
 #ifdef SHARK
 #include "shark/sharkCompiler.hpp"
 #endif
@@ -2978,3 +2979,19 @@
   Dependencies::print_statistics();
   if (xtty != NULL)  xtty->tail("statistics");
 }
+
+#ifdef GRAAL
+void DebugScopedNMethod::print_on(outputStream* st) {
+  if (_nm != NULL) {
+    st->print("nmethod@%p", _nm);
+    Method* method = _nm->method();
+    if (method != NULL) {
+      char holder[O_BUFLEN];
+      char nameAndSig[O_BUFLEN];
+      method->method_holder()->name()->as_C_string(holder, O_BUFLEN);
+      method->name_and_sig_as_C_string(nameAndSig, O_BUFLEN);
+      st->print(" - %s::%s", holder, nameAndSig);
+    }
+  }
+}
+#endif
--- a/src/share/vm/code/nmethod.hpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/code/nmethod.hpp	Wed Nov 21 19:23:43 2012 +0100
@@ -762,4 +762,19 @@
   }
 };
 
+#ifdef GRAAL
+class DebugScopedNMethod : public DebugScopedValue {
+private:
+  nmethod* _nm;
+public:
+  DebugScopedNMethod(const char* file, int line, nmethod* nm) : DebugScopedValue(file, line), _nm(nm) {}
+  void print_on(outputStream* st);
+};
+#define DS_NMETHOD(nm) DebugScopedNMethod __dsnm__(__FILE__, __LINE__, nm)
+#define DS_NMETHOD1(name, nm) DebugScopedNMethod name(__FILE__, __LINE__, nm)
+#else
+#define DS_NMETHOD(nm) do {} while (0)
+#define DS_NMETHOD1(name, nm) do {} while (0)
+#endif
+
 #endif // SHARE_VM_CODE_NMETHOD_HPP
--- a/src/share/vm/oops/method.cpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/oops/method.cpp	Wed Nov 21 19:23:43 2012 +0100
@@ -1942,3 +1942,16 @@
   guarantee(md == NULL ||
       md->is_methodData(), "should be method data");
 }
+
+#ifdef GRAAL
+void DebugScopedMethod::print_on(outputStream* st) {
+  if (_method != NULL) {
+    st->print("Method@%p", _method);
+    char holder[O_BUFLEN];
+    char nameAndSig[O_BUFLEN];
+    _method->method_holder()->name()->as_C_string(holder, O_BUFLEN);
+    _method->name_and_sig_as_C_string(nameAndSig, O_BUFLEN);
+    st->print(" - %s::%s", holder, nameAndSig);
+  }
+}
+#endif
--- a/src/share/vm/oops/method.hpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/oops/method.hpp	Wed Nov 21 19:23:43 2012 +0100
@@ -1013,4 +1013,20 @@
   }
 };
 
+#ifdef GRAAL
+class DebugScopedMethod : public DebugScopedValue {
+private:
+  Method* _method;
+public:
+  DebugScopedMethod(const char* file, int line, Method* method) : DebugScopedValue(file, line), _method(method) {}
+  void print_on(outputStream* st);
+};
+#define DS_METHOD(method) DebugScopedMethod __dsm__(__FILE__, __LINE__, method)
+#define DS_METHOD1(var, method) DebugScopedMethod var(__FILE__, __LINE__, method)
+#else
+#define DS_METHOD(method) do {} while (0)
+#define DS_METHOD1(var, method) do {} while (0)
+#endif
+
 #endif // SHARE_VM_OOPS_METHODOOP_HPP
+
--- a/src/share/vm/runtime/thread.cpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/runtime/thread.cpp	Wed Nov 21 19:23:43 2012 +0100
@@ -1444,6 +1444,7 @@
 #ifdef GRAAL
   _graal_deopt_info = NULL;
   _graal_alternate_call_target = NULL;
+  _debug_scope = NULL;
 #endif
 #ifdef HIGH_LEVEL_INTERPRETER
   _high_level_interpreter_in_vm = false;
--- a/src/share/vm/runtime/thread.hpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/runtime/thread.hpp	Wed Nov 21 19:23:43 2012 +0100
@@ -903,6 +903,7 @@
 #ifdef GRAAL
   volatile oop _graal_deopt_info;
   address _graal_alternate_call_target;
+  DebugScopedValue* _debug_scope;
 #endif
 #ifdef HIGH_LEVEL_INTERPRETER
   bool _high_level_interpreter_in_vm;
@@ -1283,6 +1284,9 @@
   void set_graal_deopt_info(oop o)               { _graal_deopt_info = o; }
   
   void set_graal_alternate_call_target(address a) { _graal_alternate_call_target = a; }
+
+  DebugScopedValue* debug_scope() const                { return _debug_scope; }
+  void set_debug_scope(DebugScopedValue* ds)           { _debug_scope = ds; }
 #endif
 #ifdef HIGH_LEVEL_INTERPRETER
   bool high_level_interpreter_in_vm()            { return _high_level_interpreter_in_vm; }
--- a/src/share/vm/utilities/debug.cpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/utilities/debug.cpp	Wed Nov 21 19:23:43 2012 +0100
@@ -860,3 +860,37 @@
 #endif
 
 #endif // !PRODUCT
+
+#ifdef GRAAL
+
+DebugScopedValue::DebugScopedValue(const char* file, int line) {
+  _file = file;
+  _line = line;
+  Thread* thread = Thread::current();
+  if (thread != NULL && thread->is_Java_thread()) {
+    JavaThread* javaThread = (JavaThread*) thread;
+    _parent = javaThread->debug_scope();
+    javaThread->set_debug_scope(this);
+  } else {
+    _parent = NULL;
+  }
+}
+
+DebugScopedValue::~DebugScopedValue() {
+  Thread* thread = Thread::current();
+  if (thread != NULL && thread->is_Java_thread()) {
+    JavaThread* javaThread = (JavaThread*) thread;
+    javaThread->set_debug_scope(_parent);
+    _parent = NULL;
+  }
+}
+
+void DebugScopedValue::print(outputStream* st) {
+  st->print("%s:%d: ", _file, _line);
+  print_on(st);
+}
+
+void DebugScopedScalar::print_on(outputStream* st) {
+  st->print("int: %d, char: %c, long: %ld, hex: %p", _value, _value, _value, _value);
+}
+#endif
--- a/src/share/vm/utilities/debug.hpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/utilities/debug.hpp	Wed Nov 21 19:23:43 2012 +0100
@@ -30,6 +30,35 @@
 
 #include <stdarg.h>
 
+#ifdef GRAAL
+// Scopes a value that may be of interest in a crash log.
+class DebugScopedValue {
+protected:
+  DebugScopedValue *_parent;
+  const char* _file;
+  int _line;
+public:
+  DebugScopedValue(const char* file, int line);
+  ~DebugScopedValue();
+  void print(outputStream* st);
+  virtual void print_on(outputStream* st) = 0;
+  DebugScopedValue* parent() { return _parent; }
+};
+
+class DebugScopedScalar : DebugScopedValue {
+private:
+  void* _value;
+public:
+  DebugScopedScalar(const char* file, int line, void* v) : DebugScopedValue(file, line), _value(v) {}
+  void print_on(outputStream* st);
+};
+#define DS_SCALAR(val) DebugScopedScalar __dss__(__FILE__, __LINE__, (void*) val)
+#define DS_SCALAR1(name, val) DebugScopedScalar name(__FILE__, __LINE__, (void*) val)
+#else
+#define DS_SCALAR(name) do {} while (0)
+#define DS_SCALAR1(name, val) do {} while (0)
+#endif
+
 // Simple class to format the ctor arguments into a fixed-sized buffer.
 class FormatBufferBase {
  protected:
--- a/src/share/vm/utilities/vmError.cpp	Tue Nov 20 22:50:44 2012 +0100
+++ b/src/share/vm/utilities/vmError.cpp	Wed Nov 21 19:23:43 2012 +0100
@@ -491,6 +491,30 @@
        print_bug_submit_message(st, _thread);
      }
 
+#ifdef GRAAL
+  STEP(67, "(printing debug scope)" )
+
+     if (_verbose) {
+       if (_thread != NULL && _thread->is_Java_thread()) {
+         JavaThread* javaThread = (JavaThread*) _thread;
+         DebugScopedValue* ds = javaThread->debug_scope();
+         int level = 0;
+         while (ds != NULL) {
+           if (level == 0) {
+             st->cr();
+             st->print_cr("---------------  D E B U G  S C O P E ---------------");
+             st->cr();
+           }
+           st->print("%d: ", level);
+           ds->print(st);
+           st->cr();
+           ds = ds->parent();
+           level++;
+         }
+       }
+     }
+#endif
+
   STEP(70, "(printing thread)" )
 
      if (_verbose) {