From 92db0175aa3b31e694b53003bf2509ffaef3f8f5 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 5 Jan 2005 09:59:00 +0000 Subject: 2004-12-13 Jakub Jelinek Revert: 2004-01-21 Tom Tromey PR java/13468: * Makefile.in: Rebuilt. * Makefile.am (interpret.lo): New target. 2004-10-18 Andrew Haley PR java/18036: * gnu/gcj/runtime/natStackTrace.cc (fillInStackTrace): Reorganize and correct logic used to find interpreter. 2004-10-13 Andrew Haley * 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: https://gcc.gnu.org/svn/gcc/branches/gcc-3_4-rhl-branch@92944 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 24 ++++++++++ libjava/Makefile.am | 7 --- libjava/Makefile.in | 3 -- libjava/gnu/gcj/runtime/natStackTrace.cc | 49 +++++++++++++++---- libjava/interpret.cc | 81 ++++++++++++++++---------------- 5 files changed, 105 insertions(+), 59 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 0d609ca83bb..bf226a054c1 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,27 @@ +2004-12-13 Jakub Jelinek + + Revert: + 2004-01-21 Tom Tromey + PR java/13468: + * Makefile.in: Rebuilt. + * Makefile.am (interpret.lo): New target. + +2004-10-18 Andrew Haley + + PR java/18036: + * gnu/gcj/runtime/natStackTrace.cc (fillInStackTrace): Reorganize + and correct logic used to find interpreter. + +2004-10-13 Andrew Haley + + * 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-12-06 Tom Tromey For PR java/14853: diff --git a/libjava/Makefile.am b/libjava/Makefile.am index d8eb43b67d5..197c4419243 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -511,13 +511,6 @@ $(nat_files) $(x_nat_files): %.lo: %.cc $(c_files): %.lo: %.c $(LTCOMPILE) -c -o $@ $< -## A special rule for interpret.lo for the time being. Our current -## approach to stack-trace handling is fragile and will not work with -## unit-at-a-time. So, for now we disable it. This will be fixed by -## a larger patch in the future. -interpret.lo: interpret.cc - $(LTCXXCOMPILE) -fno-unit-at-a-time -c -o $@ $< - $(extra_cc_files): %.lo: %.cc $(LTCXXCOMPILE) -c -o $@ $< diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 1da73747cd2..0a0f5fb6998 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -5415,9 +5415,6 @@ $(nat_files) $(x_nat_files): %.lo: %.cc $(c_files): %.lo: %.c $(LTCOMPILE) -c -o $@ $< -interpret.lo: interpret.cc - $(LTCXXCOMPILE) -fno-unit-at-a-time -c -o $@ $< - $(extra_cc_files): %.lo: %.cc $(LTCXXCOMPILE) -c -o $@ $< diff --git a/libjava/gnu/gcj/runtime/natStackTrace.cc b/libjava/gnu/gcj/runtime/natStackTrace.cc index 5e5aed87e5c..d9f3355c046 100644 --- a/libjava/gnu/gcj/runtime/natStackTrace.cc +++ b/libjava/gnu/gcj/runtime/natStackTrace.cc @@ -45,6 +45,11 @@ details. */ #include +#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,8 +63,8 @@ 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 @@ -70,16 +75,44 @@ 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 (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; + } + } } - else - frame[n].interp = 0; #endif // INTERPRETER + } } else diff --git a/libjava/interpret.cc b/libjava/interpret.cc index c5d2afdb905..332833b4454 100644 --- a/libjava/interpret.cc +++ b/libjava/interpret.cc @@ -774,46 +774,17 @@ _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; - // 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 - // rather than about the interpreter itself. FRAME_DESC has a - // destructor so it cleans up automatically when the interpreter - // returns. - java::lang::Thread *thread = java::lang::Thread::currentThread(); - _Jv_MethodChain frame_desc (this, - (_Jv_MethodChain **) &thread->interp_frame); - - _Jv_word stack[max_stack]; - _Jv_word *sp = stack; - - _Jv_word locals[max_locals]; - - /* Go straight at it! the ffi raw format matches the internal - stack representation exactly. At least, that's the idea. - */ - memcpy ((void*) locals, (void*) args, args_raw_size); - - _Jv_word *pool_data = defining_class->constants.data; - - /* These three are temporaries for common code used by several - instructions. */ - void (*fun)(); - _Jv_ResolvedMethod* rmeth; - int tmpval; - #define INSN_LABEL(op) &&insn_##op static const void *const insn_target[] = @@ -1027,6 +998,41 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args) 0 }; + // 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. + if (_Jv_StartOfInterpreter == NULL) + _Jv_StartOfInterpreter = _Unwind_FindEnclosingFunction ((void *) insn_target[0]); + + // 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 + // rather than about the interpreter itself. FRAME_DESC has a + // destructor so it cleans up automatically when the interpreter + // returns. + java::lang::Thread *thread = java::lang::Thread::currentThread(); + _Jv_MethodChain frame_desc (this, + (_Jv_MethodChain **) &thread->interp_frame); + + _Jv_word stack[max_stack]; + _Jv_word *sp = stack; + + _Jv_word locals[max_locals]; + + /* Go straight at it! the ffi raw format matches the internal + stack representation exactly. At least, that's the idea. + */ + memcpy ((void*) locals, (void*) args, args_raw_size); + + _Jv_word *pool_data = defining_class->constants.data; + + /* These three are temporaries for common code used by several + instructions. */ + void (*fun)(); + _Jv_ResolvedMethod* rmeth; + int tmpval; + pc_t pc; #ifdef DIRECT_THREADED @@ -3227,13 +3233,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) { -- cgit v1.2.3