aboutsummaryrefslogtreecommitdiff
path: root/libjava/jvmti.cc
diff options
context:
space:
mode:
authorKyle Galloway <kgallowa@redhat.com>2007-01-29 22:05:56 +0000
committerKyle Galloway <kgallowa@gcc.gnu.org>2007-01-29 22:05:56 +0000
commit392731311776d30b0910e51a5bc2aef070a9fc8b (patch)
tree832133e3bfa83e14520e76d3a01b7a61b1b3b20e /libjava/jvmti.cc
parentd75bf843440e5d372411699e81d87b273d398da6 (diff)
downloadgcc-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.cc108
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