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
This commit is contained in:
Kyle Galloway 2007-01-29 22:05:56 +00:00 committed by Kyle Galloway
parent d75bf84344
commit 3927313117
15 changed files with 537 additions and 27 deletions

View file

@ -236,6 +236,34 @@ _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
return JVMTI_ERROR_NONE;
}
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)
@ -747,6 +775,82 @@ _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
return JVMTI_ERROR_NONE;
}
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)
{
@ -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