fortran/
[official-gcc.git] / libjava / jvmti.cc
blob7c7923b2e8d81cf9189dadbf436a4c40b1a32681
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
9 details. */
11 #include <config.h>
12 #include <platform.h>
14 #include <jvm.h>
15 #include <java-threads.h>
16 #include <java-gc.h>
17 #include <java-interp.h>
18 #include <jvmti.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);
47 namespace JVMTI
49 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
50 bool enabled;
52 // Event notifications
53 bool VMInit = false;
54 bool VMDeath = false;
55 bool ThreadStart = false;
56 bool ThreadEnd = false;
57 bool ClassFileLoadHook = false;
58 bool ClassLoad = false;
59 bool ClassPrepare = false;
60 bool VMStart = 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
94 _Jv_Mutex_t mutex;
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
104 jvmtiEnv *env;
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) \
116 do \
118 if (Ajthread == NULL) \
119 Ajthread = java::lang::Thread::currentThread (); \
121 while (0)
123 #define THREAD_CHECK_VALID(Athread) \
124 do \
126 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
127 return JVMTI_ERROR_INVALID_THREAD; \
129 while (0)
131 #define THREAD_CHECK_IS_ALIVE(Athread) \
132 do \
134 if (!Athread->isAlive ()) \
135 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
137 while (0)
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) \
144 do \
146 if (Ptr == NULL) \
147 return JVMTI_ERROR_NULL_POINTER; \
149 while (0)
151 #define ILLEGAL_ARGUMENT(Cond) \
152 do \
154 if ((Cond)) \
155 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
157 while (0)
159 #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
160 do \
162 jboolean is_native; \
163 jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
164 if (jerr != JVMTI_ERROR_NONE) \
165 return jerr; \
166 if (is_native) \
167 return JVMTI_ERROR_NATIVE_METHOD; \
169 while (0)
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'
206 if (thread == NULL)
207 return JVMTI_ERROR_INVALID_THREAD;
209 THREAD_CHECK_VALID (thread);
210 THREAD_CHECK_IS_ALIVE (thread);
211 thread->interrupt();
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.
217 static jvmtiError
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++)
235 frame = frame->next;
237 if (frame == NULL)
238 return JVMTI_ERROR_NO_MORE_FRAMES;
241 if (frame->frame_type == frame_native)
242 return JVMTI_ERROR_OPAQUE_FRAME;
244 jint max_locals;
245 jvmtiError jerr = env->GetMaxLocals (reinterpret_cast<jmethodID>
246 (frame->self->get_method ()),
247 &max_locals);
248 if (jerr != JVMTI_ERROR_NONE)
249 return jerr;
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,
274 jobject *value)
276 NULL_CHECK (value);
278 _Jv_InterpFrame *frame;
279 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
281 if (jerr != JVMTI_ERROR_NONE)
282 return jerr;
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,
291 jobject value)
293 _Jv_InterpFrame *frame;
294 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
296 if (jerr != JVMTI_ERROR_NONE)
297 return jerr;
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,
306 jint *value)
308 NULL_CHECK (value);
310 _Jv_InterpFrame *frame;
311 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
313 if (jerr != JVMTI_ERROR_NONE)
314 return jerr;
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,
323 jint value)
325 _Jv_InterpFrame *frame;
326 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
328 if (jerr != JVMTI_ERROR_NONE)
329 return jerr;
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,
338 jlong *value)
340 NULL_CHECK (value);
342 _Jv_InterpFrame *frame;
343 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
345 if (jerr != JVMTI_ERROR_NONE)
346 return jerr;
348 #if SIZEOF_VOID_P==8
349 *value = frame->locals[slot].l;
350 #else
351 _Jv_word2 val;
352 val.ia[0] = frame->locals[slot].ia[0];
353 val.ia[1] = frame->locals[slot + 1].ia[0];
354 *value = val.l;
355 #endif
357 return JVMTI_ERROR_NONE;
360 static jvmtiError JNICALL
361 _Jv_JVMTI_SetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
362 jlong value)
364 _Jv_InterpFrame *frame;
365 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
367 if (jerr != JVMTI_ERROR_NONE)
368 return jerr;
370 #if SIZEOF_VOID_P==8
371 frame->locals[slot].l = value;
372 #else
373 _Jv_word2 val;
374 val.l = value;
375 frame->locals[slot].ia[0] = val.ia[0];
376 frame->locals[slot + 1].ia[0] = val.ia[1];
377 #endif
379 return JVMTI_ERROR_NONE;
383 static jvmtiError JNICALL
384 _Jv_JVMTI_GetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
385 jfloat *value)
387 NULL_CHECK (value);
389 _Jv_InterpFrame *frame;
390 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
392 if (jerr != JVMTI_ERROR_NONE)
393 return jerr;
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,
402 jfloat value)
404 _Jv_InterpFrame *frame;
405 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
407 if (jerr != JVMTI_ERROR_NONE)
408 return jerr;
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,
418 jdouble *value)
420 NULL_CHECK (value);
422 _Jv_InterpFrame *frame;
423 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
425 if (jerr != JVMTI_ERROR_NONE)
426 return jerr;
428 #if SIZEOF_VOID_P==8
429 *value = frame->locals[slot].d;
430 #else
431 _Jv_word2 val;
432 val.ia[0] = frame->locals[slot].ia[0];
433 val.ia[1] = frame->locals[slot + 1].ia[0];
434 *value = val.d;
435 #endif
437 return JVMTI_ERROR_NONE;
440 static jvmtiError JNICALL
441 _Jv_JVMTI_SetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
442 jdouble value)
444 _Jv_InterpFrame *frame;
445 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
447 if (jerr != JVMTI_ERROR_NONE)
448 return jerr;
450 #if SIZEOF_VOID_P==8
451 frame->locals[slot].d = value;
452 #else
453 _Jv_word2 val;
454 val.d = value;
455 frame->locals[slot].ia[0] = val.ia[0];
456 frame->locals[slot + 1].ia[0] = val.ia[1];
457 #endif
459 return JVMTI_ERROR_NONE;
462 static jvmtiError JNICALL
463 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
464 jthread **threads)
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
481 ((estimate * 2),
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)
495 return jerr;
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,
507 jint *frame_count)
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);
534 jint state = 0;
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
569 are never set. */
572 else
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);
589 NULL_CHECK (name);
590 NULL_CHECK (result);
591 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
592 if (*result == NULL)
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.
605 if (monitor == NULL)
606 return JVMTI_ERROR_INVALID_MONITOR;
607 // FIXME: perform checks on monitor, release it if this thread owns
608 // it.
609 #ifdef _Jv_HaveMutexDestroy
610 _Jv_MutexDestroy (&monitor->mutex);
611 #endif
612 _Jv_Free (monitor);
613 return JVMTI_ERROR_NONE;
616 static jvmtiError JNICALL
617 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
619 if (monitor == NULL)
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)
628 if (monitor == NULL)
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,
637 jlong millis)
639 if (monitor == NULL)
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)
652 if (monitor == NULL)
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)
663 if (monitor == NULL)
664 return JVMTI_ERROR_INVALID_MONITOR;
665 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
666 == _JV_NOT_OWNER)
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;
677 Breakpoint *bp
678 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
679 location);
680 if (bp == NULL)
682 jclass klass;
683 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
684 if (err != JVMTI_ERROR_NONE)
685 return err;
687 if (!_Jv_IsInterpretedClass (klass))
688 return JVMTI_ERROR_INVALID_CLASS;
690 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
691 if (base == NULL)
692 return JVMTI_ERROR_INVALID_METHODID;
694 jint flags;
695 err = env->GetMethodModifiers (method, &flags);
696 if (err != JVMTI_ERROR_NONE)
697 return err;
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),
708 location);
710 else
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,
721 jlocation location)
723 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
725 using namespace gnu::gcj::jvmti;
727 Breakpoint *bp
728 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
729 location);
730 if (bp == NULL)
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);
742 NULL_CHECK (result);
743 if (size == 0)
744 *result = NULL;
745 else
747 *result = (unsigned char *) _Jv_MallocUnchecked (size);
748 if (*result == NULL)
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)
757 if (mem != NULL)
758 _Jv_Free (mem);
759 return JVMTI_ERROR_NONE;
762 static jvmtiError JNICALL
763 _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
764 jint *status_ptr)
766 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
767 NULL_CHECK (status_ptr);
768 if (klass == NULL)
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;
775 else
777 jbyte state = _Jv_GetClassState (klass);
778 *status_ptr = 0;
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,
794 jint *mods)
796 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
797 // Don't bother checking KLASS' type.
798 if (klass == NULL)
799 return JVMTI_ERROR_INVALID_CLASS;
800 NULL_CHECK (mods);
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.
812 if (klass == NULL)
813 return JVMTI_ERROR_INVALID_CLASS;
814 NULL_CHECK (count_ptr);
815 NULL_CHECK (methods_ptr);
816 *count_ptr = JvNumMethods(klass);
818 *methods_ptr
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)
825 // FIXME: correct?
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,
833 jboolean *result)
835 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
836 if (klass == NULL)
837 return JVMTI_ERROR_INVALID_CLASS;
838 NULL_CHECK (result);
839 *result = klass->isInterface();
840 return JVMTI_ERROR_NONE;
843 static jvmtiError JNICALL
844 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
845 jboolean *result)
847 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
848 if (klass == NULL)
849 return JVMTI_ERROR_INVALID_CLASS;
850 NULL_CHECK (result);
851 *result = klass->isArray();
852 return JVMTI_ERROR_NONE;
855 static jvmtiError JNICALL
856 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
857 jobject *result)
859 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
860 if (klass == NULL)
861 return JVMTI_ERROR_INVALID_CLASS;
862 NULL_CHECK (result);
863 *result = klass->getClassLoaderInternal();
864 return JVMTI_ERROR_NONE;
867 static jvmtiError JNICALL
868 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
869 jint *result)
871 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
872 if (obj == NULL)
873 return JVMTI_ERROR_INVALID_OBJECT;
874 NULL_CHECK (result);
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);
884 if (klass == NULL)
885 return JVMTI_ERROR_INVALID_CLASS;
886 if (field == NULL)
887 return JVMTI_ERROR_INVALID_FIELDID;
888 NULL_CHECK (result);
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);
898 if (klass == NULL)
899 return JVMTI_ERROR_INVALID_CLASS;
900 if (field == NULL)
901 return JVMTI_ERROR_INVALID_FIELDID;
902 NULL_CHECK (result);
904 // FIXME: capability can_get_synthetic_attribute
905 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
906 != 0);
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,
913 char **generic_ptr)
915 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
917 if (method == NULL)
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)
946 *generic_ptr = NULL;
949 return JVMTI_ERROR_NONE;
952 static jvmtiError JNICALL
953 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
954 jint *result)
956 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
957 if (method == NULL)
958 return JVMTI_ERROR_INVALID_METHODID;
959 NULL_CHECK (result);
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);
974 jclass klass;
975 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
976 if (jerr != JVMTI_ERROR_NONE)
977 return jerr;
979 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
980 if (base == NULL)
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);
988 jlong start, end;
989 jintArray lines = NULL;
990 jlongArray indices = NULL;
991 imeth->get_line_table (start, end, lines, indices);
992 if (lines == NULL)
993 return JVMTI_ERROR_ABSENT_INFORMATION;
995 jvmtiLineNumberEntry *table;
996 jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
997 table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
998 if (table == NULL)
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];
1009 *table_ptr = table;
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,
1016 jint *num_locals,
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);
1025 jclass klass;
1026 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
1027 if (jerr != JVMTI_ERROR_NONE)
1028 return jerr;
1030 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
1031 (_Jv_FindInterpreterMethod (klass, method));
1033 if (imeth == NULL)
1034 return JVMTI_ERROR_INVALID_METHODID;
1036 jerr = env->GetMaxLocals (method, num_locals);
1037 if (jerr != JVMTI_ERROR_NONE)
1038 return jerr;
1040 jerr = env->Allocate (static_cast<jlong>
1041 ((*num_locals) * sizeof (jvmtiLocalVariableEntry)),
1042 reinterpret_cast<unsigned char **> (locals));
1044 if (jerr != JVMTI_ERROR_NONE)
1045 return jerr;
1047 //the slot in the methods local_var_table to get
1048 int table_slot = 0;
1049 char *name;
1050 char *sig;
1051 char *generic_sig;
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),
1058 table_slot)
1059 >= 0)
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)
1065 return jerr;
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)
1072 return jerr;
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)
1079 return jerr;
1080 strcpy ((*locals)[table_slot].generic_signature, generic_sig);
1082 table_slot++;
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,
1098 jboolean *result)
1100 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1101 if (method == NULL)
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,
1111 jboolean *result)
1113 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1114 if (method == NULL)
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)
1121 != 0);
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);
1133 jclass klass;
1134 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
1135 if (jerr != JVMTI_ERROR_NONE)
1136 return jerr;
1138 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
1139 (_Jv_FindInterpreterMethod (klass, method));
1141 if (imeth == NULL)
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);
1153 NULL_CHECK (size);
1155 CHECK_FOR_NATIVE_METHOD (method);
1157 jvmtiError jerr;
1158 char *sig;
1159 jint num_slots = 0;
1161 jerr = env->GetMethodName (method, NULL, &sig, NULL);
1162 if (jerr != JVMTI_ERROR_NONE)
1163 return jerr;
1165 // If the method is non-static add a slot for the "this" pointer.
1166 if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
1167 num_slots++;
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')
1173 num_slots++;
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] == '[')
1178 num_slots++;
1179 else
1180 num_slots += 2;
1182 else if (sig[i] == 'L')
1184 num_slots++;
1185 while (sig[i] != ';')
1186 i++;
1190 *size = num_slots;
1191 return JVMTI_ERROR_NONE;
1194 static jvmtiError JNICALL
1195 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
1196 jmethodID method,
1197 jclass *declaring_class_ptr)
1199 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1200 NULL_CHECK (declaring_class_ptr);
1202 jclass klass = _Jv_GetMethodDeclaringClass (method);
1203 if (klass != NULL)
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,
1215 jint *count_ptr,
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;
1226 if (loader == NULL)
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);
1233 jclass *result
1234 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
1235 if (result == NULL)
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)
1266 return jerr;
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;
1289 start_depth--;
1290 (*frame_count)--;
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 ());
1311 else
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);
1324 _Jv_RunGC();
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);
1344 *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)
1355 NULL_CHECK (env);
1357 if (_jvmtiEnvironments == NULL)
1358 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1359 else
1361 _envListLock->writeLock ()->lock ();
1362 if (_jvmtiEnvironments->env == env)
1364 struct jvmti_env_list *next = _jvmtiEnvironments->next;
1365 _Jv_Free (_jvmtiEnvironments);
1366 _jvmtiEnvironments = next;
1368 else
1370 struct jvmti_env_list *e = _jvmtiEnvironments;
1371 while (e->next != NULL && e->next->env != env)
1372 e = e->next;
1373 if (e->next == NULL)
1375 _envListLock->writeLock ()->unlock ();
1376 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1379 struct jvmti_env_list *next = e->next->next;
1380 _Jv_Free (e->next);
1381 e->next = next;
1383 _envListLock->writeLock ()->unlock ();
1386 _Jv_Free (env);
1388 check_enabled_events ();
1390 return JVMTI_ERROR_NONE;
1393 static jvmtiError JNICALL
1394 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1395 char **result)
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,
1419 const char *value)
1421 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1423 NULL_CHECK (property);
1424 if (value == NULL)
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);
1451 #else
1452 *nprocessors_ptr = 1;
1453 #endif
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);
1469 URL *url;
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,
1488 jboolean value)
1490 switch (flag)
1492 case JVMTI_VERBOSE_OTHER:
1493 case JVMTI_VERBOSE_GC:
1494 case JVMTI_VERBOSE_JNI:
1495 // Ignore.
1496 break;
1497 case JVMTI_VERBOSE_CLASS:
1498 gcj::verbose_class_flag = value;
1499 break;
1500 default:
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,
1508 jlong *result)
1510 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1511 if (object == NULL)
1512 return JVMTI_ERROR_INVALID_OBJECT;
1513 NULL_CHECK (result);
1515 jclass klass = object->getClass();
1516 if (klass->isArray())
1518 jclass comp = klass->getComponentType();
1519 jint base
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;
1527 else
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. */
1538 static void
1539 check_enabled_event (jvmtiEvent type)
1541 bool *enabled;
1542 int offset;
1544 #define GET_OFFSET(Event) \
1545 do \
1547 enabled = &JVMTI::Event; \
1548 offset = offsetof (jvmtiEventCallbacks, Event); \
1550 while (0)
1552 switch (type)
1554 case JVMTI_EVENT_VM_INIT:
1555 GET_OFFSET (VMInit);
1556 break;
1558 case JVMTI_EVENT_VM_DEATH:
1559 GET_OFFSET (VMDeath);
1560 break;
1562 case JVMTI_EVENT_THREAD_START:
1563 GET_OFFSET (ThreadStart);
1564 break;
1566 case JVMTI_EVENT_THREAD_END:
1567 GET_OFFSET (ThreadEnd);
1568 break;
1570 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1571 GET_OFFSET (ClassFileLoadHook);
1572 break;
1574 case JVMTI_EVENT_CLASS_LOAD:
1575 GET_OFFSET (ClassLoad);
1576 break;
1578 case JVMTI_EVENT_CLASS_PREPARE:
1579 GET_OFFSET (ClassPrepare);
1580 break;
1582 case JVMTI_EVENT_VM_START:
1583 GET_OFFSET (VMStart);
1584 break;
1586 case JVMTI_EVENT_EXCEPTION:
1587 GET_OFFSET (Exception);
1588 break;
1590 case JVMTI_EVENT_EXCEPTION_CATCH:
1591 GET_OFFSET (ExceptionCatch);
1592 break;
1594 case JVMTI_EVENT_SINGLE_STEP:
1595 GET_OFFSET (SingleStep);
1596 break;
1598 case JVMTI_EVENT_FRAME_POP:
1599 GET_OFFSET (FramePop);
1600 break;
1602 case JVMTI_EVENT_BREAKPOINT:
1603 GET_OFFSET (Breakpoint);
1604 break;
1606 case JVMTI_EVENT_FIELD_ACCESS:
1607 GET_OFFSET (FieldAccess);
1608 break;
1610 case JVMTI_EVENT_FIELD_MODIFICATION:
1611 GET_OFFSET (FieldModification);
1612 break;
1614 case JVMTI_EVENT_METHOD_ENTRY:
1615 GET_OFFSET (MethodEntry);
1616 break;
1618 case JVMTI_EVENT_METHOD_EXIT:
1619 GET_OFFSET (MethodExit);
1620 break;
1622 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1623 GET_OFFSET (NativeMethodBind);
1624 break;
1626 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1627 GET_OFFSET (CompiledMethodLoad);
1628 break;
1630 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1631 GET_OFFSET (CompiledMethodUnload);
1632 break;
1634 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1635 GET_OFFSET (DynamicCodeGenerated);
1636 break;
1638 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1639 GET_OFFSET (DataDumpRequest);
1640 break;
1642 case JVMTI_EVENT_MONITOR_WAIT:
1643 GET_OFFSET (MonitorWait);
1644 break;
1646 case JVMTI_EVENT_MONITOR_WAITED:
1647 GET_OFFSET (MonitorWaited);
1648 break;
1650 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1651 GET_OFFSET (MonitorContendedEnter);
1652 break;
1654 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1655 GET_OFFSET (MonitorContendedEntered);
1656 break;
1658 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1659 GET_OFFSET (GarbageCollectionStart);
1660 break;
1662 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1663 GET_OFFSET (GarbageCollectionFinish);
1664 break;
1666 case JVMTI_EVENT_OBJECT_FREE:
1667 GET_OFFSET (ObjectFree);
1668 break;
1670 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1671 GET_OFFSET (VMObjectAlloc);
1672 break;
1674 default:
1675 fprintf (stderr,
1676 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1677 (int) type);
1678 return;
1680 #undef GET_OFFSET
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)
1690 char *addr
1691 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1692 void **callback = reinterpret_cast<void **> (addr);
1693 if (e->env->enabled[index] && *callback != NULL)
1695 *enabled = true;
1696 _envListLock->readLock ()->unlock ();
1697 return;
1701 _envListLock->readLock ()->unlock ();
1704 *enabled = false;
1707 static void
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);
1754 bool enabled;
1755 switch (mode)
1757 case JVMTI_DISABLE:
1758 enabled = false;
1759 break;
1760 case JVMTI_ENABLE:
1761 enabled = true;
1762 break;
1764 default:
1765 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1768 switch (type)
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);
1779 break;
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:
1803 break;
1805 default:
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,
1836 char **name_ptr)
1838 NULL_CHECK (name_ptr);
1840 const char *name;
1841 switch (error)
1843 case JVMTI_ERROR_NONE:
1844 name = "none";
1845 break;
1847 case JVMTI_ERROR_NULL_POINTER:
1848 name = "null pointer";
1849 break;
1851 case JVMTI_ERROR_OUT_OF_MEMORY:
1852 name = "out of memory";
1853 break;
1855 case JVMTI_ERROR_ACCESS_DENIED:
1856 name = "access denied";
1857 break;
1859 case JVMTI_ERROR_WRONG_PHASE:
1860 name = "wrong phase";
1861 break;
1863 case JVMTI_ERROR_INTERNAL:
1864 name = "internal error";
1865 break;
1867 case JVMTI_ERROR_UNATTACHED_THREAD:
1868 name = "unattached thread";
1869 break;
1871 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1872 name = "invalid environment";
1873 break;
1875 case JVMTI_ERROR_INVALID_PRIORITY:
1876 name = "invalid priority";
1877 break;
1879 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1880 name = "thread not suspended";
1881 break;
1883 case JVMTI_ERROR_THREAD_SUSPENDED:
1884 name = "thread suspended";
1885 break;
1887 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1888 name = "thread not alive";
1889 break;
1891 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1892 name = "class not prepared";
1893 break;
1895 case JVMTI_ERROR_NO_MORE_FRAMES:
1896 name = "no more frames";
1897 break;
1899 case JVMTI_ERROR_OPAQUE_FRAME:
1900 name = "opaque frame";
1901 break;
1903 case JVMTI_ERROR_DUPLICATE:
1904 name = "duplicate";
1905 break;
1907 case JVMTI_ERROR_NOT_FOUND:
1908 name = "not found";
1909 break;
1911 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1912 name = "not monitor owner";
1913 break;
1915 case JVMTI_ERROR_INTERRUPT:
1916 name = "interrupted";
1917 break;
1919 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1920 name = "unmodifiable class";
1921 break;
1923 case JVMTI_ERROR_NOT_AVAILABLE:
1924 name = "not available";
1925 break;
1927 case JVMTI_ERROR_ABSENT_INFORMATION:
1928 name = "absent information";
1929 break;
1931 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1932 name = "invalid event type";
1933 break;
1935 case JVMTI_ERROR_NATIVE_METHOD:
1936 name = "native method";
1937 break;
1939 case JVMTI_ERROR_INVALID_THREAD:
1940 name = "invalid thread";
1941 break;
1943 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1944 name = "invalid thread group";
1945 break;
1947 case JVMTI_ERROR_INVALID_OBJECT:
1948 name = "invalid object";
1949 break;
1951 case JVMTI_ERROR_INVALID_CLASS:
1952 name = "invalid class";
1953 break;
1955 case JVMTI_ERROR_INVALID_METHODID:
1956 name = "invalid method ID";
1957 break;
1959 case JVMTI_ERROR_INVALID_LOCATION:
1960 name = "invalid location";
1961 break;
1963 case JVMTI_ERROR_INVALID_FIELDID:
1964 name = "invalid field ID";
1965 break;
1967 case JVMTI_ERROR_TYPE_MISMATCH:
1968 name = "type mismatch";
1969 break;
1971 case JVMTI_ERROR_INVALID_SLOT:
1972 name = "invalid slot";
1973 break;
1975 case JVMTI_ERROR_INVALID_MONITOR:
1976 name = "invalid monitor";
1977 break;
1979 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1980 name = "invalid class format";
1981 break;
1983 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1984 name = "circular class definition";
1985 break;
1987 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1988 name = "unsupported redefinition: method added";
1989 break;
1991 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1992 name = "unsupported redefinition: schema changed";
1993 break;
1995 case JVMTI_ERROR_INVALID_TYPESTATE:
1996 name = "invalid type state";
1997 break;
1999 case JVMTI_ERROR_FAILS_VERIFICATION:
2000 name = "fails verification";
2001 break;
2003 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
2004 name = "unsupported redefinition: hierarchy changed";
2005 break;
2007 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
2008 name = "unsupported redefinition: method deleted";
2009 break;
2011 case JVMTI_ERROR_UNSUPPORTED_VERSION:
2012 name = "unsupported version";
2013 break;
2015 case JVMTI_ERROR_NAMES_DONT_MATCH:
2016 name = "names do not match";
2017 break;
2019 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
2020 name = "unsupported redefinition: class modifiers changed";
2021 break;
2023 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
2024 name = "unsupported redefinition: method modifiers changed";
2025 break;
2027 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
2028 name = "must possess capability";
2029 break;
2031 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
2032 name = "illegal argument";
2033 break;
2035 default:
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
2208 _Jv_JVMTIEnv *
2209 _Jv_GetJVMTIEnv (void)
2211 _Jv_JVMTIEnv *env
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));
2217 element->env = env;
2218 element->next = NULL;
2220 _envListLock->writeLock ()->lock ();
2221 if (_jvmtiEnvironments == NULL)
2222 _jvmtiEnvironments = element;
2223 else
2225 struct jvmti_env_list *e;
2226 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
2228 e->next = element;
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;
2236 return env;
2239 void
2240 _Jv_JVMTI_Init ()
2242 _jvmtiEnvironments = NULL;
2243 _envListLock
2244 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2246 // No environments, so this should set all JVMTI:: members to false
2247 check_enabled_events ();
2250 static void
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) \
2256 ARG (int, b); \
2257 jboolean Name = (b == 0) ? false : true
2259 #define GET_CHAR_ARG(Name) \
2260 ARG (int, c); \
2261 char Name = static_cast<char> (c)
2263 switch (type)
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);
2271 break;
2273 case JVMTI_EVENT_VM_DEATH:
2274 if (env->callbacks.VMDeath != NULL)
2276 ARG (JNIEnv *, jni_env);
2277 env->callbacks.VMDeath (env, jni_env);
2279 break;
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);
2287 break;
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);
2295 break;
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,
2313 new_class_data_len,
2314 new_class_data);
2316 break;
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);
2325 break;
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);
2334 break;
2336 case JVMTI_EVENT_VM_START:
2337 if (env->callbacks.VMStart != NULL)
2339 ARG (JNIEnv *, jni_env);
2340 env->callbacks.VMStart (env, jni_env);
2342 break;
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,
2355 catch_location);
2357 break;
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);
2369 break;
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,
2378 location);
2380 break;
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);
2391 break;
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,
2400 location);
2402 break;
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);
2416 break;
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);
2433 break;
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);
2442 break;
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);
2454 break;
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);
2466 break;
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);
2480 break;
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);
2489 break;
2491 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
2492 if (env->callbacks.DynamicCodeGenerated != NULL)
2494 ARG (const char *, name);
2495 ARG (const void *, address);
2496 ARG (jint, length);
2497 env->callbacks.DynamicCodeGenerated (env, name, address, length);
2499 break;
2501 case JVMTI_EVENT_DATA_DUMP_REQUEST:
2502 if (env->callbacks.DataDumpRequest != NULL)
2504 env->callbacks.DataDumpRequest (env);
2506 break;
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,
2515 timeout);
2517 break;
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,
2526 timed_out);
2528 break;
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,
2536 object);
2538 break;
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,
2546 object);
2548 break;
2550 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
2551 if (env->callbacks.GarbageCollectionStart != NULL)
2553 env->callbacks.GarbageCollectionStart (env);
2555 break;
2557 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2558 if (env->callbacks.GarbageCollectionFinish != NULL)
2560 env->callbacks.GarbageCollectionFinish (env);
2562 break;
2564 case JVMTI_EVENT_OBJECT_FREE:
2565 if (env->callbacks.ObjectFree != NULL)
2567 ARG (jlong, tag);
2568 env->callbacks.ObjectFree (env, tag);
2570 break;
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);
2578 ARG (jlong, size);
2579 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2580 object, object_class, size);
2582 break;
2584 default:
2585 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2586 (int) type);
2587 break;
2589 va_end (args);
2590 #undef ARG
2591 #undef GET_BOOLEAN_ARG
2592 #undef GET_CHAR_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.
2602 void
2603 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2605 va_list args;
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
2616 by post_event. */
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 ();
2625 va_end (args);