2007-02-16 Kyle Galloway <kgallowa@redhat.com>
authorkgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Feb 2007 18:32:07 +0000 (18:32 +0000)
committerkgallowa <kgallowa@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 16 Feb 2007 18:32:07 +0000 (18:32 +0000)
* interpret.cc: Add extra DEBUG_LOCALS_INSN calls for multi-slot
variables to maintain type info.
* interpret-run.cc: Add local variable info to frame in the debug
interpreter.
* jvmti.cc (getLocalFrame): New method.
(_Jv_JVMTI_GetLocalObject): New method.
(_Jv_JVMTI_GetLocallInt): New method.
(_Jv_JVMTI_GetLocalFloat): New method.
(_Jv_JVMTI_GetLocalLong): New method.
(_Jv_JVMTI_GetLocalDouble): New method.
(_Jv_JVMTI_SetLocalObject): New method.
(_Jv_JVMTI_SetLocalInt): New method.
(_Jv_JVMTI_SetLocalFloat): New method.
(_Jv_JVMTI_SetLocalLong): New method.
(_Jv_JVMTI_SetLocalDouble): New method.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122048 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/interpret-run.cc
libjava/interpret.cc
libjava/jvmti.cc

index e351f65..f6c0ed0 100644 (file)
@@ -1,3 +1,21 @@
+2007-02-16  Kyle Galloway  <kgallowa@redhat.com>
+
+       * interpret.cc: Add extra DEBUG_LOCALS_INSN calls for multi-slot
+       variables to maintain type info.
+       * interpret-run.cc: Add local variable info to frame in the debug
+       interpreter.
+       * jvmti.cc (getLocalFrame): New method.
+       (_Jv_JVMTI_GetLocalObject): New method.
+       (_Jv_JVMTI_GetLocallInt): New method.
+       (_Jv_JVMTI_GetLocalFloat): New method.
+       (_Jv_JVMTI_GetLocalLong): New method.
+       (_Jv_JVMTI_GetLocalDouble): New method.
+       (_Jv_JVMTI_SetLocalObject): New method.
+       (_Jv_JVMTI_SetLocalInt): New method.
+       (_Jv_JVMTI_SetLocalFloat): New method.
+       (_Jv_JVMTI_SetLocalLong): New method.
+       (_Jv_JVMTI_SetLocalDouble): New method.
+
 2007-02-16  Gary Benson  <gbenson@redhat.com>
 
        * gnu/gcj/tools/gcj_dbtool/Main.java
 2007-02-15  Kyle Galloway  <kgallowa@redhat.com>
        
        * interpret.cc (_Jv_InterpMethod::check_handler): New method.
-    * interpret-run.cc: Change the catch section to report exception
-    events and to use the new check_handler method.
-    * include/java-interp.h (_Jv_InterpMethod): Add check_handler.
-    * gnu/gcj/jvmti/ExceptionEvent.java: New file.
-    * gnu/gcj/jvmti/ExceptionEvent.h: New file.
-    * gnu/gcj/jvmti/natExceptionEvent.cc: New file.
-    * libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: New
-    file.
-    * sources.am: Added ExceptionEvent.java.
-    * Makefile.am: Added natExceptionEvent.cc
-    * Makefile.in: Regenerated.
-    * include/Makefile.in: Regenerated.
-    * gcj/Makefile.in: Regenerated.
+       * interpret-run.cc: Change the catch section to report exception
+       events and to use the new check_handler method.
+       * include/java-interp.h (_Jv_InterpMethod): Add check_handler.
+       * gnu/gcj/jvmti/ExceptionEvent.java: New file.
+       * gnu/gcj/jvmti/ExceptionEvent.h: New file.
+       * gnu/gcj/jvmti/natExceptionEvent.cc: New file.
+       * libjava/classpath/lib/gnu/gcj/jvmti/ExceptionEvent.class: New
+       file.
+       * sources.am: Added ExceptionEvent.java.
+       * Makefile.am: Added natExceptionEvent.cc
+       * Makefile.in: Regenerated.
+       * include/Makefile.in: Regenerated.
+       * gcj/Makefile.in: Regenerated.
 
 2007-02-15  Johannes Schmidt  <jschmidt@avtrex.com>
        David Daney  <ddaney@avtrex.com>
