1 // jvmti.cc - JVMTI implementation
3 /* Copyright (C) 2006, 2007, 2010 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/Thread$State.h>
34 #include <java/lang/Throwable.h>
35 #include <java/lang/VMClassLoader.h>
36 #include <java/lang/reflect/Field.h>
37 #include <java/lang/reflect/Modifier.h>
38 #include <java/util/Collection.h>
39 #include <java/util/HashMap.h>
40 #include <java/util/concurrent/locks/Lock.h>
41 #include <java/util/concurrent/locks/ReentrantReadWriteLock.h>
42 #include <java/net/URL.h>
44 static void check_enabled_events (void);
45 static void check_enabled_event (jvmtiEvent
);
49 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
52 // Event notifications
55 bool ThreadStart
= false;
56 bool ThreadEnd
= false;
57 bool ClassFileLoadHook
= false;
58 bool ClassLoad
= false;
59 bool ClassPrepare
= false;
61 bool Exception
= false;
62 bool ExceptionCatch
= false;
63 bool SingleStep
= false;
64 bool FramePop
= false;
65 bool Breakpoint
= false;
66 bool FieldAccess
= false;
67 bool FieldModification
= false;
68 bool MethodEntry
= false;
69 bool MethodExit
= false;
70 bool NativeMethodBind
= false;
71 bool CompiledMethodLoad
= false;
72 bool CompiledMethodUnload
= false;
73 bool DynamicCodeGenerated
= false;
74 bool DataDumpRequest
= false;
75 bool reserved72
= false;
76 bool MonitorWait
= false;
77 bool MonitorWaited
= false;
78 bool MonitorContendedEnter
= false;
79 bool MonitorContendedEntered
= false;
80 bool reserved77
= false;
81 bool reserved78
= false;
82 bool reserved79
= false;
83 bool reserved80
= false;
84 bool GarbageCollectionStart
= false;
85 bool GarbageCollectionFinish
= false;
86 bool ObjectFree
= false;
87 bool VMObjectAlloc
= false;
90 extern struct JNINativeInterface _Jv_JNIFunctions
;
92 struct _Jv_rawMonitorID
95 _Jv_ConditionVariable_t condition
;
98 /* A simple linked list of all JVMTI environments. Since
99 events must be delivered to environments in the order
100 in which the environments were created, new environments
101 are added to the end of the list. */
102 struct jvmti_env_list
105 struct jvmti_env_list
*next
;
107 static struct jvmti_env_list
*_jvmtiEnvironments
= NULL
;
108 static java::util::concurrent::locks::
109 ReentrantReadWriteLock
*_envListLock
= NULL
;
110 #define FOREACH_ENVIRONMENT(Ele) \
111 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
113 // Some commonly-used checks
115 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
118 if (Ajthread == NULL) \
119 Ajthread = java::lang::Thread::currentThread (); \
123 #define THREAD_CHECK_VALID(Athread) \
126 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
127 return JVMTI_ERROR_INVALID_THREAD; \
131 #define THREAD_CHECK_IS_ALIVE(Athread) \
134 if (!Athread->isAlive ()) \
135 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
139 // FIXME: if current phase is not set in Phases,
140 // return JVMTI_ERROR_WRONG_PHASE
141 #define REQUIRE_PHASE(Env, Phases)
143 #define NULL_CHECK(Ptr) \
147 return JVMTI_ERROR_NULL_POINTER; \
151 #define ILLEGAL_ARGUMENT(Cond) \
155 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
159 #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
162 jboolean is_native; \
163 jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
164 if (jerr != JVMTI_ERROR_NONE) \
167 return JVMTI_ERROR_NATIVE_METHOD; \
171 static jvmtiError JNICALL
172 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
174 using namespace java::lang
;
176 THREAD_DEFAULT_TO_CURRENT (thread
);
177 THREAD_CHECK_VALID (thread
);
178 THREAD_CHECK_IS_ALIVE (thread
);
180 _Jv_Thread_t
*data
= _Jv_ThreadGetData (thread
);
181 _Jv_SuspendThread (data
);
182 return JVMTI_ERROR_NONE
;
185 static jvmtiError JNICALL
186 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
188 using namespace java::lang
;
190 THREAD_DEFAULT_TO_CURRENT (thread
);
191 THREAD_CHECK_VALID (thread
);
192 THREAD_CHECK_IS_ALIVE (thread
);
194 _Jv_Thread_t
*data
= _Jv_ThreadGetData (thread
);
195 _Jv_ResumeThread (data
);
196 return JVMTI_ERROR_NONE
;
199 static jvmtiError JNICALL
200 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
)
202 using namespace java::lang
;
204 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
205 // FIXME: capability handling? 'can_signal_thread'
207 return JVMTI_ERROR_INVALID_THREAD
;
209 THREAD_CHECK_VALID (thread
);
210 THREAD_CHECK_IS_ALIVE (thread
);
212 return JVMTI_ERROR_NONE
;
215 // This method performs the common tasks to get and set variables of all types.
216 // It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods.
218 getLocalFrame (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
, char type
,
219 _Jv_InterpFrame
**iframe
)
221 using namespace java::lang
;
223 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
225 ILLEGAL_ARGUMENT (depth
< 0);
227 THREAD_DEFAULT_TO_CURRENT (thread
);
228 THREAD_CHECK_VALID (thread
);
229 THREAD_CHECK_IS_ALIVE (thread
);
231 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
233 for (int i
= 0; i
< depth
; i
++)
238 return JVMTI_ERROR_NO_MORE_FRAMES
;
241 if (frame
->frame_type
== frame_native
)
242 return JVMTI_ERROR_OPAQUE_FRAME
;
245 jvmtiError jerr
= env
->GetMaxLocals (reinterpret_cast<jmethodID
>
246 (frame
->self
->get_method ()),
248 if (jerr
!= JVMTI_ERROR_NONE
)
251 _Jv_InterpFrame
*tmp_iframe
= reinterpret_cast<_Jv_InterpFrame
*> (frame
);
253 // The second slot taken up by a long type is marked as type 'x' meaning it
254 // is not valid for access since it holds only the 4 low bytes of the value.
255 if (tmp_iframe
->locals_type
[slot
] == 'x')
256 return JVMTI_ERROR_INVALID_SLOT
;
258 if (tmp_iframe
->locals_type
[slot
] != type
)
259 return JVMTI_ERROR_TYPE_MISMATCH
;
261 // Check for invalid slots, if the type is a long type, we must check that
262 // the next slot is valid as well.
263 if (slot
< 0 || slot
>= max_locals
264 || ((type
== 'l' || type
== 'd') && slot
+ 1 >= max_locals
))
265 return JVMTI_ERROR_INVALID_SLOT
;
267 *iframe
= tmp_iframe
;
269 return JVMTI_ERROR_NONE
;
272 static jvmtiError JNICALL
273 _Jv_JVMTI_GetLocalObject (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
278 _Jv_InterpFrame
*frame
;
279 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'o', &frame
);
281 if (jerr
!= JVMTI_ERROR_NONE
)
284 *value
= frame
->locals
[slot
].o
;
286 return JVMTI_ERROR_NONE
;
289 static jvmtiError JNICALL
290 _Jv_JVMTI_SetLocalObject (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
293 _Jv_InterpFrame
*frame
;
294 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'o', &frame
);
296 if (jerr
!= JVMTI_ERROR_NONE
)
299 frame
->locals
[slot
].o
= value
;
301 return JVMTI_ERROR_NONE
;
304 static jvmtiError JNICALL
305 _Jv_JVMTI_GetLocalInt (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
310 _Jv_InterpFrame
*frame
;
311 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'i', &frame
);
313 if (jerr
!= JVMTI_ERROR_NONE
)
316 *value
= frame
->locals
[slot
].i
;
318 return JVMTI_ERROR_NONE
;
321 static jvmtiError JNICALL
322 _Jv_JVMTI_SetLocalInt (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
325 _Jv_InterpFrame
*frame
;
326 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'i', &frame
);
328 if (jerr
!= JVMTI_ERROR_NONE
)
331 frame
->locals
[slot
].i
= value
;
333 return JVMTI_ERROR_NONE
;
336 static jvmtiError JNICALL
337 _Jv_JVMTI_GetLocalLong (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
342 _Jv_InterpFrame
*frame
;
343 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'l', &frame
);
345 if (jerr
!= JVMTI_ERROR_NONE
)
349 *value
= frame
->locals
[slot
].l
;
352 val
.ia
[0] = frame
->locals
[slot
].ia
[0];
353 val
.ia
[1] = frame
->locals
[slot
+ 1].ia
[0];
357 return JVMTI_ERROR_NONE
;
360 static jvmtiError JNICALL
361 _Jv_JVMTI_SetLocalLong (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
364 _Jv_InterpFrame
*frame
;
365 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'l', &frame
);
367 if (jerr
!= JVMTI_ERROR_NONE
)
371 frame
->locals
[slot
].l
= value
;
375 frame
->locals
[slot
].ia
[0] = val
.ia
[0];
376 frame
->locals
[slot
+ 1].ia
[0] = val
.ia
[1];
379 return JVMTI_ERROR_NONE
;
383 static jvmtiError JNICALL
384 _Jv_JVMTI_GetLocalFloat (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
389 _Jv_InterpFrame
*frame
;
390 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'f', &frame
);
392 if (jerr
!= JVMTI_ERROR_NONE
)
395 *value
= frame
->locals
[slot
].f
;
397 return JVMTI_ERROR_NONE
;
400 static jvmtiError JNICALL
401 _Jv_JVMTI_SetLocalFloat (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
404 _Jv_InterpFrame
*frame
;
405 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'f', &frame
);
407 if (jerr
!= JVMTI_ERROR_NONE
)
410 frame
->locals
[slot
].f
= value
;
412 return JVMTI_ERROR_NONE
;
416 static jvmtiError JNICALL
417 _Jv_JVMTI_GetLocalDouble (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
422 _Jv_InterpFrame
*frame
;
423 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'd', &frame
);
425 if (jerr
!= JVMTI_ERROR_NONE
)
429 *value
= frame
->locals
[slot
].d
;
432 val
.ia
[0] = frame
->locals
[slot
].ia
[0];
433 val
.ia
[1] = frame
->locals
[slot
+ 1].ia
[0];
437 return JVMTI_ERROR_NONE
;
440 static jvmtiError JNICALL
441 _Jv_JVMTI_SetLocalDouble (jvmtiEnv
*env
, jthread thread
, jint depth
, jint slot
,
444 _Jv_InterpFrame
*frame
;
445 jvmtiError jerr
= getLocalFrame (env
, thread
, depth
, slot
, 'd', &frame
);
447 if (jerr
!= JVMTI_ERROR_NONE
)
451 frame
->locals
[slot
].d
= value
;
455 frame
->locals
[slot
].ia
[0] = val
.ia
[0];
456 frame
->locals
[slot
+ 1].ia
[0] = val
.ia
[1];
459 return JVMTI_ERROR_NONE
;
462 static jvmtiError JNICALL
463 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv
*env
, jint
*thread_cnt
,
466 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
467 NULL_CHECK (thread_cnt
);
468 NULL_CHECK (threads
);
470 using namespace java::lang
;
472 ThreadGroup
*root_grp
= ThreadGroup::root
;
473 jint estimate
= root_grp
->activeCount ();
475 JArray
<Thread
*> *thr_arr
;
477 // Allocate some extra space since threads can be created between calls
480 thr_arr
= reinterpret_cast<JArray
<Thread
*> *> (JvNewObjectArray
482 &Thread::class$
, NULL
));
484 catch (java::lang::OutOfMemoryError
*err
)
486 return JVMTI_ERROR_OUT_OF_MEMORY
;
489 *thread_cnt
= root_grp
->enumerate (thr_arr
);
491 jvmtiError jerr
= env
->Allocate ((jlong
) ((*thread_cnt
) * sizeof (jthread
)),
492 (unsigned char **) threads
);
494 if (jerr
!= JVMTI_ERROR_NONE
)
497 // Transfer the threads to the result array
498 jthread
*tmp_arr
= reinterpret_cast<jthread
*> (elements (thr_arr
));
500 memcpy ((*threads
), tmp_arr
, (*thread_cnt
));
502 return JVMTI_ERROR_NONE
;
505 static jvmtiError JNICALL
506 _Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
509 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
511 NULL_CHECK (frame_count
);
513 using namespace java::lang
;
515 THREAD_DEFAULT_TO_CURRENT (thread
);
516 THREAD_CHECK_VALID (thread
);
517 THREAD_CHECK_IS_ALIVE (thread
);
519 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
520 (*frame_count
) = frame
->depth ();
521 return JVMTI_ERROR_NONE
;
524 static jvmtiError JNICALL
525 _Jv_JVMTI_GetThreadState (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
526 jint
*thread_state_ptr
)
528 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
530 THREAD_DEFAULT_TO_CURRENT (thread
);
531 THREAD_CHECK_VALID (thread
);
532 NULL_CHECK (thread_state_ptr
);
535 if (thread
->isAlive ())
537 state
|= JVMTI_THREAD_STATE_ALIVE
;
539 _Jv_Thread_t
*data
= _Jv_ThreadGetData (thread
);
540 if (_Jv_IsThreadSuspended (data
))
541 state
|= JVMTI_THREAD_STATE_SUSPENDED
;
543 if (thread
->isInterrupted ())
544 state
|= JVMTI_THREAD_STATE_INTERRUPTED
;
546 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
547 if (frame
!= NULL
&& frame
->frame_type
== frame_native
)
548 state
|= JVMTI_THREAD_STATE_IN_NATIVE
;
550 using namespace java::lang
;
551 Thread$State
*ts
= thread
->getState ();
552 if (ts
== Thread$
State::RUNNABLE
)
553 state
|= JVMTI_THREAD_STATE_RUNNABLE
;
554 else if (ts
== Thread$
State::BLOCKED
)
555 state
|= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
;
556 else if (ts
== Thread$
State::TIMED_WAITING
557 || ts
== Thread$
State::WAITING
)
559 state
|= JVMTI_THREAD_STATE_WAITING
;
560 state
|= ((ts
== Thread$
State::WAITING
)
561 ? JVMTI_THREAD_STATE_WAITING_INDEFINITELY
562 : JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
);
564 /* FIXME: We don't have a way to tell
565 the caller why the thread is suspended,
566 i.e., JVMTI_THREAD_STATE_SLEEPING,
567 JVMTI_THREAD_STATE_PARKED, and
568 JVMTI_THREAD_STATE_IN_OBJECT_WAIT
574 using namespace java::lang
;
575 Thread$State
*ts
= thread
->getState ();
576 if (ts
== Thread$
State::TERMINATED
)
577 state
|= JVMTI_THREAD_STATE_TERMINATED
;
580 *thread_state_ptr
= state
;
581 return JVMTI_ERROR_NONE
;
584 static jvmtiError JNICALL
585 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv
*env
, const char *name
,
586 jrawMonitorID
*result
)
588 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
591 *result
= (jrawMonitorID
) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID
));
593 return JVMTI_ERROR_OUT_OF_MEMORY
;
594 _Jv_MutexInit (&(*result
)->mutex
);
595 _Jv_CondInit (&(*result
)->condition
);
596 return JVMTI_ERROR_NONE
;
599 static jvmtiError JNICALL
600 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
602 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
603 // Note we have no better way of knowing whether this object is
604 // really a raw monitor.
606 return JVMTI_ERROR_INVALID_MONITOR
;
607 // FIXME: perform checks on monitor, release it if this thread owns
609 #ifdef _Jv_HaveMutexDestroy
610 _Jv_MutexDestroy (&monitor
->mutex
);
613 return JVMTI_ERROR_NONE
;
616 static jvmtiError JNICALL
617 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
620 return JVMTI_ERROR_INVALID_MONITOR
;
621 _Jv_MutexLock (&monitor
->mutex
);
622 return JVMTI_ERROR_NONE
;
625 static jvmtiError JNICALL
626 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
629 return JVMTI_ERROR_INVALID_MONITOR
;
630 if (_Jv_MutexUnlock (&monitor
->mutex
))
631 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
632 return JVMTI_ERROR_NONE
;
635 static jvmtiError JNICALL
636 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
,
640 return JVMTI_ERROR_INVALID_MONITOR
;
641 int r
= _Jv_CondWait (&monitor
->condition
, &monitor
->mutex
, millis
, 0);
642 if (r
== _JV_NOT_OWNER
)
643 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
644 if (r
== _JV_INTERRUPTED
)
645 return JVMTI_ERROR_INTERRUPT
;
646 return JVMTI_ERROR_NONE
;
649 static jvmtiError JNICALL
650 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv
*env
, jrawMonitorID monitor
)
653 return JVMTI_ERROR_INVALID_MONITOR
;
654 if (_Jv_CondNotify (&monitor
->condition
, &monitor
->mutex
) == _JV_NOT_OWNER
)
655 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
656 return JVMTI_ERROR_NONE
;
659 static jvmtiError JNICALL
660 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv
*env
,
661 jrawMonitorID monitor
)
664 return JVMTI_ERROR_INVALID_MONITOR
;
665 if (_Jv_CondNotifyAll (&monitor
->condition
, &monitor
->mutex
)
667 return JVMTI_ERROR_NOT_MONITOR_OWNER
;
668 return JVMTI_ERROR_NONE
;
671 static jvmtiError JNICALL
672 _Jv_JVMTI_SetBreakpoint (jvmtiEnv
*env
, jmethodID method
, jlocation location
)
674 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
676 using namespace gnu::gcj::jvmti
;
678 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong
> (method
),
683 jvmtiError err
= env
->GetMethodDeclaringClass (method
, &klass
);
684 if (err
!= JVMTI_ERROR_NONE
)
687 if (!_Jv_IsInterpretedClass (klass
))
688 return JVMTI_ERROR_INVALID_CLASS
;
690 _Jv_MethodBase
*base
= _Jv_FindInterpreterMethod (klass
, method
);
692 return JVMTI_ERROR_INVALID_METHODID
;
695 err
= env
->GetMethodModifiers (method
, &flags
);
696 if (err
!= JVMTI_ERROR_NONE
)
699 if (flags
& java::lang::reflect::Modifier::NATIVE
)
700 return JVMTI_ERROR_NATIVE_METHOD
;
702 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*> (base
);
703 if (imeth
->get_insn (location
) == NULL
)
704 return JVMTI_ERROR_INVALID_LOCATION
;
706 // Now the breakpoint can be safely installed
707 bp
= BreakpointManager::newBreakpoint (reinterpret_cast<jlong
> (method
),
712 // Duplicate breakpoints are not permitted by JVMTI
713 return JVMTI_ERROR_DUPLICATE
;
716 return JVMTI_ERROR_NONE
;
719 static jvmtiError JNICALL
720 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
723 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
725 using namespace gnu::gcj::jvmti
;
728 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong
> (method
),
731 return JVMTI_ERROR_NOT_FOUND
;
733 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong
> (method
), location
);
734 return JVMTI_ERROR_NONE
;
737 static jvmtiError JNICALL
738 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv
*env
, jlong size
,
739 unsigned char **result
)
741 ILLEGAL_ARGUMENT (size
< 0);
747 *result
= (unsigned char *) _Jv_MallocUnchecked (size
);
749 return JVMTI_ERROR_OUT_OF_MEMORY
;
751 return JVMTI_ERROR_NONE
;
754 static jvmtiError JNICALL
755 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv
*env
, unsigned char *mem
)
759 return JVMTI_ERROR_NONE
;
762 static jvmtiError JNICALL
763 _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
766 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
767 NULL_CHECK (status_ptr
);
769 return JVMTI_ERROR_INVALID_CLASS
;
771 if (klass
->isArray ())
772 *status_ptr
= JVMTI_CLASS_STATUS_ARRAY
;
773 else if (klass
->isPrimitive ())
774 *status_ptr
= JVMTI_CLASS_STATUS_PRIMITIVE
;
777 jbyte state
= _Jv_GetClassState (klass
);
779 if (state
>= JV_STATE_LINKED
)
780 (*status_ptr
) |= JVMTI_CLASS_STATUS_VERIFIED
;
781 if (state
>= JV_STATE_PREPARED
)
782 (*status_ptr
) |= JVMTI_CLASS_STATUS_PREPARED
;
783 if (state
== JV_STATE_ERROR
|| state
== JV_STATE_PHANTOM
)
784 (*status_ptr
) |= JVMTI_CLASS_STATUS_ERROR
;
785 else if (state
== JV_STATE_DONE
)
786 (*status_ptr
) |= JVMTI_CLASS_STATUS_INITIALIZED
;
789 return JVMTI_ERROR_NONE
;
792 static jvmtiError JNICALL
793 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
796 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
797 // Don't bother checking KLASS' type.
799 return JVMTI_ERROR_INVALID_CLASS
;
801 *mods
= klass
->getModifiers();
802 return JVMTI_ERROR_NONE
;
805 static jvmtiError JNICALL
806 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
807 jint
*count_ptr
, jmethodID
**methods_ptr
)
809 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
810 // FIXME: capability can_maintain_original_method_order
811 // Don't bother checking KLASS' type.
813 return JVMTI_ERROR_INVALID_CLASS
;
814 NULL_CHECK (count_ptr
);
815 NULL_CHECK (methods_ptr
);
816 *count_ptr
= JvNumMethods(klass
);
819 = (jmethodID
*) _Jv_MallocUnchecked (*count_ptr
* sizeof (jmethodID
));
820 if (*methods_ptr
== NULL
)
821 return JVMTI_ERROR_OUT_OF_MEMORY
;
823 jmethodID start
= JvGetFirstMethod (klass
);
824 for (jint i
= 0; i
< *count_ptr
; ++i
)
826 (*methods_ptr
)[i
] = start
+ i
;
828 return JVMTI_ERROR_NONE
;
831 static jvmtiError JNICALL
832 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
835 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
837 return JVMTI_ERROR_INVALID_CLASS
;
839 *result
= klass
->isInterface();
840 return JVMTI_ERROR_NONE
;
843 static jvmtiError JNICALL
844 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
847 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
849 return JVMTI_ERROR_INVALID_CLASS
;
851 *result
= klass
->isArray();
852 return JVMTI_ERROR_NONE
;
855 static jvmtiError JNICALL
856 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
859 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
861 return JVMTI_ERROR_INVALID_CLASS
;
863 *result
= klass
->getClassLoaderInternal();
864 return JVMTI_ERROR_NONE
;
867 static jvmtiError JNICALL
868 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv
*env
, jobject obj
,
871 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
873 return JVMTI_ERROR_INVALID_OBJECT
;
875 *result
= _Jv_HashCode (obj
);
876 return JVMTI_ERROR_NONE
;
879 static jvmtiError JNICALL
880 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
881 jfieldID field
, jint
*result
)
883 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
885 return JVMTI_ERROR_INVALID_CLASS
;
887 return JVMTI_ERROR_INVALID_FIELDID
;
889 *result
= field
->getModifiers();
890 return JVMTI_ERROR_NONE
;
893 static jvmtiError JNICALL
894 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv
*env
, jclass klass
,
895 jfieldID field
, jboolean
*result
)
897 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
899 return JVMTI_ERROR_INVALID_CLASS
;
901 return JVMTI_ERROR_INVALID_FIELDID
;
904 // FIXME: capability can_get_synthetic_attribute
905 *result
= ((field
->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC
)
907 return JVMTI_ERROR_NONE
;
910 static jvmtiError JNICALL
911 _Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
912 char **name_ptr
, char **signature_ptr
,
915 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
918 return JVMTI_ERROR_INVALID_METHODID
;
920 if (name_ptr
!= NULL
)
922 int len
= static_cast<int> (method
->name
->len ());
923 *name_ptr
= (char *) _Jv_MallocUnchecked (len
+ 1);
924 if (*name_ptr
== NULL
)
925 return JVMTI_ERROR_OUT_OF_MEMORY
;
926 strncpy (*name_ptr
, method
->name
->chars (), len
);
927 (*name_ptr
)[len
] = '\0';
930 if (signature_ptr
!= NULL
)
932 int len
= static_cast<int> (method
->signature
->len ());
933 *signature_ptr
= (char *) _Jv_MallocUnchecked (len
+ 1);
934 if (*signature_ptr
== NULL
)
936 if (name_ptr
!= NULL
)
937 _Jv_Free (*name_ptr
);
938 return JVMTI_ERROR_OUT_OF_MEMORY
;
940 strncpy (*signature_ptr
, method
->signature
->chars (), len
);
941 (*signature_ptr
)[len
] = '\0';
944 if (generic_ptr
!= NULL
)
949 return JVMTI_ERROR_NONE
;
952 static jvmtiError JNICALL
953 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
956 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
958 return JVMTI_ERROR_INVALID_METHODID
;
961 // FIXME: mask off some internal bits...
962 *result
= method
->accflags
;
963 return JVMTI_ERROR_NONE
;
966 static jvmtiError JNICALL
967 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv
*env
, jmethodID method
,
968 jint
*entry_count_ptr
,
969 jvmtiLineNumberEntry
**table_ptr
)
971 NULL_CHECK (entry_count_ptr
);
972 NULL_CHECK (table_ptr
);
975 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
976 if (jerr
!= JVMTI_ERROR_NONE
)
979 _Jv_MethodBase
*base
= _Jv_FindInterpreterMethod (klass
, method
);
981 return JVMTI_ERROR_INVALID_METHODID
;
983 if (java::lang::reflect::Modifier::isNative (method
->accflags
)
984 || !_Jv_IsInterpretedClass (klass
))
985 return JVMTI_ERROR_NATIVE_METHOD
;
987 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*> (base
);
989 jintArray lines
= NULL
;
990 jlongArray indices
= NULL
;
991 imeth
->get_line_table (start
, end
, lines
, indices
);
993 return JVMTI_ERROR_ABSENT_INFORMATION
;
995 jvmtiLineNumberEntry
*table
;
996 jsize len
= lines
->length
* sizeof (jvmtiLineNumberEntry
);
997 table
= (jvmtiLineNumberEntry
*) _Jv_MallocUnchecked (len
);
999 return JVMTI_ERROR_OUT_OF_MEMORY
;
1001 jint
*line
= elements (lines
);
1002 jlong
*index
= elements (indices
);
1003 for (int i
= 0; i
< lines
->length
; ++i
)
1005 table
[i
].start_location
= index
[i
];
1006 table
[i
].line_number
= line
[i
];
1010 *entry_count_ptr
= lines
->length
;
1011 return JVMTI_ERROR_NONE
;
1014 static jvmtiError JNICALL
1015 _Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
1017 jvmtiLocalVariableEntry
**locals
)
1019 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1020 NULL_CHECK (num_locals
);
1021 NULL_CHECK (locals
);
1023 CHECK_FOR_NATIVE_METHOD(method
);
1026 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
1027 if (jerr
!= JVMTI_ERROR_NONE
)
1030 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*>
1031 (_Jv_FindInterpreterMethod (klass
, method
));
1034 return JVMTI_ERROR_INVALID_METHODID
;
1036 jerr
= env
->GetMaxLocals (method
, num_locals
);
1037 if (jerr
!= JVMTI_ERROR_NONE
)
1040 jerr
= env
->Allocate (static_cast<jlong
>
1041 ((*num_locals
) * sizeof (jvmtiLocalVariableEntry
)),
1042 reinterpret_cast<unsigned char **> (locals
));
1044 if (jerr
!= JVMTI_ERROR_NONE
)
1047 //the slot in the methods local_var_table to get
1053 while (table_slot
< *num_locals
1054 && imeth
->get_local_var_table (&name
, &sig
, &generic_sig
,
1055 &((((*locals
)[table_slot
].start_location
))),
1056 &((*locals
)[table_slot
].length
),
1057 &((*locals
)[table_slot
].slot
),
1061 char **str_ptr
= &(*locals
)[table_slot
].name
;
1062 jerr
= env
->Allocate (static_cast<jlong
> (strlen (name
) + 1),
1063 reinterpret_cast<unsigned char **> (str_ptr
));
1064 if (jerr
!= JVMTI_ERROR_NONE
)
1066 strcpy ((*locals
)[table_slot
].name
, name
);
1068 str_ptr
= &(*locals
)[table_slot
].signature
;
1069 jerr
= env
->Allocate (static_cast<jlong
> (strlen (sig
) + 1),
1070 reinterpret_cast<unsigned char **> (str_ptr
));
1071 if (jerr
!= JVMTI_ERROR_NONE
)
1073 strcpy ((*locals
)[table_slot
].signature
, sig
);
1075 str_ptr
= &(*locals
)[table_slot
].generic_signature
;
1076 jerr
= env
->Allocate (static_cast<jlong
> (strlen (generic_sig
) + 1),
1077 reinterpret_cast<unsigned char **> (str_ptr
));
1078 if (jerr
!= JVMTI_ERROR_NONE
)
1080 strcpy ((*locals
)[table_slot
].generic_signature
, generic_sig
);
1085 if (table_slot
== 0)
1086 return JVMTI_ERROR_ABSENT_INFORMATION
;
1088 // If there are double or long variables in the table, the the table will be
1089 // smaller than the max number of slots, so correct for this here.
1090 if ((table_slot
) < *num_locals
)
1091 *num_locals
= table_slot
;
1093 return JVMTI_ERROR_NONE
;
1096 static jvmtiError JNICALL
1097 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
1100 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1102 return JVMTI_ERROR_INVALID_METHODID
;
1103 NULL_CHECK (result
);
1105 *result
= ((method
->accflags
& java::lang::reflect::Modifier::NATIVE
) != 0);
1106 return JVMTI_ERROR_NONE
;
1109 static jvmtiError JNICALL
1110 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv
*env
, jmethodID method
,
1113 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1115 return JVMTI_ERROR_INVALID_METHODID
;
1116 NULL_CHECK (result
);
1118 // FIXME capability can_get_synthetic_attribute
1120 *result
= ((method
->accflags
& java::lang::reflect::Modifier::SYNTHETIC
)
1122 return JVMTI_ERROR_NONE
;
1125 static jvmtiError JNICALL
1126 _Jv_JVMTI_GetMaxLocals (jvmtiEnv
*env
, jmethodID method
, jint
*max_locals
)
1128 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1129 NULL_CHECK (max_locals
);
1131 CHECK_FOR_NATIVE_METHOD (method
);
1134 jvmtiError jerr
= env
->GetMethodDeclaringClass (method
, &klass
);
1135 if (jerr
!= JVMTI_ERROR_NONE
)
1138 _Jv_InterpMethod
*imeth
= reinterpret_cast<_Jv_InterpMethod
*>
1139 (_Jv_FindInterpreterMethod (klass
, method
));
1142 return JVMTI_ERROR_INVALID_METHODID
;
1144 *max_locals
= imeth
->get_max_locals ();
1146 return JVMTI_ERROR_NONE
;
1149 static jvmtiError JNICALL
1150 _Jv_JVMTI_GetArgumentsSize (jvmtiEnv
*env
, jmethodID method
, jint
*size
)
1152 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1155 CHECK_FOR_NATIVE_METHOD (method
);
1161 jerr
= env
->GetMethodName (method
, NULL
, &sig
, NULL
);
1162 if (jerr
!= JVMTI_ERROR_NONE
)
1165 // If the method is non-static add a slot for the "this" pointer.
1166 if ((method
->accflags
& java::lang::reflect::Modifier::STATIC
) == 0)
1169 for (int i
= 0; sig
[i
] != ')'; i
++)
1171 if (sig
[i
] == 'Z' || sig
[i
] == 'B' || sig
[i
] == 'C' || sig
[i
] == 'S'
1172 || sig
[i
] == 'I' || sig
[i
] == 'F')
1174 else if (sig
[i
] == 'J' || sig
[i
] == 'D')
1176 // If this is an array of wide types it uses a single slot
1177 if (i
> 0 && sig
[i
- 1] == '[')
1182 else if (sig
[i
] == 'L')
1185 while (sig
[i
] != ';')
1191 return JVMTI_ERROR_NONE
;
1194 static jvmtiError JNICALL
1195 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv
*env
,
1197 jclass
*declaring_class_ptr
)
1199 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1200 NULL_CHECK (declaring_class_ptr
);
1202 jclass klass
= _Jv_GetMethodDeclaringClass (method
);
1205 *declaring_class_ptr
= klass
;
1206 return JVMTI_ERROR_NONE
;
1209 return JVMTI_ERROR_INVALID_METHODID
;
1212 static jvmtiError JNICALL
1213 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv
*env
,
1214 jobject init_loader
,
1216 jclass
**result_ptr
)
1218 using namespace java::lang
;
1219 using namespace java::util
;
1221 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1222 NULL_CHECK (count_ptr
);
1223 NULL_CHECK (result_ptr
);
1225 ClassLoader
*loader
= (ClassLoader
*) init_loader
;
1227 loader
= VMClassLoader::bootLoader
;
1229 Collection
*values
= loader
->loadedClasses
->values();
1230 jobjectArray array
= values
->toArray();
1231 *count_ptr
= array
->length
;
1232 jobject
*elts
= elements (array
);
1234 = (jclass
*) _Jv_MallocUnchecked (*count_ptr
* sizeof (jclass
));
1236 return JVMTI_ERROR_OUT_OF_MEMORY
;
1238 // FIXME: JNI references...
1239 memcpy (result
, elts
, *count_ptr
* sizeof (jclass
));
1241 *result_ptr
= result
;
1243 return JVMTI_ERROR_NONE
;
1246 static jvmtiError JNICALL
1247 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
1248 jint start_depth
, jint max_frames
,
1249 jvmtiFrameInfo
*frames
, jint
*frame_count
)
1251 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1253 ILLEGAL_ARGUMENT (max_frames
< 0);
1255 NULL_CHECK (frames
);
1256 NULL_CHECK (frame_count
);
1258 using namespace java::lang
;
1260 THREAD_DEFAULT_TO_CURRENT (thread
);
1261 THREAD_CHECK_VALID (thread
);
1262 THREAD_CHECK_IS_ALIVE (thread
);
1264 jvmtiError jerr
= env
->GetFrameCount (thread
, frame_count
);
1265 if (jerr
!= JVMTI_ERROR_NONE
)
1268 // start_depth can be either a positive number, indicating the depth of the
1269 // stack at which to begin the trace, or a negative number indicating the
1270 // number of frames at the bottom of the stack to exclude. These checks
1271 // ensure that it is a valid value in either case
1273 ILLEGAL_ARGUMENT (start_depth
>= (*frame_count
));
1274 ILLEGAL_ARGUMENT (start_depth
< (-(*frame_count
)));
1276 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
1278 // If start_depth is negative use this to determine at what depth to start
1279 // the trace by adding it to the length of the call stack. This allows the
1280 // use of the same frame "discarding" mechanism as for a positive start_depth
1281 if (start_depth
< 0)
1282 start_depth
= *frame_count
+ start_depth
;
1284 // If start_depth > 0 "remove" start_depth frames from the beginning
1285 // of the stack before beginning the trace by moving along the frame list.
1286 while (start_depth
> 0)
1288 frame
= frame
->next
;
1293 // Now check to see if the array supplied by the agent is large enough to
1294 // hold frame_count frames, after adjustment for start_depth.
1295 if ((*frame_count
) > max_frames
)
1296 (*frame_count
) = max_frames
;
1298 for (int i
= 0; i
< (*frame_count
); i
++)
1300 frames
[i
].method
= frame
->self
->get_method ();
1302 // Set the location in the frame, native frames have location = -1
1303 if (frame
->frame_type
== frame_interpreter
)
1305 _Jv_InterpMethod
*imeth
1306 = static_cast<_Jv_InterpMethod
*> (frame
->self
);
1307 _Jv_InterpFrame
*interp_frame
1308 = static_cast<_Jv_InterpFrame
*> (frame
);
1309 frames
[i
].location
= imeth
->insn_index (interp_frame
->get_pc ());
1312 frames
[i
].location
= -1;
1314 frame
= frame
->next
;
1317 return JVMTI_ERROR_NONE
;
1320 static jvmtiError JNICALL
1321 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv
*env
)
1323 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1325 return JVMTI_ERROR_NONE
;
1328 static jvmtiError JNICALL
1329 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1330 const jniNativeInterface
*function_table
)
1332 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1333 NULL_CHECK (function_table
);
1334 memcpy (&_Jv_JNIFunctions
, function_table
, sizeof (jniNativeInterface
));
1335 return JVMTI_ERROR_NONE
;
1338 static jvmtiError JNICALL
1339 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1340 jniNativeInterface
**function_table
)
1342 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1343 NULL_CHECK (function_table
);
1345 = (jniNativeInterface
*) _Jv_MallocUnchecked (sizeof (jniNativeInterface
));
1346 if (*function_table
== NULL
)
1347 return JVMTI_ERROR_OUT_OF_MEMORY
;
1348 memcpy (*function_table
, &_Jv_JNIFunctions
, sizeof (jniNativeInterface
));
1349 return JVMTI_ERROR_NONE
;
1352 static jvmtiError JNICALL
1353 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv
*env
)
1357 if (_jvmtiEnvironments
== NULL
)
1358 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1361 _envListLock
->writeLock ()->lock ();
1362 if (_jvmtiEnvironments
->env
== env
)
1364 struct jvmti_env_list
*next
= _jvmtiEnvironments
->next
;
1365 _Jv_Free (_jvmtiEnvironments
);
1366 _jvmtiEnvironments
= next
;
1370 struct jvmti_env_list
*e
= _jvmtiEnvironments
;
1371 while (e
->next
!= NULL
&& e
->next
->env
!= env
)
1373 if (e
->next
== NULL
)
1375 _envListLock
->writeLock ()->unlock ();
1376 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1379 struct jvmti_env_list
*next
= e
->next
->next
;
1383 _envListLock
->writeLock ()->unlock ();
1388 check_enabled_events ();
1390 return JVMTI_ERROR_NONE
;
1393 static jvmtiError JNICALL
1394 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1397 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1398 NULL_CHECK (property
);
1399 NULL_CHECK (result
);
1401 jstring name
= JvNewStringUTF(property
);
1402 jstring result_str
= gnu::classpath::SystemProperties::getProperty(name
);
1404 if (result_str
== NULL
)
1405 return JVMTI_ERROR_NOT_AVAILABLE
;
1407 int len
= JvGetStringUTFLength (result_str
);
1408 *result
= (char *) _Jv_MallocUnchecked (len
+ 1);
1409 if (*result
== NULL
)
1410 return JVMTI_ERROR_OUT_OF_MEMORY
;
1411 JvGetStringUTFRegion (result_str
, 0, result_str
->length(), *result
);
1412 (*result
)[len
] = '\0';
1414 return JVMTI_ERROR_NONE
;
1417 static jvmtiError JNICALL
1418 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1421 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1423 NULL_CHECK (property
);
1426 // FIXME: When would a property not be writeable?
1427 return JVMTI_ERROR_NONE
;
1430 jstring prop_str
= JvNewStringUTF(property
);
1431 jstring value_str
= JvNewStringUTF(value
);
1432 gnu::classpath::SystemProperties::setProperty(prop_str
, value_str
);
1433 return JVMTI_ERROR_NONE
;
1436 static jvmtiError JNICALL
1437 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv
*env
, jlong
*nanos_ptr
)
1439 NULL_CHECK (nanos_ptr
);
1440 *nanos_ptr
= _Jv_platform_nanotime();
1441 return JVMTI_ERROR_NONE
;
1444 static jvmtiError JNICALL
1445 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv
*env
,
1446 jint
*nprocessors_ptr
)
1448 NULL_CHECK (nprocessors_ptr
);
1449 #ifdef _SC_NPROCESSORS_ONLN
1450 *nprocessors_ptr
= sysconf(_SC_NPROCESSORS_ONLN
);
1452 *nprocessors_ptr
= 1;
1454 return JVMTI_ERROR_NONE
;
1457 static jvmtiError JNICALL
1458 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv
*env
,
1459 const char *segment
)
1461 using namespace java::lang
;
1462 using namespace java::net
;
1463 using namespace gnu::gcj::runtime
;
1465 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1466 NULL_CHECK (segment
);
1468 jstring str_segment
= JvNewStringUTF(segment
);
1472 url
= new URL(JvNewStringUTF("file"), NULL
, str_segment
);
1474 catch (jthrowable ignore
)
1476 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1479 BootClassLoader
*loader
= VMClassLoader::bootLoader
;
1480 // Don't call this too early.
1481 // assert (loader != NULL);
1482 loader
->addURL(url
);
1483 return JVMTI_ERROR_NONE
;
1486 static jvmtiError JNICALL
1487 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiVerboseFlag flag
,
1492 case JVMTI_VERBOSE_OTHER
:
1493 case JVMTI_VERBOSE_GC
:
1494 case JVMTI_VERBOSE_JNI
:
1497 case JVMTI_VERBOSE_CLASS
:
1498 gcj::verbose_class_flag
= value
;
1501 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1503 return JVMTI_ERROR_NONE
;
1506 static jvmtiError JNICALL
1507 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv
*env
, jobject object
,
1510 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1512 return JVMTI_ERROR_INVALID_OBJECT
;
1513 NULL_CHECK (result
);
1515 jclass klass
= object
->getClass();
1516 if (klass
->isArray())
1518 jclass comp
= klass
->getComponentType();
1520 = (jint
) (_Jv_uintptr_t
) _Jv_GetArrayElementFromElementType(NULL
,
1521 klass
->getComponentType());
1522 // FIXME: correct for primitive types?
1523 jint compSize
= comp
->size();
1524 __JArray
*array
= (__JArray
*) object
;
1525 *result
= base
+ array
->length
* compSize
;
1529 // Note that if OBJECT is a String then it may (if
1530 // str->data==str) take more space. Do we care?
1531 *result
= klass
->size();
1533 return JVMTI_ERROR_NONE
;
1536 /* An event is enabled only if it has both an event handler
1537 and it is enabled in the environment. */
1539 check_enabled_event (jvmtiEvent type
)
1544 #define GET_OFFSET(Event) \
1547 enabled = &JVMTI::Event; \
1548 offset = offsetof (jvmtiEventCallbacks, Event); \
1554 case JVMTI_EVENT_VM_INIT
:
1555 GET_OFFSET (VMInit
);
1558 case JVMTI_EVENT_VM_DEATH
:
1559 GET_OFFSET (VMDeath
);
1562 case JVMTI_EVENT_THREAD_START
:
1563 GET_OFFSET (ThreadStart
);
1566 case JVMTI_EVENT_THREAD_END
:
1567 GET_OFFSET (ThreadEnd
);
1570 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1571 GET_OFFSET (ClassFileLoadHook
);
1574 case JVMTI_EVENT_CLASS_LOAD
:
1575 GET_OFFSET (ClassLoad
);
1578 case JVMTI_EVENT_CLASS_PREPARE
:
1579 GET_OFFSET (ClassPrepare
);
1582 case JVMTI_EVENT_VM_START
:
1583 GET_OFFSET (VMStart
);
1586 case JVMTI_EVENT_EXCEPTION
:
1587 GET_OFFSET (Exception
);
1590 case JVMTI_EVENT_EXCEPTION_CATCH
:
1591 GET_OFFSET (ExceptionCatch
);
1594 case JVMTI_EVENT_SINGLE_STEP
:
1595 GET_OFFSET (SingleStep
);
1598 case JVMTI_EVENT_FRAME_POP
:
1599 GET_OFFSET (FramePop
);
1602 case JVMTI_EVENT_BREAKPOINT
:
1603 GET_OFFSET (Breakpoint
);
1606 case JVMTI_EVENT_FIELD_ACCESS
:
1607 GET_OFFSET (FieldAccess
);
1610 case JVMTI_EVENT_FIELD_MODIFICATION
:
1611 GET_OFFSET (FieldModification
);
1614 case JVMTI_EVENT_METHOD_ENTRY
:
1615 GET_OFFSET (MethodEntry
);
1618 case JVMTI_EVENT_METHOD_EXIT
:
1619 GET_OFFSET (MethodExit
);
1622 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1623 GET_OFFSET (NativeMethodBind
);
1626 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1627 GET_OFFSET (CompiledMethodLoad
);
1630 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1631 GET_OFFSET (CompiledMethodUnload
);
1634 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1635 GET_OFFSET (DynamicCodeGenerated
);
1638 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1639 GET_OFFSET (DataDumpRequest
);
1642 case JVMTI_EVENT_MONITOR_WAIT
:
1643 GET_OFFSET (MonitorWait
);
1646 case JVMTI_EVENT_MONITOR_WAITED
:
1647 GET_OFFSET (MonitorWaited
);
1650 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1651 GET_OFFSET (MonitorContendedEnter
);
1654 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1655 GET_OFFSET (MonitorContendedEntered
);
1658 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1659 GET_OFFSET (GarbageCollectionStart
);
1662 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1663 GET_OFFSET (GarbageCollectionFinish
);
1666 case JVMTI_EVENT_OBJECT_FREE
:
1667 GET_OFFSET (ObjectFree
);
1670 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1671 GET_OFFSET (VMObjectAlloc
);
1676 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1682 int index
= EVENT_INDEX (type
); // safe since caller checks this
1684 if (_jvmtiEnvironments
!= NULL
)
1686 _envListLock
->readLock ()->lock ();
1687 struct jvmti_env_list
*e
;
1688 FOREACH_ENVIRONMENT (e
)
1691 = reinterpret_cast<char *> (&e
->env
->callbacks
) + offset
;
1692 void **callback
= reinterpret_cast<void **> (addr
);
1693 if (e
->env
->enabled
[index
] && *callback
!= NULL
)
1696 _envListLock
->readLock ()->unlock ();
1701 _envListLock
->readLock ()->unlock ();
1708 check_enabled_events ()
1710 check_enabled_event (JVMTI_EVENT_VM_INIT
);
1711 check_enabled_event (JVMTI_EVENT_VM_DEATH
);
1712 check_enabled_event (JVMTI_EVENT_THREAD_START
);
1713 check_enabled_event (JVMTI_EVENT_THREAD_END
);
1714 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
);
1715 check_enabled_event (JVMTI_EVENT_CLASS_LOAD
);
1716 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE
);
1717 check_enabled_event (JVMTI_EVENT_VM_START
);
1718 check_enabled_event (JVMTI_EVENT_EXCEPTION
);
1719 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH
);
1720 check_enabled_event (JVMTI_EVENT_SINGLE_STEP
);
1721 check_enabled_event (JVMTI_EVENT_FRAME_POP
);
1722 check_enabled_event (JVMTI_EVENT_BREAKPOINT
);
1723 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS
);
1724 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION
);
1725 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY
);
1726 check_enabled_event (JVMTI_EVENT_METHOD_EXIT
);
1727 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND
);
1728 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD
);
1729 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD
);
1730 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED
);
1731 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST
);
1732 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT
);
1733 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED
);
1734 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER
);
1735 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
);
1736 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START
);
1737 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
);
1738 check_enabled_event (JVMTI_EVENT_OBJECT_FREE
);
1739 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC
);
1742 static jvmtiError JNICALL
1743 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv
*env
, jvmtiEventMode mode
,
1744 jvmtiEvent type
, jthread event_thread
, ...)
1746 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1748 if (event_thread
!= NULL
)
1750 THREAD_CHECK_VALID (event_thread
);
1751 THREAD_CHECK_IS_ALIVE (event_thread
);
1765 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1770 case JVMTI_EVENT_VM_INIT
:
1771 case JVMTI_EVENT_VM_DEATH
:
1772 case JVMTI_EVENT_THREAD_START
:
1773 case JVMTI_EVENT_VM_START
:
1774 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1775 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1776 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1777 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1778 ILLEGAL_ARGUMENT (event_thread
!= NULL
);
1781 case JVMTI_EVENT_THREAD_END
:
1782 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1783 case JVMTI_EVENT_CLASS_LOAD
:
1784 case JVMTI_EVENT_CLASS_PREPARE
:
1785 case JVMTI_EVENT_EXCEPTION
:
1786 case JVMTI_EVENT_EXCEPTION_CATCH
:
1787 case JVMTI_EVENT_SINGLE_STEP
:
1788 case JVMTI_EVENT_FRAME_POP
:
1789 case JVMTI_EVENT_BREAKPOINT
:
1790 case JVMTI_EVENT_FIELD_ACCESS
:
1791 case JVMTI_EVENT_FIELD_MODIFICATION
:
1792 case JVMTI_EVENT_METHOD_ENTRY
:
1793 case JVMTI_EVENT_METHOD_EXIT
:
1794 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1795 case JVMTI_EVENT_MONITOR_WAIT
:
1796 case JVMTI_EVENT_MONITOR_WAITED
:
1797 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1798 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1799 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1800 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1801 case JVMTI_EVENT_OBJECT_FREE
:
1802 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1806 return JVMTI_ERROR_INVALID_EVENT_TYPE
;
1809 env
->thread
[EVENT_INDEX(type
)] = event_thread
;
1810 env
->enabled
[EVENT_INDEX(type
)] = enabled
;
1811 check_enabled_event (type
);
1812 return JVMTI_ERROR_NONE
;
1815 static jvmtiError JNICALL
1816 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv
*env
,
1817 const jvmtiEventCallbacks
*callbacks
,
1818 jint size_of_callbacks
)
1820 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1821 ILLEGAL_ARGUMENT (size_of_callbacks
< 0);
1823 // Copy the list of callbacks into the environment
1824 memcpy (&env
->callbacks
, callbacks
, sizeof (jvmtiEventCallbacks
));
1826 /* Check which events are now enabeld (JVMTI makes no requirements
1827 about the order in which SetEventCallbacks and SetEventNotifications
1828 are called. So we must check all events here. */
1829 check_enabled_events ();
1831 return JVMTI_ERROR_NONE
;
1834 static jvmtiError JNICALL
1835 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiError error
,
1838 NULL_CHECK (name_ptr
);
1843 case JVMTI_ERROR_NONE
:
1847 case JVMTI_ERROR_NULL_POINTER
:
1848 name
= "null pointer";
1851 case JVMTI_ERROR_OUT_OF_MEMORY
:
1852 name
= "out of memory";
1855 case JVMTI_ERROR_ACCESS_DENIED
:
1856 name
= "access denied";
1859 case JVMTI_ERROR_WRONG_PHASE
:
1860 name
= "wrong phase";
1863 case JVMTI_ERROR_INTERNAL
:
1864 name
= "internal error";
1867 case JVMTI_ERROR_UNATTACHED_THREAD
:
1868 name
= "unattached thread";
1871 case JVMTI_ERROR_INVALID_ENVIRONMENT
:
1872 name
= "invalid environment";
1875 case JVMTI_ERROR_INVALID_PRIORITY
:
1876 name
= "invalid priority";
1879 case JVMTI_ERROR_THREAD_NOT_SUSPENDED
:
1880 name
= "thread not suspended";
1883 case JVMTI_ERROR_THREAD_SUSPENDED
:
1884 name
= "thread suspended";
1887 case JVMTI_ERROR_THREAD_NOT_ALIVE
:
1888 name
= "thread not alive";
1891 case JVMTI_ERROR_CLASS_NOT_PREPARED
:
1892 name
= "class not prepared";
1895 case JVMTI_ERROR_NO_MORE_FRAMES
:
1896 name
= "no more frames";
1899 case JVMTI_ERROR_OPAQUE_FRAME
:
1900 name
= "opaque frame";
1903 case JVMTI_ERROR_DUPLICATE
:
1907 case JVMTI_ERROR_NOT_FOUND
:
1911 case JVMTI_ERROR_NOT_MONITOR_OWNER
:
1912 name
= "not monitor owner";
1915 case JVMTI_ERROR_INTERRUPT
:
1916 name
= "interrupted";
1919 case JVMTI_ERROR_UNMODIFIABLE_CLASS
:
1920 name
= "unmodifiable class";
1923 case JVMTI_ERROR_NOT_AVAILABLE
:
1924 name
= "not available";
1927 case JVMTI_ERROR_ABSENT_INFORMATION
:
1928 name
= "absent information";
1931 case JVMTI_ERROR_INVALID_EVENT_TYPE
:
1932 name
= "invalid event type";
1935 case JVMTI_ERROR_NATIVE_METHOD
:
1936 name
= "native method";
1939 case JVMTI_ERROR_INVALID_THREAD
:
1940 name
= "invalid thread";
1943 case JVMTI_ERROR_INVALID_THREAD_GROUP
:
1944 name
= "invalid thread group";
1947 case JVMTI_ERROR_INVALID_OBJECT
:
1948 name
= "invalid object";
1951 case JVMTI_ERROR_INVALID_CLASS
:
1952 name
= "invalid class";
1955 case JVMTI_ERROR_INVALID_METHODID
:
1956 name
= "invalid method ID";
1959 case JVMTI_ERROR_INVALID_LOCATION
:
1960 name
= "invalid location";
1963 case JVMTI_ERROR_INVALID_FIELDID
:
1964 name
= "invalid field ID";
1967 case JVMTI_ERROR_TYPE_MISMATCH
:
1968 name
= "type mismatch";
1971 case JVMTI_ERROR_INVALID_SLOT
:
1972 name
= "invalid slot";
1975 case JVMTI_ERROR_INVALID_MONITOR
:
1976 name
= "invalid monitor";
1979 case JVMTI_ERROR_INVALID_CLASS_FORMAT
:
1980 name
= "invalid class format";
1983 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION
:
1984 name
= "circular class definition";
1987 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED
:
1988 name
= "unsupported redefinition: method added";
1991 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED
:
1992 name
= "unsupported redefinition: schema changed";
1995 case JVMTI_ERROR_INVALID_TYPESTATE
:
1996 name
= "invalid type state";
1999 case JVMTI_ERROR_FAILS_VERIFICATION
:
2000 name
= "fails verification";
2003 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED
:
2004 name
= "unsupported redefinition: hierarchy changed";
2007 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED
:
2008 name
= "unsupported redefinition: method deleted";
2011 case JVMTI_ERROR_UNSUPPORTED_VERSION
:
2012 name
= "unsupported version";
2015 case JVMTI_ERROR_NAMES_DONT_MATCH
:
2016 name
= "names do not match";
2019 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED
:
2020 name
= "unsupported redefinition: class modifiers changed";
2023 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED
:
2024 name
= "unsupported redefinition: method modifiers changed";
2027 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY
:
2028 name
= "must possess capability";
2031 case JVMTI_ERROR_ILLEGAL_ARGUMENT
:
2032 name
= "illegal argument";
2036 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
2039 *name_ptr
= (char *) _Jv_MallocUnchecked (strlen (name
) + 1);
2040 if (*name_ptr
== NULL
)
2041 return JVMTI_ERROR_OUT_OF_MEMORY
;
2043 strcpy (*name_ptr
, name
);
2044 return JVMTI_ERROR_NONE
;
2047 #define RESERVED NULL
2048 #define UNIMPLEMENTED NULL
2050 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface
=
2052 RESERVED
, // reserved1
2053 _Jv_JVMTI_SetEventNotificationMode
, // SetEventNotificationMode
2054 RESERVED
, // reserved3
2055 _Jv_JVMTI_GetAllThreads
, // GetAllThreads
2056 _Jv_JVMTI_SuspendThread
, // SuspendThread
2057 _Jv_JVMTI_ResumeThread
, // ResumeThread
2058 UNIMPLEMENTED
, // StopThread
2059 _Jv_JVMTI_InterruptThread
, // InterruptThread
2060 UNIMPLEMENTED
, // GetThreadInfo
2061 UNIMPLEMENTED
, // GetOwnedMonitorInfo
2062 UNIMPLEMENTED
, // GetCurrentContendedMonitor
2063 UNIMPLEMENTED
, // RunAgentThread
2064 UNIMPLEMENTED
, // GetTopThreadGroups
2065 UNIMPLEMENTED
, // GetThreadGroupInfo
2066 UNIMPLEMENTED
, // GetThreadGroupChildren
2067 _Jv_JVMTI_GetFrameCount
, // GetFrameCount
2068 _Jv_JVMTI_GetThreadState
, // GetThreadState
2069 RESERVED
, // reserved18
2070 UNIMPLEMENTED
, // GetFrameLocation
2071 UNIMPLEMENTED
, // NotifyPopFrame
2072 _Jv_JVMTI_GetLocalObject
, // GetLocalObject
2073 _Jv_JVMTI_GetLocalInt
, // GetLocalInt
2074 _Jv_JVMTI_GetLocalLong
, // GetLocalLong
2075 _Jv_JVMTI_GetLocalFloat
, // GetLocalFloat
2076 _Jv_JVMTI_GetLocalDouble
, // GetLocalDouble
2077 _Jv_JVMTI_SetLocalObject
, // SetLocalObject
2078 _Jv_JVMTI_SetLocalInt
, // SetLocalInt
2079 _Jv_JVMTI_SetLocalLong
, // SetLocalLong
2080 _Jv_JVMTI_SetLocalFloat
, // SetLocalFloat
2081 _Jv_JVMTI_SetLocalDouble
, // SetLocalDouble
2082 _Jv_JVMTI_CreateRawMonitor
, // CreateRawMonitor
2083 _Jv_JVMTI_DestroyRawMonitor
, // DestroyRawMonitor
2084 _Jv_JVMTI_RawMonitorEnter
, // RawMonitorEnter
2085 _Jv_JVMTI_RawMonitorExit
, // RawMonitorExit
2086 _Jv_JVMTI_RawMonitorWait
, // RawMonitorWait
2087 _Jv_JVMTI_RawMonitorNotify
, // RawMonitorNotify
2088 _Jv_JVMTI_RawMonitorNotifyAll
, // RawMonitorNotifyAll
2089 _Jv_JVMTI_SetBreakpoint
, // SetBreakpoint
2090 _Jv_JVMTI_ClearBreakpoint
, // ClearBreakpoint
2091 RESERVED
, // reserved40
2092 UNIMPLEMENTED
, // SetFieldAccessWatch
2093 UNIMPLEMENTED
, // ClearFieldAccessWatch
2094 UNIMPLEMENTED
, // SetFieldModificationWatch
2095 UNIMPLEMENTED
, // ClearFieldModificationWatch
2096 RESERVED
, // reserved45
2097 _Jv_JVMTI_Allocate
, // Allocate
2098 _Jv_JVMTI_Deallocate
, // Deallocate
2099 UNIMPLEMENTED
, // GetClassSignature
2100 _Jv_JVMTI_GetClassStatus
, // GetClassStatus
2101 UNIMPLEMENTED
, // GetSourceFileName
2102 _Jv_JVMTI_GetClassModifiers
, // GetClassModifiers
2103 _Jv_JVMTI_GetClassMethods
, // GetClassMethods
2104 UNIMPLEMENTED
, // GetClassFields
2105 UNIMPLEMENTED
, // GetImplementedInterfaces
2106 _Jv_JVMTI_IsInterface
, // IsInterface
2107 _Jv_JVMTI_IsArrayClass
, // IsArrayClass
2108 _Jv_JVMTI_GetClassLoader
, // GetClassLoader
2109 _Jv_JVMTI_GetObjectHashCode
, // GetObjectHashCode
2110 UNIMPLEMENTED
, // GetObjectMonitorUsage
2111 UNIMPLEMENTED
, // GetFieldName
2112 UNIMPLEMENTED
, // GetFieldDeclaringClass
2113 _Jv_JVMTI_GetFieldModifiers
, // GetFieldModifiers
2114 _Jv_JVMTI_IsFieldSynthetic
, // IsFieldSynthetic
2115 _Jv_JVMTI_GetMethodName
, // GetMethodName
2116 _Jv_JVMTI_GetMethodDeclaringClass
, // GetMethodDeclaringClass
2117 _Jv_JVMTI_GetMethodModifiers
, // GetMethodModifers
2118 RESERVED
, // reserved67
2119 _Jv_JVMTI_GetMaxLocals
, // GetMaxLocals
2120 _Jv_JVMTI_GetArgumentsSize
, // GetArgumentsSize
2121 _Jv_JVMTI_GetLineNumberTable
, // GetLineNumberTable
2122 UNIMPLEMENTED
, // GetMethodLocation
2123 _Jv_JVMTI_GetLocalVariableTable
, // GetLocalVariableTable
2124 RESERVED
, // reserved73
2125 RESERVED
, // reserved74
2126 UNIMPLEMENTED
, // GetBytecodes
2127 _Jv_JVMTI_IsMethodNative
, // IsMethodNative
2128 _Jv_JVMTI_IsMethodSynthetic
, // IsMethodSynthetic
2129 UNIMPLEMENTED
, // GetLoadedClasses
2130 _Jv_JVMTI_GetClassLoaderClasses
, // GetClassLoaderClasses
2131 UNIMPLEMENTED
, // PopFrame
2132 RESERVED
, // reserved81
2133 RESERVED
, // reserved82
2134 RESERVED
, // reserved83
2135 RESERVED
, // reserved84
2136 RESERVED
, // reserved85
2137 RESERVED
, // reserved86
2138 UNIMPLEMENTED
, // RedefineClasses
2139 UNIMPLEMENTED
, // GetVersionNumber
2140 UNIMPLEMENTED
, // GetCapabilities
2141 UNIMPLEMENTED
, // GetSourceDebugExtension
2142 UNIMPLEMENTED
, // IsMethodObsolete
2143 UNIMPLEMENTED
, // SuspendThreadList
2144 UNIMPLEMENTED
, // ResumeThreadList
2145 RESERVED
, // reserved94
2146 RESERVED
, // reserved95
2147 RESERVED
, // reserved96
2148 RESERVED
, // reserved97
2149 RESERVED
, // reserved98
2150 RESERVED
, // reserved99
2151 UNIMPLEMENTED
, // GetAllStackTraces
2152 UNIMPLEMENTED
, // GetThreadListStackTraces
2153 UNIMPLEMENTED
, // GetThreadLocalStorage
2154 UNIMPLEMENTED
, // SetThreadLocalStorage
2155 _Jv_JVMTI_GetStackTrace
, // GetStackTrace
2156 RESERVED
, // reserved105
2157 UNIMPLEMENTED
, // GetTag
2158 UNIMPLEMENTED
, // SetTag
2159 _Jv_JVMTI_ForceGarbageCollection
, // ForceGarbageCollection
2160 UNIMPLEMENTED
, // IterateOverObjectsReachable
2161 UNIMPLEMENTED
, // IterateOverReachableObjects
2162 UNIMPLEMENTED
, // IterateOverHeap
2163 UNIMPLEMENTED
, // IterateOverInstanceOfClass
2164 RESERVED
, // reserved113
2165 UNIMPLEMENTED
, // GetObjectsWithTags
2166 RESERVED
, // reserved115
2167 RESERVED
, // reserved116
2168 RESERVED
, // reserved117
2169 RESERVED
, // reserved118
2170 RESERVED
, // reserved119
2171 _Jv_JVMTI_SetJNIFunctionTable
, // SetJNIFunctionTable
2172 _Jv_JVMTI_GetJNIFunctionTable
, // GetJNIFunctionTable
2173 _Jv_JVMTI_SetEventCallbacks
, // SetEventCallbacks
2174 UNIMPLEMENTED
, // GenerateEvents
2175 UNIMPLEMENTED
, // GetExtensionFunctions
2176 UNIMPLEMENTED
, // GetExtensionEvents
2177 UNIMPLEMENTED
, // SetExtensionEventCallback
2178 _Jv_JVMTI_DisposeEnvironment
, // DisposeEnvironment
2179 _Jv_JVMTI_GetErrorName
, // GetErrorName
2180 UNIMPLEMENTED
, // GetJLocationFormat
2181 UNIMPLEMENTED
, // GetSystemProperties
2182 _Jv_JVMTI_GetSystemProperty
, // GetSystemProperty
2183 _Jv_JVMTI_SetSystemProperty
, // SetSystemProperty
2184 UNIMPLEMENTED
, // GetPhase
2185 UNIMPLEMENTED
, // GetCurrentThreadCpuTimerInfo
2186 UNIMPLEMENTED
, // GetCurrentThreadCpuTime
2187 UNIMPLEMENTED
, // GetThreadCpuTimerInfo
2188 UNIMPLEMENTED
, // GetThreadCpuTime
2189 UNIMPLEMENTED
, // GetTimerInfo
2190 _Jv_JVMTI_GetTime
, // GetTime
2191 UNIMPLEMENTED
, // GetPotentialCapabilities
2192 RESERVED
, // reserved141
2193 UNIMPLEMENTED
, // AddCapabilities
2194 UNIMPLEMENTED
, // RelinquishCapabilities
2195 _Jv_JVMTI_GetAvailableProcessors
, // GetAvailableProcessors
2196 RESERVED
, // reserved145
2197 RESERVED
, // reserved146
2198 UNIMPLEMENTED
, // GetEnvironmentLocalStorage
2199 UNIMPLEMENTED
, // SetEnvironmentLocalStorage
2200 _Jv_JVMTI_AddToBootstrapClassLoaderSearch
, // AddToBootstrapClassLoaderSearch
2201 _Jv_JVMTI_SetVerboseFlag
, // SetVerboseFlag
2202 RESERVED
, // reserved151
2203 RESERVED
, // reserved152
2204 RESERVED
, // reserved153
2205 _Jv_JVMTI_GetObjectSize
// GetObjectSize
2209 _Jv_GetJVMTIEnv (void)
2212 = (_Jv_JVMTIEnv
*) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv
));
2213 memset (env
, 0, sizeof (_Jv_JVMTIEnv
));
2214 env
->p
= &_Jv_JVMTI_Interface
;
2215 struct jvmti_env_list
*element
2216 = (struct jvmti_env_list
*) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list
));
2218 element
->next
= NULL
;
2220 _envListLock
->writeLock ()->lock ();
2221 if (_jvmtiEnvironments
== NULL
)
2222 _jvmtiEnvironments
= element
;
2225 struct jvmti_env_list
*e
;
2226 for (e
= _jvmtiEnvironments
; e
->next
!= NULL
; e
= e
->next
)
2230 _envListLock
->writeLock ()->unlock ();
2232 /* Mark JVMTI active. This is used to force the interpreter
2233 to use either debugging or non-debugging code. Once JVMTI
2234 has been enabled, the non-debug interpreter cannot be used. */
2235 JVMTI::enabled
= true;
2242 _jvmtiEnvironments
= NULL
;
2244 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2246 // No environments, so this should set all JVMTI:: members to false
2247 check_enabled_events ();
2251 post_event (jvmtiEnv
*env
, jvmtiEvent type
, jthread event_thread
, va_list args
)
2253 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2255 #define GET_BOOLEAN_ARG(Name) \
2257 jboolean Name = (b == 0) ? false : true
2259 #define GET_CHAR_ARG(Name) \
2261 char Name = static_cast<char> (c)
2265 case JVMTI_EVENT_VM_INIT
:
2266 if (env
->callbacks
.VMInit
!= NULL
)
2268 ARG (JNIEnv
*, jni_env
);
2269 env
->callbacks
.VMInit (env
, jni_env
, event_thread
);
2273 case JVMTI_EVENT_VM_DEATH
:
2274 if (env
->callbacks
.VMDeath
!= NULL
)
2276 ARG (JNIEnv
*, jni_env
);
2277 env
->callbacks
.VMDeath (env
, jni_env
);
2281 case JVMTI_EVENT_THREAD_START
:
2282 if (env
->callbacks
.ThreadStart
!= NULL
)
2284 ARG (JNIEnv
*, jni_env
);
2285 env
->callbacks
.ThreadStart (env
, jni_env
, event_thread
);
2289 case JVMTI_EVENT_THREAD_END
:
2290 if (env
->callbacks
.ThreadEnd
!= NULL
)
2292 ARG (JNIEnv
*, jni_env
);
2293 env
->callbacks
.ThreadEnd (env
, jni_env
, event_thread
);
2297 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
2298 if (env
->callbacks
.ClassFileLoadHook
!= NULL
)
2300 ARG (JNIEnv
*, jni_env
);
2301 ARG (jclass
, class_being_redefined
);
2302 ARG (jobject
, loader
);
2303 ARG (const char *, name
);
2304 ARG (jobject
, protection_domain
);
2305 ARG (jint
, class_data_len
);
2306 ARG (const unsigned char *, class_data
);
2307 ARG (jint
*, new_class_data_len
);
2308 ARG (unsigned char **, new_class_data
);
2309 env
->callbacks
.ClassFileLoadHook (env
, jni_env
,
2310 class_being_redefined
, loader
,
2311 name
, protection_domain
,
2312 class_data_len
, class_data
,
2318 case JVMTI_EVENT_CLASS_LOAD
:
2319 if (env
->callbacks
.ClassLoad
!= NULL
)
2321 ARG (JNIEnv
*, jni_env
);
2322 ARG (jclass
, klass
);
2323 env
->callbacks
.ClassLoad (env
, jni_env
, event_thread
, klass
);
2327 case JVMTI_EVENT_CLASS_PREPARE
:
2328 if (env
->callbacks
.ClassPrepare
!= NULL
)
2330 ARG (JNIEnv
*, jni_env
);
2331 ARG (jclass
, klass
);
2332 env
->callbacks
.ClassPrepare (env
, jni_env
, event_thread
, klass
);
2336 case JVMTI_EVENT_VM_START
:
2337 if (env
->callbacks
.VMStart
!= NULL
)
2339 ARG (JNIEnv
*, jni_env
);
2340 env
->callbacks
.VMStart (env
, jni_env
);
2344 case JVMTI_EVENT_EXCEPTION
:
2345 if (env
->callbacks
.Exception
!= NULL
)
2347 ARG (JNIEnv
*, jni_env
);
2348 ARG (jmethodID
, method
);
2349 ARG (jlocation
, location
);
2350 ARG (jobject
, exception
);
2351 ARG (jmethodID
, catch_method
);
2352 ARG (jlocation
, catch_location
);
2353 env
->callbacks
.Exception (env
, jni_env
, event_thread
, method
,
2354 location
, exception
, catch_method
,
2359 case JVMTI_EVENT_EXCEPTION_CATCH
:
2360 if (env
->callbacks
.ExceptionCatch
!= NULL
)
2362 ARG (JNIEnv
*, jni_env
);
2363 ARG (jmethodID
, method
);
2364 ARG (jlocation
, location
);
2365 ARG (jobject
, exception
);
2366 env
->callbacks
.ExceptionCatch (env
, jni_env
, event_thread
, method
,
2367 location
, exception
);
2371 case JVMTI_EVENT_SINGLE_STEP
:
2372 if (env
->callbacks
.SingleStep
!= NULL
)
2374 ARG (JNIEnv
*, jni_env
);
2375 ARG (jmethodID
, method
);
2376 ARG (jlocation
, location
);
2377 env
->callbacks
.SingleStep (env
, jni_env
, event_thread
, method
,
2382 case JVMTI_EVENT_FRAME_POP
:
2383 if (env
->callbacks
.FramePop
!= NULL
)
2385 ARG (JNIEnv
*, jni_env
);
2386 ARG (jmethodID
, method
);
2387 GET_BOOLEAN_ARG (was_popped_by_exception
);
2388 env
->callbacks
.FramePop (env
, jni_env
, event_thread
, method
,
2389 was_popped_by_exception
);
2393 case JVMTI_EVENT_BREAKPOINT
:
2394 if (env
->callbacks
.Breakpoint
!= NULL
)
2396 ARG (JNIEnv
*, jni_env
);
2397 ARG (jmethodID
, method
);
2398 ARG (jlocation
, location
);
2399 env
->callbacks
.Breakpoint (env
, jni_env
, event_thread
, method
,
2404 case JVMTI_EVENT_FIELD_ACCESS
:
2405 if (env
->callbacks
.FieldAccess
!= NULL
)
2407 ARG (JNIEnv
*, jni_env
);
2408 ARG (jmethodID
, method
);
2409 ARG (jlocation
, location
);
2410 ARG (jclass
, field_class
);
2411 ARG (jobject
, object
);
2412 ARG (jfieldID
, field
);
2413 env
->callbacks
.FieldAccess (env
, jni_env
, event_thread
, method
,
2414 location
, field_class
, object
, field
);
2418 case JVMTI_EVENT_FIELD_MODIFICATION
:
2419 if (env
->callbacks
.FieldModification
!= NULL
)
2421 ARG (JNIEnv
*, jni_env
);
2422 ARG (jmethodID
, method
);
2423 ARG (jlocation
, location
);
2424 ARG (jclass
, field_class
);
2425 ARG (jobject
, object
);
2426 ARG (jfieldID
, field
);
2427 GET_CHAR_ARG (signature_type
);
2428 ARG (jvalue
, new_value
);
2429 env
->callbacks
.FieldModification (env
, jni_env
, event_thread
, method
,
2430 location
, field_class
, object
,
2431 field
, signature_type
, new_value
);
2435 case JVMTI_EVENT_METHOD_ENTRY
:
2436 if (env
->callbacks
.MethodEntry
!= NULL
)
2438 ARG (JNIEnv
*, jni_env
);
2439 ARG (jmethodID
, method
);
2440 env
->callbacks
.MethodEntry (env
, jni_env
, event_thread
, method
);
2444 case JVMTI_EVENT_METHOD_EXIT
:
2445 if (env
->callbacks
.MethodExit
!= NULL
)
2447 ARG (JNIEnv
*, jni_env
);
2448 ARG (jmethodID
, method
);
2449 GET_BOOLEAN_ARG (was_popped_by_exception
);
2450 ARG (jvalue
, return_value
);
2451 env
->callbacks
.MethodExit (env
, jni_env
, event_thread
, method
,
2452 was_popped_by_exception
, return_value
);
2456 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
2457 if (env
->callbacks
.NativeMethodBind
!= NULL
)
2459 ARG (JNIEnv
*, jni_env
);
2460 ARG (jmethodID
, method
);
2461 ARG (void *, address
);
2462 ARG (void **, new_address_ptr
);
2463 env
->callbacks
.NativeMethodBind (env
, jni_env
, event_thread
, method
,
2464 address
, new_address_ptr
);
2468 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
2469 if (env
->callbacks
.CompiledMethodLoad
!= NULL
)
2471 ARG (jmethodID
, method
);
2472 ARG (jint
, code_size
);
2473 ARG (const void *, code_addr
);
2474 ARG (jint
, map_length
);
2475 ARG (const jvmtiAddrLocationMap
*, map
);
2476 ARG (const void *, compile_info
);
2477 env
->callbacks
.CompiledMethodLoad (env
, method
, code_size
, code_addr
,
2478 map_length
, map
, compile_info
);
2482 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
2483 if (env
->callbacks
.CompiledMethodUnload
!= NULL
)
2485 ARG (jmethodID
, method
);
2486 ARG (const void *, code_addr
);
2487 env
->callbacks
.CompiledMethodUnload (env
, method
, code_addr
);
2491 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
2492 if (env
->callbacks
.DynamicCodeGenerated
!= NULL
)
2494 ARG (const char *, name
);
2495 ARG (const void *, address
);
2497 env
->callbacks
.DynamicCodeGenerated (env
, name
, address
, length
);
2501 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
2502 if (env
->callbacks
.DataDumpRequest
!= NULL
)
2504 env
->callbacks
.DataDumpRequest (env
);
2508 case JVMTI_EVENT_MONITOR_WAIT
:
2509 if (env
->callbacks
.MonitorWait
!= NULL
)
2511 ARG (JNIEnv
*, jni_env
);
2512 ARG (jobject
, object
);
2513 ARG (jlong
, timeout
);
2514 env
->callbacks
.MonitorWait (env
, jni_env
, event_thread
, object
,
2519 case JVMTI_EVENT_MONITOR_WAITED
:
2520 if (env
->callbacks
.MonitorWaited
!= NULL
)
2522 ARG (JNIEnv
*, jni_env
);
2523 ARG (jobject
, object
);
2524 GET_BOOLEAN_ARG (timed_out
);
2525 env
->callbacks
.MonitorWaited (env
, jni_env
, event_thread
, object
,
2530 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
2531 if (env
->callbacks
.MonitorContendedEnter
!= NULL
)
2533 ARG (JNIEnv
*, jni_env
);
2534 ARG (jobject
, object
);
2535 env
->callbacks
.MonitorContendedEnter (env
, jni_env
, event_thread
,
2540 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
2541 if (env
->callbacks
.MonitorContendedEntered
!= NULL
)
2543 ARG (JNIEnv
*, jni_env
);
2544 ARG (jobject
, object
);
2545 env
->callbacks
.MonitorContendedEntered (env
, jni_env
, event_thread
,
2550 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
2551 if (env
->callbacks
.GarbageCollectionStart
!= NULL
)
2553 env
->callbacks
.GarbageCollectionStart (env
);
2557 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
2558 if (env
->callbacks
.GarbageCollectionFinish
!= NULL
)
2560 env
->callbacks
.GarbageCollectionFinish (env
);
2564 case JVMTI_EVENT_OBJECT_FREE
:
2565 if (env
->callbacks
.ObjectFree
!= NULL
)
2568 env
->callbacks
.ObjectFree (env
, tag
);
2572 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
2573 if (env
->callbacks
.VMObjectAlloc
!= NULL
)
2575 ARG (JNIEnv
*, jni_env
);
2576 ARG (jobject
, object
);
2577 ARG (jclass
, object_class
);
2579 env
->callbacks
.VMObjectAlloc (env
, jni_env
, event_thread
,
2580 object
, object_class
, size
);
2585 fprintf (stderr
, "libgcj: post of unknown JVMTI event (%d)\n",
2591 #undef GET_BOOLEAN_ARG
2595 /* Post an event to requesting JVMTI environments
2597 * This function should not be called without consulting the
2598 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2599 * harm (other than kill speed), since this function will still
2600 * only send the event if it was properly requested by an environment.
2603 _Jv_JVMTI_PostEvent (jvmtiEvent type
, jthread event_thread
, ...)
2606 va_start (args
, event_thread
);
2608 _envListLock
->readLock ()->lock ();
2609 struct jvmti_env_list
*e
;
2610 FOREACH_ENVIRONMENT (e
)
2612 /* Events are only posted if the event was explicitly enabled,
2613 it has a registered event handler, and the event thread
2614 matches (either globally or restricted to a specific thread).
2615 Here we check all but the event handler, which will be handled
2617 if (e
->env
->enabled
[EVENT_INDEX(type
)]
2618 && (e
->env
->thread
[EVENT_INDEX(type
)] == NULL
2619 || e
->env
->thread
[EVENT_INDEX(type
)] == event_thread
))
2621 post_event (e
->env
, type
, event_thread
, args
);
2624 _envListLock
->readLock ()->unlock ();