]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
jvm.h (struct _Jv_frame_info): New structure.
authorTom Tromey <tromey@redhat.com>
Thu, 29 Aug 2002 17:53:28 +0000 (17:53 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Thu, 29 Aug 2002 17:53:28 +0000 (17:53 +0000)
* include/jvm.h (struct _Jv_frame_info): New structure.
* gnu/gcj/runtime/natNameFinder.cc: Include StringBuffer.h,
java-interp.h.
(lookupInterp): New method.
(getAddrAsString): Use _Jv_frame_info.
(dladdrLookup): Likewise.
* gnu/gcj/runtime/NameFinder.java (lookup): Try to look up
interpreted frame.
(lookupInterp): Declare.
* java/lang/natVMThrowable.cc: Include Thread.h, java-interp.h.
(fillInStackTrace): Collect information on interpreted frames.
Use _Jv_frame_info.
* interpret.cc: Include Thread.h.
(run): Create and push _Jv_MethodChain object.
(_Jv_EndOfInterpreter): New global.
* java/lang/Thread.java (interp_frame): New field.
* include/java-interp.h (struct _Jv_MethodChain): New structure.
Include NameFinder.h.

From-SVN: r56657

libjava/ChangeLog
libjava/gnu/gcj/runtime/NameFinder.java
libjava/gnu/gcj/runtime/natNameFinder.cc
libjava/include/java-interp.h
libjava/include/jvm.h
libjava/interpret.cc
libjava/java/lang/Thread.java
libjava/java/lang/natVMThrowable.cc

index 442350028cfa8a7a1ae411730c04d16fcf4190ae..8d8f248bed3a75fb0bcdba3121913344dd89a2f8 100644 (file)
@@ -1,3 +1,24 @@
+2002-08-29  Tom Tromey  <tromey@redhat.com>
+
+       * include/jvm.h (struct _Jv_frame_info): New structure.
+       * gnu/gcj/runtime/natNameFinder.cc: Include StringBuffer.h,
+       java-interp.h.
+       (lookupInterp): New method.
+       (getAddrAsString): Use _Jv_frame_info.
+       (dladdrLookup): Likewise.
+       * gnu/gcj/runtime/NameFinder.java (lookup): Try to look up
+       interpreted frame.
+       (lookupInterp): Declare.
+       * java/lang/natVMThrowable.cc: Include Thread.h, java-interp.h.
+       (fillInStackTrace): Collect information on interpreted frames.
+       Use _Jv_frame_info.
+       * interpret.cc: Include Thread.h.
+       (run): Create and push _Jv_MethodChain object.
+       (_Jv_EndOfInterpreter): New global.
+       * java/lang/Thread.java (interp_frame): New field.
+       * include/java-interp.h (struct _Jv_MethodChain): New structure.
+       Include NameFinder.h.
+
 2002-08-28  Tom Tromey  <tromey@redhat.com>
 
        * java/lang/Class.h: Include Package.h.
index 60f47ac64fecf7a4dd4a3fa2bdd2617c38de219c..f32ebe0f530dd2a0e3516befc411b586ce1888b6 100644 (file)
@@ -172,6 +172,12 @@ public class NameFinder
    */
   native private String getAddrAsString(RawData addrs, int n);
 
+  /**
+   * If nth element of stack is an interpreted frame, return the
+   * element representing the method being interpreted.
+   */
+  native private StackTraceElement lookupInterp(RawData addrs, int n);
+
   /**
    * Creates the nth StackTraceElement from the given native stacktrace.
    */
@@ -179,11 +185,14 @@ public class NameFinder
   {
     StackTraceElement result;
 
-    result = dladdrLookup(addrs, n);
+    result = lookupInterp(addrs, n);
+    if (result == null)
+      result = dladdrLookup(addrs, n);
     if (result == null)
       {
        String name = null;
        String file = null;
+
        String hex = getAddrAsString(addrs, n);
        
        if (addr2line != null)
index 42cc164c3242c897ebaef6b58bc441c06e53b6ac..29488eddda72bdbf8874b5c16a4eff3d11689293 100644 (file)
@@ -1,4 +1,4 @@
-// natNameFinder.cc - native helper methods for NameFiner.java
+// natNameFinder.cc - native helper methods for NameFinder.java
 
 /* Copyright (C) 2002  Free Software Foundation, Inc
 
@@ -19,6 +19,8 @@ details.  */
 #include <jvm.h>
 #include <java/lang/String.h>
 #include <java/lang/StackTraceElement.h>
+#include <java/lang/StringBuffer.h>
+#include <java-interp.h>
 
 #include <gnu/gcj/runtime/NameFinder.h>
 
@@ -29,15 +31,15 @@ details.  */
 java::lang::String*
 gnu::gcj::runtime::NameFinder::getExecutable (void)
 {
-    return JvNewStringLatin1 (_Jv_ThisExecutable ());
+  return JvNewStringLatin1 (_Jv_ThisExecutable ());
 }
 
 java::lang::String*
 gnu::gcj::runtime::NameFinder::getAddrAsString(RawData* addrs, jint n)
 {
-  void **p = (void **) addrs;
+  _Jv_frame_info *p = (_Jv_frame_info *) addrs;
   typedef unsigned word_t __attribute ((mode (word)));
-  word_t w = (word_t) p[n];
+  word_t w = (word_t) p[n].addr;
   int digits = sizeof (void *) * 2;
   char hex[digits+5];
 
@@ -61,8 +63,8 @@ gnu::gcj::runtime::NameFinder::dladdrLookup(RawData* addrs, jint n)
   extern char **_Jv_argv;
   char name[1024];
   char file_name[1024];
-  void **stack = (void **) addrs;
-  void* p = stack[n];
+  _Jv_frame_info *stack = (_Jv_frame_info *) addrs;
+  void* p = stack[n].addr;
   Dl_info dl_info;
    
   if (dladdr (p, &dl_info))
@@ -82,3 +84,29 @@ gnu::gcj::runtime::NameFinder::dladdrLookup(RawData* addrs, jint n)
 #endif
   return NULL;
 }
+
+java::lang::StackTraceElement *
+gnu::gcj::runtime::NameFinder::lookupInterp(RawData* addrs, jint n)
+{
+#ifdef INTERPRETER
+  _Jv_frame_info *stack = (_Jv_frame_info *) addrs;
+  if (stack[n].interp == NULL)
+    return NULL;
+
+  _Jv_InterpMethod *meth
+    = reinterpret_cast<_Jv_InterpMethod *> (stack[n].interp);
+  // FIXME: demangle.
+  java::lang::StringBuffer *sb = new java::lang::StringBuffer();
+  sb->append(_Jv_NewStringUtf8Const(meth->self->name));
+  sb->append(_Jv_NewStringUtf8Const(meth->self->signature));
+  // FIXME: source file name and line number can be found from
+  // bytecode debug information.  But currently we don't keep that
+  // around.
+  // FIXME: is using the defining class correct here?
+  return new java::lang::StackTraceElement(NULL, -1,
+                                          meth->defining_class->getName(),
+                                          sb->toString(), false);
+#else // INTERPRETER
+  return NULL;
+#endif // INTERPRETER
+}
index de1d88f452e2e22c6c2cf3d90b445f7c2996a035..e3f96713ce77c09418f0cc1cee31aed03bec842f 100644 (file)
@@ -13,6 +13,7 @@ details.  */
 
 #include <jvm.h>
 #include <java-cpool.h>
+#include <gnu/gcj/runtime/NameFinder.h>
 
 #ifdef INTERPRETER
 
@@ -138,6 +139,7 @@ class _Jv_InterpMethod : public _Jv_MethodBase
 
   friend class _Jv_ClassReader;
   friend class _Jv_BytecodeVerifier;
+  friend class gnu::gcj::runtime::NameFinder;
 
   friend void _Jv_PrepareClass(jclass);
 };
@@ -205,6 +207,28 @@ public:
   }
 };
 
