diff options
author | Kyle Galloway <kgallowa@redhat.com> | 2007-01-29 22:05:56 +0000 |
---|---|---|
committer | Kyle Galloway <kgallowa@gcc.gnu.org> | 2007-01-29 22:05:56 +0000 |
commit | 392731311776d30b0910e51a5bc2aef070a9fc8b (patch) | |
tree | 832133e3bfa83e14520e76d3a01b7a61b1b3b20e /libjava/jvmti.cc | |
parent | d75bf843440e5d372411699e81d87b273d398da6 (diff) | |
download | gcc-392731311776d30b0910e51a5bc2aef070a9fc8b.zip gcc-392731311776d30b0910e51a5bc2aef070a9fc8b.tar.gz gcc-392731311776d30b0910e51a5bc2aef070a9fc8b.tar.bz2 |
java-interp.h: Added _Jv_Frame class and its two subclasses _Jv_InterpFrame and _Jv_NativeFrame.
2007-01-29 Kyle Galloway <kgallowa@redhat.com>
* include/java-interp.h: Added _Jv_Frame class and its two
subclasses _Jv_InterpFrame and _Jv_NativeFrame. Also moved
_Jv_FrameType from java-stack.h.
* include/java-stack.h: Removed _Jv_FrameType.
* java/lang/Thread.java: Added frame member to hold new
composite frame stack.
* java/lang/Thread.h: Regenerated.
* java/lang/Thread.class: Rebuilt.
* jni.cc (_Jv_JNIMethod::call): Push a frame onto the stack when
calling a JNI method.
* jvmti.cc (_Jv_JVMTI_GetStackTrace): New Method.
(_Jv_JVMTI_GetFrameCount): New method.
* stacktrace.cc (UnwindTraceFn): Modified to use new _Jv_Frame
classes.
* testsuite/libjava.jvmti/interp/getstacktrace.jar: New test.
* testsuite/libjava.jvmti/interp/natgetstacktrace.cc: New test.
* testsuite/libjava.jvmti/interp/getstacktrace.h: New test.
* testsuite/libjava.jvmti/interp/getstacktrace.jar: New test.
* testsuite/libjava.jvmti/interp/getstacktrace.out: Output file
for test.
From-SVN: r121314
Diffstat (limited to 'libjava/jvmti.cc')
-rw-r--r-- | libjava/jvmti.cc | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/libjava/jvmti.cc b/libjava/jvmti.cc index 03eec74..c9c7e7b 100644 --- a/libjava/jvmti.cc +++ b/libjava/jvmti.cc @@ -237,6 +237,34 @@ _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt, } static jvmtiError JNICALL +_Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread, + jint* frame_count) +{ + REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); + + NULL_CHECK (frame_count); + + using namespace java::lang; + + THREAD_DEFAULT_TO_CURRENT (thread); + + Thread *thr = reinterpret_cast<Thread *> (thread); + THREAD_CHECK_VALID (thr); + THREAD_CHECK_IS_ALIVE (thr); + + _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thr->frame); + (*frame_count) = 0; + + while (frame != NULL) + { + (*frame_count)++; + frame = frame->next; + } + + return JVMTI_ERROR_NONE; +} + +static jvmtiError JNICALL _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name, jrawMonitorID *result) { @@ -748,6 +776,82 @@ _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env, } static jvmtiError JNICALL +_Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread, + jint start_depth, jint max_frames, + jvmtiFrameInfo *frames, jint *frame_count) +{ + REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); + + ILLEGAL_ARGUMENT (max_frames < 0); + + NULL_CHECK (frames); + NULL_CHECK (frame_count); + + using namespace java::lang; + + THREAD_DEFAULT_TO_CURRENT (thread); + + Thread *thr = reinterpret_cast<Thread *> (thread); + THREAD_CHECK_VALID (thr); + THREAD_CHECK_IS_ALIVE (thr); + + jvmtiError jerr = env->GetFrameCount (thread, frame_count); + if (jerr != JVMTI_ERROR_NONE) + return jerr; + + // start_depth can be either a positive number, indicating the depth of the + // stack at which to begin the trace, or a negative number indicating the + // number of frames at the bottom of the stack to exclude. These checks + // ensure that it is a valid value in either case + + ILLEGAL_ARGUMENT (start_depth >= (*frame_count)); + ILLEGAL_ARGUMENT (start_depth < (-(*frame_count))); + + _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thr->frame); + + // If start_depth is negative use this to determine at what depth to start + // the trace by adding it to the length of the call stack. This allows the + // use of the same frame "discarding" mechanism as for a positive start_depth + if (start_depth < 0) + start_depth = *frame_count + start_depth; + + // If start_depth > 0 "remove" start_depth frames from the beginning + // of the stack before beginning the trace by moving along the frame list. + while (start_depth > 0) + { + frame = frame->next; + start_depth--; + (*frame_count)--; + } + + // Now check to see if the array supplied by the agent is large enough to + // hold frame_count frames, after adjustment for start_depth. + if ((*frame_count) > max_frames) + (*frame_count) = max_frames; + + for (int i = 0; i < (*frame_count); i++) + { + frames[i].method = frame->self->get_method (); + + // Set the location in the frame, native frames have location = -1 + if (frame->frame_type == frame_interpreter) + { + _Jv_InterpMethod *imeth + = static_cast<_Jv_InterpMethod *> (frame->self); + _Jv_InterpFrame *interp_frame + = static_cast<_Jv_InterpFrame *> (frame); + frames[i].location = imeth->insn_index (interp_frame->pc); + } + else + frames[i].location = -1; + + frame = frame->next; + } + + return JVMTI_ERROR_NONE; +} + +static jvmtiError JNICALL _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env) { REQUIRE_PHASE (env, JVMTI_PHASE_LIVE); @@ -1484,7 +1588,7 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface = UNIMPLEMENTED, // GetTopThreadGroups UNIMPLEMENTED, // GetThreadGroupInfo UNIMPLEMENTED, // GetThreadGroupChildren - UNIMPLEMENTED, // GetFrameCount + _Jv_JVMTI_GetFrameCount, // GetFrameCount UNIMPLEMENTED, // GetThreadState RESERVED, // reserved18 UNIMPLEMENTED, // GetFrameLocation @@ -1572,7 +1676,7 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface = UNIMPLEMENTED, // GetThreadListStackTraces UNIMPLEMENTED, // GetThreadLocalStorage UNIMPLEMENTED, // SetThreadLocalStorage - UNIMPLEMENTED, // GetStackTrace + _Jv_JVMTI_GetStackTrace, // GetStackTrace RESERVED, // reserved105 UNIMPLEMENTED, // GetTag UNIMPLEMENTED, // SetTag |