aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2004-10-14 15:21:13 +0000
committerAndrew Haley <aph@gcc.gnu.org>2004-10-14 15:21:13 +0000
commit180a373d0d5d4534d7393b1ad5537d9f9ab7e79e (patch)
treef9e1b10a90a60b5918f10b2519f9520b57f64915 /libjava
parentb79187bb541c3d842f2a3aee554b4b3f2e63f804 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libjava/gnu/gcj/runtime/natStackTrace.cc48
-rw-r--r--libjava/interpret.cc26
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)
{