< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page
rev 53693 : wq8218628: Add detailed message to NullPointerException describing what is null.

@@ -1523,11 +1523,11 @@
 
 bool java_lang_Class::offsets_computed = false;
 int  java_lang_Class::classRedefinedCount_offset = -1;
 
 #define CLASS_FIELDS_DO(macro) \
-  macro(classRedefinedCount_offset, k, "classRedefinedCount", int_signature,         false) ; \
+  macro(classRedefinedCount_offset, k, "classRedefinedCount", int_signature,         false); \
   macro(_class_loader_offset,       k, "classLoader",         classloader_signature, false); \
   macro(_component_mirror_offset,   k, "componentType",       class_signature,       false); \
   macro(_module_offset,             k, "module",              module_signature,      false); \
   macro(_name_offset,               k, "name",                string_signature,      false); \
 

@@ -1968,10 +1968,60 @@
 static inline bool version_matches(Method* method, int version) {
   assert(version < MAX_VERSION, "version is too big");
   return method != NULL && (method->constants()->version() == version);
 }
 
+bool java_lang_Throwable::get_method_and_bci(oop throwable, int index, Method** method, int* bci) {
+  if (index < 0) {
+    return false;
+  }
+
+  objArrayOop bt = (objArrayOop)backtrace(throwable);
+  int depth = 0;
+
+  while (bt != NULL) {
+    oop m = bt->obj_at(trace_methods_offset);
+    typeArrayOop methods = typeArrayOop(m);
+    typeArrayOop bcis = (typeArrayOop)bt->obj_at(trace_bcis_offset);
+    objArrayOop mirrors = (objArrayOop)bt->obj_at(trace_mirrors_offset);
+
+    if ((methods == NULL) || (bcis == NULL) || (mirrors == NULL)) {
+      return false;
+    }
+
+    int length = methods->length();
+
+    for (int i = 0; i < length; i++) {
+      oop m = mirrors->obj_at(i);
+      if (m == NULL) {
+        return false;
+      }
+      InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(m));
+      int method_id = methods->short_at(i);
+      Method* act_method = holder->method_with_idnum(method_id);
+
+      if (act_method == NULL) {
+        return false;
+      }
+
+      int act_bci = Backtrace::bci_at(bcis->int_at(i));
+
+      if (depth == index) {
+        *method = act_method;
+        *bci = act_bci;
+
+        return true;
+      }
+
+      depth += 1;
+    }
+
+    bt = (objArrayOop)bt->obj_at(trace_next_offset);
+  }
+
+  return false;
+}
 
 // This class provides a simple wrapper over the internal structure of
 // exception backtrace to insulate users of the backtrace from needing
 // to know what it looks like.
 class BacktraceBuilder: public StackObj {
< prev index next >