index b98092e..9d37c19 100644 (file)
@@ -27,6 +27,13 @@ details.  */
 
   _Jv_word locals[meth->max_locals];
 
+#ifdef DEBUG  
+  frame_desc.locals = locals;
+  char locals_type[meth->max_locals];
+  memset (locals_type, 'x', meth->max_locals);
+  frame_desc.locals_type = locals_type;
+#endif
+
 #define INSN_LABEL(op) &&insn_##op
 
   static const void *const insn_target[] = 
index dbd5323..7927625 100644 (file)
@@ -172,47 +172,51 @@ convert (FROM val, TO min, TO max)
 # define LOADD(I)  LOADL(I)
 #endif
 
-#define STOREA(I)                              \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'o');                        \
-    locals[I].o = (--sp)->o;                   \
+#define STOREA(I)               \
+  do {                          \
+    DEBUG_LOCALS_INSN (I, 'o'); \
+    locals[I].o = (--sp)->o;    \
   } while (0)
-#define STOREI(I)                              \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'i');                        \
-    locals[I].i = (--sp)->i;                   \
+#define STOREI(I)               \
+  do {                          \
+    DEBUG_LOCALS_INSN (I, 'i'); \
+    locals[I].i = (--sp)->i;    \
   } while (0)
-#define STOREF(I)                              \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'f');                        \
-    locals[I].f = (--sp)->f;                   \
+#define STOREF(I)               \
+  do {                          \
+    DEBUG_LOCALS_INSN (I, 'f'); \
+    locals[I].f = (--sp)->f;    \
   } while (0)
 #if SIZEOF_VOID_P == 8
-# define STOREL(I)                             \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'l');                        \
-    (sp -= 2, locals[I].l = sp->l);            \
+# define STOREL(I)                   \
+  do {                               \
+    DEBUG_LOCALS_INSN (I, 'l');      \
+    DEBUG_LOCALS_INSN (I + 1, 'x');  \
+    (sp -= 2, locals[I].l = sp->l);  \
   } while (0)
-# define STORED(I)                             \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'd');                        \
-    (sp -= 2, locals[I].d = sp->d);            \
+# define STORED(I)                   \
+  do {                               \
+    DEBUG_LOCALS_INSN (I, 'd');      \
+    DEBUG_LOCALS_INSN (I + 1, 'x');  \
+    (sp -= 2, locals[I].d = sp->d);  \
   } while (0)
 
 #else
