OSDN Git Service

2004-10-13 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Oct 2004 15:21:13 +0000 (15:21 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Oct 2004 15:21:13 +0000 (15:21 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89037 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/gnu/gcj/runtime/natStackTrace.cc
libjava/interpret.cc

index 75d69ee..980490d 100644 (file)
@@ -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:
index 5e5aed8..fbe403a 100644 (file)
@@ -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
index 109ee10..0446c72 100644 (file)
@@ -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)
 {