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 char **str_ptr
= &(*locals
)[table_slot
].name
;
1001 jerr
= env
->Allocate (static_cast<jlong
> (strlen (name
) + 1),
1002 reinterpret_cast<unsigned char **> (str_ptr
));
1003 if (jerr
!= JVMTI_ERROR_NONE
)
1005 strcpy ((*locals
)[table_slot
].name
, name
);
1007 str_ptr
= &(*locals
)[table_slot
].signature
;
1008 jerr
= env
->Allocate (static_cast<jlong
> (strlen (sig
) + 1),
1009 reinterpret_cast<unsigned char **> (str_ptr
));
1010 if (jerr
!= JVMTI_ERROR_NONE
)
1012 strcpy ((*locals
)[table_slot
].signature
, sig
);
1014 str_ptr
= &(*locals
)[table_slot
].generic_signature
;
1015 jerr
= env
->Allocate (static_cast<jlong
> (strlen (generic_sig
) + 1),
1016 reinterpret_cast<unsigned char **> (str_ptr
));
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_GetArgumentsSize (jvmtiEnv
*env
, jmethodID method
, jint
*size
)
1091 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1094 CHECK_FOR_NATIVE_METHOD (method
);
1100 jerr
= env
->GetMethodName (method
, NULL
, &sig
, NULL
);
1101 if (jerr
!= JVMTI_ERROR_NONE
)
1104 // If the method is non-static add a slot for the "this" pointer.
1105 if ((method
->accflags
& java::lang::reflect::Modifier::STATIC
) == 0)
1108 for (int i
= 0; sig
[i
] != ')'; i
++)
1110 if (sig
[i
] == 'Z' || sig
[i
] == 'B' || sig
[i
] == 'C' || sig
[i
] == 'S'
1111 || sig
[i
] == 'I' || sig
[i
] == 'F')
1113 else if (sig
[i
] == 'J' || sig
[i
] == 'D')
1115 // If this is an array of wide types it uses a single slot
1116 if (i
> 0 && sig
[i
-1] == '[')
1121 else if (sig
[i
] == 'L')
1124 while (sig
[i
] != ';')
1130 return JVMTI_ERROR_NONE
;
1133 static jvmtiError JNICALL
1134 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv
*env
,
1136 jclass
*declaring_class_ptr
)
1138 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1139 NULL_CHECK (declaring_class_ptr
);
1141 jclass klass
= _Jv_GetMethodDeclaringClass (method
);
1144 *declaring_class_ptr
= klass
;
1145 return JVMTI_ERROR_NONE
;
1148 return JVMTI_ERROR_INVALID_METHODID
;
1151 static jvmtiError JNICALL
1152 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv
*env
,
1153 jobject init_loader
,
1155 jclass
**result_ptr
)
1157 using namespace java::lang
;
1158 using namespace java::util
;
1160 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1161 NULL_CHECK (count_ptr
);
1162 NULL_CHECK (result_ptr
);
1164 ClassLoader
*loader
= (ClassLoader
*) init_loader
;
1166 loader
= VMClassLoader::bootLoader
;
1168 Collection
*values
= loader
->loadedClasses
->values();
1169 jobjectArray array
= values
->toArray();
1170 *count_ptr
= array
->length
;
1171 jobject
*elts
= elements (array
);
1173 = (jclass
*) _Jv_MallocUnchecked (*count_ptr
* sizeof (jclass
));
1175 return JVMTI_ERROR_OUT_OF_MEMORY
;
1177 // FIXME: JNI references...
1178 memcpy (result
, elts
, *count_ptr
* sizeof (jclass
));
1180 *result_ptr
= result
;
1182 return JVMTI_ERROR_NONE
;
1185 static jvmtiError JNICALL
1186 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv
*env
, jthread thread
,
1187 jint start_depth
, jint max_frames
,
1188 jvmtiFrameInfo
*frames
, jint
*frame_count
)
1190 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1192 ILLEGAL_ARGUMENT (max_frames
< 0);
1194 NULL_CHECK (frames
);
1195 NULL_CHECK (frame_count
);
1197 using namespace java::lang
;
1199 THREAD_DEFAULT_TO_CURRENT (thread
);
1200 THREAD_CHECK_VALID (thread
);
1201 THREAD_CHECK_IS_ALIVE (thread
);
1203 jvmtiError jerr
= env
->GetFrameCount (thread
, frame_count
);
1204 if (jerr
!= JVMTI_ERROR_NONE
)
1207 // start_depth can be either a positive number, indicating the depth of the
1208 // stack at which to begin the trace, or a negative number indicating the
1209 // number of frames at the bottom of the stack to exclude. These checks
1210 // ensure that it is a valid value in either case
1212 ILLEGAL_ARGUMENT (start_depth
>= (*frame_count
));
1213 ILLEGAL_ARGUMENT (start_depth
< (-(*frame_count
)));
1215 _Jv_Frame
*frame
= reinterpret_cast<_Jv_Frame
*> (thread
->frame
);
1217 // If start_depth is negative use this to determine at what depth to start
1218 // the trace by adding it to the length of the call stack. This allows the
1219 // use of the same frame "discarding" mechanism as for a positive start_depth
1220 if (start_depth
< 0)
1221 start_depth
= *frame_count
+ start_depth
;
1223 // If start_depth > 0 "remove" start_depth frames from the beginning
1224 // of the stack before beginning the trace by moving along the frame list.
1225 while (start_depth
> 0)
1227 frame
= frame
->next
;
1232 // Now check to see if the array supplied by the agent is large enough to
1233 // hold frame_count frames, after adjustment for start_depth.
1234 if ((*frame_count
) > max_frames
)
1235 (*frame_count
) = max_frames
;
1237 for (int i
= 0; i
< (*frame_count
); i
++)
1239 frames
[i
].method
= frame
->self
->get_method ();
1241 // Set the location in the frame, native frames have location = -1
1242 if (frame
->frame_type
== frame_interpreter
)
1244 _Jv_InterpMethod
*imeth
1245 = static_cast<_Jv_InterpMethod
*> (frame
->self
);
1246 _Jv_InterpFrame
*interp_frame
1247 = static_cast<_Jv_InterpFrame
*> (frame
);
1248 frames
[i
].location
= imeth
->insn_index (interp_frame
->pc
);
1251 frames
[i
].location
= -1;
1253 frame
= frame
->next
;
1256 return JVMTI_ERROR_NONE
;
1259 static jvmtiError JNICALL
1260 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv
*env
)
1262 REQUIRE_PHASE (env
, JVMTI_PHASE_LIVE
);
1264 return JVMTI_ERROR_NONE
;
1267 static jvmtiError JNICALL
1268 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1269 const jniNativeInterface
*function_table
)
1271 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1272 NULL_CHECK (function_table
);
1273 memcpy (&_Jv_JNIFunctions
, function_table
, sizeof (jniNativeInterface
));
1274 return JVMTI_ERROR_NONE
;
1277 static jvmtiError JNICALL
1278 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv
*env
,
1279 jniNativeInterface
**function_table
)
1281 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1282 NULL_CHECK (function_table
);
1284 = (jniNativeInterface
*) _Jv_MallocUnchecked (sizeof (jniNativeInterface
));
1285 if (*function_table
== NULL
)
1286 return JVMTI_ERROR_OUT_OF_MEMORY
;
1287 memcpy (*function_table
, &_Jv_JNIFunctions
, sizeof (jniNativeInterface
));
1288 return JVMTI_ERROR_NONE
;
1291 static jvmtiError JNICALL
1292 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv
*env
)
1296 if (_jvmtiEnvironments
== NULL
)
1297 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1300 _envListLock
->writeLock ()->lock ();
1301 if (_jvmtiEnvironments
->env
== env
)
1303 struct jvmti_env_list
*next
= _jvmtiEnvironments
->next
;
1304 _Jv_Free (_jvmtiEnvironments
);
1305 _jvmtiEnvironments
= next
;
1309 struct jvmti_env_list
*e
= _jvmtiEnvironments
;
1310 while (e
->next
!= NULL
&& e
->next
->env
!= env
)
1312 if (e
->next
== NULL
)
1314 _envListLock
->writeLock ()->unlock ();
1315 return JVMTI_ERROR_INVALID_ENVIRONMENT
;
1318 struct jvmti_env_list
*next
= e
->next
->next
;
1322 _envListLock
->writeLock ()->unlock ();
1327 check_enabled_events ();
1329 return JVMTI_ERROR_NONE
;
1332 static jvmtiError JNICALL
1333 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1336 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1337 NULL_CHECK (property
);
1338 NULL_CHECK (result
);
1340 jstring name
= JvNewStringUTF(property
);
1341 jstring result_str
= gnu::classpath::SystemProperties::getProperty(name
);
1343 if (result_str
== NULL
)
1344 return JVMTI_ERROR_NOT_AVAILABLE
;
1346 int len
= JvGetStringUTFLength (result_str
);
1347 *result
= (char *) _Jv_MallocUnchecked (len
+ 1);
1348 if (*result
== NULL
)
1349 return JVMTI_ERROR_OUT_OF_MEMORY
;
1350 JvGetStringUTFRegion (result_str
, 0, result_str
->length(), *result
);
1351 (*result
)[len
] = '\0';
1353 return JVMTI_ERROR_NONE
;
1356 static jvmtiError JNICALL
1357 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv
*env
, const char *property
,
1360 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1362 NULL_CHECK (property
);
1365 // FIXME: When would a property not be writeable?
1366 return JVMTI_ERROR_NONE
;
1369 jstring prop_str
= JvNewStringUTF(property
);
1370 jstring value_str
= JvNewStringUTF(value
);
1371 gnu::classpath::SystemProperties::setProperty(prop_str
, value_str
);
1372 return JVMTI_ERROR_NONE
;
1375 static jvmtiError JNICALL
1376 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv
*env
, jlong
*nanos_ptr
)
1378 NULL_CHECK (nanos_ptr
);
1379 *nanos_ptr
= _Jv_platform_nanotime();
1380 return JVMTI_ERROR_NONE
;
1383 static jvmtiError JNICALL
1384 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv
*env
,
1385 jint
*nprocessors_ptr
)
1387 NULL_CHECK (nprocessors_ptr
);
1388 #ifdef _SC_NPROCESSORS_ONLN
1389 *nprocessors_ptr
= sysconf(_SC_NPROCESSORS_ONLN
);
1391 *nprocessors_ptr
= 1;
1393 return JVMTI_ERROR_NONE
;
1396 static jvmtiError JNICALL
1397 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv
*env
,
1398 const char *segment
)
1400 using namespace java::lang
;
1401 using namespace java::net
;
1402 using namespace gnu::gcj::runtime
;
1404 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
);
1405 NULL_CHECK (segment
);
1407 jstring str_segment
= JvNewStringUTF(segment
);
1411 url
= new URL(JvNewStringUTF("file"), NULL
, str_segment
);
1413 catch (jthrowable ignore
)
1415 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1418 BootClassLoader
*loader
= VMClassLoader::bootLoader
;
1419 // Don't call this too early.
1420 // assert (loader != NULL);
1421 loader
->addURL(url
);
1422 return JVMTI_ERROR_NONE
;
1425 static jvmtiError JNICALL
1426 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiVerboseFlag flag
,
1431 case JVMTI_VERBOSE_OTHER
:
1432 case JVMTI_VERBOSE_GC
:
1433 case JVMTI_VERBOSE_JNI
:
1436 case JVMTI_VERBOSE_CLASS
:
1437 gcj::verbose_class_flag
= value
;
1440 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1442 return JVMTI_ERROR_NONE
;
1445 static jvmtiError JNICALL
1446 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv
*env
, jobject object
,
1449 REQUIRE_PHASE (env
, JVMTI_PHASE_START
| JVMTI_PHASE_LIVE
);
1451 return JVMTI_ERROR_INVALID_OBJECT
;
1452 NULL_CHECK (result
);
1454 jclass klass
= object
->getClass();
1455 if (klass
->isArray())
1457 jclass comp
= klass
->getComponentType();
1459 = (jint
) (_Jv_uintptr_t
) _Jv_GetArrayElementFromElementType(NULL
,
1460 klass
->getComponentType());
1461 // FIXME: correct for primitive types?
1462 jint compSize
= comp
->size();
1463 __JArray
*array
= (__JArray
*) object
;
1464 *result
= base
+ array
->length
* compSize
;
1468 // Note that if OBJECT is a String then it may (if
1469 // str->data==str) take more space. Do we care?
1470 *result
= klass
->size();
1472 return JVMTI_ERROR_NONE
;
1475 /* An event is enabled only if it has both an event handler
1476 and it is enabled in the environment. */
1478 check_enabled_event (jvmtiEvent type
)
1483 #define GET_OFFSET(Event) \
1486 enabled = &JVMTI::Event; \
1487 offset = offsetof (jvmtiEventCallbacks, Event); \
1493 case JVMTI_EVENT_VM_INIT
:
1494 GET_OFFSET (VMInit
);
1497 case JVMTI_EVENT_VM_DEATH
:
1498 GET_OFFSET (VMDeath
);
1501 case JVMTI_EVENT_THREAD_START
:
1502 GET_OFFSET (ThreadStart
);
1505 case JVMTI_EVENT_THREAD_END
:
1506 GET_OFFSET (ThreadEnd
);
1509 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1510 GET_OFFSET (ClassFileLoadHook
);
1513 case JVMTI_EVENT_CLASS_LOAD
:
1514 GET_OFFSET (ClassLoad
);
1517 case JVMTI_EVENT_CLASS_PREPARE
:
1518 GET_OFFSET (ClassPrepare
);
1521 case JVMTI_EVENT_VM_START
:
1522 GET_OFFSET (VMStart
);
1525 case JVMTI_EVENT_EXCEPTION
:
1526 GET_OFFSET (Exception
);
1529 case JVMTI_EVENT_EXCEPTION_CATCH
:
1530 GET_OFFSET (ExceptionCatch
);
1533 case JVMTI_EVENT_SINGLE_STEP
:
1534 GET_OFFSET (SingleStep
);
1537 case JVMTI_EVENT_FRAME_POP
:
1538 GET_OFFSET (FramePop
);
1541 case JVMTI_EVENT_BREAKPOINT
:
1542 GET_OFFSET (Breakpoint
);
1545 case JVMTI_EVENT_FIELD_ACCESS
:
1546 GET_OFFSET (FieldAccess
);
1549 case JVMTI_EVENT_FIELD_MODIFICATION
:
1550 GET_OFFSET (FieldModification
);
1553 case JVMTI_EVENT_METHOD_ENTRY
:
1554 GET_OFFSET (MethodEntry
);
1557 case JVMTI_EVENT_METHOD_EXIT
:
1558 GET_OFFSET (MethodExit
);
1561 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1562 GET_OFFSET (NativeMethodBind
);
1565 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1566 GET_OFFSET (CompiledMethodLoad
);
1569 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1570 GET_OFFSET (CompiledMethodUnload
);
1573 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1574 GET_OFFSET (DynamicCodeGenerated
);
1577 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1578 GET_OFFSET (DataDumpRequest
);
1581 case JVMTI_EVENT_MONITOR_WAIT
:
1582 GET_OFFSET (MonitorWait
);
1585 case JVMTI_EVENT_MONITOR_WAITED
:
1586 GET_OFFSET (MonitorWaited
);
1589 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1590 GET_OFFSET (MonitorContendedEnter
);
1593 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1594 GET_OFFSET (MonitorContendedEntered
);
1597 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1598 GET_OFFSET (GarbageCollectionStart
);
1601 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1602 GET_OFFSET (GarbageCollectionFinish
);
1605 case JVMTI_EVENT_OBJECT_FREE
:
1606 GET_OFFSET (ObjectFree
);
1609 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1610 GET_OFFSET (VMObjectAlloc
);
1615 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1621 int index
= EVENT_INDEX (type
); // safe since caller checks this
1623 if (_jvmtiEnvironments
!= NULL
)
1625 _envListLock
->readLock ()->lock ();
1626 struct jvmti_env_list
*e
;
1627 FOREACH_ENVIRONMENT (e
)
1630 = reinterpret_cast<char *> (&e
->env
->callbacks
) + offset
;
1631 void **callback
= reinterpret_cast<void **> (addr
);
1632 if (e
->env
->enabled
[index
] && *callback
!= NULL
)
1635 _envListLock
->readLock ()->unlock ();
1640 _envListLock
->readLock ()->unlock ();
1647 check_enabled_events ()
1649 check_enabled_event (JVMTI_EVENT_VM_INIT
);
1650 check_enabled_event (JVMTI_EVENT_VM_DEATH
);
1651 check_enabled_event (JVMTI_EVENT_THREAD_START
);
1652 check_enabled_event (JVMTI_EVENT_THREAD_END
);
1653 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
);
1654 check_enabled_event (JVMTI_EVENT_CLASS_LOAD
);
1655 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE
);
1656 check_enabled_event (JVMTI_EVENT_VM_START
);
1657 check_enabled_event (JVMTI_EVENT_EXCEPTION
);
1658 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH
);
1659 check_enabled_event (JVMTI_EVENT_SINGLE_STEP
);
1660 check_enabled_event (JVMTI_EVENT_FRAME_POP
);
1661 check_enabled_event (JVMTI_EVENT_BREAKPOINT
);
1662 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS
);
1663 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION
);
1664 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY
);
1665 check_enabled_event (JVMTI_EVENT_METHOD_EXIT
);
1666 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND
);
1667 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD
);
1668 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD
);
1669 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED
);
1670 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST
);
1671 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT
);
1672 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED
);
1673 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER
);
1674 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
);
1675 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START
);
1676 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
);
1677 check_enabled_event (JVMTI_EVENT_OBJECT_FREE
);
1678 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC
);
1681 static jvmtiError JNICALL
1682 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv
*env
, jvmtiEventMode mode
,
1683 jvmtiEvent type
, jthread event_thread
, ...)
1685 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1687 if (event_thread
!= NULL
)
1689 THREAD_CHECK_VALID (event_thread
);
1690 THREAD_CHECK_IS_ALIVE (event_thread
);
1704 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1709 case JVMTI_EVENT_VM_INIT
:
1710 case JVMTI_EVENT_VM_DEATH
:
1711 case JVMTI_EVENT_THREAD_START
:
1712 case JVMTI_EVENT_VM_START
:
1713 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
1714 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
1715 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
1716 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
1717 ILLEGAL_ARGUMENT (event_thread
!= NULL
);
1720 case JVMTI_EVENT_THREAD_END
:
1721 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
1722 case JVMTI_EVENT_CLASS_LOAD
:
1723 case JVMTI_EVENT_CLASS_PREPARE
:
1724 case JVMTI_EVENT_EXCEPTION
:
1725 case JVMTI_EVENT_EXCEPTION_CATCH
:
1726 case JVMTI_EVENT_SINGLE_STEP
:
1727 case JVMTI_EVENT_FRAME_POP
:
1728 case JVMTI_EVENT_BREAKPOINT
:
1729 case JVMTI_EVENT_FIELD_ACCESS
:
1730 case JVMTI_EVENT_FIELD_MODIFICATION
:
1731 case JVMTI_EVENT_METHOD_ENTRY
:
1732 case JVMTI_EVENT_METHOD_EXIT
:
1733 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
1734 case JVMTI_EVENT_MONITOR_WAIT
:
1735 case JVMTI_EVENT_MONITOR_WAITED
:
1736 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
1737 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
1738 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
1739 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
1740 case JVMTI_EVENT_OBJECT_FREE
:
1741 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
1745 return JVMTI_ERROR_INVALID_EVENT_TYPE
;
1748 env
->thread
[EVENT_INDEX(type
)] = event_thread
;
1749 env
->enabled
[EVENT_INDEX(type
)] = enabled
;
1750 check_enabled_event (type
);
1751 return JVMTI_ERROR_NONE
;
1754 static jvmtiError JNICALL
1755 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv
*env
,
1756 const jvmtiEventCallbacks
*callbacks
,
1757 jint size_of_callbacks
)
1759 REQUIRE_PHASE (env
, JVMTI_PHASE_ONLOAD
| JVMTI_PHASE_LIVE
);
1760 ILLEGAL_ARGUMENT (size_of_callbacks
< 0);
1762 // Copy the list of callbacks into the environment
1763 memcpy (&env
->callbacks
, callbacks
, sizeof (jvmtiEventCallbacks
));
1765 /* Check which events are now enabeld (JVMTI makes no requirements
1766 about the order in which SetEventCallbacks and SetEventNotifications
1767 are called. So we must check all events here. */
1768 check_enabled_events ();
1770 return JVMTI_ERROR_NONE
;
1773 static jvmtiError JNICALL
1774 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv
*env
, jvmtiError error
,
1777 NULL_CHECK (name_ptr
);
1782 case JVMTI_ERROR_NONE
:
1786 case JVMTI_ERROR_NULL_POINTER
:
1787 name
= "null pointer";
1790 case JVMTI_ERROR_OUT_OF_MEMORY
:
1791 name
= "out of memory";
1794 case JVMTI_ERROR_ACCESS_DENIED
:
1795 name
= "access denied";
1798 case JVMTI_ERROR_WRONG_PHASE
:
1799 name
= "wrong phase";
1802 case JVMTI_ERROR_INTERNAL
:
1803 name
= "internal error";
1806 case JVMTI_ERROR_UNATTACHED_THREAD
:
1807 name
= "unattached thread";
1810 case JVMTI_ERROR_INVALID_ENVIRONMENT
:
1811 name
= "invalid environment";
1814 case JVMTI_ERROR_INVALID_PRIORITY
:
1815 name
= "invalid priority";
1818 case JVMTI_ERROR_THREAD_NOT_SUSPENDED
:
1819 name
= "thread not suspended";
1822 case JVMTI_ERROR_THREAD_SUSPENDED
:
1823 name
= "thread suspended";
1826 case JVMTI_ERROR_THREAD_NOT_ALIVE
:
1827 name
= "thread not alive";
1830 case JVMTI_ERROR_CLASS_NOT_PREPARED
:
1831 name
= "class not prepared";
1834 case JVMTI_ERROR_NO_MORE_FRAMES
:
1835 name
= "no more frames";
1838 case JVMTI_ERROR_OPAQUE_FRAME
:
1839 name
= "opaque frame";
1842 case JVMTI_ERROR_DUPLICATE
:
1846 case JVMTI_ERROR_NOT_FOUND
:
1850 case JVMTI_ERROR_NOT_MONITOR_OWNER
:
1851 name
= "not monitor owner";
1854 case JVMTI_ERROR_INTERRUPT
:
1855 name
= "interrupted";
1858 case JVMTI_ERROR_UNMODIFIABLE_CLASS
:
1859 name
= "unmodifiable class";
1862 case JVMTI_ERROR_NOT_AVAILABLE
:
1863 name
= "not available";
1866 case JVMTI_ERROR_ABSENT_INFORMATION
:
1867 name
= "absent information";
1870 case JVMTI_ERROR_INVALID_EVENT_TYPE
:
1871 name
= "invalid event type";
1874 case JVMTI_ERROR_NATIVE_METHOD
:
1875 name
= "native method";
1878 case JVMTI_ERROR_INVALID_THREAD
:
1879 name
= "invalid thread";
1882 case JVMTI_ERROR_INVALID_THREAD_GROUP
:
1883 name
= "invalid thread group";
1886 case JVMTI_ERROR_INVALID_OBJECT
:
1887 name
= "invalid object";
1890 case JVMTI_ERROR_INVALID_CLASS
:
1891 name
= "invalid class";
1894 case JVMTI_ERROR_INVALID_METHODID
:
1895 name
= "invalid method ID";
1898 case JVMTI_ERROR_INVALID_LOCATION
:
1899 name
= "invalid location";
1902 case JVMTI_ERROR_INVALID_FIELDID
:
1903 name
= "invalid field ID";
1906 case JVMTI_ERROR_TYPE_MISMATCH
:
1907 name
= "type mismatch";
1910 case JVMTI_ERROR_INVALID_SLOT
:
1911 name
= "invalid slot";
1914 case JVMTI_ERROR_INVALID_MONITOR
:
1915 name
= "invalid monitor";
1918 case JVMTI_ERROR_INVALID_CLASS_FORMAT
:
1919 name
= "invalid class format";
1922 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION
:
1923 name
= "circular class definition";
1926 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED
:
1927 name
= "unsupported redefinition: method added";
1930 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED
:
1931 name
= "unsupported redefinition: schema changed";
1934 case JVMTI_ERROR_INVALID_TYPESTATE
:
1935 name
= "invalid type state";
1938 case JVMTI_ERROR_FAILS_VERIFICATION
:
1939 name
= "fails verification";
1942 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED
:
1943 name
= "unsupported redefinition: hierarchy changed";
1946 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED
:
1947 name
= "unsupported redefinition: method deleted";
1950 case JVMTI_ERROR_UNSUPPORTED_VERSION
:
1951 name
= "unsupported version";
1954 case JVMTI_ERROR_NAMES_DONT_MATCH
:
1955 name
= "names do not match";
1958 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED
:
1959 name
= "unsupported redefinition: class modifiers changed";
1962 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED
:
1963 name
= "unsupported redefinition: method modifiers changed";
1966 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY
:
1967 name
= "must possess capability";
1970 case JVMTI_ERROR_ILLEGAL_ARGUMENT
:
1971 name
= "illegal argument";
1975 return JVMTI_ERROR_ILLEGAL_ARGUMENT
;
1978 *name_ptr
= (char *) _Jv_MallocUnchecked (strlen (name
) + 1);
1979 if (*name_ptr
== NULL
)
1980 return JVMTI_ERROR_OUT_OF_MEMORY
;
1982 strcpy (*name_ptr
, name
);
1983 return JVMTI_ERROR_NONE
;
1986 #define RESERVED NULL
1987 #define UNIMPLEMENTED NULL
1989 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface
=
1991 RESERVED
, // reserved1
1992 _Jv_JVMTI_SetEventNotificationMode
, // SetEventNotificationMode
1993 RESERVED
, // reserved3
1994 _Jv_JVMTI_GetAllThreads
, // GetAllThreads
1995 _Jv_JVMTI_SuspendThread
, // SuspendThread
1996 _Jv_JVMTI_ResumeThread
, // ResumeThread
1997 UNIMPLEMENTED
, // StopThread
1998 _Jv_JVMTI_InterruptThread
, // InterruptThread
1999 UNIMPLEMENTED
, // GetThreadInfo
2000 UNIMPLEMENTED
, // GetOwnedMonitorInfo
2001 UNIMPLEMENTED
, // GetCurrentContendedMonitor
2002 UNIMPLEMENTED
, // RunAgentThread
2003 UNIMPLEMENTED
, // GetTopThreadGroups
2004 UNIMPLEMENTED
, // GetThreadGroupInfo
2005 UNIMPLEMENTED
, // GetThreadGroupChildren
2006 _Jv_JVMTI_GetFrameCount
, // GetFrameCount
2007 UNIMPLEMENTED
, // GetThreadState
2008 RESERVED
, // reserved18
2009 UNIMPLEMENTED
, // GetFrameLocation
2010 UNIMPLEMENTED
, // NotifyPopFrame
2011 _Jv_JVMTI_GetLocalObject
, // GetLocalObject
2012 _Jv_JVMTI_GetLocalInt
, // GetLocalInt
2013 _Jv_JVMTI_GetLocalLong
, // GetLocalLong
2014 _Jv_JVMTI_GetLocalFloat
, // GetLocalFloat
2015 _Jv_JVMTI_GetLocalDouble
, // GetLocalDouble
2016 _Jv_JVMTI_SetLocalObject
, // SetLocalObject
2017 _Jv_JVMTI_SetLocalInt
, // SetLocalInt
2018 _Jv_JVMTI_SetLocalLong
, // SetLocalLong
2019 _Jv_JVMTI_SetLocalFloat
, // SetLocalFloat
2020 _Jv_JVMTI_SetLocalDouble
, // SetLocalDouble
2021 _Jv_JVMTI_CreateRawMonitor
, // CreateRawMonitor
2022 _Jv_JVMTI_DestroyRawMonitor
, // DestroyRawMonitor
2023 _Jv_JVMTI_RawMonitorEnter
, // RawMonitorEnter
2024 _Jv_JVMTI_RawMonitorExit
, // RawMonitorExit
2025 _Jv_JVMTI_RawMonitorWait
, // RawMonitorWait
2026 _Jv_JVMTI_RawMonitorNotify
, // RawMonitorNotify
2027 _Jv_JVMTI_RawMonitorNotifyAll
, // RawMonitorNotifyAll
2028 _Jv_JVMTI_SetBreakpoint
, // SetBreakpoint
2029 _Jv_JVMTI_ClearBreakpoint
, // ClearBreakpoint
2030 RESERVED
, // reserved40
2031 UNIMPLEMENTED
, // SetFieldAccessWatch
2032 UNIMPLEMENTED
, // ClearFieldAccessWatch
2033 UNIMPLEMENTED
, // SetFieldModificationWatch
2034 UNIMPLEMENTED
, // ClearFieldModificationWatch
2035 RESERVED
, // reserved45
2036 _Jv_JVMTI_Allocate
, // Allocate
2037 _Jv_JVMTI_Deallocate
, // Deallocate
2038 UNIMPLEMENTED
, // GetClassSignature
2039 _Jv_JVMTI_GetClassStatus
, // GetClassStatus
2040 UNIMPLEMENTED
, // GetSourceFileName
2041 _Jv_JVMTI_GetClassModifiers
, // GetClassModifiers
2042 _Jv_JVMTI_GetClassMethods
, // GetClassMethods
2043 UNIMPLEMENTED
, // GetClassFields
2044 UNIMPLEMENTED
, // GetImplementedInterfaces
2045 _Jv_JVMTI_IsInterface
, // IsInterface
2046 _Jv_JVMTI_IsArrayClass
, // IsArrayClass
2047 _Jv_JVMTI_GetClassLoader
, // GetClassLoader
2048 _Jv_JVMTI_GetObjectHashCode
, // GetObjectHashCode
2049 UNIMPLEMENTED
, // GetObjectMonitorUsage
2050 UNIMPLEMENTED
, // GetFieldName
2051 UNIMPLEMENTED
, // GetFieldDeclaringClass
2052 _Jv_JVMTI_GetFieldModifiers
, // GetFieldModifiers
2053 _Jv_JVMTI_IsFieldSynthetic
, // IsFieldSynthetic
2054 _Jv_JVMTI_GetMethodName
, // GetMethodName
2055 _Jv_JVMTI_GetMethodDeclaringClass
, // GetMethodDeclaringClass
2056 _Jv_JVMTI_GetMethodModifiers
, // GetMethodModifers
2057 RESERVED
, // reserved67
2058 _Jv_JVMTI_GetMaxLocals
, // GetMaxLocals
2059 _Jv_JVMTI_GetArgumentsSize
, // GetArgumentsSize
2060 _Jv_JVMTI_GetLineNumberTable
, // GetLineNumberTable
2061 UNIMPLEMENTED
, // GetMethodLocation
2062 _Jv_JVMTI_GetLocalVariableTable
, // GetLocalVariableTable
2063 RESERVED
, // reserved73
2064 RESERVED
, // reserved74
2065 UNIMPLEMENTED
, // GetBytecodes
2066 _Jv_JVMTI_IsMethodNative
, // IsMethodNative
2067 _Jv_JVMTI_IsMethodSynthetic
, // IsMethodSynthetic
2068 UNIMPLEMENTED
, // GetLoadedClasses
2069 _Jv_JVMTI_GetClassLoaderClasses
, // GetClassLoaderClasses
2070 UNIMPLEMENTED
, // PopFrame
2071 RESERVED
, // reserved81
2072 RESERVED
, // reserved82
2073 RESERVED
, // reserved83
2074 RESERVED
, // reserved84
2075 RESERVED
, // reserved85
2076 RESERVED
, // reserved86
2077 UNIMPLEMENTED
, // RedefineClasses
2078 UNIMPLEMENTED
, // GetVersionNumber
2079 UNIMPLEMENTED
, // GetCapabilities
2080 UNIMPLEMENTED
, // GetSourceDebugExtension
2081 UNIMPLEMENTED
, // IsMethodObsolete
2082 UNIMPLEMENTED
, // SuspendThreadList
2083 UNIMPLEMENTED
, // ResumeThreadList
2084 RESERVED
, // reserved94
2085 RESERVED
, // reserved95
2086 RESERVED
, // reserved96
2087 RESERVED
, // reserved97
2088 RESERVED
, // reserved98
2089 RESERVED
, // reserved99
2090 UNIMPLEMENTED
, // GetAllStackTraces
2091 UNIMPLEMENTED
, // GetThreadListStackTraces
2092 UNIMPLEMENTED
, // GetThreadLocalStorage
2093 UNIMPLEMENTED
, // SetThreadLocalStorage
2094 _Jv_JVMTI_GetStackTrace
, // GetStackTrace
2095 RESERVED
, // reserved105
2096 UNIMPLEMENTED
, // GetTag
2097 UNIMPLEMENTED
, // SetTag
2098 _Jv_JVMTI_ForceGarbageCollection
, // ForceGarbageCollection
2099 UNIMPLEMENTED
, // IterateOverObjectsReachable
2100 UNIMPLEMENTED
, // IterateOverReachableObjects
2101 UNIMPLEMENTED
, // IterateOverHeap
2102 UNIMPLEMENTED
, // IterateOverInstanceOfClass
2103 RESERVED
, // reserved113
2104 UNIMPLEMENTED
, // GetObjectsWithTags
2105 RESERVED
, // reserved115
2106 RESERVED
, // reserved116
2107 RESERVED
, // reserved117
2108 RESERVED
, // reserved118
2109 RESERVED
, // reserved119
2110 _Jv_JVMTI_SetJNIFunctionTable
, // SetJNIFunctionTable
2111 _Jv_JVMTI_GetJNIFunctionTable
, // GetJNIFunctionTable
2112 _Jv_JVMTI_SetEventCallbacks
, // SetEventCallbacks
2113 UNIMPLEMENTED
, // GenerateEvents
2114 UNIMPLEMENTED
, // GetExtensionFunctions
2115 UNIMPLEMENTED
, // GetExtensionEvents
2116 UNIMPLEMENTED
, // SetExtensionEventCallback
2117 _Jv_JVMTI_DisposeEnvironment
, // DisposeEnvironment
2118 _Jv_JVMTI_GetErrorName
, // GetErrorName
2119 UNIMPLEMENTED
, // GetJLocationFormat
2120 UNIMPLEMENTED
, // GetSystemProperties
2121 _Jv_JVMTI_GetSystemProperty
, // GetSystemProperty
2122 _Jv_JVMTI_SetSystemProperty
, // SetSystemProperty
2123 UNIMPLEMENTED
, // GetPhase
2124 UNIMPLEMENTED
, // GetCurrentThreadCpuTimerInfo
2125 UNIMPLEMENTED
, // GetCurrentThreadCpuTime
2126 UNIMPLEMENTED
, // GetThreadCpuTimerInfo
2127 UNIMPLEMENTED
, // GetThreadCpuTime
2128 UNIMPLEMENTED
, // GetTimerInfo
2129 _Jv_JVMTI_GetTime
, // GetTime
2130 UNIMPLEMENTED
, // GetPotentialCapabilities
2131 RESERVED
, // reserved141
2132 UNIMPLEMENTED
, // AddCapabilities
2133 UNIMPLEMENTED
, // RelinquishCapabilities
2134 _Jv_JVMTI_GetAvailableProcessors
, // GetAvailableProcessors
2135 RESERVED
, // reserved145
2136 RESERVED
, // reserved146
2137 UNIMPLEMENTED
, // GetEnvironmentLocalStorage
2138 UNIMPLEMENTED
, // SetEnvironmentLocalStorage
2139 _Jv_JVMTI_AddToBootstrapClassLoaderSearch
, // AddToBootstrapClassLoaderSearch
2140 _Jv_JVMTI_SetVerboseFlag
, // SetVerboseFlag
2141 RESERVED
, // reserved151
2142 RESERVED
, // reserved152
2143 RESERVED
, // reserved153
2144 _Jv_JVMTI_GetObjectSize
// GetObjectSize
2148 _Jv_GetJVMTIEnv (void)
2151 = (_Jv_JVMTIEnv
*) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv
));
2152 env
->p
= &_Jv_JVMTI_Interface
;
2153 struct jvmti_env_list
*element
2154 = (struct jvmti_env_list
*) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list
));
2156 element
->next
= NULL
;
2158 _envListLock
->writeLock ()->lock ();
2159 if (_jvmtiEnvironments
== NULL
)
2160 _jvmtiEnvironments
= element
;
2163 struct jvmti_env_list
*e
;
2164 for (e
= _jvmtiEnvironments
; e
->next
!= NULL
; e
= e
->next
)
2168 _envListLock
->writeLock ()->unlock ();
2170 /* Mark JVMTI active. This is used to force the interpreter
2171 to use either debugging or non-debugging code. Once JVMTI
2172 has been enabled, the non-debug interpreter cannot be used. */
2173 JVMTI::enabled
= true;
2180 _jvmtiEnvironments
= NULL
;
2182 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2184 // No environments, so this should set all JVMTI:: members to false
2185 check_enabled_events ();
2189 post_event (jvmtiEnv
*env
, jvmtiEvent type
, jthread event_thread
, va_list args
)
2191 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2193 #define GET_BOOLEAN_ARG(Name) \
2195 jboolean Name = (b == 0) ? false : true
2197 #define GET_CHAR_ARG(Name) \
2199 char Name = static_cast<char> (c)
2203 case JVMTI_EVENT_VM_INIT
:
2204 if (env
->callbacks
.VMInit
!= NULL
)
2206 ARG (JNIEnv
*, jni_env
);
2207 env
->callbacks
.VMInit (env
, jni_env
, event_thread
);
2211 case JVMTI_EVENT_VM_DEATH
:
2212 if (env
->callbacks
.VMDeath
!= NULL
)
2214 ARG (JNIEnv
*, jni_env
);
2215 env
->callbacks
.VMDeath (env
, jni_env
);
2219 case JVMTI_EVENT_THREAD_START
:
2220 if (env
->callbacks
.ThreadStart
!= NULL
)
2222 ARG (JNIEnv
*, jni_env
);
2223 env
->callbacks
.ThreadStart (env
, jni_env
, event_thread
);
2227 case JVMTI_EVENT_THREAD_END
:
2228 if (env
->callbacks
.ThreadEnd
!= NULL
)
2230 ARG (JNIEnv
*, jni_env
);
2231 env
->callbacks
.ThreadEnd (env
, jni_env
, event_thread
);
2235 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK
:
2236 if (env
->callbacks
.ClassFileLoadHook
!= NULL
)
2238 ARG (JNIEnv
*, jni_env
);
2239 ARG (jclass
, class_being_redefined
);
2240 ARG (jobject
, loader
);
2241 ARG (const char *, name
);
2242 ARG (jobject
, protection_domain
);
2243 ARG (jint
, class_data_len
);
2244 ARG (const unsigned char *, class_data
);
2245 ARG (jint
*, new_class_data_len
);
2246 ARG (unsigned char **, new_class_data
);
2247 env
->callbacks
.ClassFileLoadHook (env
, jni_env
,
2248 class_being_redefined
, loader
,
2249 name
, protection_domain
,
2250 class_data_len
, class_data
,
2256 case JVMTI_EVENT_CLASS_LOAD
:
2257 if (env
->callbacks
.ClassLoad
!= NULL
)
2259 ARG (JNIEnv
*, jni_env
);
2260 ARG (jclass
, klass
);
2261 env
->callbacks
.ClassLoad (env
, jni_env
, event_thread
, klass
);
2265 case JVMTI_EVENT_CLASS_PREPARE
:
2266 if (env
->callbacks
.ClassPrepare
!= NULL
)
2268 ARG (JNIEnv
*, jni_env
);
2269 ARG (jclass
, klass
);
2270 env
->callbacks
.ClassPrepare (env
, jni_env
, event_thread
, klass
);
2274 case JVMTI_EVENT_VM_START
:
2275 if (env
->callbacks
.VMStart
!= NULL
)
2277 ARG (JNIEnv
*, jni_env
);
2278 env
->callbacks
.VMStart (env
, jni_env
);
2282 case JVMTI_EVENT_EXCEPTION
:
2283 if (env
->callbacks
.Exception
!= NULL
)
2285 ARG (JNIEnv
*, jni_env
);
2286 ARG (jmethodID
, method
);
2287 ARG (jlocation
, location
);
2288 ARG (jobject
, exception
);
2289 ARG (jmethodID
, catch_method
);
2290 ARG (jlocation
, catch_location
);
2291 env
->callbacks
.Exception (env
, jni_env
, event_thread
, method
,
2292 location
, exception
, catch_method
,
2297 case JVMTI_EVENT_EXCEPTION_CATCH
:
2298 if (env
->callbacks
.ExceptionCatch
!= NULL
)
2300 ARG (JNIEnv
*, jni_env
);
2301 ARG (jmethodID
, method
);
2302 ARG (jlocation
, location
);
2303 ARG (jobject
, exception
);
2304 env
->callbacks
.ExceptionCatch (env
, jni_env
, event_thread
, method
,
2305 location
, exception
);
2309 case JVMTI_EVENT_SINGLE_STEP
:
2310 if (env
->callbacks
.SingleStep
!= NULL
)
2312 ARG (JNIEnv
*, jni_env
);
2313 ARG (jmethodID
, method
);
2314 ARG (jlocation
, location
);
2315 env
->callbacks
.SingleStep (env
, jni_env
, event_thread
, method
,
2320 case JVMTI_EVENT_FRAME_POP
:
2321 if (env
->callbacks
.FramePop
!= NULL
)
2323 ARG (JNIEnv
*, jni_env
);
2324 ARG (jmethodID
, method
);
2325 GET_BOOLEAN_ARG (was_popped_by_exception
);
2326 env
->callbacks
.FramePop (env
, jni_env
, event_thread
, method
,
2327 was_popped_by_exception
);
2331 case JVMTI_EVENT_BREAKPOINT
:
2332 if (env
->callbacks
.Breakpoint
!= NULL
)
2334 ARG (JNIEnv
*, jni_env
);
2335 ARG (jmethodID
, method
);
2336 ARG (jlocation
, location
);
2337 env
->callbacks
.Breakpoint (env
, jni_env
, event_thread
, method
,
2342 case JVMTI_EVENT_FIELD_ACCESS
:
2343 if (env
->callbacks
.FieldAccess
!= NULL
)
2345 ARG (JNIEnv
*, jni_env
);
2346 ARG (jmethodID
, method
);
2347 ARG (jlocation
, location
);
2348 ARG (jclass
, field_class
);
2349 ARG (jobject
, object
);
2350 ARG (jfieldID
, field
);
2351 env
->callbacks
.FieldAccess (env
, jni_env
, event_thread
, method
,
2352 location
, field_class
, object
, field
);
2356 case JVMTI_EVENT_FIELD_MODIFICATION
:
2357 if (env
->callbacks
.FieldModification
!= NULL
)
2359 ARG (JNIEnv
*, jni_env
);
2360 ARG (jmethodID
, method
);
2361 ARG (jlocation
, location
);
2362 ARG (jclass
, field_class
);
2363 ARG (jobject
, object
);
2364 ARG (jfieldID
, field
);
2365 GET_CHAR_ARG (signature_type
);
2366 ARG (jvalue
, new_value
);
2367 env
->callbacks
.FieldModification (env
, jni_env
, event_thread
, method
,
2368 location
, field_class
, object
,
2369 field
, signature_type
, new_value
);
2373 case JVMTI_EVENT_METHOD_ENTRY
:
2374 if (env
->callbacks
.MethodEntry
!= NULL
)
2376 ARG (JNIEnv
*, jni_env
);
2377 ARG (jmethodID
, method
);
2378 env
->callbacks
.MethodEntry (env
, jni_env
, event_thread
, method
);
2382 case JVMTI_EVENT_METHOD_EXIT
:
2383 if (env
->callbacks
.MethodExit
!= NULL
)
2385 ARG (JNIEnv
*, jni_env
);
2386 ARG (jmethodID
, method
);
2387 GET_BOOLEAN_ARG (was_popped_by_exception
);
2388 ARG (jvalue
, return_value
);
2389 env
->callbacks
.MethodExit (env
, jni_env
, event_thread
, method
,
2390 was_popped_by_exception
, return_value
);
2394 case JVMTI_EVENT_NATIVE_METHOD_BIND
:
2395 if (env
->callbacks
.NativeMethodBind
!= NULL
)
2397 ARG (JNIEnv
*, jni_env
);
2398 ARG (jmethodID
, method
);
2399 ARG (void *, address
);
2400 ARG (void **, new_address_ptr
);
2401 env
->callbacks
.NativeMethodBind (env
, jni_env
, event_thread
, method
,
2402 address
, new_address_ptr
);
2406 case JVMTI_EVENT_COMPILED_METHOD_LOAD
:
2407 if (env
->callbacks
.CompiledMethodLoad
!= NULL
)
2409 ARG (jmethodID
, method
);
2410 ARG (jint
, code_size
);
2411 ARG (const void *, code_addr
);
2412 ARG (jint
, map_length
);
2413 ARG (const jvmtiAddrLocationMap
*, map
);
2414 ARG (const void *, compile_info
);
2415 env
->callbacks
.CompiledMethodLoad (env
, method
, code_size
, code_addr
,
2416 map_length
, map
, compile_info
);
2420 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD
:
2421 if (env
->callbacks
.CompiledMethodUnload
!= NULL
)
2423 ARG (jmethodID
, method
);
2424 ARG (const void *, code_addr
);
2425 env
->callbacks
.CompiledMethodUnload (env
, method
, code_addr
);
2429 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED
:
2430 if (env
->callbacks
.DynamicCodeGenerated
!= NULL
)
2432 ARG (const char *, name
);
2433 ARG (const void *, address
);
2435 env
->callbacks
.DynamicCodeGenerated (env
, name
, address
, length
);
2439 case JVMTI_EVENT_DATA_DUMP_REQUEST
:
2440 if (env
->callbacks
.DataDumpRequest
!= NULL
)
2442 env
->callbacks
.DataDumpRequest (env
);
2446 case JVMTI_EVENT_MONITOR_WAIT
:
2447 if (env
->callbacks
.MonitorWait
!= NULL
)
2449 ARG (JNIEnv
*, jni_env
);
2450 ARG (jobject
, object
);
2451 ARG (jlong
, timeout
);
2452 env
->callbacks
.MonitorWait (env
, jni_env
, event_thread
, object
,
2457 case JVMTI_EVENT_MONITOR_WAITED
:
2458 if (env
->callbacks
.MonitorWaited
!= NULL
)
2460 ARG (JNIEnv
*, jni_env
);
2461 ARG (jobject
, object
);
2462 GET_BOOLEAN_ARG (timed_out
);
2463 env
->callbacks
.MonitorWaited (env
, jni_env
, event_thread
, object
,
2468 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER
:
2469 if (env
->callbacks
.MonitorContendedEnter
!= NULL
)
2471 ARG (JNIEnv
*, jni_env
);
2472 ARG (jobject
, object
);
2473 env
->callbacks
.MonitorContendedEnter (env
, jni_env
, event_thread
,
2478 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED
:
2479 if (env
->callbacks
.MonitorContendedEntered
!= NULL
)
2481 ARG (JNIEnv
*, jni_env
);
2482 ARG (jobject
, object
);
2483 env
->callbacks
.MonitorContendedEntered (env
, jni_env
, event_thread
,
2488 case JVMTI_EVENT_GARBAGE_COLLECTION_START
:
2489 if (env
->callbacks
.GarbageCollectionStart
!= NULL
)
2491 env
->callbacks
.GarbageCollectionStart (env
);
2495 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH
:
2496 if (env
->callbacks
.GarbageCollectionFinish
!= NULL
)
2498 env
->callbacks
.GarbageCollectionFinish (env
);
2502 case JVMTI_EVENT_OBJECT_FREE
:
2503 if (env
->callbacks
.ObjectFree
!= NULL
)
2506 env
->callbacks
.ObjectFree (env
, tag
);
2510 case JVMTI_EVENT_VM_OBJECT_ALLOC
:
2511 if (env
->callbacks
.VMObjectAlloc
!= NULL
)
2513 ARG (JNIEnv
*, jni_env
);
2514 ARG (jobject
, object
);
2515 ARG (jclass
, object_class
);
2517 env
->callbacks
.VMObjectAlloc (env
, jni_env
, event_thread
,
2518 object
, object_class
, size
);
2523 fprintf (stderr
, "libgcj: post of unknown JVMTI event (%d)\n",
2529 #undef GET_BOOLEAN_ARG
2533 /* Post an event to requesting JVMTI environments
2535 * This function should not be called without consulting the
2536 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2537 * harm (other than kill speed), since this function will still
2538 * only send the event if it was properly requested by an environment.
2541 _Jv_JVMTI_PostEvent (jvmtiEvent type
, jthread event_thread
, ...)
2544 va_start (args
, event_thread
);
2546 _envListLock
->readLock ()->lock ();
2547 struct jvmti_env_list
*e
;
2548 FOREACH_ENVIRONMENT (e
)
2550 /* Events are only posted if the event was explicitly enabled,
2551 it has a registered event handler, and the event thread
2552 matches (either globally or restricted to a specific thread).
2553 Here we check all but the event handler, which will be handled
2555 if (e
->env
->enabled
[EVENT_INDEX(type
)]
2556 && (e
->env
->thread
[EVENT_INDEX(type
)] == NULL
2557 || e
->env
->thread
[EVENT_INDEX(type
)] == event_thread
))
2559 post_event (e
->env
, type
, event_thread
, args
);
2562 _envListLock
->readLock ()->unlock ();