-# define STOREL(I)                             \
-  do {                                         \
-    DEBUG_LOCALS_INSN (I, 'l');                        \
-    jint __idx = (I);                          \
-    locals[__idx+1].ia[0] = (--sp)->ia[0];     \
-    locals[__idx].ia[0] = (--sp)->ia[0];       \
+# define STOREL(I)                   \
+  do {                               \
+    DEBUG_LOCALS_INSN (I, 'l');      \
+    DEBUG_LOCALS_INSN (I + 1, 'x');  \
+    jint __idx = (I);                \
+    locals[__idx+1].ia[0] = (--sp)->ia[0];  \
+    locals[__idx].ia[0] = (--sp)->ia[0];    \
   } while (0)
-# define STORED(I)                             \
-  do {                                         \
-    DEBUG_LOCALS_INSN(I, 'd');                 \
-    jint __idx = (I);                          \
-    locals[__idx+1].ia[0] = (--sp)->ia[0];     \
-    locals[__idx].ia[0] = (--sp)->ia[0];       \
+# define STORED(I)                   \
+  do {                               \
+    DEBUG_LOCALS_INSN (I, 'd');      \
+    DEBUG_LOCALS_INSN (I + 1, 'x');  \
+    jint __idx = (I);                \
+    locals[__idx+1].ia[0] = (--sp)->ia[0];  \
+    locals[__idx].ia[0] = (--sp)->ia[0];    \
   } while (0)
 #endif
 
@@ -929,7 +933,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
 {
 #undef DEBUG
 #undef DEBUG_LOCALS_INSN
-#define DEBUG_LOCALS_INSN(s, t) do {} while(0)
+#define DEBUG_LOCALS_INSN(s, t) do {} while (0)
 
 #include "interpret-run.cc"
 }
@@ -939,7 +943,12 @@ _Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
 {
 #define DEBUG
 #undef DEBUG_LOCALS_INSN
-#define DEBUG_LOCALS_INSN(s, t) do {} while(0)
+#define DEBUG_LOCALS_INSN(s, t)  \
+  do    \
+    {   \
+      frame_desc.locals_type[s] = t;  \
+    }   \
+  while (0)
 
 #include "interpret-run.cc"
 }
index ae906a0..51f9d1d 100644 (file)
@@ -211,6 +211,253 @@ _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
   return JVMTI_ERROR_NONE;
 }
 
+// This method performs the common tasks to get and set variables of all types.
+// It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods.
+static jvmtiError
+getLocalFrame (jvmtiEnv *env, jthread thread, jint depth, jint slot, char type,
+               _Jv_InterpFrame **iframe)
+{
+  using namespace java::lang;
+   
+  REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
+   
+  ILLEGAL_ARGUMENT (depth < 0);
+  
+  THREAD_DEFAULT_TO_CURRENT (thread);
+  THREAD_CHECK_VALID (thread);
+  THREAD_CHECK_IS_ALIVE (thread);
+  
+  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
+  
+  for (int i = 0; i < depth; i++)
+    {    
+      frame = frame->next;
+    
+      if (frame == NULL)
+        return JVMTI_ERROR_NO_MORE_FRAMES; 
+    }
+  
+  if (frame->frame_type == frame_native)
+    return JVMTI_ERROR_OPAQUE_FRAME;
+  
+  jint max_locals;
+  jvmtiError jerr = env->GetMaxLocals (reinterpret_cast<jmethodID> 
+                                         (frame->self->get_method ()),
+                                       &max_locals);
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr; 
+  
+  _Jv_InterpFrame *tmp_iframe = reinterpret_cast<_Jv_InterpFrame *> (frame);
+  
+  // The second slot taken up by a long type is marked as type 'x' meaning it
+  // is not valid for access since it holds only the 4 low bytes of the value.
+  if (tmp_iframe->locals_type[slot] == 'x')
+    return JVMTI_ERROR_INVALID_SLOT;
+  
+  if (tmp_iframe->locals_type[slot] != type)
+    return JVMTI_ERROR_TYPE_MISMATCH;
+  
+  // Check for invalid slots, if the type is a long type, we must check that
+  // the next slot is valid as well.
+  if (slot < 0 || slot >= max_locals 
+      || ((type == 'l' || type == 'd') && slot + 1 >= max_locals))
+    return JVMTI_ERROR_INVALID_SLOT;
+  
+  *iframe = tmp_iframe;
+  
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_GetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                          jobject *value)
+{
+  NULL_CHECK (value);
+
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+  *value = frame->locals[slot].o;
+  
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_SetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                          jobject value)
+{
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+  frame->locals[slot].o = value;
+
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_GetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                       jint *value)
+{
+  NULL_CHECK (value);
+  
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
+
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+
+  *value = frame->locals[slot].i;
+
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_SetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                       jint value)
+{
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+  frame->locals[slot].i = value;
+
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_GetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                        jlong *value)
+{
+  NULL_CHECK (value);
+
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+
+#if SIZEOF_VOID_P==8
+  *value = frame->locals[slot].l;
+#else
+  _Jv_word2 val;
+  val.ia[0] = frame->locals[slot].ia[0];
+  val.ia[1] = frame->locals[slot + 1].ia[0];
+  *value = val.l;
+#endif
+  
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_SetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                        jlong value)
+{
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+
+#if SIZEOF_VOID_P==8
+  frame->locals[slot].l = value;
+#else
+  _Jv_word2 val;
+       val.l = value;
+       frame->locals[slot].ia[0] = val.ia[0];
+       frame->locals[slot + 1].ia[0] = val.ia[1];
+#endif
+
+  return JVMTI_ERROR_NONE;
+}
+
+
+static jvmtiError JNICALL
+_Jv_JVMTI_GetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                         jfloat *value)
+{
+  NULL_CHECK (value);
+
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+  *value = frame->locals[slot].f;
+
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_SetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                         jfloat value)
+{
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+  frame->locals[slot].f = value;
+
+  return JVMTI_ERROR_NONE;
+}
+
+
+static jvmtiError JNICALL
+_Jv_JVMTI_GetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                          jdouble *value)
+{
+  NULL_CHECK (value);
+
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+  
+#if SIZEOF_VOID_P==8
+  *value = frame->locals[slot].d;
+#else
+  _Jv_word2 val;
+  val.ia[0] = frame->locals[slot].ia[0];
+  val.ia[1] = frame->locals[slot + 1].ia[0];
+  *value = val.d;
+#endif
+
+  return JVMTI_ERROR_NONE;
+}
+
+static jvmtiError JNICALL
+_Jv_JVMTI_SetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
+                          jdouble value)
+{
+  _Jv_InterpFrame *frame;
+  jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
+  
+  if (jerr != JVMTI_ERROR_NONE)
+    return jerr;
+    
+#if SIZEOF_VOID_P==8
+  frame->locals[slot].d = value;
+#else
+  _Jv_word2 val;
+  val.d = value;
+  frame->locals[slot].ia[0] = val.ia[0];
+  frame->locals[slot + 1].ia[0] = val.ia[1]; 
+#endif
+
+  return JVMTI_ERROR_NONE;
+}
+
 static jvmtiError JNICALL
 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
                         jthread **threads)
