interpret.cc (_Jv_InterpMethod::run): Initialize _Jv_StartOfInterpreter.
2004-10-13 Andrew Haley <aph@redhat.com> * interpret.cc (_Jv_InterpMethod::run): Initialize _Jv_StartOfInterpreter. (_Jv_StartOfInterpreter, _Jv_EndOfInterpreter): Functions removed. (_Jv_StartOfInterpreter, _Jv_EndOfInterpreter): New variables. * gnu/gcj/runtime/natStackTrace.cc (fillInStackTrace): Use _Unwind_FindEnclosingFunction to discover whether PC is within the interpreter. From-SVN: r89037
This commit is contained in:
parent
b79187bb54
commit
180a373d0d
@ -1,3 +1,13 @@
|
|||||||
|
2004-10-13 Andrew Haley <aph@redhat.com>
|
||||||
|
|
||||||
|
* interpret.cc (_Jv_InterpMethod::run): Initialize
|
||||||
|
_Jv_StartOfInterpreter.
|
||||||
|
(_Jv_StartOfInterpreter, _Jv_EndOfInterpreter): Functions removed.
|
||||||
|
(_Jv_StartOfInterpreter, _Jv_EndOfInterpreter): New variables.
|
||||||
|
* gnu/gcj/runtime/natStackTrace.cc (fillInStackTrace): Use
|
||||||
|
_Unwind_FindEnclosingFunction to discover whether PC is within the
|
||||||
|
interpreter.
|
||||||
|
|
||||||
2004-10-12 Rutger Ovidius <ovidr@users.sourceforge.net>
|
2004-10-12 Rutger Ovidius <ovidr@users.sourceforge.net>
|
||||||
|
|
||||||
PR libgcj/17903:
|
PR libgcj/17903:
|
||||||
|
@ -45,6 +45,11 @@ details. */
|
|||||||
#include <unwind.h>
|
#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.
|
// Fill in this stack trace with MAXLEN elements starting at offset.
|
||||||
void
|
void
|
||||||
gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
|
gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
|
||||||
@ -58,9 +63,9 @@ gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
|
|||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
#ifdef INTERPRETER
|
#ifdef INTERPRETER
|
||||||
extern void _Jv_StartOfInterpreter (void);
|
extern void *const _Jv_StartOfInterpreter;
|
||||||
extern void _Jv_EndOfInterpreter (void);
|
extern void * _Jv_EndOfInterpreter;
|
||||||
|
|
||||||
java::lang::Thread *thread = java::lang::Thread::currentThread();
|
java::lang::Thread *thread = java::lang::Thread::currentThread();
|
||||||
_Jv_MethodChain *interp_frame
|
_Jv_MethodChain *interp_frame
|
||||||
= (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
|
= (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
|
||||||
@ -70,16 +75,41 @@ gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
|
|||||||
frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
|
frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
|
||||||
for (int n = 0; n < len; n++)
|
for (int n = 0; n < len; n++)
|
||||||
{
|
{
|
||||||
frame[n].addr = p[n];
|
void *pc = p[n];
|
||||||
|
frame[n].addr = pc;
|
||||||
|
|
||||||
#ifdef INTERPRETER
|
#ifdef INTERPRETER
|
||||||
if (p[n] >= &_Jv_StartOfInterpreter && p[n] <= &_Jv_EndOfInterpreter)
|
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))
|
||||||
{
|
{
|
||||||
frame[n].interp = (void *) interp_frame->self;
|
// _Jv_StartOfInterpreter marks the very first
|
||||||
interp_frame = interp_frame->next;
|
// 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 ((_Jv_EndOfInterpreter == NULL || pc < _Jv_EndOfInterpreter)
|
||||||
|
&& (_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.
|
||||||
|
if (_Jv_EndOfInterpreter == NULL || pc < _Jv_EndOfInterpreter)
|
||||||
|
_Jv_EndOfInterpreter = pc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
frame[n].interp = 0;
|
|
||||||
#endif // INTERPRETER
|
#endif // INTERPRETER
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -774,18 +774,25 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
|
|||||||
}
|
}
|
||||||
#endif /* DIRECT_THREADED */
|
#endif /* DIRECT_THREADED */
|
||||||
|
|
||||||
// This function exists so that the stack-tracing code can find the
|
// These exist so that the stack-tracing code can find the boundaries
|
||||||
// boundaries of the interpreter.
|
// of the interpreter.
|
||||||
void
|
void *_Jv_StartOfInterpreter;
|
||||||
_Jv_StartOfInterpreter (void)
|
void *_Jv_EndOfInterpreter;
|
||||||
{
|
extern "C" void *_Unwind_FindEnclosingFunction (void *pc);
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_Jv_InterpMethod::run (void *retp, ffi_raw *args)
|
_Jv_InterpMethod::run (void *retp, ffi_raw *args)
|
||||||
{
|
{
|
||||||
using namespace java::lang::reflect;
|
using namespace java::lang::reflect;
|
||||||
|
|
||||||
|
// Record the address of the start of this member function in
|
||||||
|
// _Jv_StartOfInterpreter. Such a write to a global variable
|
||||||
|
// without acquiring a lock is correct iff reads and writes of words
|
||||||
|
// in memory are atomic, but Java requires that anyway.
|
||||||
|
foo:
|
||||||
|
if (_Jv_StartOfInterpreter == NULL)
|
||||||
|
_Jv_StartOfInterpreter = _Unwind_FindEnclosingFunction (&&foo);
|
||||||
|
|
||||||
// FRAME_DESC registers this particular invocation as the top-most
|
// FRAME_DESC registers this particular invocation as the top-most
|
||||||
// interpreter frame. This lets the stack tracing code (for
|
// interpreter frame. This lets the stack tracing code (for
|
||||||
// Throwable) print information about the method being interpreted
|
// Throwable) print information about the method being interpreted
|
||||||
@ -3219,13 +3226,6 @@ _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
|
static void
|
||||||
throw_internal_error (char *msg)
|
throw_internal_error (char *msg)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user