diff options
author | Andrew Haley <aph@redhat.com> | 2004-10-14 15:21:13 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2004-10-14 15:21:13 +0000 |
commit | 180a373d0d5d4534d7393b1ad5537d9f9ab7e79e (patch) | |
tree | f9e1b10a90a60b5918f10b2519f9520b57f64915 /libjava | |
parent | b79187bb541c3d842f2a3aee554b4b3f2e63f804 (diff) | |
download | gcc-180a373d0d5d4534d7393b1ad5537d9f9ab7e79e.zip gcc-180a373d0d5d4534d7393b1ad5537d9f9ab7e79e.tar.gz gcc-180a373d0d5d4534d7393b1ad5537d9f9ab7e79e.tar.bz2 |
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
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 10 | ||||
-rw-r--r-- | libjava/gnu/gcj/runtime/natStackTrace.cc | 48 | ||||
-rw-r--r-- | libjava/interpret.cc | 26 |
3 files changed, 62 insertions, 22 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 75d69ee..980490d 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -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> PR libgcj/17903: diff --git a/libjava/gnu/gcj/runtime/natStackTrace.cc b/libjava/gnu/gcj/runtime/natStackTrace.cc index 5e5aed8..fbe403a 100644 --- a/libjava/gnu/gcj/runtime/natStackTrace.cc +++ b/libjava/gnu/gcj/runtime/natStackTrace.cc @@ -45,6 +45,11 @@ details. */ #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) @@ -58,9 +63,9 @@ gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset) if (len > 0) { #ifdef INTERPRETER - extern void _Jv_StartOfInterpreter (void); - extern void _Jv_EndOfInterpreter (void); - + 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) @@ -70,16 +75,41 @@ gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset) frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info)); for (int n = 0; n < len; n++) { - frame[n].addr = p[n]; + void *pc = p[n]; + frame[n].addr = pc; + #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; - interp_frame = interp_frame->next; + // _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 ((_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 + } } else diff --git a/libjava/interpret.cc b/libjava/interpret.cc index 109ee10..0446c72 100644 --- a/libjava/interpret.cc +++ b/libjava/interpret.cc @@ -774,18 +774,25 @@ _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) -{ -} +// These exist so that the stack-tracing code can find the boundaries +// of the interpreter. +void *_Jv_StartOfInterpreter; +void *_Jv_EndOfInterpreter; +extern "C" void *_Unwind_FindEnclosingFunction (void *pc); void _Jv_InterpMethod::run (void *retp, ffi_raw *args) { 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 // interpreter frame. This lets the stack tracing code (for // 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 throw_internal_error (char *msg) { |