2007-01-17 Jack Howarth <howarth@bromo.med.uc.edu>
[official-gcc.git] / libjava / jvmti.cc
blobf6df8c560846617b332fedc46decf5c8af19846a
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/Object.h>
31 #include <java/lang/OutOfMemoryError.h>
32 #include <java/lang/Thread.h>
33 #include <java/lang/ThreadGroup.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/net/URL.h>
42 static void check_enabled_events (void);
43 static void check_enabled_event (jvmtiEvent);
45 namespace JVMTI
47 bool VMInit = false;
48 bool VMDeath = false;
49 bool ThreadStart = false;
50 bool ThreadEnd = false;
51 bool ClassFileLoadHook = false;
52 bool ClassLoad = false;
53 bool ClassPrepare = false;
54 bool VMStart = false;
55 bool Exception = false;
56 bool ExceptionCatch = false;
57 bool SingleStep = false;
58 bool FramePop = false;
59 bool Breakpoint = false;
60 bool FieldAccess = false;
61 bool FieldModification = false;
62 bool MethodEntry = false;
63 bool MethodExit = false;
64 bool NativeMethodBind = false;
65 bool CompiledMethodLoad = false;
66 bool CompiledMethodUnload = false;
67 bool DynamicCodeGenerated = false;
68 bool DataDumpRequest = false;
69 bool reserved72 = false;
70 bool MonitorWait = false;
71 bool MonitorWaited = false;
72 bool MonitorContendedEnter = false;
73 bool MonitorContendedEntered = false;
74 bool reserved77 = false;
75 bool reserved78 = false;
76 bool reserved79 = false;
77 bool reserved80 = false;
78 bool GarbageCollectionStart = false;
79 bool GarbageCollectionFinish = false;
80 bool ObjectFree = false;
81 bool VMObjectAlloc = false;
84 extern struct JNINativeInterface _Jv_JNIFunctions;
86 struct _Jv_rawMonitorID
88 _Jv_Mutex_t mutex;
89 _Jv_ConditionVariable_t condition;
92 /* A simple linked list of all JVMTI environments. Since
93 events must be delivered to environments in the order
94 in which the environments were created, new environments
95 are added to the end of the list. */
96 struct jvmti_env_list
98 jvmtiEnv *env;
99 struct jvmti_env_list *next;
101 static struct jvmti_env_list *_jvmtiEnvironments = NULL;
102 static java::lang::Object *_envListLock = NULL;
103 #define FOREACH_ENVIRONMENT(Ele) \
104 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
106 // Some commonly-used checks
108 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
109 do \
111 if (Ajthread == NULL) \
112 Ajthread = java::lang::Thread::currentThread (); \
114 while (0)
116 #define THREAD_CHECK_VALID(Athread) \
117 do \
119 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
120 return JVMTI_ERROR_INVALID_THREAD; \
122 while (0)
124 #define THREAD_CHECK_IS_ALIVE(Athread) \
125 do \
127 if (!Athread->isAlive ()) \
128 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
130 while (0)
132 // FIXME: if current phase is not set in Phases,
133 // return JVMTI_ERROR_WRONG_PHASE
134 #define REQUIRE_PHASE(Env, Phases)
136 #define NULL_CHECK(Ptr) \
137 do \
139 if (Ptr == NULL) \
140 return JVMTI_ERROR_NULL_POINTER; \
142 while (0)
144 #define ILLEGAL_ARGUMENT(Cond) \
145 do \
147 if ((Cond)) \
148 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
150 while (0)
152 static jvmtiError JNICALL
153 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
155 using namespace java::lang;
157 THREAD_DEFAULT_TO_CURRENT (thread);
159 Thread *t = reinterpret_cast<Thread *> (thread);
160 THREAD_CHECK_VALID (t);
161 THREAD_CHECK_IS_ALIVE (t);
163 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
164 _Jv_SuspendThread (data);
165 return JVMTI_ERROR_NONE;
168 static jvmtiError JNICALL
169 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
171 using namespace java::lang;
173 THREAD_DEFAULT_TO_CURRENT (thread);
175 Thread *t = reinterpret_cast<Thread *> (thread);
176 THREAD_CHECK_VALID (t);
177 THREAD_CHECK_IS_ALIVE (t);
179 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
180 _Jv_ResumeThread (data);
181 return JVMTI_ERROR_NONE;
184 static jvmtiError JNICALL
185 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
187 using namespace java::lang;
189 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
190 // FIXME: capability handling? 'can_signal_thread'
191 if (thread == NULL)
192 return JVMTI_ERROR_INVALID_THREAD;
194 Thread *real_thread = reinterpret_cast<Thread *> (thread);
195 THREAD_CHECK_VALID (real_thread);
196 THREAD_CHECK_IS_ALIVE (real_thread);
197 real_thread->interrupt();
198 return JVMTI_ERROR_NONE;
201 static jvmtiError JNICALL
202 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
203 jthread **threads)
205 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
206 NULL_CHECK (thread_cnt);
207 NULL_CHECK (threads);
209 using namespace java::lang;
211 ThreadGroup *root_grp = ThreadGroup::root;
212 jint estimate = root_grp->activeCount ();
214 JArray<Thread *> *thr_arr;
216 // Allocate some extra space since threads can be created between calls
219 thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
220 ((estimate * 2),
221 &Thread::class$, NULL));
223 catch (java::lang::OutOfMemoryError *err)
225 return JVMTI_ERROR_OUT_OF_MEMORY;
228 *thread_cnt = root_grp->enumerate (thr_arr);
230 jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)),
231 (unsigned char **) threads);
233 if (jerr != JVMTI_ERROR_NONE)
234 return jerr;
236 // Transfer the threads to the result array
237 jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr));
239 memcpy ((*threads), tmp_arr, (*thread_cnt));
241 return JVMTI_ERROR_NONE;
244 static jvmtiError JNICALL
245 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
246 jrawMonitorID *result)
248 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
249 NULL_CHECK (name);
250 NULL_CHECK (result);
251 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
252 if (*result == NULL)
253 return JVMTI_ERROR_OUT_OF_MEMORY;
254 _Jv_MutexInit (&(*result)->mutex);
255 _Jv_CondInit (&(*result)->condition);
256 return JVMTI_ERROR_NONE;
259 static jvmtiError JNICALL
260 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
262 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
263 // Note we have no better way of knowing whether this object is
264 // really a raw monitor.
265 if (monitor == NULL)
266 return JVMTI_ERROR_INVALID_MONITOR;
267 // FIXME: perform checks on monitor, release it if this thread owns
268 // it.
269 #ifdef _Jv_HaveMutexDestroy
270 _Jv_MutexDestroy (&monitor->mutex);
271 #endif
272 _Jv_Free (monitor);
273 return JVMTI_ERROR_NONE;
276 static jvmtiError JNICALL
277 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
279 if (monitor == NULL)
280 return JVMTI_ERROR_INVALID_MONITOR;
281 _Jv_MutexLock (&monitor->mutex);
282 return JVMTI_ERROR_NONE;
285 static jvmtiError JNICALL
286 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
288 if (monitor == NULL)
289 return JVMTI_ERROR_INVALID_MONITOR;
290 if (_Jv_MutexUnlock (&monitor->mutex))
291 return JVMTI_ERROR_NOT_MONITOR_OWNER;
292 return JVMTI_ERROR_NONE;
295 static jvmtiError JNICALL
296 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
297 jlong millis)
299 if (monitor == NULL)
300 return JVMTI_ERROR_INVALID_MONITOR;
301 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
302 if (r == _JV_NOT_OWNER)
303 return JVMTI_ERROR_NOT_MONITOR_OWNER;
304 if (r == _JV_INTERRUPTED)
305 return JVMTI_ERROR_INTERRUPT;
306 return JVMTI_ERROR_NONE;
309 static jvmtiError JNICALL
310 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
312 if (monitor == NULL)
313 return JVMTI_ERROR_INVALID_MONITOR;
314 if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
315 return JVMTI_ERROR_NOT_MONITOR_OWNER;
316 return JVMTI_ERROR_NONE;
319 static jvmtiError JNICALL
320 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
321 jrawMonitorID monitor)
323 if (monitor == NULL)
324 return JVMTI_ERROR_INVALID_MONITOR;
325 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
326 == _JV_NOT_OWNER)
327 return JVMTI_ERROR_NOT_MONITOR_OWNER;
328 return JVMTI_ERROR_NONE;
331 static jvmtiError JNICALL
332 _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
334 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
336 using namespace gnu::gcj::jvmti;
337 Breakpoint *bp
338 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
339 location);
340 if (bp == NULL)
342 jclass klass;
343 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
344 if (err != JVMTI_ERROR_NONE)
345 return err;
347 if (!_Jv_IsInterpretedClass (klass))
348 return JVMTI_ERROR_INVALID_CLASS;
350 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
351 if (base == NULL)
352 return JVMTI_ERROR_INVALID_METHODID;
354 jint flags;
355 err = env->GetMethodModifiers (method, &flags);
356 if (err != JVMTI_ERROR_NONE)
357 return err;
359 if (flags & java::lang::reflect::Modifier::NATIVE)
360 return JVMTI_ERROR_NATIVE_METHOD;
362 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
363 if (imeth->get_insn (location) == NULL)
364 return JVMTI_ERROR_INVALID_LOCATION;
366 // Now the breakpoint can be safely installed
367 bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
368 location);
370 else
372 // Duplicate breakpoints are not permitted by JVMTI
373 return JVMTI_ERROR_DUPLICATE;
376 return JVMTI_ERROR_NONE;
379 static jvmtiError JNICALL
380 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
381 jlocation location)
383 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
385 using namespace gnu::gcj::jvmti;
387 Breakpoint *bp
388 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
389 location);
390 if (bp == NULL)
391 return JVMTI_ERROR_NOT_FOUND;
393 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
394 return JVMTI_ERROR_NONE;
397 static jvmtiError JNICALL
398 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
399 unsigned char **result)
401 ILLEGAL_ARGUMENT (size < 0);
402 NULL_CHECK (result);
403 if (size == 0)
404 *result = NULL;
405 else
407 *result = (unsigned char *) _Jv_MallocUnchecked (size);
408 if (*result == NULL)
409 return JVMTI_ERROR_OUT_OF_MEMORY;
411 return JVMTI_ERROR_NONE;
414 static jvmtiError JNICALL
415 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
417 if (mem != NULL)
418 _Jv_Free (mem);
419 return JVMTI_ERROR_NONE;
422 static jvmtiError JNICALL
423 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
424 jint *mods)
426 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
427 // Don't bother checking KLASS' type.
428 if (klass == NULL)
429 return JVMTI_ERROR_INVALID_CLASS;
430 NULL_CHECK (mods);
431 *mods = klass->getModifiers();
432 return JVMTI_ERROR_NONE;
435 static jvmtiError JNICALL
436 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
437 jint *count_ptr, jmethodID **methods_ptr)
439 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
440 // FIXME: capability can_maintain_original_method_order
441 // Don't bother checking KLASS' type.
442 if (klass == NULL)
443 return JVMTI_ERROR_INVALID_CLASS;
444 NULL_CHECK (count_ptr);
445 NULL_CHECK (methods_ptr);
446 *count_ptr = JvNumMethods(klass);
448 *methods_ptr
449 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
450 if (*methods_ptr == NULL)
451 return JVMTI_ERROR_OUT_OF_MEMORY;
453 jmethodID start = JvGetFirstMethod (klass);
454 for (jint i = 0; i < *count_ptr; ++i)
455 // FIXME: correct?
456 (*methods_ptr)[i] = start + i;
458 return JVMTI_ERROR_NONE;
461 static jvmtiError JNICALL
462 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
463 jboolean *result)
465 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
466 if (klass == NULL)
467 return JVMTI_ERROR_INVALID_CLASS;
468 NULL_CHECK (result);
469 *result = klass->isInterface();
470 return JVMTI_ERROR_NONE;
473 static jvmtiError JNICALL
474 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
475 jboolean *result)
477 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
478 if (klass == NULL)
479 return JVMTI_ERROR_INVALID_CLASS;
480 NULL_CHECK (result);
481 *result = klass->isArray();
482 return JVMTI_ERROR_NONE;
485 static jvmtiError JNICALL
486 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
487 jobject *result)
489 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
490 if (klass == NULL)
491 return JVMTI_ERROR_INVALID_CLASS;
492 NULL_CHECK (result);
493 *result = klass->getClassLoaderInternal();
494 return JVMTI_ERROR_NONE;
497 static jvmtiError JNICALL
498 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
499 jint *result)
501 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
502 if (obj == NULL)
503 return JVMTI_ERROR_INVALID_OBJECT;
504 NULL_CHECK (result);
505 *result = _Jv_HashCode (obj);
506 return JVMTI_ERROR_NONE;
509 static jvmtiError JNICALL
510 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
511 jfieldID field, jint *result)
513 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
514 if (klass == NULL)
515 return JVMTI_ERROR_INVALID_CLASS;
516 if (field == NULL)
517 return JVMTI_ERROR_INVALID_FIELDID;
518 NULL_CHECK (result);
519 *result = field->getModifiers();
520 return JVMTI_ERROR_NONE;
523 static jvmtiError JNICALL
524 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
525 jfieldID field, jboolean *result)
527 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
528 if (klass == NULL)
529 return JVMTI_ERROR_INVALID_CLASS;
530 if (field == NULL)
531 return JVMTI_ERROR_INVALID_FIELDID;
532 NULL_CHECK (result);
534 // FIXME: capability can_get_synthetic_attribute
535 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
536 != 0);
537 return JVMTI_ERROR_NONE;
540 static jvmtiError JNICALL
541 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
542 jint *result)
544 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
545 if (method == NULL)
546 return JVMTI_ERROR_INVALID_METHODID;
547 NULL_CHECK (result);
549 // FIXME: mask off some internal bits...
550 *result = method->accflags;
551 return JVMTI_ERROR_NONE;
554 static jvmtiError JNICALL
555 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
556 jint *entry_count_ptr,
557 jvmtiLineNumberEntry **table_ptr)
559 NULL_CHECK (entry_count_ptr);
560 NULL_CHECK (table_ptr);
562 jclass klass;
563 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
564 if (jerr != JVMTI_ERROR_NONE)
565 return jerr;
567 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
568 if (base == NULL)
569 return JVMTI_ERROR_INVALID_METHODID;
571 if (java::lang::reflect::Modifier::isNative (method->accflags)
572 || !_Jv_IsInterpretedClass (klass))
573 return JVMTI_ERROR_NATIVE_METHOD;
575 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
576 jlong start, end;
577 jintArray lines = NULL;
578 jlongArray indices = NULL;
579 imeth->get_line_table (start, end, lines, indices);
580 if (lines == NULL)
581 return JVMTI_ERROR_ABSENT_INFORMATION;
583 jvmtiLineNumberEntry *table;
584 jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
585 table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
586 if (table == NULL)
587 return JVMTI_ERROR_OUT_OF_MEMORY;
589 jint *line = elements (lines);
590 jlong *index = elements (indices);
591 for (int i = 0; i < lines->length; ++i)
593 table[i].start_location = index[i];
594 table[i].line_number = line[i];
597 *table_ptr = table;
598 *entry_count_ptr = lines->length;
599 return JVMTI_ERROR_NONE;
602 static jvmtiError JNICALL
603 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
604 jboolean *result)
606 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
607 if (method == NULL)
608 return JVMTI_ERROR_INVALID_METHODID;
609 NULL_CHECK (result);
611 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
612 return JVMTI_ERROR_NONE;
615 static jvmtiError JNICALL
616 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
617 jboolean *result)
619 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
620 if (method == NULL)
621 return JVMTI_ERROR_INVALID_METHODID;
622 NULL_CHECK (result);
624 // FIXME capability can_get_synthetic_attribute
626 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
627 != 0);
628 return JVMTI_ERROR_NONE;
631 static jvmtiError JNICALL
632 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
633 jmethodID method,
634 jclass *declaring_class_ptr)
636 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
637 NULL_CHECK (declaring_class_ptr);
639 jclass klass = _Jv_GetMethodDeclaringClass (method);
640 if (klass != NULL)
642 *declaring_class_ptr = klass;
643 return JVMTI_ERROR_NONE;
646 return JVMTI_ERROR_INVALID_METHODID;
649 static jvmtiError JNICALL
650 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
651 jobject init_loader,
652 jint *count_ptr,
653 jclass **result_ptr)
655 using namespace java::lang;
656 using namespace java::util;
658 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
659 NULL_CHECK (count_ptr);
660 NULL_CHECK (result_ptr);
662 ClassLoader *loader = (ClassLoader *) init_loader;
663 if (loader == NULL)
664 loader = VMClassLoader::bootLoader;
666 Collection *values = loader->loadedClasses->values();
667 jobjectArray array = values->toArray();
668 *count_ptr = array->length;
669 jobject *elts = elements (array);
670 jclass *result
671 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
672 if (result == NULL)
673 return JVMTI_ERROR_OUT_OF_MEMORY;
675 // FIXME: JNI references...
676 memcpy (result, elts, *count_ptr * sizeof (jclass));
678 *result_ptr = result;
680 return JVMTI_ERROR_NONE;
683 static jvmtiError JNICALL
684 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
686 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
687 _Jv_RunGC();
688 return JVMTI_ERROR_NONE;
691 static jvmtiError JNICALL
692 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
693 const jniNativeInterface *function_table)
695 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
696 NULL_CHECK (function_table);
697 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
698 return JVMTI_ERROR_NONE;
701 static jvmtiError JNICALL
702 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
703 jniNativeInterface **function_table)
705 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
706 NULL_CHECK (function_table);
707 *function_table
708 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
709 if (*function_table == NULL)
710 return JVMTI_ERROR_OUT_OF_MEMORY;
711 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
712 return JVMTI_ERROR_NONE;
715 static jvmtiError JNICALL
716 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
718 NULL_CHECK (env);
720 if (_jvmtiEnvironments == NULL)
721 return JVMTI_ERROR_INVALID_ENVIRONMENT;
722 else
724 JvSynchronize dummy (_envListLock);
725 if (_jvmtiEnvironments->env == env)
727 struct jvmti_env_list *next = _jvmtiEnvironments->next;
728 _Jv_Free (_jvmtiEnvironments);
729 _jvmtiEnvironments = next;
731 else
733 struct jvmti_env_list *e = _jvmtiEnvironments;
734 while (e->next != NULL && e->next->env != env)
735 e = e->next;
736 if (e->next == NULL)
737 return JVMTI_ERROR_INVALID_ENVIRONMENT;
739 struct jvmti_env_list *next = e->next->next;
740 _Jv_Free (e->next);
741 e->next = next;
745 _Jv_Free (env);
747 check_enabled_events ();
749 return JVMTI_ERROR_NONE;
752 static jvmtiError JNICALL
753 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
754 char **result)
756 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
757 NULL_CHECK (property);
758 NULL_CHECK (result);
760 jstring name = JvNewStringUTF(property);
761 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
763 if (result_str == NULL)
764 return JVMTI_ERROR_NOT_AVAILABLE;
766 int len = JvGetStringUTFLength (result_str);
767 *result = (char *) _Jv_MallocUnchecked (len + 1);
768 if (*result == NULL)
769 return JVMTI_ERROR_OUT_OF_MEMORY;
770 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
771 (*result)[len] = '\0';
773 return JVMTI_ERROR_NONE;
776 static jvmtiError JNICALL
777 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
778 const char *value)
780 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
782 NULL_CHECK (property);
783 if (value == NULL)
785 // FIXME: When would a property not be writeable?
786 return JVMTI_ERROR_NONE;
789 jstring prop_str = JvNewStringUTF(property);
790 jstring value_str = JvNewStringUTF(value);
791 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
792 return JVMTI_ERROR_NONE;
795 static jvmtiError JNICALL
796 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
798 NULL_CHECK (nanos_ptr);
799 *nanos_ptr = _Jv_platform_nanotime();
800 return JVMTI_ERROR_NONE;
803 static jvmtiError JNICALL
804 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
805 jint *nprocessors_ptr)
807 NULL_CHECK (nprocessors_ptr);
808 #ifdef _SC_NPROCESSORS_ONLN
809 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
810 #else
811 *nprocessors_ptr = 1;
812 #endif
813 return JVMTI_ERROR_NONE;
816 static jvmtiError JNICALL
817 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
818 const char *segment)
820 using namespace java::lang;
821 using namespace java::net;
822 using namespace gnu::gcj::runtime;
824 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
825 NULL_CHECK (segment);
827 jstring str_segment = JvNewStringUTF(segment);
828 URL *url;
831 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
833 catch (jthrowable ignore)
835 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
838 BootClassLoader *loader = VMClassLoader::bootLoader;
839 // Don't call this too early.
840 // assert (loader != NULL);
841 loader->addURL(url);
842 return JVMTI_ERROR_NONE;
845 static jvmtiError JNICALL
846 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
847 jboolean value)
849 switch (flag)
851 case JVMTI_VERBOSE_OTHER:
852 case JVMTI_VERBOSE_GC:
853 case JVMTI_VERBOSE_JNI:
854 // Ignore.
855 break;
856 case JVMTI_VERBOSE_CLASS:
857 gcj::verbose_class_flag = value;
858 break;
859 default:
860 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
862 return JVMTI_ERROR_NONE;
865 static jvmtiError JNICALL
866 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
867 jlong *result)
869 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
870 if (object == NULL)
871 return JVMTI_ERROR_INVALID_OBJECT;
872 NULL_CHECK (result);
874 jclass klass = object->getClass();
875 if (klass->isArray())
877 jclass comp = klass->getComponentType();
878 jint base
879 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
880 klass->getComponentType());
881 // FIXME: correct for primitive types?
882 jint compSize = comp->size();
883 __JArray *array = (__JArray *) object;
884 *result = base + array->length * compSize;
886 else
888 // Note that if OBJECT is a String then it may (if
889 // str->data==str) take more space. Do we care?
890 *result = klass->size();
892 return JVMTI_ERROR_NONE;
895 /* An event is enabled only if it has both an event handler
896 and it is enabled in the environment. */
897 static void
898 check_enabled_event (jvmtiEvent type)
900 bool *enabled;
901 int offset;
903 #define GET_OFFSET(Event) \
904 do \
906 enabled = &JVMTI::Event; \
907 offset = offsetof (jvmtiEventCallbacks, Event); \
909 while (0)
911 switch (type)
913 case JVMTI_EVENT_VM_INIT:
914 GET_OFFSET (VMInit);
915 break;
917 case JVMTI_EVENT_VM_DEATH:
918 GET_OFFSET (VMDeath);
919 break;
921 case JVMTI_EVENT_THREAD_START:
922 GET_OFFSET (ThreadStart);
923 break;
925 case JVMTI_EVENT_THREAD_END:
926 GET_OFFSET (ThreadEnd);
927 break;
929 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
930 GET_OFFSET (ClassFileLoadHook);
931 break;
933 case JVMTI_EVENT_CLASS_LOAD:
934 GET_OFFSET (ClassLoad);
935 break;
937 case JVMTI_EVENT_CLASS_PREPARE:
938 GET_OFFSET (ClassPrepare);
939 break;
941 case JVMTI_EVENT_VM_START:
942 GET_OFFSET (VMStart);
943 break;
945 case JVMTI_EVENT_EXCEPTION:
946 GET_OFFSET (Exception);
947 break;
949 case JVMTI_EVENT_EXCEPTION_CATCH:
950 GET_OFFSET (ExceptionCatch);
951 break;
953 case JVMTI_EVENT_SINGLE_STEP:
954 GET_OFFSET (SingleStep);
955 break;
957 case JVMTI_EVENT_FRAME_POP:
958 GET_OFFSET (FramePop);
959 break;
961 case JVMTI_EVENT_BREAKPOINT:
962 GET_OFFSET (Breakpoint);
963 break;
965 case JVMTI_EVENT_FIELD_ACCESS:
966 GET_OFFSET (FieldAccess);
967 break;
969 case JVMTI_EVENT_FIELD_MODIFICATION:
970 GET_OFFSET (FieldModification);
971 break;
973 case JVMTI_EVENT_METHOD_ENTRY:
974 GET_OFFSET (MethodEntry);
975 break;
977 case JVMTI_EVENT_METHOD_EXIT:
978 GET_OFFSET (MethodExit);
979 break;
981 case JVMTI_EVENT_NATIVE_METHOD_BIND:
982 GET_OFFSET (NativeMethodBind);
983 break;
985 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
986 GET_OFFSET (CompiledMethodLoad);
987 break;
989 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
990 GET_OFFSET (CompiledMethodUnload);
991 break;
993 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
994 GET_OFFSET (DynamicCodeGenerated);
995 break;
997 case JVMTI_EVENT_DATA_DUMP_REQUEST:
998 GET_OFFSET (DataDumpRequest);
999 break;
1001 case JVMTI_EVENT_MONITOR_WAIT:
1002 GET_OFFSET (MonitorWait);
1003 break;
1005 case JVMTI_EVENT_MONITOR_WAITED:
1006 GET_OFFSET (MonitorWaited);
1007 break;
1009 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1010 GET_OFFSET (MonitorContendedEnter);
1011 break;
1013 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1014 GET_OFFSET (MonitorContendedEntered);
1015 break;
1017 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1018 GET_OFFSET (GarbageCollectionStart);
1019 break;
1021 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1022 GET_OFFSET (GarbageCollectionFinish);
1023 break;
1025 case JVMTI_EVENT_OBJECT_FREE:
1026 GET_OFFSET (ObjectFree);
1027 break;
1029 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1030 GET_OFFSET (VMObjectAlloc);
1031 break;
1033 default:
1034 fprintf (stderr,
1035 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1036 (int) type);
1037 return;
1039 #undef GET_OFFSET
1041 int index = EVENT_INDEX (type); // safe since caller checks this
1043 JvSynchronize dummy (_envListLock);
1044 struct jvmti_env_list *e;
1045 FOREACH_ENVIRONMENT (e)
1047 char *addr
1048 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1049 void **callback = reinterpret_cast<void **> (addr);
1050 if (e->env->enabled[index] && *callback != NULL)
1052 *enabled = true;
1053 return;
1057 *enabled = false;
1060 static void
1061 check_enabled_events ()
1063 check_enabled_event (JVMTI_EVENT_VM_INIT);
1064 check_enabled_event (JVMTI_EVENT_VM_DEATH);
1065 check_enabled_event (JVMTI_EVENT_THREAD_START);
1066 check_enabled_event (JVMTI_EVENT_THREAD_END);
1067 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1068 check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1069 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1070 check_enabled_event (JVMTI_EVENT_VM_START);
1071 check_enabled_event (JVMTI_EVENT_EXCEPTION);
1072 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1073 check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1074 check_enabled_event (JVMTI_EVENT_FRAME_POP);
1075 check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1076 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1077 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1078 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1079 check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1080 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1081 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1082 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1083 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1084 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1085 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1086 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1087 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1088 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1089 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1090 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1091 check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1092 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1095 static jvmtiError JNICALL
1096 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1097 jvmtiEvent type, jthread event_thread, ...)
1099 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1101 if (event_thread != NULL)
1103 using namespace java::lang;
1104 Thread *t = reinterpret_cast<Thread *> (event_thread);
1105 THREAD_CHECK_VALID (t);
1106 THREAD_CHECK_IS_ALIVE (t);
1109 bool enabled;
1110 switch (mode)
1112 case JVMTI_DISABLE:
1113 enabled = false;
1114 break;
1115 case JVMTI_ENABLE:
1116 enabled = true;
1117 break;
1119 default:
1120 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1123 switch (type)
1125 case JVMTI_EVENT_VM_INIT:
1126 case JVMTI_EVENT_VM_DEATH:
1127 case JVMTI_EVENT_THREAD_START:
1128 case JVMTI_EVENT_VM_START:
1129 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1130 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1131 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1132 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1133 ILLEGAL_ARGUMENT (event_thread != NULL);
1134 break;
1136 case JVMTI_EVENT_THREAD_END:
1137 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1138 case JVMTI_EVENT_CLASS_LOAD:
1139 case JVMTI_EVENT_CLASS_PREPARE:
1140 case JVMTI_EVENT_EXCEPTION:
1141 case JVMTI_EVENT_EXCEPTION_CATCH:
1142 case JVMTI_EVENT_SINGLE_STEP:
1143 case JVMTI_EVENT_FRAME_POP:
1144 case JVMTI_EVENT_BREAKPOINT:
1145 case JVMTI_EVENT_FIELD_ACCESS:
1146 case JVMTI_EVENT_FIELD_MODIFICATION:
1147 case JVMTI_EVENT_METHOD_ENTRY:
1148 case JVMTI_EVENT_METHOD_EXIT:
1149 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1150 case JVMTI_EVENT_MONITOR_WAIT:
1151 case JVMTI_EVENT_MONITOR_WAITED:
1152 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1153 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1154 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1155 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1156 case JVMTI_EVENT_OBJECT_FREE:
1157 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1158 break;
1160 default:
1161 return JVMTI_ERROR_INVALID_EVENT_TYPE;
1164 env->thread[EVENT_INDEX(type)] = event_thread;
1165 env->enabled[EVENT_INDEX(type)] = enabled;
1166 check_enabled_event (type);
1167 return JVMTI_ERROR_NONE;
1170 static jvmtiError JNICALL
1171 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1172 const jvmtiEventCallbacks *callbacks,
1173 jint size_of_callbacks)
1175 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1176 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1178 // Copy the list of callbacks into the environment
1179 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1181 /* Check which events are now enabeld (JVMTI makes no requirements
1182 about the order in which SetEventCallbacks and SetEventNotifications
1183 are called. So we must check all events here. */
1184 check_enabled_events ();
1186 return JVMTI_ERROR_NONE;
1189 static jvmtiError JNICALL
1190 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1191 char **name_ptr)
1193 NULL_CHECK (name_ptr);
1195 const char *name;
1196 switch (error)
1198 case JVMTI_ERROR_NONE:
1199 name = "none";
1200 break;
1202 case JVMTI_ERROR_NULL_POINTER:
1203 name = "null pointer";
1204 break;
1206 case JVMTI_ERROR_OUT_OF_MEMORY:
1207 name = "out of memory";
1208 break;
1210 case JVMTI_ERROR_ACCESS_DENIED:
1211 name = "access denied";
1212 break;
1214 case JVMTI_ERROR_WRONG_PHASE:
1215 name = "wrong phase";
1216 break;
1218 case JVMTI_ERROR_INTERNAL:
1219 name = "internal error";
1220 break;
1222 case JVMTI_ERROR_UNATTACHED_THREAD:
1223 name = "unattached thread";
1224 break;
1226 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1227 name = "invalid environment";
1228 break;
1230 case JVMTI_ERROR_INVALID_PRIORITY:
1231 name = "invalid priority";
1232 break;
1234 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1235 name = "thread not suspended";
1236 break;
1238 case JVMTI_ERROR_THREAD_SUSPENDED:
1239 name = "thread suspended";
1240 break;
1242 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1243 name = "thread not alive";
1244 break;
1246 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1247 name = "class not prepared";
1248 break;
1250 case JVMTI_ERROR_NO_MORE_FRAMES:
1251 name = "no more frames";
1252 break;
1254 case JVMTI_ERROR_OPAQUE_FRAME:
1255 name = "opaque frame";
1256 break;
1258 case JVMTI_ERROR_DUPLICATE:
1259 name = "duplicate";
1260 break;
1262 case JVMTI_ERROR_NOT_FOUND:
1263 name = "not found";
1264 break;
1266 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1267 name = "not monitor owner";
1268 break;
1270 case JVMTI_ERROR_INTERRUPT:
1271 name = "interrupted";
1272 break;
1274 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1275 name = "unmodifiable class";
1276 break;
1278 case JVMTI_ERROR_NOT_AVAILABLE:
1279 name = "not available";
1280 break;
1282 case JVMTI_ERROR_ABSENT_INFORMATION:
1283 name = "absent information";
1284 break;
1286 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1287 name = "invalid event type";
1288 break;
1290 case JVMTI_ERROR_NATIVE_METHOD:
1291 name = "native method";
1292 break;
1294 case JVMTI_ERROR_INVALID_THREAD:
1295 name = "invalid thread";
1296 break;
1298 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1299 name = "invalid thread group";
1300 break;
1302 case JVMTI_ERROR_INVALID_OBJECT:
1303 name = "invalid object";
1304 break;
1306 case JVMTI_ERROR_INVALID_CLASS:
1307 name = "invalid class";
1308 break;
1310 case JVMTI_ERROR_INVALID_METHODID:
1311 name = "invalid method ID";
1312 break;
1314 case JVMTI_ERROR_INVALID_LOCATION:
1315 name = "invalid location";
1316 break;
1318 case JVMTI_ERROR_INVALID_FIELDID:
1319 name = "invalid field ID";
1320 break;
1322 case JVMTI_ERROR_TYPE_MISMATCH:
1323 name = "type mismatch";
1324 break;
1326 case JVMTI_ERROR_INVALID_SLOT:
1327 name = "invalid slot";
1328 break;
1330 case JVMTI_ERROR_INVALID_MONITOR:
1331 name = "invalid monitor";
1332 break;
1334 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1335 name = "invalid class format";
1336 break;
1338 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1339 name = "circular class definition";
1340 break;
1342 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1343 name = "unsupported redefinition: method added";
1344 break;
1346 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1347 name = "unsupported redefinition: schema changed";
1348 break;
1350 case JVMTI_ERROR_INVALID_TYPESTATE:
1351 name = "invalid type state";
1352 break;
1354 case JVMTI_ERROR_FAILS_VERIFICATION:
1355 name = "fails verification";
1356 break;
1358 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1359 name = "unsupported redefinition: hierarchy changed";
1360 break;
1362 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1363 name = "unsupported redefinition: method deleted";
1364 break;
1366 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1367 name = "unsupported version";
1368 break;
1370 case JVMTI_ERROR_NAMES_DONT_MATCH:
1371 name = "names do not match";
1372 break;
1374 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1375 name = "unsupported redefinition: class modifiers changed";
1376 break;
1378 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1379 name = "unsupported redefinition: method modifiers changed";
1380 break;
1382 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1383 name = "must possess capability";
1384 break;
1386 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1387 name = "illegal argument";
1388 break;
1390 default:
1391 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1394 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1395 if (*name_ptr == NULL)
1396 return JVMTI_ERROR_OUT_OF_MEMORY;
1398 strcpy (*name_ptr, name);
1399 return JVMTI_ERROR_NONE;
1402 #define RESERVED NULL
1403 #define UNIMPLEMENTED NULL
1405 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1407 RESERVED, // reserved1
1408 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1409 RESERVED, // reserved3
1410 _Jv_JVMTI_GetAllThreads, // GetAllThreads
1411 _Jv_JVMTI_SuspendThread, // SuspendThread
1412 _Jv_JVMTI_ResumeThread, // ResumeThread
1413 UNIMPLEMENTED, // StopThread
1414 _Jv_JVMTI_InterruptThread, // InterruptThread
1415 UNIMPLEMENTED, // GetThreadInfo
1416 UNIMPLEMENTED, // GetOwnedMonitorInfo
1417 UNIMPLEMENTED, // GetCurrentContendedMonitor
1418 UNIMPLEMENTED, // RunAgentThread
1419 UNIMPLEMENTED, // GetTopThreadGroups
1420 UNIMPLEMENTED, // GetThreadGroupInfo
1421 UNIMPLEMENTED, // GetThreadGroupChildren
1422 UNIMPLEMENTED, // GetFrameCount
1423 UNIMPLEMENTED, // GetThreadState
1424 RESERVED, // reserved18
1425 UNIMPLEMENTED, // GetFrameLocation
1426 UNIMPLEMENTED, // NotifyPopFrame
1427 UNIMPLEMENTED, // GetLocalObject
1428 UNIMPLEMENTED, // GetLocalInt
1429 UNIMPLEMENTED, // GetLocalLong
1430 UNIMPLEMENTED, // GetLocalFloat
1431 UNIMPLEMENTED, // GetLocalDouble
1432 UNIMPLEMENTED, // SetLocalObject
1433 UNIMPLEMENTED, // SetLocalInt
1434 UNIMPLEMENTED, // SetLocalLong
1435 UNIMPLEMENTED, // SetLocalFloat
1436 UNIMPLEMENTED, // SetLocalDouble
1437 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
1438 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
1439 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
1440 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
1441 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
1442 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
1443 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
1444 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
1445 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
1446 RESERVED, // reserved40
1447 UNIMPLEMENTED, // SetFieldAccessWatch
1448 UNIMPLEMENTED, // ClearFieldAccessWatch
1449 UNIMPLEMENTED, // SetFieldModificationWatch
1450 UNIMPLEMENTED, // ClearFieldModificationWatch
1451 RESERVED, // reserved45
1452 _Jv_JVMTI_Allocate, // Allocate
1453 _Jv_JVMTI_Deallocate, // Deallocate
1454 UNIMPLEMENTED, // GetClassSignature
1455 UNIMPLEMENTED, // GetClassStatus
1456 UNIMPLEMENTED, // GetSourceFileName
1457 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
1458 _Jv_JVMTI_GetClassMethods, // GetClassMethods
1459 UNIMPLEMENTED, // GetClassFields
1460 UNIMPLEMENTED, // GetImplementedInterfaces
1461 _Jv_JVMTI_IsInterface, // IsInterface
1462 _Jv_JVMTI_IsArrayClass, // IsArrayClass
1463 _Jv_JVMTI_GetClassLoader, // GetClassLoader
1464 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
1465 UNIMPLEMENTED, // GetObjectMonitorUsage
1466 UNIMPLEMENTED, // GetFieldName
1467 UNIMPLEMENTED, // GetFieldDeclaringClass
1468 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
1469 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
1470 UNIMPLEMENTED, // GetMethodName
1471 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
1472 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
1473 RESERVED, // reserved67
1474 UNIMPLEMENTED, // GetMaxLocals
1475 UNIMPLEMENTED, // GetArgumentsSize
1476 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
1477 UNIMPLEMENTED, // GetMethodLocation
1478 UNIMPLEMENTED, // GetLocalVariableTable
1479 RESERVED, // reserved73
1480 RESERVED, // reserved74
1481 UNIMPLEMENTED, // GetBytecodes
1482 _Jv_JVMTI_IsMethodNative, // IsMethodNative
1483 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
1484 UNIMPLEMENTED, // GetLoadedClasses
1485 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
1486 UNIMPLEMENTED, // PopFrame
1487 RESERVED, // reserved81
1488 RESERVED, // reserved82
1489 RESERVED, // reserved83
1490 RESERVED, // reserved84
1491 RESERVED, // reserved85
1492 RESERVED, // reserved86
1493 UNIMPLEMENTED, // RedefineClasses
1494 UNIMPLEMENTED, // GetVersionNumber
1495 UNIMPLEMENTED, // GetCapabilities
1496 UNIMPLEMENTED, // GetSourceDebugExtension
1497 UNIMPLEMENTED, // IsMethodObsolete
1498 UNIMPLEMENTED, // SuspendThreadList
1499 UNIMPLEMENTED, // ResumeThreadList
1500 RESERVED, // reserved94
1501 RESERVED, // reserved95
1502 RESERVED, // reserved96
1503 RESERVED, // reserved97
1504 RESERVED, // reserved98
1505 RESERVED, // reserved99
1506 UNIMPLEMENTED, // GetAllStackTraces
1507 UNIMPLEMENTED, // GetThreadListStackTraces
1508 UNIMPLEMENTED, // GetThreadLocalStorage
1509 UNIMPLEMENTED, // SetThreadLocalStorage
1510 UNIMPLEMENTED, // GetStackTrace
1511 RESERVED, // reserved105
1512 UNIMPLEMENTED, // GetTag
1513 UNIMPLEMENTED, // SetTag
1514 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
1515 UNIMPLEMENTED, // IterateOverObjectsReachable
1516 UNIMPLEMENTED, // IterateOverReachableObjects
1517 UNIMPLEMENTED, // IterateOverHeap
1518 UNIMPLEMENTED, // IterateOverInstanceOfClass
1519 RESERVED, // reserved113
1520 UNIMPLEMENTED, // GetObjectsWithTags
1521 RESERVED, // reserved115
1522 RESERVED, // reserved116
1523 RESERVED, // reserved117
1524 RESERVED, // reserved118
1525 RESERVED, // reserved119
1526 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
1527 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
1528 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
1529 UNIMPLEMENTED, // GenerateEvents
1530 UNIMPLEMENTED, // GetExtensionFunctions
1531 UNIMPLEMENTED, // GetExtensionEvents
1532 UNIMPLEMENTED, // SetExtensionEventCallback
1533 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
1534 _Jv_JVMTI_GetErrorName, // GetErrorName
1535 UNIMPLEMENTED, // GetJLocationFormat
1536 UNIMPLEMENTED, // GetSystemProperties
1537 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
1538 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
1539 UNIMPLEMENTED, // GetPhase
1540 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
1541 UNIMPLEMENTED, // GetCurrentThreadCpuTime
1542 UNIMPLEMENTED, // GetThreadCpuTimerInfo
1543 UNIMPLEMENTED, // GetThreadCpuTime
1544 UNIMPLEMENTED, // GetTimerInfo
1545 _Jv_JVMTI_GetTime, // GetTime
1546 UNIMPLEMENTED, // GetPotentialCapabilities
1547 RESERVED, // reserved141
1548 UNIMPLEMENTED, // AddCapabilities
1549 UNIMPLEMENTED, // RelinquishCapabilities
1550 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
1551 RESERVED, // reserved145
1552 RESERVED, // reserved146
1553 UNIMPLEMENTED, // GetEnvironmentLocalStorage
1554 UNIMPLEMENTED, // SetEnvironmentLocalStorage
1555 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
1556 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
1557 RESERVED, // reserved151
1558 RESERVED, // reserved152
1559 RESERVED, // reserved153
1560 _Jv_JVMTI_GetObjectSize // GetObjectSize
1563 _Jv_JVMTIEnv *
1564 _Jv_GetJVMTIEnv (void)
1566 _Jv_JVMTIEnv *env
1567 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1568 env->p = &_Jv_JVMTI_Interface;
1571 JvSynchronize dummy (_envListLock);
1572 struct jvmti_env_list *element
1573 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
1574 element->env = env;
1575 element->next = NULL;
1577 if (_jvmtiEnvironments == NULL)
1578 _jvmtiEnvironments = element;
1579 else
1581 struct jvmti_env_list *e;
1582 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1584 e->next = element;
1588 return env;
1591 void
1592 _Jv_JVMTI_Init ()
1594 _jvmtiEnvironments = NULL;
1595 _envListLock = new java::lang::Object ();
1597 // No environments, so this should set all JVMTI:: members to false
1598 check_enabled_events ();
1601 static void
1602 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
1604 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
1606 #define GET_BOOLEAN_ARG(Name) \
1607 ARG (int, b); \
1608 jboolean Name = (b == 0) ? false : true
1610 #define GET_CHAR_ARG(Name) \
1611 ARG (int, c); \
1612 char Name = static_cast<char> (c)
1614 switch (type)
1616 case JVMTI_EVENT_VM_INIT:
1617 if (env->callbacks.VMInit != NULL)
1619 ARG (JNIEnv *, jni_env);
1620 env->callbacks.VMInit (env, jni_env, event_thread);
1622 break;
1624 case JVMTI_EVENT_VM_DEATH:
1625 if (env->callbacks.VMDeath != NULL)
1627 ARG (JNIEnv *, jni_env);
1628 env->callbacks.VMDeath (env, jni_env);
1630 break;
1632 case JVMTI_EVENT_THREAD_START:
1633 if (env->callbacks.ThreadStart != NULL)
1635 ARG (JNIEnv *, jni_env);
1636 env->callbacks.ThreadStart (env, jni_env, event_thread);
1638 break;
1640 case JVMTI_EVENT_THREAD_END:
1641 if (env->callbacks.ThreadEnd != NULL)
1643 ARG (JNIEnv *, jni_env);
1644 env->callbacks.ThreadEnd (env, jni_env, event_thread);
1646 break;
1648 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1649 if (env->callbacks.ClassFileLoadHook != NULL)
1651 ARG (JNIEnv *, jni_env);
1652 ARG (jclass, class_being_redefined);
1653 ARG (jobject, loader);
1654 ARG (const char *, name);
1655 ARG (jobject, protection_domain);
1656 ARG (jint, class_data_len);
1657 ARG (const unsigned char *, class_data);
1658 ARG (jint *, new_class_data_len);
1659 ARG (unsigned char **, new_class_data);
1660 env->callbacks.ClassFileLoadHook (env, jni_env,
1661 class_being_redefined, loader,
1662 name, protection_domain,
1663 class_data_len, class_data,
1664 new_class_data_len,
1665 new_class_data);
1667 break;
1669 case JVMTI_EVENT_CLASS_LOAD:
1670 if (env->callbacks.ClassLoad != NULL)
1672 ARG (JNIEnv *, jni_env);
1673 ARG (jclass, klass);
1674 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
1676 break;
1678 case JVMTI_EVENT_CLASS_PREPARE:
1679 if (env->callbacks.ClassPrepare != NULL)
1681 ARG (JNIEnv *, jni_env);
1682 ARG (jclass, klass);
1683 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
1685 break;
1687 case JVMTI_EVENT_VM_START:
1688 if (env->callbacks.VMStart != NULL)
1690 ARG (JNIEnv *, jni_env);
1691 env->callbacks.VMStart (env, jni_env);
1693 break;
1695 case JVMTI_EVENT_EXCEPTION:
1696 if (env->callbacks.Exception != NULL)
1698 ARG (JNIEnv *, jni_env);
1699 ARG (jmethodID, method);
1700 ARG (jlocation, location);
1701 ARG (jobject, exception);
1702 ARG (jmethodID, catch_method);
1703 ARG (jlocation, catch_location);
1704 env->callbacks.Exception (env, jni_env, event_thread, method,
1705 location, exception, catch_method,
1706 catch_location);
1708 break;
1710 case JVMTI_EVENT_EXCEPTION_CATCH:
1711 if (env->callbacks.ExceptionCatch != NULL)
1713 ARG (JNIEnv *, jni_env);
1714 ARG (jmethodID, method);
1715 ARG (jlocation, location);
1716 ARG (jobject, exception);
1717 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
1718 location, exception);
1720 break;
1722 case JVMTI_EVENT_SINGLE_STEP:
1723 if (env->callbacks.SingleStep != NULL)
1725 ARG (JNIEnv *, jni_env);
1726 ARG (jmethodID, method);
1727 ARG (jlocation, location);
1728 env->callbacks.SingleStep (env, jni_env, event_thread, method,
1729 location);
1731 break;
1733 case JVMTI_EVENT_FRAME_POP:
1734 if (env->callbacks.FramePop != NULL)
1736 ARG (JNIEnv *, jni_env);
1737 ARG (jmethodID, method);
1738 GET_BOOLEAN_ARG (was_popped_by_exception);
1739 env->callbacks.FramePop (env, jni_env, event_thread, method,
1740 was_popped_by_exception);
1742 break;
1744 case JVMTI_EVENT_BREAKPOINT:
1745 if (env->callbacks.Breakpoint != NULL)
1747 ARG (JNIEnv *, jni_env);
1748 ARG (jmethodID, method);
1749 ARG (jlocation, location);
1750 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
1751 location);
1753 break;
1755 case JVMTI_EVENT_FIELD_ACCESS:
1756 if (env->callbacks.FieldAccess != NULL)
1758 ARG (JNIEnv *, jni_env);
1759 ARG (jmethodID, method);
1760 ARG (jlocation, location);
1761 ARG (jclass, field_class);
1762 ARG (jobject, object);
1763 ARG (jfieldID, field);
1764 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
1765 location, field_class, object, field);
1767 break;
1769 case JVMTI_EVENT_FIELD_MODIFICATION:
1770 if (env->callbacks.FieldModification != NULL)
1772 ARG (JNIEnv *, jni_env);
1773 ARG (jmethodID, method);
1774 ARG (jlocation, location);
1775 ARG (jclass, field_class);
1776 ARG (jobject, object);
1777 ARG (jfieldID, field);
1778 GET_CHAR_ARG (signature_type);
1779 ARG (jvalue, new_value);
1780 env->callbacks.FieldModification (env, jni_env, event_thread, method,
1781 location, field_class, object,
1782 field, signature_type, new_value);
1784 break;
1786 case JVMTI_EVENT_METHOD_ENTRY:
1787 if (env->callbacks.MethodEntry != NULL)
1789 ARG (JNIEnv *, jni_env);
1790 ARG (jmethodID, method);
1791 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
1793 break;
1795 case JVMTI_EVENT_METHOD_EXIT:
1796 if (env->callbacks.MethodExit != NULL)
1798 ARG (JNIEnv *, jni_env);
1799 ARG (jmethodID, method);
1800 GET_BOOLEAN_ARG (was_popped_by_exception);
1801 ARG (jvalue, return_value);
1802 env->callbacks.MethodExit (env, jni_env, event_thread, method,
1803 was_popped_by_exception, return_value);
1805 break;
1807 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1808 if (env->callbacks.NativeMethodBind != NULL)
1810 ARG (JNIEnv *, jni_env);
1811 ARG (jmethodID, method);
1812 ARG (void *, address);
1813 ARG (void **, new_address_ptr);
1814 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
1815 address, new_address_ptr);
1817 break;
1819 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1820 if (env->callbacks.CompiledMethodLoad != NULL)
1822 ARG (jmethodID, method);
1823 ARG (jint, code_size);
1824 ARG (const void *, code_addr);
1825 ARG (jint, map_length);
1826 ARG (const jvmtiAddrLocationMap *, map);
1827 ARG (const void *, compile_info);
1828 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
1829 map_length, map, compile_info);
1831 break;
1833 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1834 if (env->callbacks.CompiledMethodUnload != NULL)
1836 ARG (jmethodID, method);
1837 ARG (const void *, code_addr);
1838 env->callbacks.CompiledMethodUnload (env, method, code_addr);
1840 break;
1842 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1843 if (env->callbacks.DynamicCodeGenerated != NULL)
1845 ARG (const char *, name);
1846 ARG (const void *, address);
1847 ARG (jint, length);
1848 env->callbacks.DynamicCodeGenerated (env, name, address, length);
1850 break;
1852 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1853 if (env->callbacks.DataDumpRequest != NULL)
1855 env->callbacks.DataDumpRequest (env);
1857 break;
1859 case JVMTI_EVENT_MONITOR_WAIT:
1860 if (env->callbacks.MonitorWait != NULL)
1862 ARG (JNIEnv *, jni_env);
1863 ARG (jobject, object);
1864 ARG (jlong, timeout);
1865 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
1866 timeout);
1868 break;
1870 case JVMTI_EVENT_MONITOR_WAITED:
1871 if (env->callbacks.MonitorWaited != NULL)
1873 ARG (JNIEnv *, jni_env);
1874 ARG (jobject, object);
1875 GET_BOOLEAN_ARG (timed_out);
1876 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
1877 timed_out);
1879 break;
1881 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1882 if (env->callbacks.MonitorContendedEnter != NULL)
1884 ARG (JNIEnv *, jni_env);
1885 ARG (jobject, object);
1886 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
1887 object);
1889 break;
1891 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1892 if (env->callbacks.MonitorContendedEntered != NULL)
1894 ARG (JNIEnv *, jni_env);
1895 ARG (jobject, object);
1896 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
1897 object);
1899 break;
1901 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1902 if (env->callbacks.GarbageCollectionStart != NULL)
1904 env->callbacks.GarbageCollectionStart (env);
1906 break;
1908 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1909 if (env->callbacks.GarbageCollectionFinish != NULL)
1911 env->callbacks.GarbageCollectionFinish (env);
1913 break;
1915 case JVMTI_EVENT_OBJECT_FREE:
1916 if (env->callbacks.ObjectFree != NULL)
1918 ARG (jlong, tag);
1919 env->callbacks.ObjectFree (env, tag);
1921 break;
1923 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1924 if (env->callbacks.VMObjectAlloc != NULL)
1926 ARG (JNIEnv *, jni_env);
1927 ARG (jobject, object);
1928 ARG (jclass, object_class);
1929 ARG (jlong, size);
1930 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
1931 object, object_class, size);
1933 break;
1935 default:
1936 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
1937 (int) type);
1938 break;
1940 va_end (args);
1941 #undef ARG
1942 #undef GET_BOOLEAN_ARG
1943 #undef GET_CHAR_ARG
1946 /* Post an event to requesting JVMTI environments
1948 * This function should not be called without consulting the
1949 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
1950 * harm (other than kill speed), since this function will still
1951 * only send the event if it was properly requested by an environment.
1953 void
1954 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
1956 va_list args;
1957 va_start (args, event_thread);
1959 JvSynchronize dummy (_envListLock);
1960 struct jvmti_env_list *e;
1961 FOREACH_ENVIRONMENT (e)
1963 /* Events are only posted if the event was explicitly enabled,
1964 it has a registered event handler, and the event thread
1965 matches (either globally or restricted to a specific thread).
1966 Here we check all but the event handler, which will be handled
1967 by post_event. */
1968 if (e->env->enabled[EVENT_INDEX(type)]
1969 && (e->env->thread[EVENT_INDEX(type)] == NULL
1970 || e->env->thread[EVENT_INDEX(type)] == event_thread))
1972 post_event (e->env, type, event_thread, args);
1976 va_end (args);