+// A structure of this type is used to link together interpreter
+// invocations on the stack.
+struct _Jv_MethodChain
+{
+  const _Jv_InterpMethod *self;
+  _Jv_MethodChain **ptr;
+  _Jv_MethodChain *next;
+
+  _Jv_MethodChain (const _Jv_InterpMethod *s, _Jv_MethodChain **n)
+  {
+    self = s;
+    ptr = n;
+    next = *n;
+    *n = this;
+  }
+
+  ~_Jv_MethodChain ()
+  {
+    *ptr = next;
+  }
+};
+
 #endif /* INTERPRETER */
 
 #endif /* __JAVA_INTERP_H__ */
index fc3a7f73ecf0a4da944ed34d07a5f102d978c71e..e02901de824dc7411f931552a5b4bb625ae4b870 100644 (file)
@@ -111,6 +111,20 @@ union _Jv_word2
   jdouble d;
 };                              
 
+// An instance of this type is used to represent a single frame in a
+// backtrace.  If the interpreter has been built, we also include
+// information about the interpreted method.
+struct _Jv_frame_info
+{
+  // PC value.
+  void *addr;
+#ifdef INTERPRETER
+  // Actually a _Jv_InterpMethod, but we don't want to include
+  // java-interp.h everywhere.
+  void *interp;
+#endif // INTERPRETER
+};
+
 /* Extract a character from a Java-style Utf8 string.
  * PTR points to the current character.
  * LIMIT points to the end of the Utf8 string.
index e5c40cff15039de6651f36c6dd582925d9d99ed9..d231387dc9a40b1b48ca2d6904329efcb39bb1c8 100644 (file)
@@ -22,7 +22,6 @@ details.  */
 #include <jvm.h>
 #include <java-cpool.h>
 #include <java-interp.h>
