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