mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
exception.cc: Remove stray MethodRef.h include.
2005-03-10 Bryce McKinlay <mckinlay@redhat.com> * exception.cc: Remove stray MethodRef.h include. * java/lang/natClass.cc: Likewise. * gnu/gcj/runtime/MethodRef.java: Removed. * gnu/gcj/runtime/StackTrace.java, gnu/gcj/runtime/natNameFinder.cc, gnu/gcj/runtime/natStackTrace.cc: Really removed. * java/lang/natRuntime.cc (_load): Remove unsed variable. * Makefile.am (ordinary_java_source_files): Remove MethodRef.java. * Makefile.in: Rebuilt. From-SVN: r96288
This commit is contained in:
parent
694d73e165
commit
c0cbd60130
@ -1,3 +1,14 @@
|
||||
2005-03-10 Bryce McKinlay <mckinlay@redhat.com>
|
||||
|
||||
* exception.cc: Remove stray MethodRef.h include.
|
||||
* java/lang/natClass.cc: Likewise.
|
||||
* gnu/gcj/runtime/MethodRef.java: Removed.
|
||||
* gnu/gcj/runtime/StackTrace.java, gnu/gcj/runtime/natNameFinder.cc,
|
||||
gnu/gcj/runtime/natStackTrace.cc: Really removed.
|
||||
* java/lang/natRuntime.cc (_load): Remove unsed variable.
|
||||
* Makefile.am (ordinary_java_source_files): Remove MethodRef.java.
|
||||
* Makefile.in: Rebuilt.
|
||||
|
||||
2005-03-10 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* Makefile.in: Rebuilt.
|
||||
@ -12,7 +23,7 @@
|
||||
|
||||
New Stack Trace infrastructure.
|
||||
* Makefile.am (libgcj0_convenience_la_SOURCES): Add stacktrace.cc.
|
||||
(gnu/gcj/runtime/StackTrace.lo): Removed.
|
||||
(gnu/gcj/runtime/StackTrace.java): Removed.
|
||||
(ordinary_java_source_files): Remove obsolete files.
|
||||
(nat_source_files): Remove obsolete files. Add natVMThrowable.cc.
|
||||
* configure.host (fallback_backtrace_h): Set backtrace header
|
||||
|
@ -2903,7 +2903,6 @@ gnu/gcj/io/SimpleSHSStream.java \
|
||||
gnu/gcj/runtime/FileDeleter.java \
|
||||
gnu/gcj/runtime/FinalizerThread.java \
|
||||
gnu/gcj/runtime/JNIWeakRef.java \
|
||||
gnu/gcj/runtime/MethodRef.java \
|
||||
gnu/gcj/runtime/NameFinder.java \
|
||||
gnu/gcj/runtime/PersistentByteMap.java \
|
||||
gnu/gcj/runtime/SharedLibHelper.java \
|
||||
|
@ -554,7 +554,7 @@ am__libgcj0_convenience_la_SOURCES_DIST = prims.cc jni.cc exception.cc \
|
||||
gnu/gcj/io/MimeTypes.java gnu/gcj/io/SimpleSHSStream.java \
|
||||
gnu/gcj/runtime/FileDeleter.java \
|
||||
gnu/gcj/runtime/FinalizerThread.java \
|
||||
gnu/gcj/runtime/JNIWeakRef.java gnu/gcj/runtime/MethodRef.java \
|
||||
gnu/gcj/runtime/JNIWeakRef.java \
|
||||
gnu/gcj/runtime/NameFinder.java \
|
||||
gnu/gcj/runtime/PersistentByteMap.java \
|
||||
gnu/gcj/runtime/SharedLibHelper.java \
|
||||
@ -3992,8 +3992,7 @@ am__objects_15 = $(am__objects_9) gnu/classpath/ServiceFactory.lo \
|
||||
gnu/gcj/io/DefaultMimeTypes.lo gnu/gcj/io/MimeTypes.lo \
|
||||
gnu/gcj/io/SimpleSHSStream.lo gnu/gcj/runtime/FileDeleter.lo \
|
||||
gnu/gcj/runtime/FinalizerThread.lo \
|
||||
gnu/gcj/runtime/JNIWeakRef.lo gnu/gcj/runtime/MethodRef.lo \
|
||||
gnu/gcj/runtime/NameFinder.lo \
|
||||
gnu/gcj/runtime/JNIWeakRef.lo gnu/gcj/runtime/NameFinder.lo \
|
||||
gnu/gcj/runtime/PersistentByteMap.lo \
|
||||
gnu/gcj/runtime/SharedLibHelper.lo \
|
||||
gnu/gcj/runtime/SharedLibLoader.lo \
|
||||
@ -7302,7 +7301,6 @@ gnu/gcj/io/SimpleSHSStream.java \
|
||||
gnu/gcj/runtime/FileDeleter.java \
|
||||
gnu/gcj/runtime/FinalizerThread.java \
|
||||
gnu/gcj/runtime/JNIWeakRef.java \
|
||||
gnu/gcj/runtime/MethodRef.java \
|
||||
gnu/gcj/runtime/NameFinder.java \
|
||||
gnu/gcj/runtime/PersistentByteMap.java \
|
||||
gnu/gcj/runtime/SharedLibHelper.java \
|
||||
@ -9604,8 +9602,6 @@ gnu/gcj/runtime/FinalizerThread.lo: gnu/gcj/runtime/$(am__dirstamp) \
|
||||
gnu/gcj/runtime/$(DEPDIR)/$(am__dirstamp)
|
||||
gnu/gcj/runtime/JNIWeakRef.lo: gnu/gcj/runtime/$(am__dirstamp) \
|
||||
gnu/gcj/runtime/$(DEPDIR)/$(am__dirstamp)
|
||||
gnu/gcj/runtime/MethodRef.lo: gnu/gcj/runtime/$(am__dirstamp) \
|
||||
gnu/gcj/runtime/$(DEPDIR)/$(am__dirstamp)
|
||||
gnu/gcj/runtime/NameFinder.lo: gnu/gcj/runtime/$(am__dirstamp) \
|
||||
gnu/gcj/runtime/$(DEPDIR)/$(am__dirstamp)
|
||||
gnu/gcj/runtime/PersistentByteMap.lo: gnu/gcj/runtime/$(am__dirstamp) \
|
||||
@ -16353,8 +16349,6 @@ mostlyclean-compile:
|
||||
-rm -f gnu/gcj/runtime/FinalizerThread.lo
|
||||
-rm -f gnu/gcj/runtime/JNIWeakRef.$(OBJEXT)
|
||||
-rm -f gnu/gcj/runtime/JNIWeakRef.lo
|
||||
-rm -f gnu/gcj/runtime/MethodRef.$(OBJEXT)
|
||||
-rm -f gnu/gcj/runtime/MethodRef.lo
|
||||
-rm -f gnu/gcj/runtime/NameFinder.$(OBJEXT)
|
||||
-rm -f gnu/gcj/runtime/NameFinder.lo
|
||||
-rm -f gnu/gcj/runtime/PersistentByteMap.$(OBJEXT)
|
||||
@ -21979,7 +21973,6 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/FileDeleter.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/FinalizerThread.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/JNIWeakRef.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/MethodRef.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/NameFinder.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/PersistentByteMap.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gnu/gcj/runtime/$(DEPDIR)/SharedLibHelper.Plo@am__quote@
|
||||
|
@ -15,7 +15,6 @@ details. */
|
||||
|
||||
#include <java/lang/Class.h>
|
||||
#include <java/lang/NullPointerException.h>
|
||||
#include <gnu/gcj/runtime/MethodRef.h>
|
||||
#include <gnu/gcj/RawData.h>
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
|
@ -1,25 +0,0 @@
|
||||
// gnu.gcj.runtime.MethodRef -- used by StackTrace.
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
package gnu.gcj.runtime;
|
||||
|
||||
import gnu.gcj.RawData;
|
||||
|
||||
class MethodRef
|
||||
{
|
||||
MethodRef(RawData /* Actually _Jv_Method */ m, Class k)
|
||||
{
|
||||
klass = k;
|
||||
method = m;
|
||||
}
|
||||
|
||||
public RawData method; // Actually a raw pointer to _Jv_Method
|
||||
public Class klass;
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
/* gnu.gcj.runtime.StackTrace -- VM support methods for walking the
|
||||
stack.
|
||||
Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.gcj.runtime;
|
||||
|
||||
import gnu.gcj.RawData;
|
||||
import java.util.TreeMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.SortedMap;
|
||||
import gnu.gcj.runtime.NameFinder;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* VM dependent state and support methods for walking the stack.
|
||||
* <p>
|
||||
* This is the version used by libgcj (http://gcc.gnu.org/java/).
|
||||
*
|
||||
* @author Mark Wielaard (mark@klomp.org)
|
||||
* @author Andrew Haley (aph@redhat.com)
|
||||
*/
|
||||
public final class StackTrace
|
||||
{
|
||||
/**
|
||||
* Fill in the stack trace with the top n frames on current
|
||||
* execution stack. Can return null if the VM does not support
|
||||
* capturing the VM execution state.
|
||||
*
|
||||
* @see Throwable#fillInStackTrace()
|
||||
*/
|
||||
public StackTrace(int n)
|
||||
{
|
||||
fillInStackTrace(n, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the stack trace with state of the entire execution stack,
|
||||
* starting from frame <code>offset</code>. Can return null if the
|
||||
* VM does not support capturing the VM execution state.
|
||||
*
|
||||
* This can be very expensive. If you only want part of the stack,
|
||||
* see <code>Throwable.fillInStackTrace(int)</code>
|
||||
*
|
||||
* @see Throwable#fillInStackTrace()
|
||||
*/
|
||||
public StackTrace()
|
||||
{
|
||||
int n = 64;
|
||||
|
||||
do
|
||||
{
|
||||
n *= 4;
|
||||
fillInStackTrace(n, 1);
|
||||
}
|
||||
while (len >= n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class containing the execution point represented by
|
||||
* the Nth frame down the stack. The zeroth frame represents the
|
||||
* top of the stack, which is the method that called classAt().
|
||||
*
|
||||
* If the Nth frame down the stack was not create by a method
|
||||
* invocation, return null.
|
||||
*
|
||||
* It is not necessary to call <code>fillInStackTrace()</code> with
|
||||
* a size greater than N before calling this method; if the current
|
||||
* stack trace is insufficiently large, it will be expanded as
|
||||
* required. This requires some caution if
|
||||
* <code>fillInStackTrace()</code> is called from a different
|
||||
* invocation to the one that calls <code>classAt()</code>.
|
||||
* classAt() will not call <code>fillInStackTrace()</code> unless N
|
||||
* is greater than the current length.
|
||||
*
|
||||
*/
|
||||
public native Class classAt(int n);
|
||||
|
||||
/**
|
||||
* Return the name of the method containing the execution point
|
||||
* represented by the Nth frame down the stack. The zeroth frame
|
||||
* represents the top of the stack, which is the method that called
|
||||
* classAt().
|
||||
*
|
||||
* If the Nth frame down the stack was not create by a method
|
||||
* invocation, return null.
|
||||
*
|
||||
* It is not necessary to call <code>fillInStackTrace()</code> with
|
||||
* a size greater than N before calling this method; if the current
|
||||
* stack trace is insufficiently large, it will be expanded as
|
||||
* required. This requires some caution if
|
||||
* <code>fillInStackTrace()</code> is called from a different
|
||||
* invocation to the one that calls <code>classAt()</code>.
|
||||
* classAt() will not call <code>fillInStackTrace()</code> unless N
|
||||
* is greater than the current length.
|
||||
*
|
||||
*/
|
||||
public native String methodAt(int n);
|
||||
|
||||
/**
|
||||
* Return the length of this stack trace.
|
||||
*
|
||||
*/
|
||||
public int length ()
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
public static native Class getClass(RawData ip);
|
||||
|
||||
private static native void update();
|
||||
private static MethodRef methodAtAddress(RawData addr)
|
||||
{
|
||||
update();
|
||||
synchronized (map)
|
||||
{
|
||||
return (MethodRef) map.get (addr);
|
||||
}
|
||||
}
|
||||
|
||||
gnu.gcj.RawData stackTraceAddrs()
|
||||
{
|
||||
return addrs;
|
||||
}
|
||||
|
||||
private native void fillInStackTrace(int n, int offset);
|
||||
protected native void finalize();
|
||||
|
||||
private static native MethodRef getCompiledMethodRef(RawData addr);
|
||||
private static IdentityHashMap map = new IdentityHashMap();
|
||||
|
||||
private gnu.gcj.RawData addrs;
|
||||
private int len;
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
// natNameFinder.cc - native helper methods for NameFinder.java
|
||||
|
||||
/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
/**
|
||||
* @author Mark Wielaard (mark@klomp.org)
|
||||
* Based on the old name-finder.cc by Andrew Haley <aph@cygnus.com>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <gcj/cni.h>
|
||||
#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>
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
// On some systems, a prefix is attached to a method name before
|
||||
// it is exported as a label. The GCC preprocessor predefines
|
||||
// this prefix as the macro __USER_LABEL_PREFIX__ which expands to
|
||||
// a string (not string constant) representing the prefix, if any.
|
||||
#undef LABEL_PREFIX
|
||||
#ifdef __USER_LABEL_PREFIX__
|
||||
|
||||
#define USER_LABEL_PREFIX_STRING_0(s) #s
|
||||
#define USER_LABEL_PREFIX_STRING(s) USER_LABEL_PREFIX_STRING_0(s)
|
||||
|
||||
#define LABEL_PREFIX USER_LABEL_PREFIX_STRING(__USER_LABEL_PREFIX__)
|
||||
|
||||
#else /* __USER_LABEL_PREFIX__ */
|
||||
|
||||
#define LABEL_PREFIX ""
|
||||
|
||||
#endif /* ! __USER_LABEL_PREFIX__ */
|
||||
|
||||
java::lang::StackTraceElement*
|
||||
gnu::gcj::runtime::NameFinder::newElement (java::lang::String* fileName,
|
||||
jint lineNumber,
|
||||
java::lang::String* className,
|
||||
java::lang::String* methName,
|
||||
jboolean isNative)
|
||||
{
|
||||
return new java::lang::StackTraceElement( fileName, lineNumber,
|
||||
className, methName, isNative);
|
||||
}
|
||||
|
||||
java::lang::String*
|
||||
gnu::gcj::runtime::NameFinder::getExternalLabel (java::lang::String* name)
|
||||
{
|
||||
jsize nameLen = JvGetStringUTFLength (name);
|
||||
jsize pfxLen = strlen (LABEL_PREFIX);
|
||||
char *newName = (char *) JvMalloc (pfxLen + nameLen + 1);
|
||||
*(newName + 0) = '\0';
|
||||
strcpy (newName, LABEL_PREFIX);
|
||||
JvGetStringUTFRegion (name, 0, name->length(), newName + pfxLen);
|
||||
*(newName + pfxLen + nameLen) = '\0';
|
||||
return JvNewStringLatin1 (newName);
|
||||
}
|
||||
|
||||
java::lang::String*
|
||||
gnu::gcj::runtime::NameFinder::getExecutable (void)
|
||||
{
|
||||
return JvNewStringLatin1 (_Jv_ThisExecutable ());
|
||||
}
|
||||
|
||||
java::lang::String*
|
||||
gnu::gcj::runtime::NameFinder::getAddrAsString(RawData* addrs, jint n)
|
||||
{
|
||||
_Jv_frame_info *p = (_Jv_frame_info *) addrs;
|
||||
typedef unsigned word_t __attribute ((mode (word)));
|
||||
word_t w = (word_t) p[n].addr;
|
||||
int digits = sizeof (void *) * 2;
|
||||
char hex[digits+5];
|
||||
|
||||
strcpy (hex, "0x");
|
||||
for (int i = digits - 1; i >= 0; i--)
|
||||
{
|
||||
int digit = w % 16;
|
||||
|
||||
w /= 16;
|
||||
hex[i+2] = digit > 9 ? 'a' + digit - 10 : '0' + digit;
|
||||
}
|
||||
hex [digits+2] = 0;
|
||||
|
||||
return JvNewStringLatin1(hex);
|
||||
}
|
||||
|
||||
java::lang::StackTraceElement*
|
||||
gnu::gcj::runtime::NameFinder::dladdrLookup(RawData* addrs, jint n)
|
||||
{
|
||||
#if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
|
||||
extern char **_Jv_argv;
|
||||
char name[1024];
|
||||
char file_name[1024];
|
||||
_Jv_frame_info *stack = (_Jv_frame_info *) addrs;
|
||||
void* p = stack[n].addr;
|
||||
Dl_info dl_info;
|
||||
|
||||
if (dladdr (p, &dl_info))
|
||||
{
|
||||
if (dl_info.dli_fname)
|
||||
strncpy (file_name, dl_info.dli_fname, sizeof file_name);
|
||||
if (dl_info.dli_sname)
|
||||
strncpy (name, dl_info.dli_sname, sizeof name);
|
||||
|
||||
/* Don't trust dladdr() if the address is from the main program. */
|
||||
if (dl_info.dli_fname != NULL
|
||||
&& dl_info.dli_sname != NULL
|
||||
&& (_Jv_argv == NULL || strcmp (file_name, _Jv_argv[0]) != 0))
|
||||
return createStackTraceElement (JvNewStringLatin1 (name),
|
||||
JvNewStringLatin1 (file_name));
|
||||
}
|
||||
#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);
|
||||
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?
|
||||
java::lang::String *className = meth->defining_class->getName();
|
||||
java::lang::String *methodName
|
||||
= demangleInterpreterMethod(sb->toString(), className);
|
||||
return new java::lang::StackTraceElement(NULL, -1,
|
||||
className, methodName, false);
|
||||
#else // INTERPRETER
|
||||
return NULL;
|
||||
#endif // INTERPRETER
|
||||
}
|
@ -1,241 +0,0 @@
|
||||
// natStackTrace.cc - native helper methods for Throwable
|
||||
|
||||
/* Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
/**
|
||||
* @author Andrew Haley <aph@cygnus.com>
|
||||
* @author Mark Wielaard <mark@klomp.org>
|
||||
*
|
||||
* Native helper methods for VM specific Throwable support.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <platform.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <jvm.h>
|
||||
#include <gcj/cni.h>
|
||||
#include <gnu/gcj/RawData.h>
|
||||
#include <java/lang/Object.h>
|
||||
#include <java-threads.h>
|
||||
#include <gnu/gcj/runtime/MethodRef.h>
|
||||
#include <gnu/gcj/runtime/StackTrace.h>
|
||||
#include <java/lang/Thread.h>
|
||||
#include <java-interp.h>
|
||||
#include <java/util/IdentityHashMap.h>
|
||||
#include <java/lang/ArrayIndexOutOfBoundsException.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#include <unwind.h>
|
||||
|
||||
|
||||
#ifdef INTERPRETER
|
||||
extern "C" void *_Unwind_FindEnclosingFunction (void *pc)
|
||||
__attribute__((pure));
|
||||
#endif // INTERPRETER
|
||||
|
||||
// Fill in this stack trace with MAXLEN elements starting at offset.
|
||||
void
|
||||
gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
|
||||
{
|
||||
#ifdef HAVE_BACKTRACE
|
||||
offset += 1;
|
||||
void *_p[maxlen + offset];
|
||||
len = backtrace (_p, maxlen + offset) - offset;
|
||||
void **p = _p + offset;
|
||||
_Jv_frame_info *frame;
|
||||
if (len > 0)
|
||||
{
|
||||
#ifdef INTERPRETER
|
||||
extern void *const _Jv_StartOfInterpreter;
|
||||
extern void * _Jv_EndOfInterpreter;
|
||||
|
||||
java::lang::Thread *thread = java::lang::Thread::currentThread();
|
||||
_Jv_MethodChain *interp_frame
|
||||
= (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
|
||||
: NULL);
|
||||
#endif // INTERPRETER
|
||||
|
||||
frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
|
||||
for (int n = 0; n < len; n++)
|
||||
{
|
||||
void *pc = p[n];
|
||||
frame[n].addr = pc;
|
||||
|
||||
#ifdef INTERPRETER
|
||||
frame[n].interp = 0;
|
||||
|
||||
// If _Jv_StartOfInterpreter is NULL either we've never
|
||||
// entered the intepreter or _Unwind_FindEnclosingFunction
|
||||
// is broken.
|
||||
if (__builtin_expect (_Jv_StartOfInterpreter != NULL, false))
|
||||
{
|
||||
// _Jv_StartOfInterpreter marks the very first
|
||||
// instruction in the interpreter, but
|
||||
// _Jv_EndOfInterpreter is an upper bound. If PC is
|
||||
// less than _Jv_EndOfInterpreter it might be in the
|
||||
// interpreter: we call _Unwind_FindEnclosingFunction to
|
||||
// find out.
|
||||
if (pc >= _Jv_StartOfInterpreter
|
||||
&& (pc < _Jv_EndOfInterpreter
|
||||
|| _Jv_EndOfInterpreter == NULL))
|
||||
{
|
||||
if (_Unwind_FindEnclosingFunction (pc)
|
||||
== _Jv_StartOfInterpreter)
|
||||
{
|
||||
frame[n].interp = (void *) interp_frame->self;
|
||||
interp_frame = interp_frame->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We've found an address that we know is not within
|
||||
// the interpreter. We use that to refine our upper
|
||||
// bound on where the interpreter ends.
|
||||
_Jv_EndOfInterpreter = pc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // INTERPRETER
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
frame = NULL;
|
||||
|
||||
addrs = reinterpret_cast<gnu::gcj::RawData *> (frame);
|
||||
#else // HAVE_BACKTRACE
|
||||
(void)maxlen;
|
||||
(void)offset;
|
||||
#endif // HAVE_BACKTRACE
|
||||
}
|
||||
|
||||
/* Obtain the next power-of-2 of some integer. */
|
||||
static inline jint
|
||||
nextpowerof2 (jint n)
|
||||
{
|
||||
n |= (n >> 1);
|
||||
n |= (n >> 2);
|
||||
n |= (n >> 4);
|
||||
n |= (n >> 8);
|
||||
n |= (n >> 16);
|
||||
return n+1;
|
||||
}
|
||||
|
||||
#define GET_FRAME(N) \
|
||||
({ \
|
||||
if ((N) >= len) \
|
||||
fillInStackTrace (nextpowerof2 (N), 1); \
|
||||
if ((N) < 0 || (N) >= len) \
|
||||
throw new ::java::lang::ArrayIndexOutOfBoundsException (); \
|
||||
\
|
||||
_Jv_frame_info *frame = (_Jv_frame_info *)addrs; \
|
||||
&frame[N]; \
|
||||
})
|
||||
|
||||
gnu::gcj::runtime::MethodRef *
|
||||
gnu::gcj::runtime::StackTrace::getCompiledMethodRef (gnu::gcj::RawData *addr)
|
||||
{
|
||||
void *p = _Unwind_FindEnclosingFunction (addr);
|
||||
return gnu::gcj::runtime::StackTrace
|
||||
::methodAtAddress ((gnu::gcj::RawData *)p);
|
||||
}
|
||||
|
||||
java::lang::Class *
|
||||
gnu::gcj::runtime::StackTrace::getClass (gnu::gcj::RawData *p)
|
||||
{
|
||||
gnu::gcj::runtime::MethodRef *ref = getCompiledMethodRef (p);
|
||||
if (ref)
|
||||
return ref->klass;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
java::lang::Class *
|
||||
gnu::gcj::runtime::StackTrace::classAt (jint n)
|
||||
{
|
||||
_Jv_frame_info *frame = GET_FRAME (n);
|
||||
|
||||
#ifdef INTERPRETER
|
||||
if (frame->interp)
|
||||
{
|
||||
_Jv_InterpMethod *meth
|
||||
= reinterpret_cast<_Jv_InterpMethod *> (frame->interp);
|
||||
return meth->defining_class;
|
||||
}
|
||||
#endif // INTERPRETER
|
||||
|
||||
return getClass ((gnu::gcj::RawData *)frame->addr);
|
||||
}
|
||||
|
||||
java::lang::String*
|
||||
gnu::gcj::runtime::StackTrace::methodAt (jint n)
|
||||
{
|
||||
_Jv_frame_info *frame = GET_FRAME (n);
|
||||
_Jv_Method *meth = NULL;
|
||||
|
||||
#ifdef INTERPRETER
|
||||
if (frame->interp)
|
||||
{
|
||||
meth
|
||||
= reinterpret_cast<_Jv_InterpMethod *> (frame->interp)
|
||||
->get_method();
|
||||
}
|
||||
#endif // INTERPRETER
|
||||
|
||||
if (! meth)
|
||||
{
|
||||
gnu::gcj::runtime::MethodRef *ref
|
||||
= getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
|
||||
if (ref)
|
||||
meth = (_Jv_Method *)ref->method;
|
||||
}
|
||||
|
||||
return meth
|
||||
? _Jv_NewStringUtf8Const (meth->name)
|
||||
: NULL ;
|
||||
}
|
||||
|
||||
void
|
||||
gnu::gcj::runtime::StackTrace::update(void)
|
||||
{
|
||||
jclass klass;
|
||||
|
||||
while ((klass = _Jv_PopClass ()))
|
||||
{
|
||||
for (int i=0; i<klass->method_count; i++)
|
||||
{
|
||||
JvSynchronize sync (map);
|
||||
_Jv_Method *meth = &(klass->methods[i]);
|
||||
if (meth->ncode) // i.e. if p is not abstract
|
||||
{
|
||||
gnu::gcj::runtime::MethodRef *ref
|
||||
= new gnu::gcj::runtime::MethodRef
|
||||
((gnu::gcj::RawData *)meth, klass);
|
||||
map->put ((java::lang::Object*)(meth->ncode), ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gnu::gcj::runtime::StackTrace::finalize(void)
|
||||
{
|
||||
if (addrs != NULL)
|
||||
_Jv_Free (addrs);
|
||||
}
|
@ -54,7 +54,6 @@ details. */
|
||||
#include <java/lang/StringBuffer.h>
|
||||
#include <java/lang/VMClassLoader.h>
|
||||
#include <gcj/method.h>
|
||||
#include <gnu/gcj/runtime/MethodRef.h>
|
||||
#include <gnu/gcj/RawData.h>
|
||||
#include <java/lang/VerifyError.h>
|
||||
|
||||
|
@ -162,7 +162,6 @@ java::lang::Runtime::_load (jstring path, jboolean do_search)
|
||||
|
||||
if (do_search)
|
||||
{
|
||||
ClassLoader *sys = ClassLoader::systemClassLoader;
|
||||
ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
|
||||
|
||||
if (look != NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user