./:
[official-gcc.git] / libjava / jvmti.cc
blobae906a0da464e10899de54650aa8bad89f8b6d59
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
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/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);
46 namespace JVMTI
48 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
49 bool enabled;
51 // Event notifications
52 bool VMInit = false;
53 bool VMDeath = false;
54 bool ThreadStart = false;
55 bool ThreadEnd = false;
56 bool ClassFileLoadHook = false;
57 bool ClassLoad = false;
58 bool ClassPrepare = false;
59 bool VMStart = 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
93 _Jv_Mutex_t mutex;
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
103 jvmtiEnv *env;
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) \
115 do \
117 if (Ajthread == NULL) \
118 Ajthread = java::lang::Thread::currentThread (); \
120 while (0)
122 #define THREAD_CHECK_VALID(Athread) \
123 do \
125 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
126 return JVMTI_ERROR_INVALID_THREAD; \
128 while (0)
130 #define THREAD_CHECK_IS_ALIVE(Athread) \
131 do \
133 if (!Athread->isAlive ()) \
134 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
136 while (0)
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) \
143 do \
145 if (Ptr == NULL) \
146 return JVMTI_ERROR_NULL_POINTER; \
148 while (0)
150 #define ILLEGAL_ARGUMENT(Cond) \
151 do \
153 if ((Cond)) \
154 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
156 while (0)
158 #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
159 do \
161 jboolean is_native; \
162 jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
163 if (jerr != JVMTI_ERROR_NONE) \
164 return jerr; \
165 if (is_native) \
166 return JVMTI_ERROR_NATIVE_METHOD; \
168 while (0)
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'
205 if (thread == NULL)
206 return JVMTI_ERROR_INVALID_THREAD;
208 THREAD_CHECK_VALID (thread);
209 THREAD_CHECK_IS_ALIVE (thread);
210 thread->interrupt();
211 return JVMTI_ERROR_NONE;
214 static jvmtiError JNICALL
215 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
216 jthread **threads)
218 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
219 NULL_CHECK (thread_cnt);
220 NULL_CHECK (threads);
222 using namespace java::lang;
224 ThreadGroup *root_grp = ThreadGroup::root;
225 jint estimate = root_grp->activeCount ();
227 JArray<Thread *> *thr_arr;
229 // Allocate some extra space since threads can be created between calls
232 thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
233 ((estimate * 2),
234 &Thread::class$, NULL));
236 catch (java::lang::OutOfMemoryError *err)
238 return JVMTI_ERROR_OUT_OF_MEMORY;
241 *thread_cnt = root_grp->enumerate (thr_arr);
243 jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)),
244 (unsigned char **) threads);
246 if (jerr != JVMTI_ERROR_NONE)
247 return jerr;
249 // Transfer the threads to the result array
250 jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr));
252 memcpy ((*threads), tmp_arr, (*thread_cnt));
254 return JVMTI_ERROR_NONE;
257 static jvmtiError JNICALL
258 _Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
259 jint *frame_count)
261 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
263 NULL_CHECK (frame_count);
265 using namespace java::lang;
267 THREAD_DEFAULT_TO_CURRENT (thread);
268 THREAD_CHECK_VALID (thread);
269 THREAD_CHECK_IS_ALIVE (thread);
271 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
272 (*frame_count) = frame->depth ();
273 return JVMTI_ERROR_NONE;
276 static jvmtiError JNICALL
277 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
278 jrawMonitorID *result)
280 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
281 NULL_CHECK (name);
282 NULL_CHECK (result);
283 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
284 if (*result == NULL)
285 return JVMTI_ERROR_OUT_OF_MEMORY;
286 _Jv_MutexInit (&(*result)->mutex);
287 _Jv_CondInit (&(*result)->condition);
288 return JVMTI_ERROR_NONE;
291 static jvmtiError JNICALL
292 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
294 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
295 // Note we have no better way of knowing whether this object is
296 // really a raw monitor.
297 if (monitor == NULL)
298 return JVMTI_ERROR_INVALID_MONITOR;
299 // FIXME: perform checks on monitor, release it if this thread owns
300 // it.
301 #ifdef _Jv_HaveMutexDestroy
302 _Jv_MutexDestroy (&monitor->mutex);
303 #endif
304 _Jv_Free (monitor);
305 return JVMTI_ERROR_NONE;
308 static jvmtiError JNICALL
309 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
311 if (monitor == NULL)
312 return JVMTI_ERROR_INVALID_MONITOR;
313 _Jv_MutexLock (&monitor->mutex);
314 return JVMTI_ERROR_NONE;
317 static jvmtiError JNICALL
318 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
320 if (monitor == NULL)
321 return JVMTI_ERROR_INVALID_MONITOR;
322 if (_Jv_MutexUnlock (&monitor->mutex))
323 return JVMTI_ERROR_NOT_MONITOR_OWNER;
324 return JVMTI_ERROR_NONE;
327 static jvmtiError JNICALL
328 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
329 jlong millis)
331 if (monitor == NULL)
332 return JVMTI_ERROR_INVALID_MONITOR;
333 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
334 if (r == _JV_NOT_OWNER)
335 return JVMTI_ERROR_NOT_MONITOR_OWNER;
336 if (r == _JV_INTERRUPTED)
337 return JVMTI_ERROR_INTERRUPT;
338 return JVMTI_ERROR_NONE;
341 static jvmtiError JNICALL
342 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
344 if (monitor == NULL)
345 return JVMTI_ERROR_INVALID_MONITOR;
346 if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
347 return JVMTI_ERROR_NOT_MONITOR_OWNER;
348 return JVMTI_ERROR_NONE;
351 static jvmtiError JNICALL
352 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
353 jrawMonitorID monitor)
355 if (monitor == NULL)
356 return JVMTI_ERROR_INVALID_MONITOR;
357 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
358 == _JV_NOT_OWNER)
359 return JVMTI_ERROR_NOT_MONITOR_OWNER;
360 return JVMTI_ERROR_NONE;
363 static jvmtiError JNICALL
364 _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
366 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
368 using namespace gnu::gcj::jvmti;
369 Breakpoint *bp
370 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
371 location);
372 if (bp == NULL)
374 jclass klass;
375 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
376 if (err != JVMTI_ERROR_NONE)
377 return err;
379 if (!_Jv_IsInterpretedClass (klass))
380 return JVMTI_ERROR_INVALID_CLASS;
382 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
383 if (base == NULL)
384 return JVMTI_ERROR_INVALID_METHODID;
386 jint flags;
387 err = env->GetMethodModifiers (method, &flags);
388 if (err != JVMTI_ERROR_NONE)
389 return err;
391 if (flags & java::lang::reflect::Modifier::NATIVE)
392 return JVMTI_ERROR_NATIVE_METHOD;
394 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
395 if (imeth->get_insn (location) == NULL)
396 return JVMTI_ERROR_INVALID_LOCATION;
398 // Now the breakpoint can be safely installed
399 bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
400 location);
402 else
404 // Duplicate breakpoints are not permitted by JVMTI
405 return JVMTI_ERROR_DUPLICATE;
408 return JVMTI_ERROR_NONE;
411 static jvmtiError JNICALL
412 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
413 jlocation location)
415 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
417 using namespace gnu::gcj::jvmti;
419 Breakpoint *bp
420 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
421 location);
422 if (bp == NULL)
423 return JVMTI_ERROR_NOT_FOUND;
425 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
426 return JVMTI_ERROR_NONE;
429 static jvmtiError JNICALL
430 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
431 unsigned char **result)
433 ILLEGAL_ARGUMENT (size < 0);
434 NULL_CHECK (result);
435 if (size == 0)
436 *result = NULL;
437 else
439 *result = (unsigned char *) _Jv_MallocUnchecked (size);
440 if (*result == NULL)
441 return JVMTI_ERROR_OUT_OF_MEMORY;
443 return JVMTI_ERROR_NONE;
446 static jvmtiError JNICALL
447 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
449 if (mem != NULL)
450 _Jv_Free (mem);
451 return JVMTI_ERROR_NONE;
454 static jvmtiError JNICALL
455 _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
456 jint *status_ptr)
458 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
459 NULL_CHECK (status_ptr);
460 if (klass == NULL)
461 return JVMTI_ERROR_INVALID_CLASS;
463 if (klass->isArray ())
464 *status_ptr = JVMTI_CLASS_STATUS_ARRAY;
465 else if (klass->isPrimitive ())
466 *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE;
467 else
469 jbyte state = _Jv_GetClassState (klass);
470 *status_ptr = 0;
471 if (state >= JV_STATE_LINKED)
472 (*status_ptr) |= JVMTI_CLASS_STATUS_VERIFIED;
473 if (state >= JV_STATE_PREPARED)
474 (*status_ptr) |= JVMTI_CLASS_STATUS_PREPARED;
475 if (state == JV_STATE_ERROR || state == JV_STATE_PHANTOM)
476 (*status_ptr) |= JVMTI_CLASS_STATUS_ERROR;
477 else if (state == JV_STATE_DONE)
478 (*status_ptr) |= JVMTI_CLASS_STATUS_INITIALIZED;
481 return JVMTI_ERROR_NONE;
484 static jvmtiError JNICALL
485 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
486 jint *mods)
488 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
489 // Don't bother checking KLASS' type.
490 if (klass == NULL)
491 return JVMTI_ERROR_INVALID_CLASS;
492 NULL_CHECK (mods);
493 *mods = klass->getModifiers();
494 return JVMTI_ERROR_NONE;
497 static jvmtiError JNICALL
498 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
499 jint *count_ptr, jmethodID **methods_ptr)
501 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
502 // FIXME: capability can_maintain_original_method_order
503 // Don't bother checking KLASS' type.
504 if (klass == NULL)
505 return JVMTI_ERROR_INVALID_CLASS;
506 NULL_CHECK (count_ptr);
507 NULL_CHECK (methods_ptr);
508 *count_ptr = JvNumMethods(klass);
510 *methods_ptr
511 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
512 if (*methods_ptr == NULL)
513 return JVMTI_ERROR_OUT_OF_MEMORY;
515 jmethodID start = JvGetFirstMethod (klass);
516 for (jint i = 0; i < *count_ptr; ++i)
517 // FIXME: correct?
518 (*methods_ptr)[i] = start + i;
520 return JVMTI_ERROR_NONE;
523 static jvmtiError JNICALL
524 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
525 jboolean *result)
527 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
528 if (klass == NULL)
529 return JVMTI_ERROR_INVALID_CLASS;
530 NULL_CHECK (result);
531 *result = klass->isInterface();
532 return JVMTI_ERROR_NONE;
535 static jvmtiError JNICALL
536 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
537 jboolean *result)
539 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
540 if (klass == NULL)
541 return JVMTI_ERROR_INVALID_CLASS;
542 NULL_CHECK (result);
543 *result = klass->isArray();
544 return JVMTI_ERROR_NONE;
547 static jvmtiError JNICALL
548 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
549 jobject *result)
551 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
552 if (klass == NULL)
553 return JVMTI_ERROR_INVALID_CLASS;
554 NULL_CHECK (result);
555 *result = klass->getClassLoaderInternal();
556 return JVMTI_ERROR_NONE;
559 static jvmtiError JNICALL
560 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
561 jint *result)
563 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
564 if (obj == NULL)
565 return JVMTI_ERROR_INVALID_OBJECT;
566 NULL_CHECK (result);
567 *result = _Jv_HashCode (obj);
568 return JVMTI_ERROR_NONE;
571 static jvmtiError JNICALL
572 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
573 jfieldID field, jint *result)
575 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
576 if (klass == NULL)
577 return JVMTI_ERROR_INVALID_CLASS;
578 if (field == NULL)
579 return JVMTI_ERROR_INVALID_FIELDID;
580 NULL_CHECK (result);
581 *result = field->getModifiers();
582 return JVMTI_ERROR_NONE;
585 static jvmtiError JNICALL
586 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
587 jfieldID field, jboolean *result)
589 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
590 if (klass == NULL)
591 return JVMTI_ERROR_INVALID_CLASS;
592 if (field == NULL)
593 return JVMTI_ERROR_INVALID_FIELDID;
594 NULL_CHECK (result);
596 // FIXME: capability can_get_synthetic_attribute
597 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
598 != 0);
599 return JVMTI_ERROR_NONE;
602 static jvmtiError JNICALL
603 _Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
604 char **name_ptr, char **signature_ptr,
605 char **generic_ptr)
607 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
609 if (method == NULL)
610 return JVMTI_ERROR_INVALID_METHODID;
612 if (name_ptr != NULL)
614 int len = static_cast<int> (method->name->len ());
615 *name_ptr = (char *) _Jv_MallocUnchecked (len + 1);
616 if (*name_ptr == NULL)
617 return JVMTI_ERROR_OUT_OF_MEMORY;
618 strncpy (*name_ptr, method->name->chars (), len);
619 (*name_ptr)[len] = '\0';
622 if (signature_ptr != NULL)
624 int len = static_cast<int> (method->signature->len ());
625 *signature_ptr = (char *) _Jv_MallocUnchecked (len + 1);
626 if (*signature_ptr == NULL)
628 if (name_ptr != NULL)
629 _Jv_Free (*name_ptr);
630 return JVMTI_ERROR_OUT_OF_MEMORY;
632 strncpy (*signature_ptr, method->signature->chars (), len);
633 (*signature_ptr)[len] = '\0';
636 if (generic_ptr != NULL)
638 *generic_ptr = NULL;
641 return JVMTI_ERROR_NONE;
644 static jvmtiError JNICALL
645 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
646 jint *result)
648 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
649 if (method == NULL)
650 return JVMTI_ERROR_INVALID_METHODID;
651 NULL_CHECK (result);
653 // FIXME: mask off some internal bits...
654 *result = method->accflags;
655 return JVMTI_ERROR_NONE;
658 static jvmtiError JNICALL
659 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
660 jint *entry_count_ptr,
661 jvmtiLineNumberEntry **table_ptr)
663 NULL_CHECK (entry_count_ptr);
664 NULL_CHECK (table_ptr);
666 jclass klass;
667 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
668 if (jerr != JVMTI_ERROR_NONE)
669 return jerr;
671 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
672 if (base == NULL)
673 return JVMTI_ERROR_INVALID_METHODID;
675 if (java::lang::reflect::Modifier::isNative (method->accflags)
676 || !_Jv_IsInterpretedClass (klass))
677 return JVMTI_ERROR_NATIVE_METHOD;
679 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
680 jlong start, end;
681 jintArray lines = NULL;
682 jlongArray indices = NULL;
683 imeth->get_line_table (start, end, lines, indices);
684 if (lines == NULL)
685 return JVMTI_ERROR_ABSENT_INFORMATION;
687 jvmtiLineNumberEntry *table;
688 jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
689 table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
690 if (table == NULL)
691 return JVMTI_ERROR_OUT_OF_MEMORY;
693 jint *line = elements (lines);
694 jlong *index = elements (indices);
695 for (int i = 0; i < lines->length; ++i)
697 table[i].start_location = index[i];
698 table[i].line_number = line[i];
701 *table_ptr = table;
702 *entry_count_ptr = lines->length;
703 return JVMTI_ERROR_NONE;
706 static jvmtiError JNICALL
707 _Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
708 jint *num_locals,
709 jvmtiLocalVariableEntry **locals)
711 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
712 NULL_CHECK (num_locals);
713 NULL_CHECK (locals);
715 CHECK_FOR_NATIVE_METHOD(method);
717 jclass klass;
718 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
719 if (jerr != JVMTI_ERROR_NONE)
720 return jerr;
722 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
723 (_Jv_FindInterpreterMethod (klass, method));
725 if (imeth == NULL)
726 return JVMTI_ERROR_INVALID_METHODID;
728 jerr = env->GetMaxLocals (method, num_locals);
729 if (jerr != JVMTI_ERROR_NONE)
730 return jerr;
732 jerr = env->Allocate (static_cast<jlong>
733 ((*num_locals) * sizeof (jvmtiLocalVariableEntry)),
734 reinterpret_cast<unsigned char **> (locals));
736 if (jerr != JVMTI_ERROR_NONE)
737 return jerr;
739 //the slot in the methods local_var_table to get
740 int table_slot = 0;
741 char *name;
742 char *sig;
743 char *generic_sig;
745 while (table_slot < *num_locals
746 && imeth->get_local_var_table (&name, &sig, &generic_sig,
747 &((((*locals)[table_slot].start_location))),
748 &((*locals)[table_slot].length),
749 &((*locals)[table_slot].slot),
750 table_slot)
751 >= 0)
753 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
754 reinterpret_cast<unsigned char **>
755 (&(*locals)[table_slot].name));
756 if (jerr != JVMTI_ERROR_NONE)
757 return jerr;
758 strcpy ((*locals)[table_slot].name, name);
760 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
761 reinterpret_cast<unsigned char **>
762 (&(*locals)[table_slot].signature));
763 if (jerr != JVMTI_ERROR_NONE)
764 return jerr;
765 strcpy ((*locals)[table_slot].signature, sig);
767 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
768 reinterpret_cast<unsigned char **>
769 (&(*locals)[table_slot].generic_signature));
770 if (jerr != JVMTI_ERROR_NONE)
771 return jerr;
772 strcpy ((*locals)[table_slot].generic_signature, generic_sig);
774 table_slot++;
777 if (table_slot == 0)
778 return JVMTI_ERROR_ABSENT_INFORMATION;
780 // If there are double or long variables in the table, the the table will be
781 // smaller than the max number of slots, so correct for this here.
782 if ((table_slot) < *num_locals)
783 *num_locals = table_slot;
785 return JVMTI_ERROR_NONE;
788 static jvmtiError JNICALL
789 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
790 jboolean *result)
792 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
793 if (method == NULL)
794 return JVMTI_ERROR_INVALID_METHODID;
795 NULL_CHECK (result);
797 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
798 return JVMTI_ERROR_NONE;
801 static jvmtiError JNICALL
802 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
803 jboolean *result)
805 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
806 if (method == NULL)
807 return JVMTI_ERROR_INVALID_METHODID;
808 NULL_CHECK (result);
810 // FIXME capability can_get_synthetic_attribute
812 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
813 != 0);
814 return JVMTI_ERROR_NONE;
817 static jvmtiError JNICALL
818 _Jv_JVMTI_GetMaxLocals (jvmtiEnv *env, jmethodID method, jint *max_locals)
820 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
821 NULL_CHECK (max_locals);
823 CHECK_FOR_NATIVE_METHOD (method);
825 jclass klass;
826 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
827 if (jerr != JVMTI_ERROR_NONE)
828 return jerr;
830 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
831 (_Jv_FindInterpreterMethod (klass, method));
833 if (imeth == NULL)
834 return JVMTI_ERROR_INVALID_METHODID;
836 *max_locals = imeth->get_max_locals ();
838 return JVMTI_ERROR_NONE;
841 static jvmtiError JNICALL
842 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
843 jmethodID method,
844 jclass *declaring_class_ptr)
846 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
847 NULL_CHECK (declaring_class_ptr);
849 jclass klass = _Jv_GetMethodDeclaringClass (method);
850 if (klass != NULL)
852 *declaring_class_ptr = klass;
853 return JVMTI_ERROR_NONE;
856 return JVMTI_ERROR_INVALID_METHODID;
859 static jvmtiError JNICALL
860 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
861 jobject init_loader,
862 jint *count_ptr,
863 jclass **result_ptr)
865 using namespace java::lang;
866 using namespace java::util;
868 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
869 NULL_CHECK (count_ptr);
870 NULL_CHECK (result_ptr);
872 ClassLoader *loader = (ClassLoader *) init_loader;
873 if (loader == NULL)
874 loader = VMClassLoader::bootLoader;
876 Collection *values = loader->loadedClasses->values();
877 jobjectArray array = values->toArray();
878 *count_ptr = array->length;
879 jobject *elts = elements (array);
880 jclass *result
881 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
882 if (result == NULL)
883 return JVMTI_ERROR_OUT_OF_MEMORY;
885 // FIXME: JNI references...
886 memcpy (result, elts, *count_ptr * sizeof (jclass));
888 *result_ptr = result;
890 return JVMTI_ERROR_NONE;
893 static jvmtiError JNICALL
894 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
895 jint start_depth, jint max_frames,
896 jvmtiFrameInfo *frames, jint *frame_count)
898 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
900 ILLEGAL_ARGUMENT (max_frames < 0);
902 NULL_CHECK (frames);
903 NULL_CHECK (frame_count);
905 using namespace java::lang;
907 THREAD_DEFAULT_TO_CURRENT (thread);
908 THREAD_CHECK_VALID (thread);
909 THREAD_CHECK_IS_ALIVE (thread);
911 jvmtiError jerr = env->GetFrameCount (thread, frame_count);
912 if (jerr != JVMTI_ERROR_NONE)
913 return jerr;
915 // start_depth can be either a positive number, indicating the depth of the
916 // stack at which to begin the trace, or a negative number indicating the
917 // number of frames at the bottom of the stack to exclude. These checks
918 // ensure that it is a valid value in either case
920 ILLEGAL_ARGUMENT (start_depth >= (*frame_count));
921 ILLEGAL_ARGUMENT (start_depth < (-(*frame_count)));
923 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
925 // If start_depth is negative use this to determine at what depth to start
926 // the trace by adding it to the length of the call stack. This allows the
927 // use of the same frame "discarding" mechanism as for a positive start_depth
928 if (start_depth < 0)
929 start_depth = *frame_count + start_depth;
931 // If start_depth > 0 "remove" start_depth frames from the beginning
932 // of the stack before beginning the trace by moving along the frame list.
933 while (start_depth > 0)
935 frame = frame->next;
936 start_depth--;
937 (*frame_count)--;
940 // Now check to see if the array supplied by the agent is large enough to
941 // hold frame_count frames, after adjustment for start_depth.
942 if ((*frame_count) > max_frames)
943 (*frame_count) = max_frames;
945 for (int i = 0; i < (*frame_count); i++)
947 frames[i].method = frame->self->get_method ();
949 // Set the location in the frame, native frames have location = -1
950 if (frame->frame_type == frame_interpreter)
952 _Jv_InterpMethod *imeth
953 = static_cast<_Jv_InterpMethod *> (frame->self);
954 _Jv_InterpFrame *interp_frame
955 = static_cast<_Jv_InterpFrame *> (frame);
956 frames[i].location = imeth->insn_index (interp_frame->pc);
958 else
959 frames[i].location = -1;
961 frame = frame->next;
964 return JVMTI_ERROR_NONE;
967 static jvmtiError JNICALL
968 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
970 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
971 _Jv_RunGC();
972 return JVMTI_ERROR_NONE;
975 static jvmtiError JNICALL
976 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
977 const jniNativeInterface *function_table)
979 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
980 NULL_CHECK (function_table);
981 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
982 return JVMTI_ERROR_NONE;
985 static jvmtiError JNICALL
986 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
987 jniNativeInterface **function_table)
989 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
990 NULL_CHECK (function_table);
991 *function_table
992 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
993 if (*function_table == NULL)
994 return JVMTI_ERROR_OUT_OF_MEMORY;
995 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
996 return JVMTI_ERROR_NONE;
999 static jvmtiError JNICALL
1000 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
1002 NULL_CHECK (env);
1004 if (_jvmtiEnvironments == NULL)
1005 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1006 else
1008 _envListLock->writeLock ()->lock ();
1009 if (_jvmtiEnvironments->env == env)
1011 struct jvmti_env_list *next = _jvmtiEnvironments->next;
1012 _Jv_Free (_jvmtiEnvironments);
1013 _jvmtiEnvironments = next;
1015 else
1017 struct jvmti_env_list *e = _jvmtiEnvironments;
1018 while (e->next != NULL && e->next->env != env)
1019 e = e->next;
1020 if (e->next == NULL)
1022 _envListLock->writeLock ()->unlock ();
1023 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1026 struct jvmti_env_list *next = e->next->next;
1027 _Jv_Free (e->next);
1028 e->next = next;
1030 _envListLock->writeLock ()->unlock ();
1033 _Jv_Free (env);
1035 check_enabled_events ();
1037 return JVMTI_ERROR_NONE;
1040 static jvmtiError JNICALL
1041 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1042 char **result)
1044 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1045 NULL_CHECK (property);
1046 NULL_CHECK (result);
1048 jstring name = JvNewStringUTF(property);
1049 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
1051 if (result_str == NULL)
1052 return JVMTI_ERROR_NOT_AVAILABLE;
1054 int len = JvGetStringUTFLength (result_str);
1055 *result = (char *) _Jv_MallocUnchecked (len + 1);
1056 if (*result == NULL)
1057 return JVMTI_ERROR_OUT_OF_MEMORY;
1058 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
1059 (*result)[len] = '\0';
1061 return JVMTI_ERROR_NONE;
1064 static jvmtiError JNICALL
1065 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1066 const char *value)
1068 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1070 NULL_CHECK (property);
1071 if (value == NULL)
1073 // FIXME: When would a property not be writeable?
1074 return JVMTI_ERROR_NONE;
1077 jstring prop_str = JvNewStringUTF(property);
1078 jstring value_str = JvNewStringUTF(value);
1079 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
1080 return JVMTI_ERROR_NONE;
1083 static jvmtiError JNICALL
1084 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
1086 NULL_CHECK (nanos_ptr);
1087 *nanos_ptr = _Jv_platform_nanotime();
1088 return JVMTI_ERROR_NONE;
1091 static jvmtiError JNICALL
1092 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
1093 jint *nprocessors_ptr)
1095 NULL_CHECK (nprocessors_ptr);
1096 #ifdef _SC_NPROCESSORS_ONLN
1097 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
1098 #else
1099 *nprocessors_ptr = 1;
1100 #endif
1101 return JVMTI_ERROR_NONE;
1104 static jvmtiError JNICALL
1105 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
1106 const char *segment)
1108 using namespace java::lang;
1109 using namespace java::net;
1110 using namespace gnu::gcj::runtime;
1112 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1113 NULL_CHECK (segment);
1115 jstring str_segment = JvNewStringUTF(segment);
1116 URL *url;
1119 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
1121 catch (jthrowable ignore)
1123 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1126 BootClassLoader *loader = VMClassLoader::bootLoader;
1127 // Don't call this too early.
1128 // assert (loader != NULL);
1129 loader->addURL(url);
1130 return JVMTI_ERROR_NONE;
1133 static jvmtiError JNICALL
1134 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
1135 jboolean value)
1137 switch (flag)
1139 case JVMTI_VERBOSE_OTHER:
1140 case JVMTI_VERBOSE_GC:
1141 case JVMTI_VERBOSE_JNI:
1142 // Ignore.
1143 break;
1144 case JVMTI_VERBOSE_CLASS:
1145 gcj::verbose_class_flag = value;
1146 break;
1147 default:
1148 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1150 return JVMTI_ERROR_NONE;
1153 static jvmtiError JNICALL
1154 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
1155 jlong *result)
1157 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1158 if (object == NULL)
1159 return JVMTI_ERROR_INVALID_OBJECT;
1160 NULL_CHECK (result);
1162 jclass klass = object->getClass();
1163 if (klass->isArray())
1165 jclass comp = klass->getComponentType();
1166 jint base
1167 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
1168 klass->getComponentType());
1169 // FIXME: correct for primitive types?
1170 jint compSize = comp->size();
1171 __JArray *array = (__JArray *) object;
1172 *result = base + array->length * compSize;
1174 else
1176 // Note that if OBJECT is a String then it may (if
1177 // str->data==str) take more space. Do we care?
1178 *result = klass->size();
1180 return JVMTI_ERROR_NONE;
1183 /* An event is enabled only if it has both an event handler
1184 and it is enabled in the environment. */
1185 static void
1186 check_enabled_event (jvmtiEvent type)
1188 bool *enabled;
1189 int offset;
1191 #define GET_OFFSET(Event) \
1192 do \
1194 enabled = &JVMTI::Event; \
1195 offset = offsetof (jvmtiEventCallbacks, Event); \
1197 while (0)
1199 switch (type)
1201 case JVMTI_EVENT_VM_INIT:
1202 GET_OFFSET (VMInit);
1203 break;
1205 case JVMTI_EVENT_VM_DEATH:
1206 GET_OFFSET (VMDeath);
1207 break;
1209 case JVMTI_EVENT_THREAD_START:
1210 GET_OFFSET (ThreadStart);
1211 break;
1213 case JVMTI_EVENT_THREAD_END:
1214 GET_OFFSET (ThreadEnd);
1215 break;
1217 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1218 GET_OFFSET (ClassFileLoadHook);
1219 break;
1221 case JVMTI_EVENT_CLASS_LOAD:
1222 GET_OFFSET (ClassLoad);
1223 break;
1225 case JVMTI_EVENT_CLASS_PREPARE:
1226 GET_OFFSET (ClassPrepare);
1227 break;
1229 case JVMTI_EVENT_VM_START:
1230 GET_OFFSET (VMStart);
1231 break;
1233 case JVMTI_EVENT_EXCEPTION:
1234 GET_OFFSET (Exception);
1235 break;
1237 case JVMTI_EVENT_EXCEPTION_CATCH:
1238 GET_OFFSET (ExceptionCatch);
1239 break;
1241 case JVMTI_EVENT_SINGLE_STEP:
1242 GET_OFFSET (SingleStep);
1243 break;
1245 case JVMTI_EVENT_FRAME_POP:
1246 GET_OFFSET (FramePop);
1247 break;
1249 case JVMTI_EVENT_BREAKPOINT:
1250 GET_OFFSET (Breakpoint);
1251 break;
1253 case JVMTI_EVENT_FIELD_ACCESS:
1254 GET_OFFSET (FieldAccess);
1255 break;
1257 case JVMTI_EVENT_FIELD_MODIFICATION:
1258 GET_OFFSET (FieldModification);
1259 break;
1261 case JVMTI_EVENT_METHOD_ENTRY:
1262 GET_OFFSET (MethodEntry);
1263 break;
1265 case JVMTI_EVENT_METHOD_EXIT:
1266 GET_OFFSET (MethodExit);
1267 break;
1269 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1270 GET_OFFSET (NativeMethodBind);
1271 break;
1273 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1274 GET_OFFSET (CompiledMethodLoad);
1275 break;
1277 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1278 GET_OFFSET (CompiledMethodUnload);
1279 break;
1281 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1282 GET_OFFSET (DynamicCodeGenerated);
1283 break;
1285 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1286 GET_OFFSET (DataDumpRequest);
1287 break;
1289 case JVMTI_EVENT_MONITOR_WAIT:
1290 GET_OFFSET (MonitorWait);
1291 break;
1293 case JVMTI_EVENT_MONITOR_WAITED:
1294 GET_OFFSET (MonitorWaited);
1295 break;
1297 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1298 GET_OFFSET (MonitorContendedEnter);
1299 break;
1301 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1302 GET_OFFSET (MonitorContendedEntered);
1303 break;
1305 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1306 GET_OFFSET (GarbageCollectionStart);
1307 break;
1309 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1310 GET_OFFSET (GarbageCollectionFinish);
1311 break;
1313 case JVMTI_EVENT_OBJECT_FREE:
1314 GET_OFFSET (ObjectFree);
1315 break;
1317 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1318 GET_OFFSET (VMObjectAlloc);
1319 break;
1321 default:
1322 fprintf (stderr,
1323 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1324 (int) type);
1325 return;
1327 #undef GET_OFFSET
1329 int index = EVENT_INDEX (type); // safe since caller checks this
1331 if (_jvmtiEnvironments != NULL)
1333 _envListLock->readLock ()->lock ();
1334 struct jvmti_env_list *e;
1335 FOREACH_ENVIRONMENT (e)
1337 char *addr
1338 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1339 void **callback = reinterpret_cast<void **> (addr);
1340 if (e->env->enabled[index] && *callback != NULL)
1342 *enabled = true;
1343 _envListLock->readLock ()->unlock ();
1344 return;
1348 _envListLock->readLock ()->unlock ();
1351 *enabled = false;
1354 static void
1355 check_enabled_events ()
1357 check_enabled_event (JVMTI_EVENT_VM_INIT);
1358 check_enabled_event (JVMTI_EVENT_VM_DEATH);
1359 check_enabled_event (JVMTI_EVENT_THREAD_START);
1360 check_enabled_event (JVMTI_EVENT_THREAD_END);
1361 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1362 check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1363 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1364 check_enabled_event (JVMTI_EVENT_VM_START);
1365 check_enabled_event (JVMTI_EVENT_EXCEPTION);
1366 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1367 check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1368 check_enabled_event (JVMTI_EVENT_FRAME_POP);
1369 check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1370 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1371 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1372 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1373 check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1374 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1375 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1376 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1377 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1378 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1379 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1380 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1381 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1382 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1383 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1384 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1385 check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1386 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1389 static jvmtiError JNICALL
1390 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1391 jvmtiEvent type, jthread event_thread, ...)
1393 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1395 if (event_thread != NULL)
1397 THREAD_CHECK_VALID (event_thread);
1398 THREAD_CHECK_IS_ALIVE (event_thread);
1401 bool enabled;
1402 switch (mode)
1404 case JVMTI_DISABLE:
1405 enabled = false;
1406 break;
1407 case JVMTI_ENABLE:
1408 enabled = true;
1409 break;
1411 default:
1412 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1415 switch (type)
1417 case JVMTI_EVENT_VM_INIT:
1418 case JVMTI_EVENT_VM_DEATH:
1419 case JVMTI_EVENT_THREAD_START:
1420 case JVMTI_EVENT_VM_START:
1421 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1422 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1423 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1424 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1425 ILLEGAL_ARGUMENT (event_thread != NULL);
1426 break;
1428 case JVMTI_EVENT_THREAD_END:
1429 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1430 case JVMTI_EVENT_CLASS_LOAD:
1431 case JVMTI_EVENT_CLASS_PREPARE:
1432 case JVMTI_EVENT_EXCEPTION:
1433 case JVMTI_EVENT_EXCEPTION_CATCH:
1434 case JVMTI_EVENT_SINGLE_STEP:
1435 case JVMTI_EVENT_FRAME_POP:
1436 case JVMTI_EVENT_BREAKPOINT:
1437 case JVMTI_EVENT_FIELD_ACCESS:
1438 case JVMTI_EVENT_FIELD_MODIFICATION:
1439 case JVMTI_EVENT_METHOD_ENTRY:
1440 case JVMTI_EVENT_METHOD_EXIT:
1441 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1442 case JVMTI_EVENT_MONITOR_WAIT:
1443 case JVMTI_EVENT_MONITOR_WAITED:
1444 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1445 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1446 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1447 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1448 case JVMTI_EVENT_OBJECT_FREE:
1449 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1450 break;
1452 default:
1453 return JVMTI_ERROR_INVALID_EVENT_TYPE;
1456 env->thread[EVENT_INDEX(type)] = event_thread;
1457 env->enabled[EVENT_INDEX(type)] = enabled;
1458 check_enabled_event (type);
1459 return JVMTI_ERROR_NONE;
1462 static jvmtiError JNICALL
1463 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1464 const jvmtiEventCallbacks *callbacks,
1465 jint size_of_callbacks)
1467 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1468 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1470 // Copy the list of callbacks into the environment
1471 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1473 /* Check which events are now enabeld (JVMTI makes no requirements
1474 about the order in which SetEventCallbacks and SetEventNotifications
1475 are called. So we must check all events here. */
1476 check_enabled_events ();
1478 return JVMTI_ERROR_NONE;
1481 static jvmtiError JNICALL
1482 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1483 char **name_ptr)
1485 NULL_CHECK (name_ptr);
1487 const char *name;
1488 switch (error)
1490 case JVMTI_ERROR_NONE:
1491 name = "none";
1492 break;
1494 case JVMTI_ERROR_NULL_POINTER:
1495 name = "null pointer";
1496 break;
1498 case JVMTI_ERROR_OUT_OF_MEMORY:
1499 name = "out of memory";
1500 break;
1502 case JVMTI_ERROR_ACCESS_DENIED:
1503 name = "access denied";
1504 break;
1506 case JVMTI_ERROR_WRONG_PHASE:
1507 name = "wrong phase";
1508 break;
1510 case JVMTI_ERROR_INTERNAL:
1511 name = "internal error";
1512 break;
1514 case JVMTI_ERROR_UNATTACHED_THREAD:
1515 name = "unattached thread";
1516 break;
1518 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1519 name = "invalid environment";
1520 break;
1522 case JVMTI_ERROR_INVALID_PRIORITY:
1523 name = "invalid priority";
1524 break;
1526 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1527 name = "thread not suspended";
1528 break;
1530 case JVMTI_ERROR_THREAD_SUSPENDED:
1531 name = "thread suspended";
1532 break;
1534 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1535 name = "thread not alive";
1536 break;
1538 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1539 name = "class not prepared";
1540 break;
1542 case JVMTI_ERROR_NO_MORE_FRAMES:
1543 name = "no more frames";
1544 break;
1546 case JVMTI_ERROR_OPAQUE_FRAME:
1547 name = "opaque frame";
1548 break;
1550 case JVMTI_ERROR_DUPLICATE:
1551 name = "duplicate";
1552 break;
1554 case JVMTI_ERROR_NOT_FOUND:
1555 name = "not found";
1556 break;
1558 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1559 name = "not monitor owner";
1560 break;
1562 case JVMTI_ERROR_INTERRUPT:
1563 name = "interrupted";
1564 break;
1566 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1567 name = "unmodifiable class";
1568 break;
1570 case JVMTI_ERROR_NOT_AVAILABLE:
1571 name = "not available";
1572 break;
1574 case JVMTI_ERROR_ABSENT_INFORMATION:
1575 name = "absent information";
1576 break;
1578 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1579 name = "invalid event type";
1580 break;
1582 case JVMTI_ERROR_NATIVE_METHOD:
1583 name = "native method";
1584 break;
1586 case JVMTI_ERROR_INVALID_THREAD:
1587 name = "invalid thread";
1588 break;
1590 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1591 name = "invalid thread group";
1592 break;
1594 case JVMTI_ERROR_INVALID_OBJECT:
1595 name = "invalid object";
1596 break;
1598 case JVMTI_ERROR_INVALID_CLASS:
1599 name = "invalid class";
1600 break;
1602 case JVMTI_ERROR_INVALID_METHODID:
1603 name = "invalid method ID";
1604 break;
1606 case JVMTI_ERROR_INVALID_LOCATION:
1607 name = "invalid location";
1608 break;
1610 case JVMTI_ERROR_INVALID_FIELDID:
1611 name = "invalid field ID";
1612 break;
1614 case JVMTI_ERROR_TYPE_MISMATCH:
1615 name = "type mismatch";
1616 break;
1618 case JVMTI_ERROR_INVALID_SLOT:
1619 name = "invalid slot";
1620 break;
1622 case JVMTI_ERROR_INVALID_MONITOR:
1623 name = "invalid monitor";
1624 break;
1626 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1627 name = "invalid class format";
1628 break;
1630 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1631 name = "circular class definition";
1632 break;
1634 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1635 name = "unsupported redefinition: method added";
1636 break;
1638 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1639 name = "unsupported redefinition: schema changed";
1640 break;
1642 case JVMTI_ERROR_INVALID_TYPESTATE:
1643 name = "invalid type state";
1644 break;
1646 case JVMTI_ERROR_FAILS_VERIFICATION:
1647 name = "fails verification";
1648 break;
1650 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1651 name = "unsupported redefinition: hierarchy changed";
1652 break;
1654 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1655 name = "unsupported redefinition: method deleted";
1656 break;
1658 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1659 name = "unsupported version";
1660 break;
1662 case JVMTI_ERROR_NAMES_DONT_MATCH:
1663 name = "names do not match";
1664 break;
1666 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1667 name = "unsupported redefinition: class modifiers changed";
1668 break;
1670 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1671 name = "unsupported redefinition: method modifiers changed";
1672 break;
1674 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1675 name = "must possess capability";
1676 break;
1678 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1679 name = "illegal argument";
1680 break;
1682 default:
1683 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1686 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1687 if (*name_ptr == NULL)
1688 return JVMTI_ERROR_OUT_OF_MEMORY;
1690 strcpy (*name_ptr, name);
1691 return JVMTI_ERROR_NONE;
1694 #define RESERVED NULL
1695 #define UNIMPLEMENTED NULL
1697 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1699 RESERVED, // reserved1
1700 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1701 RESERVED, // reserved3
1702 _Jv_JVMTI_GetAllThreads, // GetAllThreads
1703 _Jv_JVMTI_SuspendThread, // SuspendThread
1704 _Jv_JVMTI_ResumeThread, // ResumeThread
1705 UNIMPLEMENTED, // StopThread
1706 _Jv_JVMTI_InterruptThread, // InterruptThread
1707 UNIMPLEMENTED, // GetThreadInfo
1708 UNIMPLEMENTED, // GetOwnedMonitorInfo
1709 UNIMPLEMENTED, // GetCurrentContendedMonitor
1710 UNIMPLEMENTED, // RunAgentThread
1711 UNIMPLEMENTED, // GetTopThreadGroups
1712 UNIMPLEMENTED, // GetThreadGroupInfo
1713 UNIMPLEMENTED, // GetThreadGroupChildren
1714 _Jv_JVMTI_GetFrameCount, // GetFrameCount
1715 UNIMPLEMENTED, // GetThreadState
1716 RESERVED, // reserved18
1717 UNIMPLEMENTED, // GetFrameLocation
1718 UNIMPLEMENTED, // NotifyPopFrame
1719 UNIMPLEMENTED, // GetLocalObject
1720 UNIMPLEMENTED, // GetLocalInt
1721 UNIMPLEMENTED, // GetLocalLong
1722 UNIMPLEMENTED, // GetLocalFloat
1723 UNIMPLEMENTED, // GetLocalDouble
1724 UNIMPLEMENTED, // SetLocalObject
1725 UNIMPLEMENTED, // SetLocalInt
1726 UNIMPLEMENTED, // SetLocalLong
1727 UNIMPLEMENTED, // SetLocalFloat
1728 UNIMPLEMENTED, // SetLocalDouble
1729 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
1730 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
1731 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
1732 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
1733 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
1734 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
1735 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
1736 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
1737 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
1738 RESERVED, // reserved40
1739 UNIMPLEMENTED, // SetFieldAccessWatch
1740 UNIMPLEMENTED, // ClearFieldAccessWatch
1741 UNIMPLEMENTED, // SetFieldModificationWatch
1742 UNIMPLEMENTED, // ClearFieldModificationWatch
1743 RESERVED, // reserved45
1744 _Jv_JVMTI_Allocate, // Allocate
1745 _Jv_JVMTI_Deallocate, // Deallocate
1746 UNIMPLEMENTED, // GetClassSignature
1747 _Jv_JVMTI_GetClassStatus, // GetClassStatus
1748 UNIMPLEMENTED, // GetSourceFileName
1749 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
1750 _Jv_JVMTI_GetClassMethods, // GetClassMethods
1751 UNIMPLEMENTED, // GetClassFields
1752 UNIMPLEMENTED, // GetImplementedInterfaces
1753 _Jv_JVMTI_IsInterface, // IsInterface
1754 _Jv_JVMTI_IsArrayClass, // IsArrayClass
1755 _Jv_JVMTI_GetClassLoader, // GetClassLoader
1756 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
1757 UNIMPLEMENTED, // GetObjectMonitorUsage
1758 UNIMPLEMENTED, // GetFieldName
1759 UNIMPLEMENTED, // GetFieldDeclaringClass
1760 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
1761 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
1762 _Jv_JVMTI_GetMethodName, // GetMethodName
1763 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
1764 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
1765 RESERVED, // reserved67
1766 _Jv_JVMTI_GetMaxLocals, // GetMaxLocals
1767 UNIMPLEMENTED, // GetArgumentsSize
1768 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
1769 UNIMPLEMENTED, // GetMethodLocation
1770 _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable
1771 RESERVED, // reserved73
1772 RESERVED, // reserved74
1773 UNIMPLEMENTED, // GetBytecodes
1774 _Jv_JVMTI_IsMethodNative, // IsMethodNative
1775 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
1776 UNIMPLEMENTED, // GetLoadedClasses
1777 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
1778 UNIMPLEMENTED, // PopFrame
1779 RESERVED, // reserved81
1780 RESERVED, // reserved82
1781 RESERVED, // reserved83
1782 RESERVED, // reserved84
1783 RESERVED, // reserved85
1784 RESERVED, // reserved86
1785 UNIMPLEMENTED, // RedefineClasses
1786 UNIMPLEMENTED, // GetVersionNumber
1787 UNIMPLEMENTED, // GetCapabilities
1788 UNIMPLEMENTED, // GetSourceDebugExtension
1789 UNIMPLEMENTED, // IsMethodObsolete
1790 UNIMPLEMENTED, // SuspendThreadList
1791 UNIMPLEMENTED, // ResumeThreadList
1792 RESERVED, // reserved94
1793 RESERVED, // reserved95
1794 RESERVED, // reserved96
1795 RESERVED, // reserved97
1796 RESERVED, // reserved98
1797 RESERVED, // reserved99
1798 UNIMPLEMENTED, // GetAllStackTraces
1799 UNIMPLEMENTED, // GetThreadListStackTraces
1800 UNIMPLEMENTED, // GetThreadLocalStorage
1801 UNIMPLEMENTED, // SetThreadLocalStorage
1802 _Jv_JVMTI_GetStackTrace, // GetStackTrace
1803 RESERVED, // reserved105
1804 UNIMPLEMENTED, // GetTag
1805 UNIMPLEMENTED, // SetTag
1806 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
1807 UNIMPLEMENTED, // IterateOverObjectsReachable
1808 UNIMPLEMENTED, // IterateOverReachableObjects
1809 UNIMPLEMENTED, // IterateOverHeap
1810 UNIMPLEMENTED, // IterateOverInstanceOfClass
1811 RESERVED, // reserved113
1812 UNIMPLEMENTED, // GetObjectsWithTags
1813 RESERVED, // reserved115
1814 RESERVED, // reserved116
1815 RESERVED, // reserved117
1816 RESERVED, // reserved118
1817 RESERVED, // reserved119
1818 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
1819 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
1820 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
1821 UNIMPLEMENTED, // GenerateEvents
1822 UNIMPLEMENTED, // GetExtensionFunctions
1823 UNIMPLEMENTED, // GetExtensionEvents
1824 UNIMPLEMENTED, // SetExtensionEventCallback
1825 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
1826 _Jv_JVMTI_GetErrorName, // GetErrorName
1827 UNIMPLEMENTED, // GetJLocationFormat
1828 UNIMPLEMENTED, // GetSystemProperties
1829 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
1830 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
1831 UNIMPLEMENTED, // GetPhase
1832 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
1833 UNIMPLEMENTED, // GetCurrentThreadCpuTime
1834 UNIMPLEMENTED, // GetThreadCpuTimerInfo
1835 UNIMPLEMENTED, // GetThreadCpuTime
1836 UNIMPLEMENTED, // GetTimerInfo
1837 _Jv_JVMTI_GetTime, // GetTime
1838 UNIMPLEMENTED, // GetPotentialCapabilities
1839 RESERVED, // reserved141
1840 UNIMPLEMENTED, // AddCapabilities
1841 UNIMPLEMENTED, // RelinquishCapabilities
1842 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
1843 RESERVED, // reserved145
1844 RESERVED, // reserved146
1845 UNIMPLEMENTED, // GetEnvironmentLocalStorage
1846 UNIMPLEMENTED, // SetEnvironmentLocalStorage
1847 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
1848 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
1849 RESERVED, // reserved151
1850 RESERVED, // reserved152
1851 RESERVED, // reserved153
1852 _Jv_JVMTI_GetObjectSize // GetObjectSize
1855 _Jv_JVMTIEnv *
1856 _Jv_GetJVMTIEnv (void)
1858 _Jv_JVMTIEnv *env
1859 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1860 env->p = &_Jv_JVMTI_Interface;
1861 struct jvmti_env_list *element
1862 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
1863 element->env = env;
1864 element->next = NULL;
1866 _envListLock->writeLock ()->lock ();
1867 if (_jvmtiEnvironments == NULL)
1868 _jvmtiEnvironments = element;
1869 else
1871 struct jvmti_env_list *e;
1872 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1874 e->next = element;
1876 _envListLock->writeLock ()->unlock ();
1878 /* Mark JVMTI active. This is used to force the interpreter
1879 to use either debugging or non-debugging code. Once JVMTI
1880 has been enabled, the non-debug interpreter cannot be used. */
1881 JVMTI::enabled = true;
1882 return env;
1885 void
1886 _Jv_JVMTI_Init ()
1888 _jvmtiEnvironments = NULL;
1889 _envListLock
1890 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
1892 // No environments, so this should set all JVMTI:: members to false
1893 check_enabled_events ();
1896 static void
1897 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
1899 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
1901 #define GET_BOOLEAN_ARG(Name) \
1902 ARG (int, b); \
1903 jboolean Name = (b == 0) ? false : true
1905 #define GET_CHAR_ARG(Name) \
1906 ARG (int, c); \
1907 char Name = static_cast<char> (c)
1909 switch (type)
1911 case JVMTI_EVENT_VM_INIT:
1912 if (env->callbacks.VMInit != NULL)
1914 ARG (JNIEnv *, jni_env);
1915 env->callbacks.VMInit (env, jni_env, event_thread);
1917 break;
1919 case JVMTI_EVENT_VM_DEATH:
1920 if (env->callbacks.VMDeath != NULL)
1922 ARG (JNIEnv *, jni_env);
1923 env->callbacks.VMDeath (env, jni_env);
1925 break;
1927 case JVMTI_EVENT_THREAD_START:
1928 if (env->callbacks.ThreadStart != NULL)
1930 ARG (JNIEnv *, jni_env);
1931 env->callbacks.ThreadStart (env, jni_env, event_thread);
1933 break;
1935 case JVMTI_EVENT_THREAD_END:
1936 if (env->callbacks.ThreadEnd != NULL)
1938 ARG (JNIEnv *, jni_env);
1939 env->callbacks.ThreadEnd (env, jni_env, event_thread);
1941 break;
1943 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1944 if (env->callbacks.ClassFileLoadHook != NULL)
1946 ARG (JNIEnv *, jni_env);
1947 ARG (jclass, class_being_redefined);
1948 ARG (jobject, loader);
1949 ARG (const char *, name);
1950 ARG (jobject, protection_domain);
1951 ARG (jint, class_data_len);
1952 ARG (const unsigned char *, class_data);
1953 ARG (jint *, new_class_data_len);
1954 ARG (unsigned char **, new_class_data);
1955 env->callbacks.ClassFileLoadHook (env, jni_env,
1956 class_being_redefined, loader,
1957 name, protection_domain,
1958 class_data_len, class_data,
1959 new_class_data_len,
1960 new_class_data);
1962 break;
1964 case JVMTI_EVENT_CLASS_LOAD:
1965 if (env->callbacks.ClassLoad != NULL)
1967 ARG (JNIEnv *, jni_env);
1968 ARG (jclass, klass);
1969 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
1971 break;
1973 case JVMTI_EVENT_CLASS_PREPARE:
1974 if (env->callbacks.ClassPrepare != NULL)
1976 ARG (JNIEnv *, jni_env);
1977 ARG (jclass, klass);
1978 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
1980 break;
1982 case JVMTI_EVENT_VM_START:
1983 if (env->callbacks.VMStart != NULL)
1985 ARG (JNIEnv *, jni_env);
1986 env->callbacks.VMStart (env, jni_env);
1988 break;
1990 case JVMTI_EVENT_EXCEPTION:
1991 if (env->callbacks.Exception != NULL)
1993 ARG (JNIEnv *, jni_env);
1994 ARG (jmethodID, method);
1995 ARG (jlocation, location);
1996 ARG (jobject, exception);
1997 ARG (jmethodID, catch_method);
1998 ARG (jlocation, catch_location);
1999 env->callbacks.Exception (env, jni_env, event_thread, method,
2000 location, exception, catch_method,
2001 catch_location);
2003 break;
2005 case JVMTI_EVENT_EXCEPTION_CATCH:
2006 if (env->callbacks.ExceptionCatch != NULL)
2008 ARG (JNIEnv *, jni_env);
2009 ARG (jmethodID, method);
2010 ARG (jlocation, location);
2011 ARG (jobject, exception);
2012 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
2013 location, exception);
2015 break;
2017 case JVMTI_EVENT_SINGLE_STEP:
2018 if (env->callbacks.SingleStep != NULL)
2020 ARG (JNIEnv *, jni_env);
2021 ARG (jmethodID, method);
2022 ARG (jlocation, location);
2023 env->callbacks.SingleStep (env, jni_env, event_thread, method,
2024 location);
2026 break;
2028 case JVMTI_EVENT_FRAME_POP:
2029 if (env->callbacks.FramePop != NULL)
2031 ARG (JNIEnv *, jni_env);
2032 ARG (jmethodID, method);
2033 GET_BOOLEAN_ARG (was_popped_by_exception);
2034 env->callbacks.FramePop (env, jni_env, event_thread, method,
2035 was_popped_by_exception);
2037 break;
2039 case JVMTI_EVENT_BREAKPOINT:
2040 if (env->callbacks.Breakpoint != NULL)
2042 ARG (JNIEnv *, jni_env);
2043 ARG (jmethodID, method);
2044 ARG (jlocation, location);
2045 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
2046 location);
2048 break;
2050 case JVMTI_EVENT_FIELD_ACCESS:
2051 if (env->callbacks.FieldAccess != NULL)
2053 ARG (JNIEnv *, jni_env);
2054 ARG (jmethodID, method);
2055 ARG (jlocation, location);
2056 ARG (jclass, field_class);
2057 ARG (jobject, object);
2058 ARG (jfieldID, field);
2059 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
2060 location, field_class, object, field);
2062 break;
2064 case JVMTI_EVENT_FIELD_MODIFICATION:
2065 if (env->callbacks.FieldModification != NULL)
2067 ARG (JNIEnv *, jni_env);
2068 ARG (jmethodID, method);
2069 ARG (jlocation, location);
2070 ARG (jclass, field_class);
2071 ARG (jobject, object);
2072 ARG (jfieldID, field);
2073 GET_CHAR_ARG (signature_type);
2074 ARG (jvalue, new_value);
2075 env->callbacks.FieldModification (env, jni_env, event_thread, method,
2076 location, field_class, object,
2077 field, signature_type, new_value);
2079 break;
2081 case JVMTI_EVENT_METHOD_ENTRY:
2082 if (env->callbacks.MethodEntry != NULL)
2084 ARG (JNIEnv *, jni_env);
2085 ARG (jmethodID, method);
2086 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
2088 break;
2090 case JVMTI_EVENT_METHOD_EXIT:
2091 if (env->callbacks.MethodExit != NULL)
2093 ARG (JNIEnv *, jni_env);
2094 ARG (jmethodID, method);
2095 GET_BOOLEAN_ARG (was_popped_by_exception);
2096 ARG (jvalue, return_value);
2097 env->callbacks.MethodExit (env, jni_env, event_thread, method,
2098 was_popped_by_exception, return_value);
2100 break;
2102 case JVMTI_EVENT_NATIVE_METHOD_BIND:
2103 if (env->callbacks.NativeMethodBind != NULL)
2105 ARG (JNIEnv *, jni_env);
2106 ARG (jmethodID, method);
2107 ARG (void *, address);
2108 ARG (void **, new_address_ptr);
2109 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
2110 address, new_address_ptr);
2112 break;
2114 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
2115 if (env->callbacks.CompiledMethodLoad != NULL)
2117 ARG (jmethodID, method);
2118 ARG (jint, code_size);
2119 ARG (const void *, code_addr);
2120 ARG (jint, map_length);
2121 ARG (const jvmtiAddrLocationMap *, map);
2122 ARG (const void *, compile_info);
2123 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
2124 map_length, map, compile_info);
2126 break;
2128 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
2129 if (env->callbacks.CompiledMethodUnload != NULL)
2131 ARG (jmethodID, method);
2132 ARG (const void *, code_addr);
2133 env->callbacks.CompiledMethodUnload (env, method, code_addr);
2135 break;
2137 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
2138 if (env->callbacks.DynamicCodeGenerated != NULL)
2140 ARG (const char *, name);
2141 ARG (const void *, address);
2142 ARG (jint, length);
2143 env->callbacks.DynamicCodeGenerated (env, name, address, length);
2145 break;
2147 case JVMTI_EVENT_DATA_DUMP_REQUEST:
2148 if (env->callbacks.DataDumpRequest != NULL)
2150 env->callbacks.DataDumpRequest (env);
2152 break;
2154 case JVMTI_EVENT_MONITOR_WAIT:
2155 if (env->callbacks.MonitorWait != NULL)
2157 ARG (JNIEnv *, jni_env);
2158 ARG (jobject, object);
2159 ARG (jlong, timeout);
2160 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
2161 timeout);
2163 break;
2165 case JVMTI_EVENT_MONITOR_WAITED:
2166 if (env->callbacks.MonitorWaited != NULL)
2168 ARG (JNIEnv *, jni_env);
2169 ARG (jobject, object);
2170 GET_BOOLEAN_ARG (timed_out);
2171 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
2172 timed_out);
2174 break;
2176 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2177 if (env->callbacks.MonitorContendedEnter != NULL)
2179 ARG (JNIEnv *, jni_env);
2180 ARG (jobject, object);
2181 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
2182 object);
2184 break;
2186 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2187 if (env->callbacks.MonitorContendedEntered != NULL)
2189 ARG (JNIEnv *, jni_env);
2190 ARG (jobject, object);
2191 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
2192 object);
2194 break;
2196 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
2197 if (env->callbacks.GarbageCollectionStart != NULL)
2199 env->callbacks.GarbageCollectionStart (env);
2201 break;
2203 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2204 if (env->callbacks.GarbageCollectionFinish != NULL)
2206 env->callbacks.GarbageCollectionFinish (env);
2208 break;
2210 case JVMTI_EVENT_OBJECT_FREE:
2211 if (env->callbacks.ObjectFree != NULL)
2213 ARG (jlong, tag);
2214 env->callbacks.ObjectFree (env, tag);
2216 break;
2218 case JVMTI_EVENT_VM_OBJECT_ALLOC:
2219 if (env->callbacks.VMObjectAlloc != NULL)
2221 ARG (JNIEnv *, jni_env);
2222 ARG (jobject, object);
2223 ARG (jclass, object_class);
2224 ARG (jlong, size);
2225 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2226 object, object_class, size);
2228 break;
2230 default:
2231 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2232 (int) type);
2233 break;
2235 va_end (args);
2236 #undef ARG
2237 #undef GET_BOOLEAN_ARG
2238 #undef GET_CHAR_ARG
2241 /* Post an event to requesting JVMTI environments
2243 * This function should not be called without consulting the
2244 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2245 * harm (other than kill speed), since this function will still
2246 * only send the event if it was properly requested by an environment.
2248 void
2249 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2251 va_list args;
2252 va_start (args, event_thread);
2254 _envListLock->readLock ()->lock ();
2255 struct jvmti_env_list *e;
2256 FOREACH_ENVIRONMENT (e)
2258 /* Events are only posted if the event was explicitly enabled,
2259 it has a registered event handler, and the event thread
2260 matches (either globally or restricted to a specific thread).
2261 Here we check all but the event handler, which will be handled
2262 by post_event. */
2263 if (e->env->enabled[EVENT_INDEX(type)]
2264 && (e->env->thread[EVENT_INDEX(type)] == NULL
2265 || e->env->thread[EVENT_INDEX(type)] == event_thread))
2267 post_event (e->env, type, event_thread, args);
2270 _envListLock->readLock ()->unlock ();
2271 va_end (args);