-// #include <java/lang/fdlibm.h>
 #include <java/lang/System.h>
 #include <java/lang/String.h>
 #include <java/lang/Integer.h>
@@ -36,6 +35,7 @@ details.  */
 #include <java/lang/NullPointerException.h>
 #include <java/lang/ArithmeticException.h>
 #include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/Thread.h>
 #include <java-insns.h>
 #include <java-signal.h>
 
@@ -744,11 +744,28 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
 }
 #endif /* DIRECT_THREADED */
 
+// This function exists so that the stack-tracing code can find the
+// boundaries of the interpreter.
+void
+_Jv_StartOfInterpreter (void)
+{
+}
+
 void
 _Jv_InterpMethod::run (void *retp, ffi_raw *args)
 {
   using namespace java::lang::reflect;
 
+  // FRAME_DESC registers this particular invocation as the top-most
+  // interpreter frame.  This lets the stack tracing code (for
+  // Throwable) print information about the method being interpreted
+  // rather than about the interpreter itself.  FRAME_DESC has a
+  // destructor so it cleans up automatically when the interpreter
+  // returns.
+  java::lang::Thread *thread = java::lang::Thread::currentThread();
+  _Jv_MethodChain frame_desc (this,
+                             (_Jv_MethodChain **) &thread->interp_frame);
+
   _Jv_word stack[max_stack];
   _Jv_word *sp = stack;
 
@@ -3169,6 +3186,13 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
     }
 }
 
+// This function exists so that the stack-tracing code can find the
+// boundaries of the interpreter.
+void
+_Jv_EndOfInterpreter (void)
+{
+}
+
 static void
 throw_internal_error (char *msg)
 {
index af5b95f14c6bd55e1b02578aecfa956dc13f51aa..64d58dda080002fda4f604a0479a25dcafd33aba 100644 (file)
@@ -10,6 +10,8 @@ details.  */
 
 package java.lang;
 
+import gnu.gcj.RawData;
+
 /**
  * @author Tom Tromey <tromey@cygnus.com>
  * @date August 24, 1998 
@@ -311,6 +313,9 @@ public class Thread implements Runnable
   private boolean startable_flag;
   private ClassLoader context_class_loader;
 
+  // This describes the top-most interpreter frame for this thread.
+  RawData interp_frame;
+
   // Our native data - points to an instance of struct natThread.
   private Object data;
 }
index 358bab7f13b39149565ba988dc96d696d50ab4ef..f5c56c7a1d4639cd344ec8bd24d2a457e688436f 100644 (file)
@@ -26,6 +26,8 @@ details.  */
 #include <java-threads.h>
 #include <java/lang/Throwable.h>
 #include <java/lang/VMThrowable.h>
+#include <java/lang/Thread.h>
+#include <java-interp.h>
 
 #include <sys/types.h>
 
@@ -54,13 +56,35 @@ java::lang::VMThrowable::fillInStackTrace (java::lang::Throwable* t)
   // to include the calls to fillInStackTrace in the trace.
   int n = backtrace (p, 128) - 1;  
 
-  void **addrs;
+  _Jv_frame_info *addrs;
   if (n > 0)
     {
+#ifdef INTERPRETER
+      extern void _Jv_StartOfInterpreter (void);
+      extern void _Jv_EndOfInterpreter (void);
+
+      java::lang::Thread *thread = java::lang::Thread::currentThread();
+      _Jv_MethodChain *interp_frame
+       = (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
+          : NULL);
+#endif // INTERPRETER
+
       state->length = n;
-      addrs = (void **) _Jv_Malloc (n * sizeof p[0]);
+      int len = n;
+      addrs = (_Jv_frame_info *) _Jv_Malloc (n * sizeof (_Jv_frame_info));
       while (n--)
-       addrs[n] = p[n];
+       {
+         addrs[n].addr = p[n];
+#ifdef INTERPRETER
+         if (p[n] >= &_Jv_StartOfInterpreter && p[n] <= &_Jv_EndOfInterpreter)
+           {
+             addrs[n].interp = (void *) interp_frame->self;
+             interp_frame = interp_frame->next;
+           }
+         else
+           addrs[n].interp = 0;
+#endif // INTERPRETER
+       }
     }
   else
     addrs = NULL;