hotspot/src/share/vm/classfile/javaClasses.cpp
changeset 9133 1c8d07466fdb
parent 9116 9bc44be338d6
parent 9132 59f29856d4b2
child 9321 c29711c6ae35
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Sat Apr 09 21:16:12 2011 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Apr 12 14:18:53 2011 -0700
@@ -1431,32 +1431,41 @@
       }
     }
 #ifdef ASSERT
-  assert(st_method() == method && st.bci() == bci,
-         "Wrong stack trace");
-  st.next();
-  // vframeStream::method isn't GC-safe so store off a copy
-  // of the methodOop in case we GC.
-  if (!st.at_end()) {
-    st_method = st.method();
-  }
+    assert(st_method() == method && st.bci() == bci,
+           "Wrong stack trace");
+    st.next();
+    // vframeStream::method isn't GC-safe so store off a copy
+    // of the methodOop in case we GC.
+    if (!st.at_end()) {
+      st_method = st.method();
+    }
 #endif
+
+    // the format of the stacktrace will be:
+    // - 1 or more fillInStackTrace frames for the exception class (skipped)
+    // - 0 or more <init> methods for the exception class (skipped)
+    // - rest of the stack
+
     if (!skip_fillInStackTrace_check) {
-      // check "fillInStackTrace" only once, so we negate the flag
-      // after the first time check.
-      skip_fillInStackTrace_check = true;
-      if (method->name() == vmSymbols::fillInStackTrace_name()) {
+      if ((method->name() == vmSymbols::fillInStackTrace_name() ||
+           method->name() == vmSymbols::fillInStackTrace0_name()) &&
+          throwable->is_a(method->method_holder())) {
         continue;
       }
+      else {
+        skip_fillInStackTrace_check = true; // gone past them all
+      }
     }
-    // skip <init> methods of the exceptions klass. If there is <init> methods
-    // that belongs to a superclass of the exception  we are going to skipping
-    // them in stack trace. This is simlar to classic VM.
     if (!skip_throwableInit_check) {
+      assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
+
+      // skip <init> methods of the exception class and superclasses
+      // This is simlar to classic VM.
       if (method->name() == vmSymbols::object_initializer_name() &&
           throwable->is_a(method->method_holder())) {
         continue;
       } else {
-        // if no "Throwable.init()" method found, we stop checking it next time.
+        // there are none or we've seen them all - either way stop checking
         skip_throwableInit_check = true;
       }
     }