@@ -1716,16 +1963,16 @@ struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
   RESERVED,                    // reserved18
   UNIMPLEMENTED,               // GetFrameLocation
   UNIMPLEMENTED,               // NotifyPopFrame
-  UNIMPLEMENTED,               // GetLocalObject
-  UNIMPLEMENTED,               // GetLocalInt
-  UNIMPLEMENTED,               // GetLocalLong
-  UNIMPLEMENTED,               // GetLocalFloat
-  UNIMPLEMENTED,               // GetLocalDouble
-  UNIMPLEMENTED,               // SetLocalObject
-  UNIMPLEMENTED,               // SetLocalInt
-  UNIMPLEMENTED,               // SetLocalLong
-  UNIMPLEMENTED,               // SetLocalFloat
-  UNIMPLEMENTED,               // SetLocalDouble
+  _Jv_JVMTI_GetLocalObject,            // GetLocalObject
+  _Jv_JVMTI_GetLocalInt,               // GetLocalInt
+  _Jv_JVMTI_GetLocalLong,              // GetLocalLong
+  _Jv_JVMTI_GetLocalFloat,             // GetLocalFloat
+  _Jv_JVMTI_GetLocalDouble,            // GetLocalDouble
+  _Jv_JVMTI_SetLocalObject,            // SetLocalObject
+  _Jv_JVMTI_SetLocalInt,               // SetLocalInt
+  _Jv_JVMTI_SetLocalLong,              // SetLocalLong
+  _Jv_JVMTI_SetLocalFloat,             // SetLocalFloat
+  _Jv_JVMTI_SetLocalDouble,            // SetLocalDouble
   _Jv_JVMTI_CreateRawMonitor,  // CreateRawMonitor
   _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
   _Jv_JVMTI_RawMonitorEnter,   // RawMonitorEnter