1 // jvmti.cc - JVMTI implementation
3 /* Copyright (C) 2006, 2007 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
15 #include <java-threads.h>
17 #include <java-interp.h>
19 #include "jvmti-int.h"
21 #include <gcj/method.h>
23 #include <gnu/classpath/SystemProperties.h>
24 #include <gnu/gcj/runtime/BootClassLoader.h>
25 #include <gnu/gcj/jvmti/Breakpoint.h>
26 #include <gnu/gcj/jvmti/BreakpointManager.h>
28 #include <java/lang/Class.h>
29 #include <java/lang/ClassLoader.h>
30 #include <java/lang/OutOfMemoryError.h>
31 #include <java/lang/Thread.h>
32 #include <java/lang/ThreadGroup.h>
33 #include <java/lang/Throwable.h>
34 #include <java/lang/VMClassLoader.h>
35 #include <java/lang/reflect/Field.h>
36 #include <java/lang/reflect/Modifier.h>
37 #include <java/util/Collection.h>
38 #include <java/util/HashMap.h>
39 #include <java/util/concurrent/locks/Lock.h>
40 #include <java/util/concurrent/locks/ReentrantReadWriteLock.h>
41 #include <java/net/URL.h>
43 static void check_enabled_events (void);
44 static void check_enabled_event (jvmtiEvent
);
48 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
51 // Event notifications
54 bool ThreadStart
= false;
55 bool ThreadEnd
= false;
56 bool ClassFileLoadHook
= false;
57 bool ClassLoad
= false;
58 bool ClassPrepare
= false;
60 bool Exception
= false;
61 bool ExceptionCatch
= false;
62 bool SingleStep
= false;
63 bool FramePop
= false;
64 bool Breakpoint
= false;
65 bool FieldAccess
= false;
66 bool FieldModification
= false;
67 bool MethodEntry
= false;
68 bool MethodExit
= false;
69 bool NativeMethodBind
= false;
70 bool CompiledMethodLoad
= false;
71 bool CompiledMethodUnload
= false;
72 bool DynamicCodeGenerated
= false;
73 bool DataDumpRequest
= false;
74 bool reserved72
= false;
75 bool MonitorWait
= false;
76 bool MonitorWaited
= false;
77 bool MonitorContendedEnter
= false;
78 bool MonitorContendedEntered
= false;
79 bool reserved77
= false;
80 bool reserved78
= false;
81 bool reserved79
= false;
82 bool reserved80
= false;
83 bool GarbageCollectionStart
= false;
84 bool GarbageCollectionFinish
= false;
85 bool ObjectFree
= false;
86 bool VMObjectAlloc
= false;
89 extern struct JNINativeInterface _Jv_JNIFunctions
;
91 struct _Jv_rawMonitorID
94 _Jv_ConditionVariable_t condition
;
97 /* A simple linked list of all JVMTI environments. Since
98 events must be delivered to environments in the order
99 in which the environments were created, new environments
100 are added to the end of the list. */
101 struct jvmti_env_list
104 struct jvmti_env_list
*next
;
106 static struct jvmti_env_list
*_jvmtiEnvironments
= NULL
;
107 static java::util::concurrent::locks::
108 ReentrantReadWriteLock
*_envListLock
= NULL
;
109 #define FOREACH_ENVIRONMENT(Ele) \
110 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
112 // Some commonly-used checks
114 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
117 if (Ajthread == NULL) \
118 Ajthread = java::lang::Thread::currentThread (); \
122 #define THREAD_CHECK_VALID(Athread) \
125 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
126 return JVMTI_ERROR_INVALID_THREAD; \
130 #define THREAD_CHECK_IS_ALIVE(Athread) \
133 if (!Athread->isAlive ()) \
134 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
138 // FIXME: if current phase is not set in Phases,
139 // return JVMTI_ERROR_WRONG_PHASE
140 #define REQUIRE_PHASE(Env, Phases)
142 #define NULL_CHECK(Ptr) \
146 return JVMTI_ERROR_NULL_POINTER; \
150 #define ILLEGAL_ARGUMENT(Cond) \
154 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
158 #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
161 jboolean is_native; \
162 jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
163 if (jerr != JVMTI_ERROR_NONE) \
166 return JVMTI_ERROR_NATIVE_METHOD; \
170 static jvmtiError JNICALL
171 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
173 using namespace java::lang
;
175 THREAD_DEFAULT_TO_CURRENT (thread
);
176 THREAD_CHECK_VALID (thread
);
177 THREAD_CHECK_IS_ALIVE (thread
);
179 _Jv_Thread_t
*data
= _Jv_ThreadGetData (thread
);
180 _Jv_SuspendThread (data
);
181 return JVMTI_ERROR_NONE
;
184 static jvmtiError JNICALL
185 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
187 using namespace java::lang
;
189 THREAD_DEFAULT_TO_CURRENT (thread
);
190 THREAD_CHECK_VALID (thread
);
191 THREAD_CHECK_IS_ALIVE (thread
);
193 _Jv_Thread_t
*data
= _Jv_ThreadGetData (thread
);
194 _Jv_ResumeThread (data
);
195 return JVMTI_ERROR_NONE
;
198 static jvmtiError JNICALL
199 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
201 using namespace java::lang
;
203 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
204 // FIXME: capability handling? 'can_signal_thread'
206 return JVMTI_ERROR_INVALID_THREAD
;
208 THREAD_CHECK_VALID (thread
);
209 THREAD_CHECK_IS_ALIVE (thread
);
211 return JVMTI_ERROR_NONE
;
214 // This method performs the common tasks to get and set variables of all types.
215 // It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods.
217 getLocalFrame (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
, char type
,
218 _Jv_InterpFrame
**iframe
)
220 using namespace java::lang
;
222 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
224 ILLEGAL_ARGUMENT (depth
< 0);
226 THREAD_DEFAULT_TO_CURRENT (thread
);
227 THREAD_CHECK_VALID (thread
);
228 THREAD_CHECK_IS_ALIVE (thread
);
230 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
232 for (int i
= 0; i
< depth
; i
++)
237 return JVMTI_ERROR_NO_MORE_FRAMES
;
240 if (frame
->frame_type
== frame_native
)
241 return JVMTI_ERROR_OPAQUE_FRAME
;
244 jvmtiError jerr
= env
->GetMaxLocals (reinterpret_cast<jmethodID
>
245 (frame
->self
->get_method ()),
247 if (jerr
!= JVMTI_ERROR_NONE
)
250 _Jv_InterpFrame
*tmp_iframe
= reinterpret_cast<_Jv_InterpFrame
*> (frame
);
252 // The second slot taken up by a long type is marked as type 'x' meaning it
253 // is not valid for access since it holds only the 4 low bytes of the value.
254 if (tmp_iframe
->locals_type
[slot
] == 'x')
255 return JVMTI_ERROR_INVALID_SLOT
;
257 if (tmp_iframe
->locals_type
[slot
] != type
)
258 return JVMTI_ERROR_TYPE_MISMATCH
;
260 // Check for invalid slots, if the type is a long type, we must check that
261 // the next slot is valid as well.
262 if (slot
< 0 || slot
>= max_locals
263 || ((type
== 'l' || type
== 'd') && slot
+ 1 >= max_locals
))
264 return JVMTI_ERROR_INVALID_SLOT
;
266 *iframe
= tmp_iframe
;
268 return JVMTI_ERROR_NONE
;
271 static jvmtiError JNICALL
272 _Jv_JVMTI_GetLocalObject (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
277 _Jv_InterpFrame
*frame
;
278 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'o', &frame
);
280 if (jerr
!= JVMTI_ERROR_NONE
)
283 *value
= frame
->locals
[slot
].o
;
285 return JVMTI_ERROR_NONE
;
288 static jvmtiError JNICALL
289 _Jv_JVMTI_SetLocalObject (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
292 _Jv_InterpFrame
*frame
;
293 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'o', &frame
);
295 if (jerr
!= JVMTI_ERROR_NONE
)
298 frame
->locals
[slot
].o
= value
;
300 return JVMTI_ERROR_NONE
;
303 static jvmtiError JNICALL
304 _Jv_JVMTI_GetLocalInt (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
309 _Jv_InterpFrame
*frame
;
310 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'i', &frame
);
312 if (jerr
!= JVMTI_ERROR_NONE
)
315 *value
= frame
->locals
[slot
].i
;
317 return JVMTI_ERROR_NONE
;
320 static jvmtiError JNICALL
321 _Jv_JVMTI_SetLocalInt (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
324 _Jv_InterpFrame
*frame
;
325 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'i', &frame
);
327 if (jerr
!= JVMTI_ERROR_NONE
)
330 frame
->locals
[slot
].i
= value
;
332 return JVMTI_ERROR_NONE
;
335 static jvmtiError JNICALL
336 _Jv_JVMTI_GetLocalLong (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
341 _Jv_InterpFrame
*frame
;
342 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'l', &frame
);
344 if (jerr
!= JVMTI_ERROR_NONE
)
348 *value
= frame
->locals
[slot
].l
;
351 val
.ia
[0] = frame
->locals
[slot
].ia
[0];
352 val
.ia
[1] = frame
->locals
[slot
+ 1].ia
[0];
356 return JVMTI_ERROR_NONE
;
359 static jvmtiError JNICALL
360 _Jv_JVMTI_SetLocalLong (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
363 _Jv_InterpFrame
*frame
;
364 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'l', &frame
);
366 if (jerr
!= JVMTI_ERROR_NONE
)
370 frame
->locals
[slot
].l
= value
;
374 frame
->locals
[slot
].ia
[0] = val
.ia
[0];
375 frame
->locals
[slot
+ 1].ia
[0] = val
.ia
[1];
378 return JVMTI_ERROR_NONE
;
382 static jvmtiError JNICALL
383 _Jv_JVMTI_GetLocalFloat (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
388 _Jv_InterpFrame
*frame
;
389 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'f', &frame
);
391 if (jerr
!= JVMTI_ERROR_NONE
)
394 *value
= frame
->locals
[slot
].f
;
396 return JVMTI_ERROR_NONE
;
399 static jvmtiError JNICALL
400 _Jv_JVMTI_SetLocalFloat (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
403 _Jv_InterpFrame
*frame
;
404 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'f', &frame
);
406 if (jerr
!= JVMTI_ERROR_NONE
)
409 frame
->locals
[slot
].f
= value
;
411 return JVMTI_ERROR_NONE
;
415 static jvmtiError JNICALL
416 _Jv_JVMTI_GetLocalDouble (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
421 _Jv_InterpFrame
*frame
;
422 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'd', &frame
);
424 if (jerr
!= JVMTI_ERROR_NONE
)
428 *value
= frame
->locals
[slot
].d
;
431 val
.ia
[0] = frame
->locals
[slot
].ia
[0];
432 val
.ia
[1] = frame
->locals
[slot
+ 1].ia
[0];
436 return JVMTI_ERROR_NONE
;
439 static jvmtiError JNICALL
440 _Jv_JVMTI_SetLocalDouble (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
443 _Jv_InterpFrame
*frame
;
444 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'd', &frame
);
446 if (jerr
!= JVMTI_ERROR_NONE
)
450 frame
->locals
[slot
].d
= value
;
454 frame
->locals
[slot
].ia
[0] = val
.ia
[0];
455 frame
->locals
[slot
+ 1].ia
[0] = val
.ia
[1];
458 return JVMTI_ERROR_NONE
;
461 static jvmtiError JNICALL
462 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv
*env
, jint
*thread_cnt
,
465 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
466 NULL_CHECK (thread_cnt
);
467 NULL_CHECK (threads
);
469 using namespace java::lang
;
471 ThreadGroup
*root_grp
= ThreadGroup::root
;
472 jint estimate
= root_grp
->activeCount ();
474 JArray
<Thread
*> *thr_arr
;
476 // Allocate some extra space since threads can be created between calls
479 thr_arr
= reinterpret_cast<JArray
<Thread
*> *> (JvNewObjectArray
481 &Thread::class$
, NULL
));
483 catch (java::lang::OutOfMemoryError
*err
)
485 return JVMTI_ERROR_OUT_OF_MEMORY
;
488 *thread_cnt
= root_grp
->enumerate (thr_arr
);
490 jvmtiError jerr
= env
->Allocate ((jlong
) ((*thread_cnt
) * sizeof (jthread
)),
491 (unsigned char **) threads
);
493 if (jerr
!= JVMTI_ERROR_NONE
)
496 // Transfer the threads to the result array
497 jthread
*tmp_arr
= reinterpret_cast<jthread
*> (elements (thr_arr
));
499 memcpy ((*threads
), tmp_arr
, (*thread_cnt
));
501 return JVMTI_ERROR_NONE
;
504 static jvmtiError JNICALL
505 _Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
508 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
510 NULL_CHECK (frame_count
);
512 using namespace java::lang
;
514 THREAD_DEFAULT_TO_CURRENT (thread
);
515 THREAD_CHECK_VALID (thread
);
516 THREAD_CHECK_IS_ALIVE (thread
);
518 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
519 (*frame_count
) = frame
->depth ();
520 return JVMTI_ERROR_NONE
;
523 static jvmtiError JNICALL
524 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv
*env
, const char *name
,
525 jrawMonitorID
*result
)
527 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
530 *result
= (jrawMonitorID
) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID
));
532 return JVMTI_ERROR_OUT_OF_MEMORY
;
533 _Jv_MutexInit (&(*result
)->mutex
);
534 _Jv_CondInit (&(*result
)->condition
);
535 return JVMTI_ERROR_NONE
;
538 static jvmtiError JNICALL
539 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
541 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
542 // Note we have no better way of knowing whether this object is
543 // really a raw monitor.
545 return JVMTI_ERROR_INVALID_MONITOR
;
546 // FIXME: perform checks on monitor, release it if this thread owns
548 #ifdef _Jv_HaveMutexDestroy
549 _Jv_MutexDestroy (&monitor
->mutex
);
552 return JVMTI_ERROR_NONE
;
555 static jvmtiError JNICALL
556 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
559 return JVMTI_ERROR_INVALID_MONITOR
;
560 _Jv_MutexLock (&monitor
->mutex
);
561 return JVMTI_ERROR_NONE
;
564 static jvmtiError JNICALL
565 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
568 return JVMTI_ERROR_INVALID_MONITOR
;
569 if (_Jv_MutexUnlock (&monitor
->mutex
))
570 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
571 return JVMTI_ERROR_NONE
;
574 static jvmtiError JNICALL
575 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
,
579 return JVMTI_ERROR_INVALID_MONITOR
;
580 int r
= _Jv_CondWait (&monitor
->condition
, &monitor
->mutex
, millis
, 0);
581 if (r
== _JV_NOT_OWNER
)
582 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
583 if (r
== _JV_INTERRUPTED
)
584 return JVMTI_ERROR_INTERRUPT
;
585 return JVMTI_ERROR_NONE
;
588 static jvmtiError JNICALL
589 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
592 return JVMTI_ERROR_INVALID_MONITOR
;
593 if (_Jv_CondNotify (&monitor
->condition
, &monitor
->mutex
) == _JV_NOT_OWNER
)
594 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
595 return JVMTI_ERROR_NONE
;
598 static jvmtiError JNICALL
599 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv
*env
,
600 jrawMonitorID monitor
)
603 return JVMTI_ERROR_INVALID_MONITOR
;
604 if (_Jv_CondNotifyAll (&monitor
->condition
, &monitor
->mutex
)
606 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
607 return JVMTI_ERROR_NONE
;
610 static jvmtiError JNICALL
611 _Jv_JVMTI_SetBreakpoint (jvmtiEnv
*env
, jmethodID method
, jlocation location
)
613 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
615 using namespace gnu::gcj::jvmti
;
617 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong
> (method
),
622 jvmtiError err
= env
->GetMethodDeclaringClass (method
, &klass
);
623 if (err
!= JVMTI_ERROR_NONE
)
626 if (!_Jv_IsInterpretedClass (klass
))
627 return JVMTI_ERROR_INVALID_CLASS
;
629 _Jv_MethodBase
*base
= _Jv_FindInterpreterMethod (klass
, method
);
631 return JVMTI_ERROR_INVALID_METHODID
;
634 err
= env
->GetMethodModifiers (method
, &flags
);
635 if (err
!= JVMTI_ERROR_NONE
)
638 if (flags
& java::lang::reflect::Modifier::NATIVE
)
639 return JVMTI_ERROR_NATIVE_METHOD
;
641 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*> (base
);
642 if (imeth
->get_insn (location
) == NULL
)
643 return JVMTI_ERROR_INVALID_LOCATION
;
645 // Now the breakpoint can be safely installed
646 bp
= BreakpointManager::newBreakpoint (reinterpret_cast<jlong
> (method
),
651 // Duplicate breakpoints are not permitted by JVMTI
652 return JVMTI_ERROR_DUPLICATE
;
655 return JVMTI_ERROR_NONE
;
658 static jvmtiError JNICALL
659 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
662 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
664 using namespace gnu::gcj::jvmti
;
667 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong
> (method
),
670 return JVMTI_ERROR_NOT_FOUND
;
672 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong
> (method
), location
);
673 return JVMTI_ERROR_NONE
;
676 static jvmtiError JNICALL
677 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv
*env
, jlong size
,
678 unsigned char **result
)
680 ILLEGAL_ARGUMENT (size
< 0);
686 *result
= (unsigned char *) _Jv_MallocUnchecked (size
);
688 return JVMTI_ERROR_OUT_OF_MEMORY
;
690 return JVMTI_ERROR_NONE
;
693 static jvmtiError JNICALL
694 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv
*env
, unsigned char *mem
)
698 return JVMTI_ERROR_NONE
;
701 static jvmtiError JNICALL
702 _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
705 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
706 NULL_CHECK (status_ptr
);
708 return JVMTI_ERROR_INVALID_CLASS
;
710 if (klass
->isArray ())
711 *status_ptr
= JVMTI_CLASS_STATUS_ARRAY
;
712 else if (klass
->isPrimitive ())
713 *status_ptr
= JVMTI_CLASS_STATUS_PRIMITIVE
;
716 jbyte state
= _Jv_GetClassState (klass
);
718 if (state
>= JV_STATE_LINKED
)
719 (*status_ptr
) |= JVMTI_CLASS_STATUS_VERIFIED
;
720 if (state
>= JV_STATE_PREPARED
)
721 (*status_ptr
) |= JVMTI_CLASS_STATUS_PREPARED
;
722 if (state
== JV_STATE_ERROR
|| state
== JV_STATE_PHANTOM
)
723 (*status_ptr
) |= JVMTI_CLASS_STATUS_ERROR
;
724 else if (state
== JV_STATE_DONE
)
725 (*status_ptr
) |= JVMTI_CLASS_STATUS_INITIALIZED
;
728 return JVMTI_ERROR_NONE
;
731 static jvmtiError JNICALL
732 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
735 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
736 // Don't bother checking KLASS' type.
738 return JVMTI_ERROR_INVALID_CLASS
;
740 *mods
= klass
->getModifiers();
741 return JVMTI_ERROR_NONE
;
744 static jvmtiError JNICALL
745 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
746 jint
*count_ptr
, jmethodID
**methods_ptr
)
748 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
749 // FIXME: capability can_maintain_original_method_order
750 // Don't bother checking KLASS' type.
752 return JVMTI_ERROR_INVALID_CLASS
;
753 NULL_CHECK (count_ptr
);
754 NULL_CHECK (methods_ptr
);
755 *count_ptr
= JvNumMethods(klass
);
758 = (jmethodID
*) _Jv_MallocUnchecked (*count_ptr
* sizeof (jmethodID
));
759 if (*methods_ptr
== NULL
)
760 return JVMTI_ERROR_OUT_OF_MEMORY
;
762 jmethodID start
= JvGetFirstMethod (klass
);
763 for (jint i
= 0; i
< *count_ptr
; ++i
)
765 (*methods_ptr
)[i
] = start
+ i
;
767 return JVMTI_ERROR_NONE
;
770 static jvmtiError JNICALL
771 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
774 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
776 return JVMTI_ERROR_INVALID_CLASS
;
778 *result
= klass
->isInterface();
779 return JVMTI_ERROR_NONE
;
782 static jvmtiError JNICALL
783 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
786 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
788 return JVMTI_ERROR_INVALID_CLASS
;
790 *result
= klass
->isArray();
791 return JVMTI_ERROR_NONE
;
794 static jvmtiError JNICALL
795 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
798 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
800 return JVMTI_ERROR_INVALID_CLASS
;
802 *result
= klass
->getClassLoaderInternal();
803 return JVMTI_ERROR_NONE
;
806 static jvmtiError JNICALL
807 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv
*env
, jobject obj
,
810 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
812 return JVMTI_ERROR_INVALID_OBJECT
;
814 *result
= _Jv_HashCode (obj
);
815 return JVMTI_ERROR_NONE
;
818 static jvmtiError JNICALL
819 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
820 jfieldID field
, jint
*result
)
822 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
824 return JVMTI_ERROR_INVALID_CLASS
;
826 return JVMTI_ERROR_INVALID_FIELDID
;
828 *result
= field
->getModifiers();
829 return JVMTI_ERROR_NONE
;
832 static jvmtiError JNICALL
833 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
834 jfieldID field
, jboolean
*result
)
836 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
838 return JVMTI_ERROR_INVALID_CLASS
;
840 return JVMTI_ERROR_INVALID_FIELDID
;
843 // FIXME: capability can_get_synthetic_attribute
844 *result
= ((field
->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC
)
846 return JVMTI_ERROR_NONE
;
849 static jvmtiError JNICALL
850 _Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
851 char **name_ptr
, char **signature_ptr
,
854 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
857 return JVMTI_ERROR_INVALID_METHODID
;
859 if (name_ptr
!= NULL
)
861 int len
= static_cast<int> (method
->name
->len ());
862 *name_ptr
= (char *) _Jv_MallocUnchecked (len
+ 1);
863 if (*name_ptr
== NULL
)
864 return JVMTI_ERROR_OUT_OF_MEMORY
;
865 strncpy (*name_ptr
, method
->name
->chars (), len
);
866 (*name_ptr
)[len
] = '\0';
869 if (signature_ptr
!= NULL
)
871 int len
= static_cast<int> (method
->signature
->len ());
872 *signature_ptr
= (char *) _Jv_MallocUnchecked (len
+ 1);
873 if (*signature_ptr
== NULL
)
875 if (name_ptr
!= NULL
)
876 _Jv_Free (*name_ptr
);
877 return JVMTI_ERROR_OUT_OF_MEMORY
;
879 strncpy (*signature_ptr
, method
->signature
->chars (), len
);
880 (*signature_ptr
)[len
] = '\0';
883 if (generic_ptr
!= NULL
)
888 return JVMTI_ERROR_NONE
;
891 static jvmtiError JNICALL
892 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
895 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
897 return JVMTI_ERROR_INVALID_METHODID
;
900 // FIXME: mask off some internal bits...
901 *result
= method
->accflags
;
902 return JVMTI_ERROR_NONE
;
905 static jvmtiError JNICALL
906 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv
*env
, jmethodID method
,
907 jint
*entry_count_ptr
,
908 jvmtiLineNumberEntry
**table_ptr
)
910 NULL_CHECK (entry_count_ptr
);
911 NULL_CHECK (table_ptr
);
914 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
915 if (jerr
!= JVMTI_ERROR_NONE
)
918 _Jv_MethodBase
*base
= _Jv_FindInterpreterMethod (klass
, method
);
920 return JVMTI_ERROR_INVALID_METHODID
;
922 if (java::lang::reflect::Modifier::isNative (method
->accflags
)
923 || !_Jv_IsInterpretedClass (klass
))
924 return JVMTI_ERROR_NATIVE_METHOD
;
926 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*> (base
);
928 jintArray lines
= NULL
;
929 jlongArray indices
= NULL
;
930 imeth
->get_line_table (start
, end
, lines
, indices
);
932 return JVMTI_ERROR_ABSENT_INFORMATION
;
934 jvmtiLineNumberEntry
*table
;
935 jsize len
= lines
->length
* sizeof (jvmtiLineNumberEntry
);
936 table
= (jvmtiLineNumberEntry
*) _Jv_MallocUnchecked (len
);
938 return JVMTI_ERROR_OUT_OF_MEMORY
;
940 jint
*line
= elements (lines
);
941 jlong
*index
= elements (indices
);
942 for (int i
= 0; i
< lines
->length
; ++i
)
944 table
[i
].start_location
= index
[i
];
945 table
[i
].line_number
= line
[i
];
949 *entry_count_ptr
= lines
->length
;
950 return JVMTI_ERROR_NONE
;
953 static jvmtiError JNICALL
954 _Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
956 jvmtiLocalVariableEntry
**locals
)
958 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
959 NULL_CHECK (num_locals
);
962 CHECK_FOR_NATIVE_METHOD(method
);
965 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
966 if (jerr
!= JVMTI_ERROR_NONE
)
969 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*>
970 (_Jv_FindInterpreterMethod (klass
, method
));
973 return JVMTI_ERROR_INVALID_METHODID
;
975 jerr
= env
->GetMaxLocals (method
, num_locals
);
976 if (jerr
!= JVMTI_ERROR_NONE
)
979 jerr
= env
->Allocate (static_cast<jlong
>
980 ((*num_locals
) * sizeof (jvmtiLocalVariableEntry
)),
981 reinterpret_cast<unsigned char **> (locals
));
983 if (jerr
!= JVMTI_ERROR_NONE
)
986 //the slot in the methods local_var_table to get
992 while (table_slot
< *num_locals
993 && imeth
->get_local_var_table (&name
, &sig
, &generic_sig
,
994 &((((*locals
)[table_slot
].start_location
))),
995 &((*locals
)[table_slot
].length
),
996 &((*locals
)[table_slot
].slot
),
1000 jerr
= env
->Allocate (static_cast<jlong
> (strlen (name
) + 1),
1001 reinterpret_cast<unsigned char **>
1002 (&(*locals
)[table_slot
].name
));
1003 if (jerr
!= JVMTI_ERROR_NONE
)
1005 strcpy ((*locals
)[table_slot
].name
, name
);
1007 jerr
= env
->Allocate (static_cast<jlong
> (strlen (name
) + 1),
1008 reinterpret_cast<unsigned char **>
1009 (&(*locals
)[table_slot
].signature
));
1010 if (jerr
!= JVMTI_ERROR_NONE
)
1012 strcpy ((*locals
)[table_slot
].signature
, sig
);
1014 jerr
= env
->Allocate (static_cast<jlong
> (strlen (name
) + 1),
1015 reinterpret_cast<unsigned char **>
1016 (&(*locals
)[table_slot
].generic_signature
));
1017 if (jerr
!= JVMTI_ERROR_NONE
)
1019 strcpy ((*locals
)[table_slot
].generic_signature
, generic_sig
);
1024 if (table_slot
== 0)
1025 return JVMTI_ERROR_ABSENT_INFORMATION
;
1027 // If there are double or long variables in the table, the the table will be
1028 // smaller than the max number of slots, so correct for this here.
1029 if ((table_slot
) < *num_locals
)
1030 *num_locals
= table_slot
;
1032 return JVMTI_ERROR_NONE
;
1035 static jvmtiError JNICALL
1036 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
1039 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1041 return JVMTI_ERROR_INVALID_METHODID
;
1042 NULL_CHECK (result
);
1044 *result
= ((method
->accflags
& java::lang::reflect::Modifier::NATIVE
) != 0);
1045 return JVMTI_ERROR_NONE
;
1048 static jvmtiError JNICALL
1049 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
1052 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1054 return JVMTI_ERROR_INVALID_METHODID
;
1055 NULL_CHECK (result
);
1057 // FIXME capability can_get_synthetic_attribute
1059 *result
= ((method
->accflags
& java::lang::reflect::Modifier::SYNTHETIC
)
1061 return JVMTI_ERROR_NONE
;
1064 static jvmtiError JNICALL
1065 _Jv_JVMTI_GetMaxLocals (jvmtiEnv
*env
, jmethodID method
, jint
*max_locals
)
1067 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1068 NULL_CHECK (max_locals
);
1070 CHECK_FOR_NATIVE_METHOD (method
);
1073 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
1074 if (jerr
!= JVMTI_ERROR_NONE
)
1077 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*>
1078 (_Jv_FindInterpreterMethod (klass
, method
));
1081 return JVMTI_ERROR_INVALID_METHODID
;
1083 *max_locals
= imeth
->get_max_locals ();
1085 return JVMTI_ERROR_NONE
;
1088 static jvmtiError JNICALL
1089 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv
*env
,
1091 jclass
*declaring_class_ptr
)
1093 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1094 NULL_CHECK (declaring_class_ptr
);
1096 jclass klass
= _Jv_GetMethodDeclaringClass (method
);
1099 *declaring_class_ptr
= klass
;
1100 return JVMTI_ERROR_NONE
;
1103 return JVMTI_ERROR_INVALID_METHODID
;
1106 static jvmtiError JNICALL
1107 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv
*env
,
1108 jobject init_loader
,
1110 jclass
**result_ptr
)
1112 using namespace java::lang
;
1113 using namespace java::util
;
1115 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1116 NULL_CHECK (count_ptr
);
1117 NULL_CHECK (result_ptr
);
1119 ClassLoader
*loader
= (ClassLoader
*) init_loader
;
1121 loader
= VMClassLoader::bootLoader
;
1123 Collection
*values
= loader
->loadedClasses
->values();
1124 jobjectArray array
= values
->toArray();
1125 *count_ptr
= array
->length
;
1126 jobject
*elts
= elements (array
);
1128 = (jclass
*) _Jv_MallocUnchecked (*count_ptr
* sizeof (jclass
));
1130 return JVMTI_ERROR_OUT_OF_MEMORY
;
1132 // FIXME: JNI references...
1133 memcpy (result
, elts
, *count_ptr
* sizeof (jclass
));
1135 *result_ptr
= result
;
1137 return JVMTI_ERROR_NONE
;
1140 static jvmtiError JNICALL
1141 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
1142 jint start_depth
, jint max_frames
,
1143 jvmtiFrameInfo
*frames
, jint
*frame_count
)
1145 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1147 ILLEGAL_ARGUMENT (max_frames
< 0);
1149 NULL_CHECK (frames
);
1150 NULL_CHECK (frame_count
);
1152 using namespace java::lang
;
1154 THREAD_DEFAULT_TO_CURRENT (thread
);
1155 THREAD_CHECK_VALID (thread
);
1156 THREAD_CHECK_IS_ALIVE (thread
);
1158 jvmtiError jerr
= env
->GetFrameCount (thread
, frame_count
);
1159 if (jerr
!= JVMTI_ERROR_NONE
)
1162 // start_depth can be either a positive number, indicating the depth of the
1163 // stack at which to begin the trace, or a negative number indicating the
1164 // number of frames at the bottom of the stack to exclude. These checks
1165 // ensure that it is a valid value in either case
1167 ILLEGAL_ARGUMENT (start_depth
>= (*frame_count
));
1168 ILLEGAL_ARGUMENT (start_depth
< (-(*frame_count
)));
1170 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
1172 // If start_depth is negative use this to determine at what depth to start
1173 // the trace by adding it to the length of the call stack. This allows the
1174 // use of the same frame "discarding" mechanism as for a positive start_depth
1175 if (start_depth
< 0)
1176 start_depth
= *frame_count
+ start_depth
;
1178 // If start_depth > 0 "remove" start_depth frames from the beginning
1179 // of the stack before beginning the trace by moving along the frame list.
1180 while (start_depth
> 0)
1182 frame
= frame
->next
;
1187 // Now check to see if the array supplied by the agent is large enough to
1188 // hold frame_count frames, after adjustment for start_depth.
1189 if ((*frame_count
) > max_frames
)
1190 (*frame_count
) = max_frames
;
1192 for (int i
= 0; i
< (*frame_count
); i
++)
1194 frames
[i
].method
= frame
->self
->get_method ();
1196 // Set the location in the frame, native frames have location = -1
1197 if (frame
->frame_type
== frame_interpreter
)
1199 _Jv_InterpMethod
*imeth
1200 = static_cast<_Jv_InterpMethod
*> (frame
->self
);
1201 _Jv_InterpFrame
*interp_frame
1202 = static_cast<_Jv_InterpFrame
*> (frame
);
1203 frames
[i
].location
= imeth
->insn_index (interp_frame
->pc
);
1206 frames
[i
].location
= -1;
1208 frame
= frame
->next
;
1211 return JVMTI_ERROR_NONE
;
1214 static jvmtiError JNICALL
1215 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv
*env
)
1217 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1219 return JVMTI_ERROR_NONE
;
1222 static jvmtiError JNICALL
1223 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1224 const jniNativeInterface
*function_table
)
1226 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1227 NULL_CHECK (function_table
);
1228 memcpy (&_Jv_JNIFunctions
, function_table
, sizeof (jniNativeInterface
));
1229 return JVMTI_ERROR_NONE
;
1232 static jvmtiError JNICALL
1233 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1234 jniNativeInterface
**function_table
)
1236 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1237 NULL_CHECK (function_table
);
1239 = (jniNativeInterface
*) _Jv_MallocUnchecked (sizeof (jniNativeInterface
));
1240 if (*function_table
== NULL
)
1241 return JVMTI_ERROR_OUT_OF_MEMORY
;
1242 memcpy (*function_table
, &_Jv_JNIFunctions
, sizeof (jniNativeInterface
));
1243 return JVMTI_ERROR_NONE
;
1246 static jvmtiError JNICALL
1247 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv
*env
)
1251 if (_jvmtiEnvironments
== NULL
)
1252 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1255 _envListLock
->writeLock ()->lock ();
1256 if (_jvmtiEnvironments
->env
== env
)
1258 struct jvmti_env_list
*next
= _jvmtiEnvironments
->next
;
1259 _Jv_Free (_jvmtiEnvironments
);
1260 _jvmtiEnvironments
= next
;
1264 struct jvmti_env_list
*e
= _jvmtiEnvironments
;
1265 while (e
->next
!= NULL
&& e
->next
->env
!= env
)
1267 if (e
->next
== NULL
)
1269 _envListLock
->writeLock ()->unlock ();
1270 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1273 struct jvmti_env_list
*next
= e
->next
->next
;
1277 _envListLock
->writeLock ()->unlock ();
1282 check_enabled_events ();
1284 return JVMTI_ERROR_NONE
;
1287 static jvmtiError JNICALL
1288 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1291 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1292 NULL_CHECK (property
);
1293 NULL_CHECK (result
);
1295 jstring name
= JvNewStringUTF(property
);
1296 jstring result_str
= gnu::classpath::SystemProperties::getProperty(name
);
1298 if (result_str
== NULL
)
1299 return JVMTI_ERROR_NOT_AVAILABLE
;
1301 int len
= JvGetStringUTFLength (result_str
);
1302 *result
= (char *) _Jv_MallocUnchecked (len
+ 1);
1303 if (*result
== NULL
)
1304 return JVMTI_ERROR_OUT_OF_MEMORY
;
1305 JvGetStringUTFRegion (result_str
, 0, result_str
->length(), *result
);
1306 (*result
)[len
] = '\0';
1308 return JVMTI_ERROR_NONE
;
1311 static jvmtiError JNICALL
1312 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1315 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1317 NULL_CHECK (property
);
1320 // FIXME: When would a property not be writeable?
1321 return JVMTI_ERROR_NONE
;
1324 jstring prop_str
= JvNewStringUTF(property
);
1325 jstring value_str
= JvNewStringUTF(value
);
1326 gnu::classpath::SystemProperties::setProperty(prop_str
, value_str
);
1327 return JVMTI_ERROR_NONE
;
1330 static jvmtiError JNICALL
1331 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv
*env
, jlong
*nanos_ptr
)
1333 NULL_CHECK (nanos_ptr
);
1334 *nanos_ptr
= _Jv_platform_nanotime();
1335 return JVMTI_ERROR_NONE
;
1338 static jvmtiError JNICALL
1339 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv
*env
,
1340 jint
*nprocessors_ptr
)
1342 NULL_CHECK (nprocessors_ptr
);
1343 #ifdef _SC_NPROCESSORS_ONLN
1344 *nprocessors_ptr
= sysconf(_SC_NPROCESSORS_ONLN
);
1346 *nprocessors_ptr
= 1;
1348 return JVMTI_ERROR_NONE
;
1351 static jvmtiError JNICALL
1352 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv
*env
,
1353 const char *segment
)
1355 using namespace java::lang
;
1356 using namespace java::net
;
1357 using namespace gnu::gcj::runtime
;
1359 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1360 NULL_CHECK (segment
);
1362 jstring str_segment
= JvNewStringUTF(segment
);
1366 url
= new URL(JvNewStringUTF("file"), NULL
, str_segment
);
1368 catch (jthrowable ignore
)
1370 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1373 BootClassLoader
*loader
= VMClassLoader::bootLoader
;
1374 // Don't call this too early.
1375 // assert (loader != NULL);
1376 loader
->addURL(url
);
1377 return JVMTI_ERROR_NONE
;
1380 static jvmtiError JNICALL
1381 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiVerboseFlag flag
,
1386 case JVMTI_VERBOSE_OTHER
:
1387 case JVMTI_VERBOSE_GC
:
1388 case JVMTI_VERBOSE_JNI
:
1391 case JVMTI_VERBOSE_CLASS
:
1392 gcj::verbose_class_flag
= value
;
1395 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1397 return JVMTI_ERROR_NONE
;
1400 static jvmtiError JNICALL
1401 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv
*env
, jobject object
,
1404 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1406 return JVMTI_ERROR_INVALID_OBJECT
;
1407 NULL_CHECK (result
);
1409 jclass klass
= object
->getClass();
1410 if (klass
->isArray())
1412 jclass comp
= klass
->getComponentType();
1414 = (jint
) (_Jv_uintptr_t
) _Jv_GetArrayElementFromElementType(NULL
,
1415 klass
->getComponentType());
1416 // FIXME: correct for primitive types?
1417 jint compSize
= comp
->size();
1418 __JArray
*array
= (__JArray
*) object
;
1419 *result
= base
+ array
->length
* compSize
;
1423 // Note that if OBJECT is a String then it may (if
1424 // str->data==str) take more space. Do we care?
1425 *result
= klass
->size();
1427 return JVMTI_ERROR_NONE
;
1430 /* An event is enabled only if it has both an event handler
1431 and it is enabled in the environment. */
1433 check_enabled_event (jvmtiEvent type
)
1438 #define GET_OFFSET(Event) \
1441 enabled = &JVMTI::Event; \
1442 offset = offsetof (jvmtiEventCallbacks, Event); \
1448 case JVMTI_EVENT_VM_INIT
:
1449 GET_OFFSET (VMInit
);
1452 case JVMTI_EVENT_VM_DEATH
:
1453 GET_OFFSET (VMDeath
);
1456 case JVMTI_EVENT_THREAD_START
:
1457 GET_OFFSET (ThreadStart
);
1460 case JVMTI_EVENT_THREAD_END
:
1461 GET_OFFSET (ThreadEnd
);
1464 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1465 GET_OFFSET (ClassFileLoadHook
);
1468 case JVMTI_EVENT_CLASS_LOAD
:
1469 GET_OFFSET (ClassLoad
);
1472 case JVMTI_EVENT_CLASS_PREPARE
:
1473 GET_OFFSET (ClassPrepare
);
1476 case JVMTI_EVENT_VM_START
:
1477 GET_OFFSET (VMStart
);
1480 case JVMTI_EVENT_EXCEPTION
:
1481 GET_OFFSET (Exception
);
1484 case JVMTI_EVENT_EXCEPTION_CATCH
:
1485 GET_OFFSET (ExceptionCatch
);
1488 case JVMTI_EVENT_SINGLE_STEP
:
1489 GET_OFFSET (SingleStep
);
1492 case JVMTI_EVENT_FRAME_POP
:
1493 GET_OFFSET (FramePop
);
1496 case JVMTI_EVENT_BREAKPOINT
:
1497 GET_OFFSET (Breakpoint
);
1500 case JVMTI_EVENT_FIELD_ACCESS
:
1501 GET_OFFSET (FieldAccess
);
1504 case JVMTI_EVENT_FIELD_MODIFICATION
:
1505 GET_OFFSET (FieldModification
);
1508 case JVMTI_EVENT_METHOD_ENTRY
:
1509 GET_OFFSET (MethodEntry
);
1512 case JVMTI_EVENT_METHOD_EXIT
:
1513 GET_OFFSET (MethodExit
);
1516 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1517 GET_OFFSET (NativeMethodBind
);
1520 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1521 GET_OFFSET (CompiledMethodLoad
);
1524 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1525 GET_OFFSET (CompiledMethodUnload
);
1528 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1529 GET_OFFSET (DynamicCodeGenerated
);
1532 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1533 GET_OFFSET (DataDumpRequest
);
1536 case JVMTI_EVENT_MONITOR_WAIT
:
1537 GET_OFFSET (MonitorWait
);
1540 case JVMTI_EVENT_MONITOR_WAITED
:
1541 GET_OFFSET (MonitorWaited
);
1544 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1545 GET_OFFSET (MonitorContendedEnter
);
1548 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1549 GET_OFFSET (MonitorContendedEntered
);
1552 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1553 GET_OFFSET (GarbageCollectionStart
);
1556 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1557 GET_OFFSET (GarbageCollectionFinish
);
1560 case JVMTI_EVENT_OBJECT_FREE
:
1561 GET_OFFSET (ObjectFree
);
1564 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1565 GET_OFFSET (VMObjectAlloc
);
1570 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1576 int index
= EVENT_INDEX (type
); // safe since caller checks this
1578 if (_jvmtiEnvironments
!= NULL
)
1580 _envListLock
->readLock ()->lock ();
1581 struct jvmti_env_list
*e
;
1582 FOREACH_ENVIRONMENT (e
)
1585 = reinterpret_cast<char *> (&e
->env
->callbacks
) + offset
;
1586 void **callback
= reinterpret_cast<void **> (addr
);
1587 if (e
->env
->enabled
[index
] && *callback
!= NULL
)
1590 _envListLock
->readLock ()->unlock ();
1595 _envListLock
->readLock ()->unlock ();
1602 check_enabled_events ()
1604 check_enabled_event (JVMTI_EVENT_VM_INIT
);
1605 check_enabled_event (JVMTI_EVENT_VM_DEATH
);
1606 check_enabled_event (JVMTI_EVENT_THREAD_START
);
1607 check_enabled_event (JVMTI_EVENT_THREAD_END
);
1608 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
);
1609 check_enabled_event (JVMTI_EVENT_CLASS_LOAD
);
1610 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE
);
1611 check_enabled_event (JVMTI_EVENT_VM_START
);
1612 check_enabled_event (JVMTI_EVENT_EXCEPTION
);
1613 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH
);
1614 check_enabled_event (JVMTI_EVENT_SINGLE_STEP
);
1615 check_enabled_event (JVMTI_EVENT_FRAME_POP
);
1616 check_enabled_event (JVMTI_EVENT_BREAKPOINT
);
1617 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS
);
1618 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION
);
1619 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY
);
1620 check_enabled_event (JVMTI_EVENT_METHOD_EXIT
);
1621 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND
);
1622 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD
);
1623 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD
);
1624 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED
);
1625 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST
);
1626 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT
);
1627 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED
);
1628 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER
);
1629 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
);
1630 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START
);
1631 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
);
1632 check_enabled_event (JVMTI_EVENT_OBJECT_FREE
);
1633 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC
);
1636 static jvmtiError JNICALL
1637 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv
*env
, jvmtiEventMode mode
,
1638 jvmtiEvent type
, jthread event_thread
, ...)
1640 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1642 if (event_thread
!= NULL
)
1644 THREAD_CHECK_VALID (event_thread
);
1645 THREAD_CHECK_IS_ALIVE (event_thread
);
1659 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1664 case JVMTI_EVENT_VM_INIT
:
1665 case JVMTI_EVENT_VM_DEATH
:
1666 case JVMTI_EVENT_THREAD_START
:
1667 case JVMTI_EVENT_VM_START
:
1668 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1669 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1670 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1671 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1672 ILLEGAL_ARGUMENT (event_thread
!= NULL
);
1675 case JVMTI_EVENT_THREAD_END
:
1676 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1677 case JVMTI_EVENT_CLASS_LOAD
:
1678 case JVMTI_EVENT_CLASS_PREPARE
:
1679 case JVMTI_EVENT_EXCEPTION
:
1680 case JVMTI_EVENT_EXCEPTION_CATCH
:
1681 case JVMTI_EVENT_SINGLE_STEP
:
1682 case JVMTI_EVENT_FRAME_POP
:
1683 case JVMTI_EVENT_BREAKPOINT
:
1684 case JVMTI_EVENT_FIELD_ACCESS
:
1685 case JVMTI_EVENT_FIELD_MODIFICATION
:
1686 case JVMTI_EVENT_METHOD_ENTRY
:
1687 case JVMTI_EVENT_METHOD_EXIT
:
1688 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1689 case JVMTI_EVENT_MONITOR_WAIT
:
1690 case JVMTI_EVENT_MONITOR_WAITED
:
1691 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1692 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1693 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1694 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1695 case JVMTI_EVENT_OBJECT_FREE
:
1696 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1700 return JVMTI_ERROR_INVALID_EVENT_TYPE
;
1703 env
->thread
[EVENT_INDEX(type
)] = event_thread
;
1704 env
->enabled
[EVENT_INDEX(type
)] = enabled
;
1705 check_enabled_event (type
);
1706 return JVMTI_ERROR_NONE
;
1709 static jvmtiError JNICALL
1710 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv
*env
,
1711 const jvmtiEventCallbacks
*callbacks
,
1712 jint size_of_callbacks
)
1714 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1715 ILLEGAL_ARGUMENT (size_of_callbacks
< 0);
1717 // Copy the list of callbacks into the environment
1718 memcpy (&env
->callbacks
, callbacks
, sizeof (jvmtiEventCallbacks
));
1720 /* Check which events are now enabeld (JVMTI makes no requirements
1721 about the order in which SetEventCallbacks and SetEventNotifications
1722 are called. So we must check all events here. */
1723 check_enabled_events ();
1725 return JVMTI_ERROR_NONE
;
1728 static jvmtiError JNICALL
1729 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiError error
,
1732 NULL_CHECK (name_ptr
);
1737 case JVMTI_ERROR_NONE
:
1741 case JVMTI_ERROR_NULL_POINTER
:
1742 name
= "null pointer";
1745 case JVMTI_ERROR_OUT_OF_MEMORY
:
1746 name
= "out of memory";
1749 case JVMTI_ERROR_ACCESS_DENIED
:
1750 name
= "access denied";
1753 case JVMTI_ERROR_WRONG_PHASE
:
1754 name
= "wrong phase";
1757 case JVMTI_ERROR_INTERNAL
:
1758 name
= "internal error";
1761 case JVMTI_ERROR_UNATTACHED_THREAD
:
1762 name
= "unattached thread";
1765 case JVMTI_ERROR_INVALID_ENVIRONMENT
:
1766 name
= "invalid environment";
1769 case JVMTI_ERROR_INVALID_PRIORITY
:
1770 name
= "invalid priority";
1773 case JVMTI_ERROR_THREAD_NOT_SUSPENDED
:
1774 name
= "thread not suspended";
1777 case JVMTI_ERROR_THREAD_SUSPENDED
:
1778 name
= "thread suspended";
1781 case JVMTI_ERROR_THREAD_NOT_ALIVE
:
1782 name
= "thread not alive";
1785 case JVMTI_ERROR_CLASS_NOT_PREPARED
:
1786 name
= "class not prepared";
1789 case JVMTI_ERROR_NO_MORE_FRAMES
:
1790 name
= "no more frames";
1793 case JVMTI_ERROR_OPAQUE_FRAME
:
1794 name
= "opaque frame";
1797 case JVMTI_ERROR_DUPLICATE
:
1801 case JVMTI_ERROR_NOT_FOUND
:
1805 case JVMTI_ERROR_NOT_MONITOR_OWNER
:
1806 name
= "not monitor owner";
1809 case JVMTI_ERROR_INTERRUPT
:
1810 name
= "interrupted";
1813 case JVMTI_ERROR_UNMODIFIABLE_CLASS
:
1814 name
= "unmodifiable class";
1817 case JVMTI_ERROR_NOT_AVAILABLE
:
1818 name
= "not available";
1821 case JVMTI_ERROR_ABSENT_INFORMATION
:
1822 name
= "absent information";
1825 case JVMTI_ERROR_INVALID_EVENT_TYPE
:
1826 name
= "invalid event type";
1829 case JVMTI_ERROR_NATIVE_METHOD
:
1830 name
= "native method";
1833 case JVMTI_ERROR_INVALID_THREAD
:
1834 name
= "invalid thread";
1837 case JVMTI_ERROR_INVALID_THREAD_GROUP
:
1838 name
= "invalid thread group";
1841 case JVMTI_ERROR_INVALID_OBJECT
:
1842 name
= "invalid object";
1845 case JVMTI_ERROR_INVALID_CLASS
:
1846 name
= "invalid class";
1849 case JVMTI_ERROR_INVALID_METHODID
:
1850 name
= "invalid method ID";
1853 case JVMTI_ERROR_INVALID_LOCATION
:
1854 name
= "invalid location";
1857 case JVMTI_ERROR_INVALID_FIELDID
:
1858 name
= "invalid field ID";
1861 case JVMTI_ERROR_TYPE_MISMATCH
:
1862 name
= "type mismatch";
1865 case JVMTI_ERROR_INVALID_SLOT
:
1866 name
= "invalid slot";
1869 case JVMTI_ERROR_INVALID_MONITOR
:
1870 name
= "invalid monitor";
1873 case JVMTI_ERROR_INVALID_CLASS_FORMAT
:
1874 name
= "invalid class format";
1877 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION
:
1878 name
= "circular class definition";
1881 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED
:
1882 name
= "unsupported redefinition: method added";
1885 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED
:
1886 name
= "unsupported redefinition: schema changed";
1889 case JVMTI_ERROR_INVALID_TYPESTATE
:
1890 name
= "invalid type state";
1893 case JVMTI_ERROR_FAILS_VERIFICATION
:
1894 name
= "fails verification";
1897 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED
:
1898 name
= "unsupported redefinition: hierarchy changed";
1901 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED
:
1902 name
= "unsupported redefinition: method deleted";
1905 case JVMTI_ERROR_UNSUPPORTED_VERSION
:
1906 name
= "unsupported version";
1909 case JVMTI_ERROR_NAMES_DONT_MATCH
:
1910 name
= "names do not match";
1913 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED
:
1914 name
= "unsupported redefinition: class modifiers changed";
1917 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED
:
1918 name
= "unsupported redefinition: method modifiers changed";
1921 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY
:
1922 name
= "must possess capability";
1925 case JVMTI_ERROR_ILLEGAL_ARGUMENT
:
1926 name
= "illegal argument";
1930 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1933 *name_ptr
= (char *) _Jv_MallocUnchecked (strlen (name
) + 1);
1934 if (*name_ptr
== NULL
)
1935 return JVMTI_ERROR_OUT_OF_MEMORY
;
1937 strcpy (*name_ptr
, name
);
1938 return JVMTI_ERROR_NONE
;
1941 #define RESERVED NULL
1942 #define UNIMPLEMENTED NULL
1944 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface
=
1946 RESERVED
, // reserved1
1947 _Jv_JVMTI_SetEventNotificationMode
, // SetEventNotificationMode
1948 RESERVED
, // reserved3
1949 _Jv_JVMTI_GetAllThreads
, // GetAllThreads
1950 _Jv_JVMTI_SuspendThread
, // SuspendThread
1951 _Jv_JVMTI_ResumeThread
, // ResumeThread
1952 UNIMPLEMENTED
, // StopThread
1953 _Jv_JVMTI_InterruptThread
, // InterruptThread
1954 UNIMPLEMENTED
, // GetThreadInfo
1955 UNIMPLEMENTED
, // GetOwnedMonitorInfo
1956 UNIMPLEMENTED
, // GetCurrentContendedMonitor
1957 UNIMPLEMENTED
, // RunAgentThread
1958 UNIMPLEMENTED
, // GetTopThreadGroups
1959 UNIMPLEMENTED
, // GetThreadGroupInfo
1960 UNIMPLEMENTED
, // GetThreadGroupChildren
1961 _Jv_JVMTI_GetFrameCount
, // GetFrameCount
1962 UNIMPLEMENTED
, // GetThreadState
1963 RESERVED
, // reserved18
1964 UNIMPLEMENTED
, // GetFrameLocation
1965 UNIMPLEMENTED
, // NotifyPopFrame
1966 _Jv_JVMTI_GetLocalObject
, // GetLocalObject
1967 _Jv_JVMTI_GetLocalInt
, // GetLocalInt
1968 _Jv_JVMTI_GetLocalLong
, // GetLocalLong
1969 _Jv_JVMTI_GetLocalFloat
, // GetLocalFloat
1970 _Jv_JVMTI_GetLocalDouble
, // GetLocalDouble
1971 _Jv_JVMTI_SetLocalObject
, // SetLocalObject
1972 _Jv_JVMTI_SetLocalInt
, // SetLocalInt
1973 _Jv_JVMTI_SetLocalLong
, // SetLocalLong
1974 _Jv_JVMTI_SetLocalFloat
, // SetLocalFloat
1975 _Jv_JVMTI_SetLocalDouble
, // SetLocalDouble
1976 _Jv_JVMTI_CreateRawMonitor
, // CreateRawMonitor
1977 _Jv_JVMTI_DestroyRawMonitor
, // DestroyRawMonitor
1978 _Jv_JVMTI_RawMonitorEnter
, // RawMonitorEnter
1979 _Jv_JVMTI_RawMonitorExit
, // RawMonitorExit
1980 _Jv_JVMTI_RawMonitorWait
, // RawMonitorWait
1981 _Jv_JVMTI_RawMonitorNotify
, // RawMonitorNotify
1982 _Jv_JVMTI_RawMonitorNotifyAll
, // RawMonitorNotifyAll
1983 _Jv_JVMTI_SetBreakpoint
, // SetBreakpoint
1984 _Jv_JVMTI_ClearBreakpoint
, // ClearBreakpoint
1985 RESERVED
, // reserved40
1986 UNIMPLEMENTED
, // SetFieldAccessWatch
1987 UNIMPLEMENTED
, // ClearFieldAccessWatch
1988 UNIMPLEMENTED
, // SetFieldModificationWatch
1989 UNIMPLEMENTED
, // ClearFieldModificationWatch
1990 RESERVED
, // reserved45
1991 _Jv_JVMTI_Allocate
, // Allocate
1992 _Jv_JVMTI_Deallocate
, // Deallocate
1993 UNIMPLEMENTED
, // GetClassSignature
1994 _Jv_JVMTI_GetClassStatus
, // GetClassStatus
1995 UNIMPLEMENTED
, // GetSourceFileName
1996 _Jv_JVMTI_GetClassModifiers
, // GetClassModifiers
1997 _Jv_JVMTI_GetClassMethods
, // GetClassMethods
1998 UNIMPLEMENTED
, // GetClassFields
1999 UNIMPLEMENTED
, // GetImplementedInterfaces
2000 _Jv_JVMTI_IsInterface
, // IsInterface
2001 _Jv_JVMTI_IsArrayClass
, // IsArrayClass
2002 _Jv_JVMTI_GetClassLoader
, // GetClassLoader
2003 _Jv_JVMTI_GetObjectHashCode
, // GetObjectHashCode
2004 UNIMPLEMENTED
, // GetObjectMonitorUsage
2005 UNIMPLEMENTED
, // GetFieldName
2006 UNIMPLEMENTED
, // GetFieldDeclaringClass
2007 _Jv_JVMTI_GetFieldModifiers
, // GetFieldModifiers
2008 _Jv_JVMTI_IsFieldSynthetic
, // IsFieldSynthetic
2009 _Jv_JVMTI_GetMethodName
, // GetMethodName
2010 _Jv_JVMTI_GetMethodDeclaringClass
, // GetMethodDeclaringClass
2011 _Jv_JVMTI_GetMethodModifiers
, // GetMethodModifers
2012 RESERVED
, // reserved67
2013 _Jv_JVMTI_GetMaxLocals
, // GetMaxLocals
2014 UNIMPLEMENTED
, // GetArgumentsSize
2015 _Jv_JVMTI_GetLineNumberTable
, // GetLineNumberTable
2016 UNIMPLEMENTED
, // GetMethodLocation
2017 _Jv_JVMTI_GetLocalVariableTable
, // GetLocalVariableTable
2018 RESERVED
, // reserved73
2019 RESERVED
, // reserved74
2020 UNIMPLEMENTED
, // GetBytecodes
2021 _Jv_JVMTI_IsMethodNative
, // IsMethodNative
2022 _Jv_JVMTI_IsMethodSynthetic
, // IsMethodSynthetic
2023 UNIMPLEMENTED
, // GetLoadedClasses
2024 _Jv_JVMTI_GetClassLoaderClasses
, // GetClassLoaderClasses
2025 UNIMPLEMENTED
, // PopFrame
2026 RESERVED
, // reserved81
2027 RESERVED
, // reserved82
2028 RESERVED
, // reserved83
2029 RESERVED
, // reserved84
2030 RESERVED
, // reserved85
2031 RESERVED
, // reserved86
2032 UNIMPLEMENTED
, // RedefineClasses
2033 UNIMPLEMENTED
, // GetVersionNumber
2034 UNIMPLEMENTED
, // GetCapabilities
2035 UNIMPLEMENTED
, // GetSourceDebugExtension
2036 UNIMPLEMENTED
, // IsMethodObsolete
2037 UNIMPLEMENTED
, // SuspendThreadList
2038 UNIMPLEMENTED
, // ResumeThreadList
2039 RESERVED
, // reserved94
2040 RESERVED
, // reserved95
2041 RESERVED
, // reserved96
2042 RESERVED
, // reserved97
2043 RESERVED
, // reserved98
2044 RESERVED
, // reserved99
2045 UNIMPLEMENTED
, // GetAllStackTraces
2046 UNIMPLEMENTED
, // GetThreadListStackTraces
2047 UNIMPLEMENTED
, // GetThreadLocalStorage
2048 UNIMPLEMENTED
, // SetThreadLocalStorage
2049 _Jv_JVMTI_GetStackTrace
, // GetStackTrace
2050 RESERVED
, // reserved105
2051 UNIMPLEMENTED
, // GetTag
2052 UNIMPLEMENTED
, // SetTag
2053 _Jv_JVMTI_ForceGarbageCollection
, // ForceGarbageCollection
2054 UNIMPLEMENTED
, // IterateOverObjectsReachable
2055 UNIMPLEMENTED
, // IterateOverReachableObjects
2056 UNIMPLEMENTED
, // IterateOverHeap
2057 UNIMPLEMENTED
, // IterateOverInstanceOfClass
2058 RESERVED
, // reserved113
2059 UNIMPLEMENTED
, // GetObjectsWithTags
2060 RESERVED
, // reserved115
2061 RESERVED
, // reserved116
2062 RESERVED
, // reserved117
2063 RESERVED
, // reserved118
2064 RESERVED
, // reserved119
2065 _Jv_JVMTI_SetJNIFunctionTable
, // SetJNIFunctionTable
2066 _Jv_JVMTI_GetJNIFunctionTable
, // GetJNIFunctionTable
2067 _Jv_JVMTI_SetEventCallbacks
, // SetEventCallbacks
2068 UNIMPLEMENTED
, // GenerateEvents
2069 UNIMPLEMENTED
, // GetExtensionFunctions
2070 UNIMPLEMENTED
, // GetExtensionEvents
2071 UNIMPLEMENTED
, // SetExtensionEventCallback
2072 _Jv_JVMTI_DisposeEnvironment
, // DisposeEnvironment
2073 _Jv_JVMTI_GetErrorName
, // GetErrorName
2074 UNIMPLEMENTED
, // GetJLocationFormat
2075 UNIMPLEMENTED
, // GetSystemProperties
2076 _Jv_JVMTI_GetSystemProperty
, // GetSystemProperty
2077 _Jv_JVMTI_SetSystemProperty
, // SetSystemProperty
2078 UNIMPLEMENTED
, // GetPhase
2079 UNIMPLEMENTED
, // GetCurrentThreadCpuTimerInfo
2080 UNIMPLEMENTED
, // GetCurrentThreadCpuTime
2081 UNIMPLEMENTED
, // GetThreadCpuTimerInfo
2082 UNIMPLEMENTED
, // GetThreadCpuTime
2083 UNIMPLEMENTED
, // GetTimerInfo
2084 _Jv_JVMTI_GetTime
, // GetTime
2085 UNIMPLEMENTED
, // GetPotentialCapabilities
2086 RESERVED
, // reserved141
2087 UNIMPLEMENTED
, // AddCapabilities
2088 UNIMPLEMENTED
, // RelinquishCapabilities
2089 _Jv_JVMTI_GetAvailableProcessors
, // GetAvailableProcessors
2090 RESERVED
, // reserved145
2091 RESERVED
, // reserved146
2092 UNIMPLEMENTED
, // GetEnvironmentLocalStorage
2093 UNIMPLEMENTED
, // SetEnvironmentLocalStorage
2094 _Jv_JVMTI_AddToBootstrapClassLoaderSearch
, // AddToBootstrapClassLoaderSearch
2095 _Jv_JVMTI_SetVerboseFlag
, // SetVerboseFlag
2096 RESERVED
, // reserved151
2097 RESERVED
, // reserved152
2098 RESERVED
, // reserved153
2099 _Jv_JVMTI_GetObjectSize
// GetObjectSize
2103 _Jv_GetJVMTIEnv (void)
2106 = (_Jv_JVMTIEnv
*) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv
));
2107 env
->p
= &_Jv_JVMTI_Interface
;
2108 struct jvmti_env_list
*element
2109 = (struct jvmti_env_list
*) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list
));
2111 element
->next
= NULL
;
2113 _envListLock
->writeLock ()->lock ();
2114 if (_jvmtiEnvironments
== NULL
)
2115 _jvmtiEnvironments
= element
;
2118 struct jvmti_env_list
*e
;
2119 for (e
= _jvmtiEnvironments
; e
->next
!= NULL
; e
= e
->next
)
2123 _envListLock
->writeLock ()->unlock ();
2125 /* Mark JVMTI active. This is used to force the interpreter
2126 to use either debugging or non-debugging code. Once JVMTI
2127 has been enabled, the non-debug interpreter cannot be used. */
2128 JVMTI::enabled
= true;
2135 _jvmtiEnvironments
= NULL
;
2137 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2139 // No environments, so this should set all JVMTI:: members to false
2140 check_enabled_events ();
2144 post_event (jvmtiEnv
*env
, jvmtiEvent type
, jthread event_thread
, va_list args
)
2146 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2148 #define GET_BOOLEAN_ARG(Name) \
2150 jboolean Name = (b == 0) ? false : true
2152 #define GET_CHAR_ARG(Name) \
2154 char Name = static_cast<char> (c)
2158 case JVMTI_EVENT_VM_INIT
:
2159 if (env
->callbacks
.VMInit
!= NULL
)
2161 ARG (JNIEnv
*, jni_env
);
2162 env
->callbacks
.VMInit (env
, jni_env
, event_thread
);
2166 case JVMTI_EVENT_VM_DEATH
:
2167 if (env
->callbacks
.VMDeath
!= NULL
)
2169 ARG (JNIEnv
*, jni_env
);
2170 env
->callbacks
.VMDeath (env
, jni_env
);
2174 case JVMTI_EVENT_THREAD_START
:
2175 if (env
->callbacks
.ThreadStart
!= NULL
)
2177 ARG (JNIEnv
*, jni_env
);
2178 env
->callbacks
.ThreadStart (env
, jni_env
, event_thread
);
2182 case JVMTI_EVENT_THREAD_END
:
2183 if (env
->callbacks
.ThreadEnd
!= NULL
)
2185 ARG (JNIEnv
*, jni_env
);
2186 env
->callbacks
.ThreadEnd (env
, jni_env
, event_thread
);
2190 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
2191 if (env
->callbacks
.ClassFileLoadHook
!= NULL
)
2193 ARG (JNIEnv
*, jni_env
);
2194 ARG (jclass
, class_being_redefined
);
2195 ARG (jobject
, loader
);
2196 ARG (const char *, name
);
2197 ARG (jobject
, protection_domain
);
2198 ARG (jint
, class_data_len
);
2199 ARG (const unsigned char *, class_data
);
2200 ARG (jint
*, new_class_data_len
);
2201 ARG (unsigned char **, new_class_data
);
2202 env
->callbacks
.ClassFileLoadHook (env
, jni_env
,
2203 class_being_redefined
, loader
,
2204 name
, protection_domain
,
2205 class_data_len
, class_data
,
2211 case JVMTI_EVENT_CLASS_LOAD
:
2212 if (env
->callbacks
.ClassLoad
!= NULL
)
2214 ARG (JNIEnv
*, jni_env
);
2215 ARG (jclass
, klass
);
2216 env
->callbacks
.ClassLoad (env
, jni_env
, event_thread
, klass
);
2220 case JVMTI_EVENT_CLASS_PREPARE
:
2221 if (env
->callbacks
.ClassPrepare
!= NULL
)
2223 ARG (JNIEnv
*, jni_env
);
2224 ARG (jclass
, klass
);
2225 env
->callbacks
.ClassPrepare (env
, jni_env
, event_thread
, klass
);
2229 case JVMTI_EVENT_VM_START
:
2230 if (env
->callbacks
.VMStart
!= NULL
)
2232 ARG (JNIEnv
*, jni_env
);
2233 env
->callbacks
.VMStart (env
, jni_env
);
2237 case JVMTI_EVENT_EXCEPTION
:
2238 if (env
->callbacks
.Exception
!= NULL
)
2240 ARG (JNIEnv
*, jni_env
);
2241 ARG (jmethodID
, method
);
2242 ARG (jlocation
, location
);
2243 ARG (jobject
, exception
);
2244 ARG (jmethodID
, catch_method
);
2245 ARG (jlocation
, catch_location
);
2246 env
->callbacks
.Exception (env
, jni_env
, event_thread
, method
,
2247 location
, exception
, catch_method
,
2252 case JVMTI_EVENT_EXCEPTION_CATCH
:
2253 if (env
->callbacks
.ExceptionCatch
!= NULL
)
2255 ARG (JNIEnv
*, jni_env
);
2256 ARG (jmethodID
, method
);
2257 ARG (jlocation
, location
);
2258 ARG (jobject
, exception
);
2259 env
->callbacks
.ExceptionCatch (env
, jni_env
, event_thread
, method
,
2260 location
, exception
);
2264 case JVMTI_EVENT_SINGLE_STEP
:
2265 if (env
->callbacks
.SingleStep
!= NULL
)
2267 ARG (JNIEnv
*, jni_env
);
2268 ARG (jmethodID
, method
);
2269 ARG (jlocation
, location
);
2270 env
->callbacks
.SingleStep (env
, jni_env
, event_thread
, method
,
2275 case JVMTI_EVENT_FRAME_POP
:
2276 if (env
->callbacks
.FramePop
!= NULL
)
2278 ARG (JNIEnv
*, jni_env
);
2279 ARG (jmethodID
, method
);
2280 GET_BOOLEAN_ARG (was_popped_by_exception
);
2281 env
->callbacks
.FramePop (env
, jni_env
, event_thread
, method
,
2282 was_popped_by_exception
);
2286 case JVMTI_EVENT_BREAKPOINT
:
2287 if (env
->callbacks
.Breakpoint
!= NULL
)
2289 ARG (JNIEnv
*, jni_env
);
2290 ARG (jmethodID
, method
);
2291 ARG (jlocation
, location
);
2292 env
->callbacks
.Breakpoint (env
, jni_env
, event_thread
, method
,
2297 case JVMTI_EVENT_FIELD_ACCESS
:
2298 if (env
->callbacks
.FieldAccess
!= NULL
)
2300 ARG (JNIEnv
*, jni_env
);
2301 ARG (jmethodID
, method
);
2302 ARG (jlocation
, location
);
2303 ARG (jclass
, field_class
);
2304 ARG (jobject
, object
);
2305 ARG (jfieldID
, field
);
2306 env
->callbacks
.FieldAccess (env
, jni_env
, event_thread
, method
,
2307 location
, field_class
, object
, field
);
2311 case JVMTI_EVENT_FIELD_MODIFICATION
:
2312 if (env
->callbacks
.FieldModification
!= NULL
)
2314 ARG (JNIEnv
*, jni_env
);
2315 ARG (jmethodID
, method
);
2316 ARG (jlocation
, location
);
2317 ARG (jclass
, field_class
);
2318 ARG (jobject
, object
);
2319 ARG (jfieldID
, field
);
2320 GET_CHAR_ARG (signature_type
);
2321 ARG (jvalue
, new_value
);
2322 env
->callbacks
.FieldModification (env
, jni_env
, event_thread
, method
,
2323 location
, field_class
, object
,
2324 field
, signature_type
, new_value
);
2328 case JVMTI_EVENT_METHOD_ENTRY
:
2329 if (env
->callbacks
.MethodEntry
!= NULL
)
2331 ARG (JNIEnv
*, jni_env
);
2332 ARG (jmethodID
, method
);
2333 env
->callbacks
.MethodEntry (env
, jni_env
, event_thread
, method
);
2337 case JVMTI_EVENT_METHOD_EXIT
:
2338 if (env
->callbacks
.MethodExit
!= NULL
)
2340 ARG (JNIEnv
*, jni_env
);
2341 ARG (jmethodID
, method
);
2342 GET_BOOLEAN_ARG (was_popped_by_exception
);
2343 ARG (jvalue
, return_value
);
2344 env
->callbacks
.MethodExit (env
, jni_env
, event_thread
, method
,
2345 was_popped_by_exception
, return_value
);
2349 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
2350 if (env
->callbacks
.NativeMethodBind
!= NULL
)
2352 ARG (JNIEnv
*, jni_env
);
2353 ARG (jmethodID
, method
);
2354 ARG (void *, address
);
2355 ARG (void **, new_address_ptr
);
2356 env
->callbacks
.NativeMethodBind (env
, jni_env
, event_thread
, method
,
2357 address
, new_address_ptr
);
2361 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
2362 if (env
->callbacks
.CompiledMethodLoad
!= NULL
)
2364 ARG (jmethodID
, method
);
2365 ARG (jint
, code_size
);
2366 ARG (const void *, code_addr
);
2367 ARG (jint
, map_length
);
2368 ARG (const jvmtiAddrLocationMap
*, map
);
2369 ARG (const void *, compile_info
);
2370 env
->callbacks
.CompiledMethodLoad (env
, method
, code_size
, code_addr
,
2371 map_length
, map
, compile_info
);
2375 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
2376 if (env
->callbacks
.CompiledMethodUnload
!= NULL
)
2378 ARG (jmethodID
, method
);
2379 ARG (const void *, code_addr
);
2380 env
->callbacks
.CompiledMethodUnload (env
, method
, code_addr
);
2384 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
2385 if (env
->callbacks
.DynamicCodeGenerated
!= NULL
)
2387 ARG (const char *, name
);
2388 ARG (const void *, address
);
2390 env
->callbacks
.DynamicCodeGenerated (env
, name
, address
, length
);
2394 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
2395 if (env
->callbacks
.DataDumpRequest
!= NULL
)
2397 env
->callbacks
.DataDumpRequest (env
);
2401 case JVMTI_EVENT_MONITOR_WAIT
:
2402 if (env
->callbacks
.MonitorWait
!= NULL
)
2404 ARG (JNIEnv
*, jni_env
);
2405 ARG (jobject
, object
);
2406 ARG (jlong
, timeout
);
2407 env
->callbacks
.MonitorWait (env
, jni_env
, event_thread
, object
,
2412 case JVMTI_EVENT_MONITOR_WAITED
:
2413 if (env
->callbacks
.MonitorWaited
!= NULL
)
2415 ARG (JNIEnv
*, jni_env
);
2416 ARG (jobject
, object
);
2417 GET_BOOLEAN_ARG (timed_out
);
2418 env
->callbacks
.MonitorWaited (env
, jni_env
, event_thread
, object
,
2423 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
2424 if (env
->callbacks
.MonitorContendedEnter
!= NULL
)
2426 ARG (JNIEnv
*, jni_env
);
2427 ARG (jobject
, object
);
2428 env
->callbacks
.MonitorContendedEnter (env
, jni_env
, event_thread
,
2433 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
2434 if (env
->callbacks
.MonitorContendedEntered
!= NULL
)
2436 ARG (JNIEnv
*, jni_env
);
2437 ARG (jobject
, object
);
2438 env
->callbacks
.MonitorContendedEntered (env
, jni_env
, event_thread
,
2443 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
2444 if (env
->callbacks
.GarbageCollectionStart
!= NULL
)
2446 env
->callbacks
.GarbageCollectionStart (env
);
2450 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
2451 if (env
->callbacks
.GarbageCollectionFinish
!= NULL
)
2453 env
->callbacks
.GarbageCollectionFinish (env
);
2457 case JVMTI_EVENT_OBJECT_FREE
:
2458 if (env
->callbacks
.ObjectFree
!= NULL
)
2461 env
->callbacks
.ObjectFree (env
, tag
);
2465 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
2466 if (env
->callbacks
.VMObjectAlloc
!= NULL
)
2468 ARG (JNIEnv
*, jni_env
);
2469 ARG (jobject
, object
);
2470 ARG (jclass
, object_class
);
2472 env
->callbacks
.VMObjectAlloc (env
, jni_env
, event_thread
,
2473 object
, object_class
, size
);
2478 fprintf (stderr
, "libgcj: post of unknown JVMTI event (%d)\n",
2484 #undef GET_BOOLEAN_ARG
2488 /* Post an event to requesting JVMTI environments
2490 * This function should not be called without consulting the
2491 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2492 * harm (other than kill speed), since this function will still
2493 * only send the event if it was properly requested by an environment.
2496 _Jv_JVMTI_PostEvent (jvmtiEvent type
, jthread event_thread
, ...)
2499 va_start (args
, event_thread
);
2501 _envListLock
->readLock ()->lock ();
2502 struct jvmti_env_list
*e
;
2503 FOREACH_ENVIRONMENT (e
)
2505 /* Events are only posted if the event was explicitly enabled,
2506 it has a registered event handler, and the event thread
2507 matches (either globally or restricted to a specific thread).
2508 Here we check all but the event handler, which will be handled
2510 if (e
->env
->enabled
[EVENT_INDEX(type
)]
2511 && (e
->env
->thread
[EVENT_INDEX(type
)] == NULL
2512 || e
->env
->thread
[EVENT_INDEX(type
)] == event_thread
))
2514 post_event (e
->env
, type
, event_thread
, args
);
2517 _envListLock
->readLock ()->unlock ();