mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-21 14:59:49 +08:00
jvm.h (struct _Jv_frame_info): New structure.
* 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
This commit is contained in:
parent
ce4e997039
commit
3308c46e47
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user