From 392731311776d30b0910e51a5bc2aef070a9fc8b Mon Sep 17 00:00:00 2001 From: Kyle Galloway <kgallowa@redhat.com> Date: Mon, 29 Jan 2007 22:05:56 +0000 Subject: [PATCH] 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 --- libjava/ChangeLog | 23 +++ .../lib/java/lang/Thread$State.class | Bin 1242 -> 1242 bytes libjava/classpath/lib/java/lang/Thread.class | Bin 9327 -> 9343 bytes libjava/include/java-interp.h | 79 ++++++++-- libjava/include/java-stack.h | 7 - libjava/java/lang/Thread.h | 3 +- libjava/java/lang/Thread.java | 3 + libjava/jni.cc | 4 + libjava/jvmti.cc | 108 ++++++++++++- libjava/stacktrace.cc | 8 +- .../libjava.jvmti/interp/getstacktrace.h | 21 +++ .../libjava.jvmti/interp/getstacktrace.jar | Bin 0 -> 1237 bytes .../libjava.jvmti/interp/getstacktrace.java | 88 +++++++++++ .../libjava.jvmti/interp/getstacktrace.out | 76 +++++++++ .../libjava.jvmti/interp/natgetstacktrace.cc | 144 ++++++++++++++++++ 15 files changed, 537 insertions(+), 27 deletions(-) create mode 100644 libjava/testsuite/libjava.jvmti/interp/getstacktrace.h create mode 100644 libjava/testsuite/libjava.jvmti/interp/getstacktrace.jar create mode 100644 libjava/testsuite/libjava.jvmti/interp/getstacktrace.java create mode 100644 libjava/testsuite/libjava.jvmti/interp/getstacktrace.out create mode 100644 libjava/testsuite/libjava.jvmti/interp/natgetstacktrace.cc diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 20e91fdb1fd4..037b1bb650d8 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,26 @@ +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. + 2007-01-29 Tom Tromey <tromey@redhat.com> * interpret.cc (run_debug): Remove comment. diff --git a/libjava/classpath/lib/java/lang/Thread$State.class b/libjava/classpath/lib/java/lang/Thread$State.class index a7d5a333f22395a74b272ab11d3ed6608424990a..3ce018edd9c8b3d245b8578bcaff6d63be38e2de 100644 GIT binary patch delta 23 fcmcb`d5d$y2WHl#41O$&Cx2x&VO%^}i)8}<aO4Qx delta 23 fcmcb`d5d$y2WHkq41O#NCVyo%VO%g-i)8}<aEA!g diff --git a/libjava/classpath/lib/java/lang/Thread.class b/libjava/classpath/lib/java/lang/Thread.class index 7c33d004474f8821f4cd228f7c8fdf6aced0ca38..8329bc1552397dbf899da826e2a5e7aacc7593b0 100644 GIT binary patch literal 9343 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 T)^VJps5e!_CC_JZZR7s}j^@nz literal 9327 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 THRl<!I#^aNZ{wK1rtW_M`HRcs diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index 3b15b5cb2229..3a43977747fe 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -205,11 +205,11 @@ class _Jv_InterpMethod : public _Jv_MethodBase // number info is unavailable. int get_source_line(pc_t mpc); + public: + // Convenience function for indexing bytecode PC/insn slots in // line tables for JDWP jlong insn_index (pc_t pc); - - public: /* Get the line table for this method. * start is the lowest index in the method @@ -315,35 +315,86 @@ public: } }; -// The interpreted call stack, represented by a linked list of frames. -struct _Jv_InterpFrame +enum _Jv_FrameType { + frame_native, + frame_interpreter, + frame_proxy +}; + +// The composite call stack as represented by a linked list of frames +class _Jv_Frame +{ +public: + java::lang::Thread *thread; + union { + _Jv_MethodBase *self; void *meth; - _Jv_InterpMethod *self; _Jv_Method *proxyMethod; }; - java::lang::Thread *thread; - _Jv_InterpFrame *next; + + //The full list of frames, JNI and interpreted + _Jv_Frame *next; + _Jv_FrameType frame_type; + + _Jv_Frame (_Jv_MethodBase *s, java::lang::Thread *thr, _Jv_FrameType type) + { + self = s; + frame_type = type; + next = (_Jv_Frame *) thr->frame; + thr->frame = (gnu::gcj::RawData *) this; + thread = thr; + } + + ~_Jv_Frame () + { + thread->frame = (gnu::gcj::RawData *) next; + } +}; + +// An interpreted frame in the call stack +class _Jv_InterpFrame : public _Jv_Frame +{ +public: + + // Keep the purely interpreted list around so as not to break backtraces + _Jv_InterpFrame *next_interp; + union { pc_t pc; jclass proxyClass; }; - - _Jv_InterpFrame (void *meth, java::lang::Thread *thr, jclass proxyClass = NULL) + + //Debug info for local variables. + _Jv_word *locals; + char *locals_type; + + _Jv_InterpFrame (void *meth, java::lang::Thread *thr, jclass proxyCls = NULL) + : _Jv_Frame (reinterpret_cast<_Jv_MethodBase *> (meth), thr, + frame_interpreter) { - this->meth = meth; - thread = thr; - next = (_Jv_InterpFrame *) thr->interp_frame; + next_interp = (_Jv_InterpFrame *) thr->interp_frame; + proxyClass = proxyCls; thr->interp_frame = (gnu::gcj::RawData *) this; - this->proxyClass = proxyClass; } ~_Jv_InterpFrame () { - thread->interp_frame = (gnu::gcj::RawData *) next; + thread->interp_frame = (gnu::gcj::RawData *) next_interp; + } +}; + +// A native frame in the call stack really just a placeholder +class _Jv_NativeFrame : public _Jv_Frame +{ +public: + + _Jv_NativeFrame (_Jv_JNIMethod *s, java::lang::Thread *thr) + : _Jv_Frame (s, thr, frame_native) + { } }; diff --git a/libjava/include/java-stack.h b/libjava/include/java-stack.h index d4d63d743420..49e68412be63 100644 --- a/libjava/include/java-stack.h +++ b/libjava/include/java-stack.h @@ -41,13 +41,6 @@ extern "Java" } } -enum _Jv_FrameType -{ - frame_native, - frame_interpreter, - frame_proxy -}; - #ifdef INTERPRETER struct _Jv_InterpFrameInfo { diff --git a/libjava/java/lang/Thread.h b/libjava/java/lang/Thread.h index 74e149030f76..d5fce8638771 100644 --- a/libjava/java/lang/Thread.h +++ b/libjava/java/lang/Thread.h @@ -144,7 +144,8 @@ public: // actually package-private static const jbyte THREAD_PARK_DEAD = 3; ::java::lang::Object * accessControlState; ::gnu::gcj::RawData * interp_frame; - jint volatile state; + ::gnu::gcj::RawData * frame; + volatile jint state; ::gnu::gcj::RawDataManaged * data; public: static ::java::lang::Class class$; diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java index 9666482040af..7216512530df 100644 --- a/libjava/java/lang/Thread.java +++ b/libjava/java/lang/Thread.java @@ -182,6 +182,9 @@ public class Thread implements Runnable // This describes the top-most interpreter frame for this thread. RawData interp_frame; + + // This describes the top most frame in the composite (interp + JNI) stack + RawData frame; // Current state. volatile int state; diff --git a/libjava/jni.cc b/libjava/jni.cc index 59c1e5fd03e8..07ef71345409 100644 --- a/libjava/jni.cc +++ b/libjava/jni.cc @@ -2339,6 +2339,10 @@ _Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this) // Copy over passed-in arguments. memcpy (&real_args[offset], args, _this->args_raw_size); + + // Add a frame to the composite (interpreted + JNI) call stack + java::lang::Thread *thread = java::lang::Thread::currentThread(); + _Jv_NativeFrame nat_frame (_this, thread); // The actual call to the JNI function. #if FFI_NATIVE_RAW_API diff --git a/libjava/jvmti.cc b/libjava/jvmti.cc index 03eec74b4c1a..c9c7e7ba731a 100644 --- a/libjava/jvmti.cc +++ b/libjava/jvmti.cc @@ -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 diff --git a/libjava/stacktrace.cc b/libjava/stacktrace.cc index 5751e29b5f1e..c3fbdf4e6a43 100644 --- a/libjava/stacktrace.cc +++ b/libjava/stacktrace.cc @@ -131,9 +131,11 @@ _Jv_StackTrace::UnwindTraceFn (struct _Unwind_Context *context, void *state_ptr) if (func_addr == UNWRAP_FUNCTION_DESCRIPTOR (interp_run)) { state->frames[pos].type = frame_interpreter; - state->frames[pos].interp.meth = state->interp_frame->self; + _Jv_Frame *frame = static_cast<_Jv_Frame *> (state->interp_frame); + state->frames[pos].interp.meth + = static_cast<_Jv_InterpMethod *> (frame->self); state->frames[pos].interp.pc = state->interp_frame->pc; - state->interp_frame = state->interp_frame->next; + state->interp_frame = state->interp_frame->next_interp; } else #endif @@ -143,7 +145,7 @@ _Jv_StackTrace::UnwindTraceFn (struct _Unwind_Context *context, void *state_ptr) state->frames[pos].type = frame_proxy; state->frames[pos].proxyClass = state->interp_frame->proxyClass; state->frames[pos].proxyMethod = state->interp_frame->proxyMethod; - state->interp_frame = state->interp_frame->next; + state->interp_frame = state->interp_frame->next_interp; } else { diff --git a/libjava/testsuite/libjava.jvmti/interp/getstacktrace.h b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.h new file mode 100644 index 000000000000..6e5e8774e253 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ + +#ifndef __getstacktrace__ +#define __getstacktrace__ + +#include <jni.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + +JNIEXPORT void JNICALL Java_getstacktrace_natPlaceholder (JNIEnv *env, jobject); +JNIEXPORT void JNICALL Java_getstacktrace_natRunner (JNIEnv *env, jobject); +JNIEXPORT jint JNICALL Java_getstacktrace_do_1getstacktrace_1tests (JNIEnv *env, jclass, jobjectArray); + +#ifdef __cplusplus +} +#endif + +#endif /* __getstacktrace__ */ diff --git a/libjava/testsuite/libjava.jvmti/interp/getstacktrace.jar b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.jar new file mode 100644 index 0000000000000000000000000000000000000000..14b084a4de11b88f063a3ecea605f2d7e8705be4 GIT binary patch literal 1237 zcmWIWW@h1H0D%K(wq{@kl;8x?zOEsTx}JV+`T;1)cIf6N>HwudSOi&_ucM!*n`>~0 zp0As4VqRuiYH^8fSZYymW`3TPf}x%Pmvd2SVo7R>u2ZFzf`Oi;k#2f&G8Y%jbPk4X zKu2_~{;1;5%)pSv%D^BDG(A1Fq_`w8IlH7NF*#K)IVZ8WxHUL7TsU0h?sOg%Nj-U9 zrnN4-KUjrX_utBDTC~+GxY^tHNUPlghjkXSd?F4X(YyCo`0Gk}ew%RC$X&1aU&OyS z|H3&u-s}6!D+v*?tBteo7C)a;eEwegeCz#x|9-P=xU6yH;=&7?lMZdY5L+k3_HI+> z;h-1wkL-$<uUfa?D6~#SV*8?m&{z8c1HOyq><^5t5!qq7+0DJN&%i5cN&Ld-MZWBZ zJ6}Fs^}PC_YU_<3M{HiltPS@O;;NN06XL9KvbfKC+vA4BfdrY~w`NSacHJrXvcw^S zz*VK&gT72-GLHzCkkPN3BF;8%|0MAZ`xZT)J-heTB+gUsf~Nl2y-eB6EJ@<x51yzM zG8bOBh)c5Z#_uzh@>EGNUnb~&=-IoDV}Tj1Dm(9G{@BNPq&g-!X3yR)_f}2%`M7H9 zB_2zuNY2vr+kX3J`E>2q&Iq+!YRR+9>bh<4(reCBe<jV9>s}biz4F<GAI*>MU3{W$ z!MOTa)xUcc-W@7W{{%g@(c5smN_k1bS(Ej4rQMc_#=X&})hDDczJKogRPLFP&iWru zH_g}lv5+&2S$LM$G9NuNy(Be0ztRWxT$wS`B#(w44gI?Gs9@x}tQy&`C(ktn*jzU~ z_dq8<VC6lIX=h9Q)23v-t_@-^IQ2wAf3553$in3*MiYJA%rviSZsII)zI^|%etVeQ z?W)#$A^**S_PeCpJ-sCz`X=qH-H8oT@3ddr+4o|}+dT*C)VFnhxmPSQH~;gUgV%OO z9TC{^V2{iDrmquL%(i%9vA!@vc(KXiYv*-#wH}t15X*o5s{6(78*GnEgm)Vx2U`D* zD4X!!fN#P*!FB4K<$RKT#XU1`ihU_xqI$vjT+@M&vX5@F9Io-pPvE~a=SMu#@f&m3 znDr^QaxPhUDsj$(Dz5a(<l-3phsA0B+dQ89znXhs<BFSXyS5p+PWjS3cYhf-e__j% zj_f|$XO>MejLW7@n&0W^RcCr@NlahHlIKbij6XV=y8nFE|LCf<z4c|?@9-5#ZyvGr zrCol%K<wTFFU{F@n_Jh<`fz9Rf$!G!cJBjTzWFU*UUxq4@hw}+i-%{N`R4qjKeo@Z zPjZJ_-R3)@KiKas_~y!G;O?0h)MvR#d&1w`d*6hN-y20es_GX_tK7zX{||G3HzN}l z1MXq~m<f>pQlWsV4ZT=E=urnU;o6W2353Pivp&LvRv;5gK@i~0$_7%z41~LYG%E{; F2LNfB@h|`Y literal 0 HcmV?d00001 diff --git a/libjava/testsuite/libjava.jvmti/interp/getstacktrace.java b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.java new file mode 100644 index 000000000000..21a21f0fbb10 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.java @@ -0,0 +1,88 @@ +public class getstacktrace + extends Thread +{ + public boolean done = false; + + // num_frames is the number of frames > the original run () call so if + // num_frames = 1, the thread will have 2 frames, the original Thread.run + // call, plus one additional + public int num_frames, thread_num; + + public static int num_threads = 1; + + static + { + System.loadLibrary("natgetstacktrace"); + } + + public void run () + { + thread_num = num_threads++; + num_frames = thread_num; + + if (num_frames <= 1) + { + natRunner (); + } + else + { + if (thread_num % 2 == 0) + natPlaceholder (); + else + placeholder (); + } + } + + public void placeholder () + { + num_frames--; + if (num_frames <= 1) + { + if (thread_num % 2 == 1) + natRunner (); + else + runner (); + } + else + { + if (thread_num % 2 == 0) + natPlaceholder (); + else + placeholder (); + } + } + + public void runner () + { + done = true; + while (done) + yield (); + } + + public native void natPlaceholder (); + public native void natRunner (); + + public static native int do_getstacktrace_tests (Thread[] threads); + + public static void main (String[] args) + { + System.out.println ("JVMTI GetStackTrace Interpreted Test"); + + getstacktrace[] threads = new getstacktrace[10]; + + for (int i = 0; i < threads.length; i++) + { + threads[i] = new getstacktrace (); + threads[i].start (); + while (!threads[i].done) + yield (); + } + + do_getstacktrace_tests (threads); + + for (int i = 0; i < threads.length; i++) + { + threads[i].done = false; + } + } +} diff --git a/libjava/testsuite/libjava.jvmti/interp/getstacktrace.out b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.out new file mode 100644 index 000000000000..5134e6eab78e --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/interp/getstacktrace.out @@ -0,0 +1,76 @@ +JVMTI GetStackTrace Interpreted Test +Thread has 2 frames +Frame 0 is native +Frame 1 is interpreted +Thread has 3 frames +Frame 0 is interpreted +Frame 1 is native +Frame 2 is interpreted +Thread has 4 frames +Frame 0 is native +Frame 1 is interpreted +Frame 2 is interpreted +Frame 3 is interpreted +Thread has 5 frames +Frame 0 is interpreted +Frame 1 is native +Frame 2 is native +Frame 3 is native +Frame 4 is interpreted +Thread has 6 frames +Frame 0 is native +Frame 1 is interpreted +Frame 2 is interpreted +Frame 3 is interpreted +Frame 4 is interpreted +Frame 5 is interpreted +Thread has 7 frames +Frame 0 is interpreted +Frame 1 is native +Frame 2 is native +Frame 3 is native +Frame 4 is native +Frame 5 is native +Frame 6 is interpreted +Thread has 8 frames +Frame 0 is native +Frame 1 is interpreted +Frame 2 is interpreted +Frame 3 is interpreted +Frame 4 is interpreted +Frame 5 is interpreted +Frame 6 is interpreted +Frame 7 is interpreted +Thread has 9 frames +Frame 0 is interpreted +Frame 1 is native +Frame 2 is native +Frame 3 is native +Frame 4 is native +Frame 5 is native +Frame 6 is native +Frame 7 is native +Frame 8 is interpreted +Thread has 10 frames +Frame 0 is native +Frame 1 is interpreted +Frame 2 is interpreted +Frame 3 is interpreted +Frame 4 is interpreted +Frame 5 is interpreted +Frame 6 is interpreted +Frame 7 is interpreted +Frame 8 is interpreted +Frame 9 is interpreted +Thread has 11 frames +Frame 0 is interpreted +Frame 1 is native +Frame 2 is native +Frame 3 is native +Frame 4 is native +Frame 5 is native +Frame 6 is native +Frame 7 is native +Frame 8 is native +Frame 9 is native +Frame 10 is interpreted diff --git a/libjava/testsuite/libjava.jvmti/interp/natgetstacktrace.cc b/libjava/testsuite/libjava.jvmti/interp/natgetstacktrace.cc new file mode 100644 index 000000000000..e2c88ada40c4 --- /dev/null +++ b/libjava/testsuite/libjava.jvmti/interp/natgetstacktrace.cc @@ -0,0 +1,144 @@ +#include <jni.h> + +#include <jvmti.h> +#include <stdio.h> +#include <stdlib.h> + +#include <unistd.h> + +#include "getstacktrace.h" + +void +printStackTrace (jvmtiFrameInfo *frames, jint frame_cnt) +{ + printf ("Thread has %d frames\n", static_cast<int> (frame_cnt)); + + for (int i = 0; i < frame_cnt; i++) + { + jmethodID method = frames[i].method; + jlocation location = frames[i].location; + + if (location == -1) + { + printf ("Frame %d is native\n", i); + } + else + { + printf ("Frame %d is interpreted\n", i); + } + } +} + + +JNIEXPORT void JNICALL Java_getstacktrace_natPlaceholder (JNIEnv *env, jobject obj) +{ + jclass klass = env->GetObjectClass (obj); + jfieldID done_id = env->GetFieldID (klass, "done", "Z"); + jfieldID num_frames_id = env->GetFieldID (klass, "num_frames", "I"); + jfieldID thread_num_id = env->GetFieldID (klass, "thread_num", "I"); + + // num_frames-- + jint n_frames = env->GetIntField (obj, num_frames_id); + n_frames--; + env->SetIntField (obj, num_frames_id, n_frames); + + jint t_num = env->GetIntField (obj, thread_num_id); + + if (n_frames <= 1) + { + if (t_num % 2 == 1) + { + jmethodID natRunner_id = env->GetMethodID (klass, "natRunner", "()V"); + env->CallVoidMethod (obj, natRunner_id); + } + else + { + jmethodID runner_id = env->GetMethodID (klass, "runner", "()V"); + env->CallVoidMethod (obj, runner_id); + } + } + else + { + if (t_num % 2 == 0) + { + jmethodID natPlaceholder_id = env->GetMethodID (klass, + "natPlaceholder", + "()V"); + env->CallVoidMethod (obj, natPlaceholder_id); + } + else + { + jmethodID placeholder_id = env->GetMethodID (klass, "placeholder", + "()V"); + env->CallVoidMethod (obj, placeholder_id); + } + } +} + +JNIEXPORT void JNICALL Java_getstacktrace_natRunner (JNIEnv *env, jobject obj) +{ + jclass klass = env->GetObjectClass (obj); + jfieldID done_id = env->GetFieldID (klass, "done", "Z"); + + + jboolean done; + done = true; + env->SetBooleanField (obj, done_id, done); + + do + { + done = env->GetBooleanField (obj, done_id); + if (done == false) + break; + usleep (10); + } + while (done != false); +} + +JNIEXPORT jint JNICALL Java_getstacktrace_do_1getstacktrace_1tests +(JNIEnv *env, jclass klass, jobjectArray thr_arr) +{ + JavaVM *vm; + jint err = env->GetJavaVM (&vm); + if (err < 0) + { + fprintf (stderr, "error getting VM\n"); + exit (1); + } + + jvmtiEnv *jvmti = NULL; + vm->GetEnv ((void **) &jvmti, JVMTI_VERSION_1_0); + + if (jvmti == NULL) + { + fprintf (stderr, "error getting jvmti environment\n"); + exit (1); + } + + jint frame_cnt; + jvmtiFrameInfo frames[30]; + + jvmtiError jerr; + jthread thr; + + jsize num_threads = env->GetArrayLength (thr_arr); + + for (int i = 0; i < num_threads; i++) + { + thr = reinterpret_cast<jthread> + (env->GetObjectArrayElement (thr_arr, static_cast<jsize> (i))); + fflush (stdout); + jerr = jvmti->GetStackTrace (thr, 0, 30, frames, &frame_cnt); + if (jerr != JVMTI_ERROR_NONE) + { + char *error_name; + jvmti->GetErrorName (jerr, &error_name); + fprintf (stderr, "JVMTI Error: %s\n", error_name); + jvmti->Deallocate (reinterpret_cast<unsigned char *> (error_name)); + } + else + { + printStackTrace (frames, frame_cnt); + } + } +} -- GitLab