jvmti.cc (_Jv_JVMTI_GetAllThreads): New function.
[gcc.git] / libjava / jvmti.cc
1 // jvmti.cc - JVMTI implementation
2
3 /* Copyright (C) 2006 Free Software Foundation
4
5 This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
10
11 #include <config.h>
12 #include <platform.h>
13
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"
20
21 #include <gcj/method.h>
22
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>
27
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>
41
42 static void check_enabled_events (void);
43 static void check_enabled_event (jvmtiEvent);
44
45 namespace JVMTI
46 {
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;
82 };
83
84 extern struct JNINativeInterface _Jv_JNIFunctions;
85
86 struct _Jv_rawMonitorID
87 {
88 _Jv_Mutex_t mutex;
89 _Jv_ConditionVariable_t condition;
90 };
91
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
97 {
98 jvmtiEnv *env;
99 struct jvmti_env_list *next;
100 };
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)
105
106 // Some commonly-used checks
107
108 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
109 do \
110 { \
111 if (Ajthread == NULL) \
112 Ajthread = java::lang::Thread::currentThread (); \
113 } \
114 while (0)
115
116 #define THREAD_CHECK_VALID(Athread) \
117 do \
118 { \
119 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
120 return JVMTI_ERROR_INVALID_THREAD; \
121 } \
122 while (0)
123
124 #define THREAD_CHECK_IS_ALIVE(Athread) \
125 do \
126 { \
127 if (!Athread->isAlive ()) \
128 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
129 } \
130 while (0)
131
132 // FIXME: if current phase is not set in Phases,
133 // return JVMTI_ERROR_WRONG_PHASE
134 #define REQUIRE_PHASE(Env, Phases)
135
136 #define NULL_CHECK(Ptr) \
137 do \
138 { \
139 if (Ptr == NULL) \
140 return JVMTI_ERROR_NULL_POINTER; \
141 } \
142 while (0)
143
144 #define ILLEGAL_ARGUMENT(Cond) \
145 do \
146 { \
147 if ((Cond)) \
148 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
149 } \
150 while (0)
151
152 static jvmtiError JNICALL
153 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
154 {
155 using namespace java::lang;
156
157 THREAD_DEFAULT_TO_CURRENT (thread);
158
159 Thread *t = reinterpret_cast<Thread *> (thread);
160 THREAD_CHECK_VALID (t);
161 THREAD_CHECK_IS_ALIVE (t);
162
163 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
164 _Jv_SuspendThread (data);
165 return JVMTI_ERROR_NONE;
166 }
167
168 static jvmtiError JNICALL
169 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
170 {
171 using namespace java::lang;
172
173 THREAD_DEFAULT_TO_CURRENT (thread);
174
175 Thread *t = reinterpret_cast<Thread *> (thread);
176 THREAD_CHECK_VALID (t);
177 THREAD_CHECK_IS_ALIVE (t);
178
179 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
180 _Jv_ResumeThread (data);
181 return JVMTI_ERROR_NONE;
182 }
183
184 static jvmtiError JNICALL
185 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
186 {
187 using namespace java::lang;
188
189 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
190 // FIXME: capability handling? 'can_signal_thread'
191 if (thread == NULL)
192 return JVMTI_ERROR_INVALID_THREAD;
193
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;
199 }
200
201 jvmtiError
202 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
203 jthread **threads)
204 {
205 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
206 NULL_CHECK (thread_cnt);
207 NULL_CHECK (threads);
208
209 using namespace java::lang;
210 Thread *thr = Thread::currentThread ();
211
212 ThreadGroup *root_grp = ThreadGroup::root;
213 jint estimate = root_grp->activeCount ();
214
215 JArray<Thread *> *thr_arr;
216
217 // Allocate some extra space since threads can be created between calls
218 try
219 {
220 thr_arr
221 = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
222 ((estimate * 2),
223 &Thread::class$, NULL));
224 }
225 catch (java::lang::OutOfMemoryError *err)
226 {
227 return JVMTI_ERROR_OUT_OF_MEMORY;
228 }
229
230 *thread_cnt = root_grp->enumerate (thr_arr);
231
232 jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)),
233 (unsigned char **) threads);
234
235 if (jerr != JVMTI_ERROR_NONE)
236 return jerr;
237
238 // Transfer the threads to the result array
239 jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr));
240
241 memcpy ((*threads), tmp_arr, (*thread_cnt));
242
243 return JVMTI_ERROR_NONE;
244 }
245
246 static jvmtiError JNICALL
247 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
248 jrawMonitorID *result)
249 {
250 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
251 NULL_CHECK (name);
252 NULL_CHECK (result);
253 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
254 if (*result == NULL)
255 return JVMTI_ERROR_OUT_OF_MEMORY;
256 _Jv_MutexInit (&(*result)->mutex);
257 _Jv_CondInit (&(*result)->condition);
258 return JVMTI_ERROR_NONE;
259 }
260
261 static jvmtiError JNICALL
262 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
263 {
264 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
265 // Note we have no better way of knowing whether this object is
266 // really a raw monitor.
267 if (monitor == NULL)
268 return JVMTI_ERROR_INVALID_MONITOR;
269 // FIXME: perform checks on monitor, release it if this thread owns
270 // it.
271 #ifdef _Jv_HaveMutexDestroy
272 _Jv_MutexDestroy (&monitor->mutex);
273 #endif
274 _Jv_Free (monitor);
275 return JVMTI_ERROR_NONE;
276 }
277
278 static jvmtiError JNICALL
279 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
280 {
281 if (monitor == NULL)
282 return JVMTI_ERROR_INVALID_MONITOR;
283 _Jv_MutexLock (&monitor->mutex);
284 return JVMTI_ERROR_NONE;
285 }
286
287 static jvmtiError JNICALL
288 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
289 {
290 if (monitor == NULL)
291 return JVMTI_ERROR_INVALID_MONITOR;
292 if (_Jv_MutexUnlock (&monitor->mutex))
293 return JVMTI_ERROR_NOT_MONITOR_OWNER;
294 return JVMTI_ERROR_NONE;
295 }
296
297 static jvmtiError JNICALL
298 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
299 jlong millis)
300 {
301 if (monitor == NULL)
302 return JVMTI_ERROR_INVALID_MONITOR;
303 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
304 if (r == _JV_NOT_OWNER)
305 return JVMTI_ERROR_NOT_MONITOR_OWNER;
306 if (r == _JV_INTERRUPTED)
307 return JVMTI_ERROR_INTERRUPT;
308 return JVMTI_ERROR_NONE;
309 }
310
311 static jvmtiError JNICALL
312 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
313 {
314 if (monitor == NULL)
315 return JVMTI_ERROR_INVALID_MONITOR;
316 if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
317 return JVMTI_ERROR_NOT_MONITOR_OWNER;
318 return JVMTI_ERROR_NONE;
319 }
320
321 static jvmtiError JNICALL
322 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
323 jrawMonitorID monitor)
324 {
325 if (monitor == NULL)
326 return JVMTI_ERROR_INVALID_MONITOR;
327 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
328 == _JV_NOT_OWNER)
329 return JVMTI_ERROR_NOT_MONITOR_OWNER;
330 return JVMTI_ERROR_NONE;
331 }
332
333 static jvmtiError JNICALL
334 _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
335 {
336 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
337
338 using namespace gnu::gcj::jvmti;
339 Breakpoint *bp
340 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
341 location);
342 if (bp == NULL)
343 {
344 jclass klass;
345 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
346 if (err != JVMTI_ERROR_NONE)
347 return err;
348
349 if (!_Jv_IsInterpretedClass (klass))
350 return JVMTI_ERROR_INVALID_CLASS;
351
352 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
353 if (base == NULL)
354 return JVMTI_ERROR_INVALID_METHODID;
355
356 jint flags;
357 err = env->GetMethodModifiers (method, &flags);
358 if (err != JVMTI_ERROR_NONE)
359 return err;
360
361 if (flags & java::lang::reflect::Modifier::NATIVE)
362 return JVMTI_ERROR_NATIVE_METHOD;
363
364 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
365 if (imeth->get_insn (location) == NULL)
366 return JVMTI_ERROR_INVALID_LOCATION;
367
368 // Now the breakpoint can be safely installed
369 bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
370 location);
371 }
372 else
373 {
374 // Duplicate breakpoints are not permitted by JVMTI
375 return JVMTI_ERROR_DUPLICATE;
376 }
377
378 return JVMTI_ERROR_NONE;
379 }
380
381 static jvmtiError JNICALL
382 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
383 jlocation location)
384 {
385 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
386
387 using namespace gnu::gcj::jvmti;
388
389 Breakpoint *bp
390 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
391 location);
392 if (bp == NULL)
393 return JVMTI_ERROR_NOT_FOUND;
394
395 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
396 return JVMTI_ERROR_NONE;
397 }
398
399 static jvmtiError JNICALL
400 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
401 unsigned char **result)
402 {
403 ILLEGAL_ARGUMENT (size < 0);
404 NULL_CHECK (result);
405 if (size == 0)
406 *result = NULL;
407 else
408 {
409 *result = (unsigned char *) _Jv_MallocUnchecked (size);
410 if (*result == NULL)
411 return JVMTI_ERROR_OUT_OF_MEMORY;
412 }
413 return JVMTI_ERROR_NONE;
414 }
415
416 static jvmtiError JNICALL
417 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
418 {
419 if (mem != NULL)
420 _Jv_Free (mem);
421 return JVMTI_ERROR_NONE;
422 }
423
424 static jvmtiError JNICALL
425 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
426 jint *mods)
427 {
428 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
429 // Don't bother checking KLASS' type.
430 if (klass == NULL)
431 return JVMTI_ERROR_INVALID_CLASS;
432 NULL_CHECK (mods);
433 *mods = klass->getModifiers();
434 return JVMTI_ERROR_NONE;
435 }
436
437 static jvmtiError JNICALL
438 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
439 jint *count_ptr, jmethodID **methods_ptr)
440 {
441 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
442 // FIXME: capability can_maintain_original_method_order
443 // Don't bother checking KLASS' type.
444 if (klass == NULL)
445 return JVMTI_ERROR_INVALID_CLASS;
446 NULL_CHECK (count_ptr);
447 NULL_CHECK (methods_ptr);
448 *count_ptr = JvNumMethods(klass);
449
450 *methods_ptr
451 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
452 if (*methods_ptr == NULL)
453 return JVMTI_ERROR_OUT_OF_MEMORY;
454
455 jmethodID start = JvGetFirstMethod (klass);
456 for (jint i = 0; i < *count_ptr; ++i)
457 // FIXME: correct?
458 (*methods_ptr)[i] = start + i;
459
460 return JVMTI_ERROR_NONE;
461 }
462
463 static jvmtiError JNICALL
464 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
465 jboolean *result)
466 {
467 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
468 if (klass == NULL)
469 return JVMTI_ERROR_INVALID_CLASS;
470 NULL_CHECK (result);
471 *result = klass->isInterface();
472 return JVMTI_ERROR_NONE;
473 }
474
475 static jvmtiError JNICALL
476 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
477 jboolean *result)
478 {
479 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
480 if (klass == NULL)
481 return JVMTI_ERROR_INVALID_CLASS;
482 NULL_CHECK (result);
483 *result = klass->isArray();
484 return JVMTI_ERROR_NONE;
485 }
486
487 static jvmtiError JNICALL
488 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
489 jobject *result)
490 {
491 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
492 if (klass == NULL)
493 return JVMTI_ERROR_INVALID_CLASS;
494 NULL_CHECK (result);
495 *result = klass->getClassLoaderInternal();
496 return JVMTI_ERROR_NONE;
497 }
498
499 static jvmtiError JNICALL
500 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
501 jint *result)
502 {
503 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
504 if (obj == NULL)
505 return JVMTI_ERROR_INVALID_OBJECT;
506 NULL_CHECK (result);
507 *result = _Jv_HashCode (obj);
508 return JVMTI_ERROR_NONE;
509 }
510
511 static jvmtiError JNICALL
512 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
513 jfieldID field, jint *result)
514 {
515 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
516 if (klass == NULL)
517 return JVMTI_ERROR_INVALID_CLASS;
518 if (field == NULL)
519 return JVMTI_ERROR_INVALID_FIELDID;
520 NULL_CHECK (result);
521 *result = field->getModifiers();
522 return JVMTI_ERROR_NONE;
523 }
524
525 static jvmtiError JNICALL
526 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
527 jfieldID field, jboolean *result)
528 {
529 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
530 if (klass == NULL)
531 return JVMTI_ERROR_INVALID_CLASS;
532 if (field == NULL)
533 return JVMTI_ERROR_INVALID_FIELDID;
534 NULL_CHECK (result);
535
536 // FIXME: capability can_get_synthetic_attribute
537 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
538 != 0);
539 return JVMTI_ERROR_NONE;
540 }
541
542 static jvmtiError JNICALL
543 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
544 jint *result)
545 {
546 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
547 if (method == NULL)
548 return JVMTI_ERROR_INVALID_METHODID;
549 NULL_CHECK (result);
550
551 // FIXME: mask off some internal bits...
552 *result = method->accflags;
553 return JVMTI_ERROR_NONE;
554 }
555
556 static jvmtiError JNICALL
557 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
558 jint *entry_count_ptr,
559 jvmtiLineNumberEntry **table_ptr)
560 {
561 NULL_CHECK (entry_count_ptr);
562 NULL_CHECK (table_ptr);
563
564 jclass klass;
565 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
566 if (jerr != JVMTI_ERROR_NONE)
567 return jerr;
568
569 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
570 if (base == NULL)
571 return JVMTI_ERROR_INVALID_METHODID;
572
573 if (java::lang::reflect::Modifier::isNative (method->accflags)
574 || !_Jv_IsInterpretedClass (klass))
575 return JVMTI_ERROR_NATIVE_METHOD;
576
577 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
578 jlong start, end;
579 jintArray lines = NULL;
580 jlongArray indices = NULL;
581 imeth->get_line_table (start, end, lines, indices);
582 if (lines == NULL)
583 return JVMTI_ERROR_ABSENT_INFORMATION;
584
585 jvmtiLineNumberEntry *table;
586 jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
587 table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
588 if (table == NULL)
589 return JVMTI_ERROR_OUT_OF_MEMORY;
590
591 jint *line = elements (lines);
592 jlong *index = elements (indices);
593 for (int i = 0; i < lines->length; ++i)
594 {
595 table[i].start_location = index[i];
596 table[i].line_number = line[i];
597 }
598
599 *table_ptr = table;
600 *entry_count_ptr = lines->length;
601 return JVMTI_ERROR_NONE;
602 }
603
604 static jvmtiError JNICALL
605 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
606 jboolean *result)
607 {
608 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
609 if (method == NULL)
610 return JVMTI_ERROR_INVALID_METHODID;
611 NULL_CHECK (result);
612
613 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
614 return JVMTI_ERROR_NONE;
615 }
616
617 static jvmtiError JNICALL
618 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
619 jboolean *result)
620 {
621 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
622 if (method == NULL)
623 return JVMTI_ERROR_INVALID_METHODID;
624 NULL_CHECK (result);
625
626 // FIXME capability can_get_synthetic_attribute
627
628 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
629 != 0);
630 return JVMTI_ERROR_NONE;
631 }
632
633 static jvmtiError JNICALL
634 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
635 jmethodID method,
636 jclass *declaring_class_ptr)
637 {
638 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
639 NULL_CHECK (declaring_class_ptr);
640
641 jclass klass = _Jv_GetMethodDeclaringClass (method);
642 if (klass != NULL)
643 {
644 *declaring_class_ptr = klass;
645 return JVMTI_ERROR_NONE;
646 }
647
648 return JVMTI_ERROR_INVALID_METHODID;
649 }
650
651 static jvmtiError JNICALL
652 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
653 jobject init_loader,
654 jint *count_ptr,
655 jclass **result_ptr)
656 {
657 using namespace java::lang;
658 using namespace java::util;
659
660 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
661 NULL_CHECK (count_ptr);
662 NULL_CHECK (result_ptr);
663
664 ClassLoader *loader = (ClassLoader *) init_loader;
665 if (loader == NULL)
666 loader = VMClassLoader::bootLoader;
667
668 Collection *values = loader->loadedClasses->values();
669 jobjectArray array = values->toArray();
670 *count_ptr = array->length;
671 jobject *elts = elements (array);
672 jclass *result
673 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
674 if (result == NULL)
675 return JVMTI_ERROR_OUT_OF_MEMORY;
676
677 // FIXME: JNI references...
678 memcpy (result, elts, *count_ptr * sizeof (jclass));
679
680 *result_ptr = result;
681
682 return JVMTI_ERROR_NONE;
683 }
684
685 static jvmtiError JNICALL
686 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
687 {
688 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
689 _Jv_RunGC();
690 return JVMTI_ERROR_NONE;
691 }
692
693 static jvmtiError JNICALL
694 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
695 const jniNativeInterface *function_table)
696 {
697 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
698 NULL_CHECK (function_table);
699 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
700 return JVMTI_ERROR_NONE;
701 }
702
703 static jvmtiError JNICALL
704 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
705 jniNativeInterface **function_table)
706 {
707 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
708 NULL_CHECK (function_table);
709 *function_table
710 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
711 if (*function_table == NULL)
712 return JVMTI_ERROR_OUT_OF_MEMORY;
713 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
714 return JVMTI_ERROR_NONE;
715 }
716
717 static jvmtiError JNICALL
718 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
719 {
720 NULL_CHECK (env);
721
722 if (_jvmtiEnvironments == NULL)
723 return JVMTI_ERROR_INVALID_ENVIRONMENT;
724 else
725 {
726 JvSynchronize dummy (_envListLock);
727 if (_jvmtiEnvironments->env == env)
728 {
729 struct jvmti_env_list *next = _jvmtiEnvironments->next;
730 _Jv_Free (_jvmtiEnvironments);
731 _jvmtiEnvironments = next;
732 }
733 else
734 {
735 struct jvmti_env_list *e = _jvmtiEnvironments;
736 while (e->next != NULL && e->next->env != env)
737 e = e->next;
738 if (e->next == NULL)
739 return JVMTI_ERROR_INVALID_ENVIRONMENT;
740
741 struct jvmti_env_list *next = e->next->next;
742 _Jv_Free (e->next);
743 e->next = next;
744 }
745 }
746
747 _Jv_Free (env);
748
749 check_enabled_events ();
750
751 return JVMTI_ERROR_NONE;
752 }
753
754 static jvmtiError JNICALL
755 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
756 char **result)
757 {
758 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
759 NULL_CHECK (property);
760 NULL_CHECK (result);
761
762 jstring name = JvNewStringUTF(property);
763 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
764
765 if (result_str == NULL)
766 return JVMTI_ERROR_NOT_AVAILABLE;
767
768 int len = JvGetStringUTFLength (result_str);
769 *result = (char *) _Jv_MallocUnchecked (len + 1);
770 if (*result == NULL)
771 return JVMTI_ERROR_OUT_OF_MEMORY;
772 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
773 (*result)[len] = '\0';
774
775 return JVMTI_ERROR_NONE;
776 }
777
778 static jvmtiError JNICALL
779 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
780 const char *value)
781 {
782 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
783
784 NULL_CHECK (property);
785 if (value == NULL)
786 {
787 // FIXME: When would a property not be writeable?
788 return JVMTI_ERROR_NONE;
789 }
790
791 jstring prop_str = JvNewStringUTF(property);
792 jstring value_str = JvNewStringUTF(value);
793 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
794 return JVMTI_ERROR_NONE;
795 }
796
797 static jvmtiError JNICALL
798 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
799 {
800 NULL_CHECK (nanos_ptr);
801 *nanos_ptr = _Jv_platform_nanotime();
802 return JVMTI_ERROR_NONE;
803 }
804
805 static jvmtiError JNICALL
806 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
807 jint *nprocessors_ptr)
808 {
809 NULL_CHECK (nprocessors_ptr);
810 #ifdef _SC_NPROCESSORS_ONLN
811 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
812 #else
813 *nprocessors_ptr = 1;
814 #endif
815 return JVMTI_ERROR_NONE;
816 }
817
818 static jvmtiError JNICALL
819 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
820 const char *segment)
821 {
822 using namespace java::lang;
823 using namespace java::net;
824 using namespace gnu::gcj::runtime;
825
826 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
827 NULL_CHECK (segment);
828
829 jstring str_segment = JvNewStringUTF(segment);
830 URL *url;
831 try
832 {
833 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
834 }
835 catch (jthrowable ignore)
836 {
837 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
838 }
839
840 BootClassLoader *loader = VMClassLoader::bootLoader;
841 // Don't call this too early.
842 // assert (loader != NULL);
843 loader->addURL(url);
844 return JVMTI_ERROR_NONE;
845 }
846
847 static jvmtiError JNICALL
848 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
849 jboolean value)
850 {
851 switch (flag)
852 {
853 case JVMTI_VERBOSE_OTHER:
854 case JVMTI_VERBOSE_GC:
855 case JVMTI_VERBOSE_JNI:
856 // Ignore.
857 break;
858 case JVMTI_VERBOSE_CLASS:
859 gcj::verbose_class_flag = value;
860 break;
861 default:
862 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
863 }
864 return JVMTI_ERROR_NONE;
865 }
866
867 static jvmtiError JNICALL
868 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
869 jlong *result)
870 {
871 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
872 if (object == NULL)
873 return JVMTI_ERROR_INVALID_OBJECT;
874 NULL_CHECK (result);
875
876 jclass klass = object->getClass();
877 if (klass->isArray())
878 {
879 jclass comp = klass->getComponentType();
880 jint base
881 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
882 klass->getComponentType());
883 // FIXME: correct for primitive types?
884 jint compSize = comp->size();
885 __JArray *array = (__JArray *) object;
886 *result = base + array->length * compSize;
887 }
888 else
889 {
890 // Note that if OBJECT is a String then it may (if
891 // str->data==str) take more space. Do we care?
892 *result = klass->size();
893 }
894 return JVMTI_ERROR_NONE;
895 }
896
897 /* An event is enabled only if it has both an event handler
898 and it is enabled in the environment. */
899 static void
900 check_enabled_event (jvmtiEvent type)
901 {
902 bool *enabled;
903 int offset;
904
905 #define GET_OFFSET(Event) \
906 do \
907 { \
908 enabled = &JVMTI::Event; \
909 offset = offsetof (jvmtiEventCallbacks, Event); \
910 } \
911 while (0)
912
913 switch (type)
914 {
915 case JVMTI_EVENT_VM_INIT:
916 GET_OFFSET (VMInit);
917 break;
918
919 case JVMTI_EVENT_VM_DEATH:
920 GET_OFFSET (VMDeath);
921 break;
922
923 case JVMTI_EVENT_THREAD_START:
924 GET_OFFSET (ThreadStart);
925 break;
926
927 case JVMTI_EVENT_THREAD_END:
928 GET_OFFSET (ThreadEnd);
929 break;
930
931 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
932 GET_OFFSET (ClassFileLoadHook);
933 break;
934
935 case JVMTI_EVENT_CLASS_LOAD:
936 GET_OFFSET (ClassLoad);
937 break;
938
939 case JVMTI_EVENT_CLASS_PREPARE:
940 GET_OFFSET (ClassPrepare);
941 break;
942
943 case JVMTI_EVENT_VM_START:
944 GET_OFFSET (VMStart);
945 break;
946
947 case JVMTI_EVENT_EXCEPTION:
948 GET_OFFSET (Exception);
949 break;
950
951 case JVMTI_EVENT_EXCEPTION_CATCH:
952 GET_OFFSET (ExceptionCatch);
953 break;
954
955 case JVMTI_EVENT_SINGLE_STEP:
956 GET_OFFSET (SingleStep);
957 break;
958
959 case JVMTI_EVENT_FRAME_POP:
960 GET_OFFSET (FramePop);
961 break;
962
963 case JVMTI_EVENT_BREAKPOINT:
964 GET_OFFSET (Breakpoint);
965 break;
966
967 case JVMTI_EVENT_FIELD_ACCESS:
968 GET_OFFSET (FieldAccess);
969 break;
970
971 case JVMTI_EVENT_FIELD_MODIFICATION:
972 GET_OFFSET (FieldModification);
973 break;
974
975 case JVMTI_EVENT_METHOD_ENTRY:
976 GET_OFFSET (MethodEntry);
977 break;
978
979 case JVMTI_EVENT_METHOD_EXIT:
980 GET_OFFSET (MethodExit);
981 break;
982
983 case JVMTI_EVENT_NATIVE_METHOD_BIND:
984 GET_OFFSET (NativeMethodBind);
985 break;
986
987 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
988 GET_OFFSET (CompiledMethodLoad);
989 break;
990
991 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
992 GET_OFFSET (CompiledMethodUnload);
993 break;
994
995 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
996 GET_OFFSET (DynamicCodeGenerated);
997 break;
998
999 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1000 GET_OFFSET (DataDumpRequest);
1001 break;
1002
1003 case JVMTI_EVENT_MONITOR_WAIT:
1004 GET_OFFSET (MonitorWait);
1005 break;
1006
1007 case JVMTI_EVENT_MONITOR_WAITED:
1008 GET_OFFSET (MonitorWaited);
1009 break;
1010
1011 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1012 GET_OFFSET (MonitorContendedEnter);
1013 break;
1014
1015 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1016 GET_OFFSET (MonitorContendedEntered);
1017 break;
1018
1019 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1020 GET_OFFSET (GarbageCollectionStart);
1021 break;
1022
1023 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1024 GET_OFFSET (GarbageCollectionFinish);
1025 break;
1026
1027 case JVMTI_EVENT_OBJECT_FREE:
1028 GET_OFFSET (ObjectFree);
1029 break;
1030
1031 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1032 GET_OFFSET (VMObjectAlloc);
1033 break;
1034
1035 default:
1036 fprintf (stderr,
1037 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1038 (int) type);
1039 return;
1040 }
1041 #undef GET_OFFSET
1042
1043 int index = EVENT_INDEX (type); // safe since caller checks this
1044
1045 JvSynchronize dummy (_envListLock);
1046 struct jvmti_env_list *e;
1047 FOREACH_ENVIRONMENT (e)
1048 {
1049 char *addr
1050 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1051 void **callback = reinterpret_cast<void **> (addr);
1052 if (e->env->enabled[index] && *callback != NULL)
1053 {
1054 *enabled = true;
1055 return;
1056 }
1057 }
1058
1059 *enabled = false;
1060 }
1061
1062 static void
1063 check_enabled_events ()
1064 {
1065 check_enabled_event (JVMTI_EVENT_VM_INIT);
1066 check_enabled_event (JVMTI_EVENT_VM_DEATH);
1067 check_enabled_event (JVMTI_EVENT_THREAD_START);
1068 check_enabled_event (JVMTI_EVENT_THREAD_END);
1069 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1070 check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1071 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1072 check_enabled_event (JVMTI_EVENT_VM_START);
1073 check_enabled_event (JVMTI_EVENT_EXCEPTION);
1074 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1075 check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1076 check_enabled_event (JVMTI_EVENT_FRAME_POP);
1077 check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1078 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1079 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1080 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1081 check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1082 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1083 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1084 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1085 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1086 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1087 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1088 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1089 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1090 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1091 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1092 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1093 check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1094 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1095 }
1096
1097 static jvmtiError JNICALL
1098 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1099 jvmtiEvent type, jthread event_thread, ...)
1100 {
1101 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1102
1103 if (event_thread != NULL)
1104 {
1105 using namespace java::lang;
1106 Thread *t = reinterpret_cast<Thread *> (event_thread);
1107 THREAD_CHECK_VALID (t);
1108 THREAD_CHECK_IS_ALIVE (t);
1109 }
1110
1111 bool enabled;
1112 switch (mode)
1113 {
1114 case JVMTI_DISABLE:
1115 enabled = false;
1116 break;
1117 case JVMTI_ENABLE:
1118 enabled = true;
1119 break;
1120
1121 default:
1122 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1123 }
1124
1125 switch (type)
1126 {
1127 case JVMTI_EVENT_VM_INIT:
1128 case JVMTI_EVENT_VM_DEATH:
1129 case JVMTI_EVENT_THREAD_START:
1130 case JVMTI_EVENT_VM_START:
1131 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1132 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1133 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1134 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1135 ILLEGAL_ARGUMENT (event_thread != NULL);
1136 break;
1137
1138 case JVMTI_EVENT_THREAD_END:
1139 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1140 case JVMTI_EVENT_CLASS_LOAD:
1141 case JVMTI_EVENT_CLASS_PREPARE:
1142 case JVMTI_EVENT_EXCEPTION:
1143 case JVMTI_EVENT_EXCEPTION_CATCH:
1144 case JVMTI_EVENT_SINGLE_STEP:
1145 case JVMTI_EVENT_FRAME_POP:
1146 case JVMTI_EVENT_BREAKPOINT:
1147 case JVMTI_EVENT_FIELD_ACCESS:
1148 case JVMTI_EVENT_FIELD_MODIFICATION:
1149 case JVMTI_EVENT_METHOD_ENTRY:
1150 case JVMTI_EVENT_METHOD_EXIT:
1151 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1152 case JVMTI_EVENT_MONITOR_WAIT:
1153 case JVMTI_EVENT_MONITOR_WAITED:
1154 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1155 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1156 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1157 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1158 case JVMTI_EVENT_OBJECT_FREE:
1159 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1160 break;
1161
1162 default:
1163 return JVMTI_ERROR_INVALID_EVENT_TYPE;
1164 }
1165
1166 env->thread[EVENT_INDEX(type)] = event_thread;
1167 env->enabled[EVENT_INDEX(type)] = enabled;
1168 check_enabled_event (type);
1169 return JVMTI_ERROR_NONE;
1170 }
1171
1172 static jvmtiError JNICALL
1173 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1174 const jvmtiEventCallbacks *callbacks,
1175 jint size_of_callbacks)
1176 {
1177 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1178 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1179
1180 // Copy the list of callbacks into the environment
1181 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1182
1183 /* Check which events are now enabeld (JVMTI makes no requirements
1184 about the order in which SetEventCallbacks and SetEventNotifications
1185 are called. So we must check all events here. */
1186 check_enabled_events ();
1187
1188 return JVMTI_ERROR_NONE;
1189 }
1190
1191 static jvmtiError JNICALL
1192 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1193 char **name_ptr)
1194 {
1195 NULL_CHECK (name_ptr);
1196
1197 const char *name;
1198 switch (error)
1199 {
1200 case JVMTI_ERROR_NONE:
1201 name = "none";
1202 break;
1203
1204 case JVMTI_ERROR_NULL_POINTER:
1205 name = "null pointer";
1206 break;
1207
1208 case JVMTI_ERROR_OUT_OF_MEMORY:
1209 name = "out of memory";
1210 break;
1211
1212 case JVMTI_ERROR_ACCESS_DENIED:
1213 name = "access denied";
1214 break;
1215
1216 case JVMTI_ERROR_WRONG_PHASE:
1217 name = "wrong phase";
1218 break;
1219
1220 case JVMTI_ERROR_INTERNAL:
1221 name = "internal error";
1222 break;
1223
1224 case JVMTI_ERROR_UNATTACHED_THREAD:
1225 name = "unattached thread";
1226 break;
1227
1228 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1229 name = "invalid environment";
1230 break;
1231
1232 case JVMTI_ERROR_INVALID_PRIORITY:
1233 name = "invalid priority";
1234 break;
1235
1236 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1237 name = "thread not suspended";
1238 break;
1239
1240 case JVMTI_ERROR_THREAD_SUSPENDED:
1241 name = "thread suspended";
1242 break;
1243
1244 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1245 name = "thread not alive";
1246 break;
1247
1248 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1249 name = "class not prepared";
1250 break;
1251
1252 case JVMTI_ERROR_NO_MORE_FRAMES:
1253 name = "no more frames";
1254 break;
1255
1256 case JVMTI_ERROR_OPAQUE_FRAME:
1257 name = "opaque frame";
1258 break;
1259
1260 case JVMTI_ERROR_DUPLICATE:
1261 name = "duplicate";
1262 break;
1263
1264 case JVMTI_ERROR_NOT_FOUND:
1265 name = "not found";
1266 break;
1267
1268 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1269 name = "not monitor owner";
1270 break;
1271
1272 case JVMTI_ERROR_INTERRUPT:
1273 name = "interrupted";
1274 break;
1275
1276 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1277 name = "unmodifiable class";
1278 break;
1279
1280 case JVMTI_ERROR_NOT_AVAILABLE:
1281 name = "not available";
1282 break;
1283
1284 case JVMTI_ERROR_ABSENT_INFORMATION:
1285 name = "absent information";
1286 break;
1287
1288 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1289 name = "invalid event type";
1290 break;
1291
1292 case JVMTI_ERROR_NATIVE_METHOD:
1293 name = "native method";
1294 break;
1295
1296 case JVMTI_ERROR_INVALID_THREAD:
1297 name = "invalid thread";
1298 break;
1299
1300 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1301 name = "invalid thread group";
1302 break;
1303
1304 case JVMTI_ERROR_INVALID_OBJECT:
1305 name = "invalid object";
1306 break;
1307
1308 case JVMTI_ERROR_INVALID_CLASS:
1309 name = "invalid class";
1310 break;
1311
1312 case JVMTI_ERROR_INVALID_METHODID:
1313 name = "invalid method ID";
1314 break;
1315
1316 case JVMTI_ERROR_INVALID_LOCATION:
1317 name = "invalid location";
1318 break;
1319
1320 case JVMTI_ERROR_INVALID_FIELDID:
1321 name = "invalid field ID";
1322 break;
1323
1324 case JVMTI_ERROR_TYPE_MISMATCH:
1325 name = "type mismatch";
1326 break;
1327
1328 case JVMTI_ERROR_INVALID_SLOT:
1329 name = "invalid slot";
1330 break;
1331
1332 case JVMTI_ERROR_INVALID_MONITOR:
1333 name = "invalid monitor";
1334 break;
1335
1336 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1337 name = "invalid class format";
1338 break;
1339
1340 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1341 name = "circular class definition";
1342 break;
1343
1344 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1345 name = "unsupported redefinition: method added";
1346 break;
1347
1348 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1349 name = "unsupported redefinition: schema changed";
1350 break;
1351
1352 case JVMTI_ERROR_INVALID_TYPESTATE:
1353 name = "invalid type state";
1354 break;
1355
1356 case JVMTI_ERROR_FAILS_VERIFICATION:
1357 name = "fails verification";
1358 break;
1359
1360 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1361 name = "unsupported redefinition: hierarchy changed";
1362 break;
1363
1364 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1365 name = "unsupported redefinition: method deleted";
1366 break;
1367
1368 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1369 name = "unsupported version";
1370 break;
1371
1372 case JVMTI_ERROR_NAMES_DONT_MATCH:
1373 name = "names do not match";
1374 break;
1375
1376 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1377 name = "unsupported redefinition: class modifiers changed";
1378 break;
1379
1380 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1381 name = "unsupported redefinition: method modifiers changed";
1382 break;
1383
1384 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1385 name = "must possess capability";
1386 break;
1387
1388 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1389 name = "illegal argument";
1390 break;
1391
1392 default:
1393 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1394 }
1395
1396 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1397 if (*name_ptr == NULL)
1398 return JVMTI_ERROR_OUT_OF_MEMORY;
1399
1400 strcpy (*name_ptr, name);
1401 return JVMTI_ERROR_NONE;
1402 }
1403
1404 #define RESERVED NULL
1405 #define UNIMPLEMENTED NULL
1406
1407 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1408 {
1409 RESERVED, // reserved1
1410 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1411 RESERVED, // reserved3
1412 _Jv_JVMTI_GetAllThreads, // GetAllThreads
1413 _Jv_JVMTI_SuspendThread, // SuspendThread
1414 _Jv_JVMTI_ResumeThread, // ResumeThread
1415 UNIMPLEMENTED, // StopThread
1416 _Jv_JVMTI_InterruptThread, // InterruptThread
1417 UNIMPLEMENTED, // GetThreadInfo
1418 UNIMPLEMENTED, // GetOwnedMonitorInfo
1419 UNIMPLEMENTED, // GetCurrentContendedMonitor
1420 UNIMPLEMENTED, // RunAgentThread
1421 UNIMPLEMENTED, // GetTopThreadGroups
1422 UNIMPLEMENTED, // GetThreadGroupInfo
1423 UNIMPLEMENTED, // GetThreadGroupChildren
1424 UNIMPLEMENTED, // GetFrameCount
1425 UNIMPLEMENTED, // GetThreadState
1426 RESERVED, // reserved18
1427 UNIMPLEMENTED, // GetFrameLocation
1428 UNIMPLEMENTED, // NotifyPopFrame
1429 UNIMPLEMENTED, // GetLocalObject
1430 UNIMPLEMENTED, // GetLocalInt
1431 UNIMPLEMENTED, // GetLocalLong
1432 UNIMPLEMENTED, // GetLocalFloat
1433 UNIMPLEMENTED, // GetLocalDouble
1434 UNIMPLEMENTED, // SetLocalObject
1435 UNIMPLEMENTED, // SetLocalInt
1436 UNIMPLEMENTED, // SetLocalLong
1437 UNIMPLEMENTED, // SetLocalFloat
1438 UNIMPLEMENTED, // SetLocalDouble
1439 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
1440 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
1441 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
1442 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
1443 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
1444 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
1445 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
1446 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
1447 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
1448 RESERVED, // reserved40
1449 UNIMPLEMENTED, // SetFieldAccessWatch
1450 UNIMPLEMENTED, // ClearFieldAccessWatch
1451 UNIMPLEMENTED, // SetFieldModificationWatch
1452 UNIMPLEMENTED, // ClearFieldModificationWatch
1453 RESERVED, // reserved45
1454 _Jv_JVMTI_Allocate, // Allocate
1455 _Jv_JVMTI_Deallocate, // Deallocate
1456 UNIMPLEMENTED, // GetClassSignature
1457 UNIMPLEMENTED, // GetClassStatus
1458 UNIMPLEMENTED, // GetSourceFileName
1459 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
1460 _Jv_JVMTI_GetClassMethods, // GetClassMethods
1461 UNIMPLEMENTED, // GetClassFields
1462 UNIMPLEMENTED, // GetImplementedInterfaces
1463 _Jv_JVMTI_IsInterface, // IsInterface
1464 _Jv_JVMTI_IsArrayClass, // IsArrayClass
1465 _Jv_JVMTI_GetClassLoader, // GetClassLoader
1466 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
1467 UNIMPLEMENTED, // GetObjectMonitorUsage
1468 UNIMPLEMENTED, // GetFieldName
1469 UNIMPLEMENTED, // GetFieldDeclaringClass
1470 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
1471 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
1472 UNIMPLEMENTED, // GetMethodName
1473 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
1474 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
1475 RESERVED, // reserved67
1476 UNIMPLEMENTED, // GetMaxLocals
1477 UNIMPLEMENTED, // GetArgumentsSize
1478 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
1479 UNIMPLEMENTED, // GetMethodLocation
1480 UNIMPLEMENTED, // GetLocalVariableTable
1481 RESERVED, // reserved73
1482 RESERVED, // reserved74
1483 UNIMPLEMENTED, // GetBytecodes
1484 _Jv_JVMTI_IsMethodNative, // IsMethodNative
1485 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
1486 UNIMPLEMENTED, // GetLoadedClasses
1487 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
1488 UNIMPLEMENTED, // PopFrame
1489 RESERVED, // reserved81
1490 RESERVED, // reserved82
1491 RESERVED, // reserved83
1492 RESERVED, // reserved84
1493 RESERVED, // reserved85
1494 RESERVED, // reserved86
1495 UNIMPLEMENTED, // RedefineClasses
1496 UNIMPLEMENTED, // GetVersionNumber
1497 UNIMPLEMENTED, // GetCapabilities
1498 UNIMPLEMENTED, // GetSourceDebugExtension
1499 UNIMPLEMENTED, // IsMethodObsolete
1500 UNIMPLEMENTED, // SuspendThreadList
1501 UNIMPLEMENTED, // ResumeThreadList
1502 RESERVED, // reserved94
1503 RESERVED, // reserved95
1504 RESERVED, // reserved96
1505 RESERVED, // reserved97
1506 RESERVED, // reserved98
1507 RESERVED, // reserved99
1508 UNIMPLEMENTED, // GetAllStackTraces
1509 UNIMPLEMENTED, // GetThreadListStackTraces
1510 UNIMPLEMENTED, // GetThreadLocalStorage
1511 UNIMPLEMENTED, // SetThreadLocalStorage
1512 UNIMPLEMENTED, // GetStackTrace
1513 RESERVED, // reserved105
1514 UNIMPLEMENTED, // GetTag
1515 UNIMPLEMENTED, // SetTag
1516 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
1517 UNIMPLEMENTED, // IterateOverObjectsReachable
1518 UNIMPLEMENTED, // IterateOverReachableObjects
1519 UNIMPLEMENTED, // IterateOverHeap
1520 UNIMPLEMENTED, // IterateOverInstanceOfClass
1521 RESERVED, // reserved113
1522 UNIMPLEMENTED, // GetObjectsWithTags
1523 RESERVED, // reserved115
1524 RESERVED, // reserved116
1525 RESERVED, // reserved117
1526 RESERVED, // reserved118
1527 RESERVED, // reserved119
1528 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
1529 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
1530 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
1531 UNIMPLEMENTED, // GenerateEvents
1532 UNIMPLEMENTED, // GetExtensionFunctions
1533 UNIMPLEMENTED, // GetExtensionEvents
1534 UNIMPLEMENTED, // SetExtensionEventCallback
1535 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
1536 _Jv_JVMTI_GetErrorName, // GetErrorName
1537 UNIMPLEMENTED, // GetJLocationFormat
1538 UNIMPLEMENTED, // GetSystemProperties
1539 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
1540 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
1541 UNIMPLEMENTED, // GetPhase
1542 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
1543 UNIMPLEMENTED, // GetCurrentThreadCpuTime
1544 UNIMPLEMENTED, // GetThreadCpuTimerInfo
1545 UNIMPLEMENTED, // GetThreadCpuTime
1546 UNIMPLEMENTED, // GetTimerInfo
1547 _Jv_JVMTI_GetTime, // GetTime
1548 UNIMPLEMENTED, // GetPotentialCapabilities
1549 RESERVED, // reserved141
1550 UNIMPLEMENTED, // AddCapabilities
1551 UNIMPLEMENTED, // RelinquishCapabilities
1552 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
1553 RESERVED, // reserved145
1554 RESERVED, // reserved146
1555 UNIMPLEMENTED, // GetEnvironmentLocalStorage
1556 UNIMPLEMENTED, // SetEnvironmentLocalStorage
1557 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
1558 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
1559 RESERVED, // reserved151
1560 RESERVED, // reserved152
1561 RESERVED, // reserved153
1562 _Jv_JVMTI_GetObjectSize // GetObjectSize
1563 };
1564
1565 _Jv_JVMTIEnv *
1566 _Jv_GetJVMTIEnv (void)
1567 {
1568 _Jv_JVMTIEnv *env
1569 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1570 env->p = &_Jv_JVMTI_Interface;
1571
1572 {
1573 JvSynchronize dummy (_envListLock);
1574 struct jvmti_env_list *element
1575 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
1576 element->env = env;
1577 element->next = NULL;
1578
1579 if (_jvmtiEnvironments == NULL)
1580 _jvmtiEnvironments = element;
1581 else
1582 {
1583 struct jvmti_env_list *e;
1584 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1585 ;
1586 e->next = element;
1587 }
1588 }
1589
1590 return env;
1591 }
1592
1593 void
1594 _Jv_JVMTI_Init ()
1595 {
1596 _jvmtiEnvironments = NULL;
1597 _envListLock = new java::lang::Object ();
1598
1599 // No environments, so this should set all JVMTI:: members to false
1600 check_enabled_events ();
1601 }
1602
1603 static void
1604 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
1605 {
1606 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
1607
1608 #define GET_BOOLEAN_ARG(Name) \
1609 ARG (int, b); \
1610 jboolean Name = (b == 0) ? false : true
1611
1612 #define GET_CHAR_ARG(Name) \
1613 ARG (int, c); \
1614 char Name = static_cast<char> (c)
1615
1616 switch (type)
1617 {
1618 case JVMTI_EVENT_VM_INIT:
1619 if (env->callbacks.VMInit != NULL)
1620 {
1621 ARG (JNIEnv *, jni_env);
1622 env->callbacks.VMInit (env, jni_env, event_thread);
1623 }
1624 break;
1625
1626 case JVMTI_EVENT_VM_DEATH:
1627 if (env->callbacks.VMDeath != NULL)
1628 {
1629 ARG (JNIEnv *, jni_env);
1630 env->callbacks.VMDeath (env, jni_env);
1631 }
1632 break;
1633
1634 case JVMTI_EVENT_THREAD_START:
1635 if (env->callbacks.ThreadStart != NULL)
1636 {
1637 ARG (JNIEnv *, jni_env);
1638 env->callbacks.ThreadStart (env, jni_env, event_thread);
1639 }
1640 break;
1641
1642 case JVMTI_EVENT_THREAD_END:
1643 if (env->callbacks.ThreadEnd != NULL)
1644 {
1645 ARG (JNIEnv *, jni_env);
1646 env->callbacks.ThreadEnd (env, jni_env, event_thread);
1647 }
1648 break;
1649
1650 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1651 if (env->callbacks.ClassFileLoadHook != NULL)
1652 {
1653 ARG (JNIEnv *, jni_env);
1654 ARG (jclass, class_being_redefined);
1655 ARG (jobject, loader);
1656 ARG (const char *, name);
1657 ARG (jobject, protection_domain);
1658 ARG (jint, class_data_len);
1659 ARG (const unsigned char *, class_data);
1660 ARG (jint *, new_class_data_len);
1661 ARG (unsigned char **, new_class_data);
1662 env->callbacks.ClassFileLoadHook (env, jni_env,
1663 class_being_redefined, loader,
1664 name, protection_domain,
1665 class_data_len, class_data,
1666 new_class_data_len,
1667 new_class_data);
1668 }
1669 break;
1670
1671 case JVMTI_EVENT_CLASS_LOAD:
1672 if (env->callbacks.ClassLoad != NULL)
1673 {
1674 ARG (JNIEnv *, jni_env);
1675 ARG (jclass, klass);
1676 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
1677 }
1678 break;
1679
1680 case JVMTI_EVENT_CLASS_PREPARE:
1681 if (env->callbacks.ClassPrepare != NULL)
1682 {
1683 ARG (JNIEnv *, jni_env);
1684 ARG (jclass, klass);
1685 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
1686 }
1687 break;
1688
1689 case JVMTI_EVENT_VM_START:
1690 if (env->callbacks.VMStart != NULL)
1691 {
1692 ARG (JNIEnv *, jni_env);
1693 env->callbacks.VMStart (env, jni_env);
1694 }
1695 break;
1696
1697 case JVMTI_EVENT_EXCEPTION:
1698 if (env->callbacks.Exception != NULL)
1699 {
1700 ARG (JNIEnv *, jni_env);
1701 ARG (jmethodID, method);
1702 ARG (jlocation, location);
1703 ARG (jobject, exception);
1704 ARG (jmethodID, catch_method);
1705 ARG (jlocation, catch_location);
1706 env->callbacks.Exception (env, jni_env, event_thread, method,
1707 location, exception, catch_method,
1708 catch_location);
1709 }
1710 break;
1711
1712 case JVMTI_EVENT_EXCEPTION_CATCH:
1713 if (env->callbacks.ExceptionCatch != NULL)
1714 {
1715 ARG (JNIEnv *, jni_env);
1716 ARG (jmethodID, method);
1717 ARG (jlocation, location);
1718 ARG (jobject, exception);
1719 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
1720 location, exception);
1721 }
1722 break;
1723
1724 case JVMTI_EVENT_SINGLE_STEP:
1725 if (env->callbacks.SingleStep != NULL)
1726 {
1727 ARG (JNIEnv *, jni_env);
1728 ARG (jmethodID, method);
1729 ARG (jlocation, location);
1730 env->callbacks.SingleStep (env, jni_env, event_thread, method,
1731 location);
1732 }
1733 break;
1734
1735 case JVMTI_EVENT_FRAME_POP:
1736 if (env->callbacks.FramePop != NULL)
1737 {
1738 ARG (JNIEnv *, jni_env);
1739 ARG (jmethodID, method);
1740 GET_BOOLEAN_ARG (was_popped_by_exception);
1741 env->callbacks.FramePop (env, jni_env, event_thread, method,
1742 was_popped_by_exception);
1743 }
1744 break;
1745
1746 case JVMTI_EVENT_BREAKPOINT:
1747 if (env->callbacks.Breakpoint != NULL)
1748 {
1749 ARG (JNIEnv *, jni_env);
1750 ARG (jmethodID, method);
1751 ARG (jlocation, location);
1752 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
1753 location);
1754 }
1755 break;
1756
1757 case JVMTI_EVENT_FIELD_ACCESS:
1758 if (env->callbacks.FieldAccess != NULL)
1759 {
1760 ARG (JNIEnv *, jni_env);
1761 ARG (jmethodID, method);
1762 ARG (jlocation, location);
1763 ARG (jclass, field_class);
1764 ARG (jobject, object);
1765 ARG (jfieldID, field);
1766 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
1767 location, field_class, object, field);
1768 }
1769 break;
1770
1771 case JVMTI_EVENT_FIELD_MODIFICATION:
1772 if (env->callbacks.FieldModification != NULL)
1773 {
1774 ARG (JNIEnv *, jni_env);
1775 ARG (jmethodID, method);
1776 ARG (jlocation, location);
1777 ARG (jclass, field_class);
1778 ARG (jobject, object);
1779 ARG (jfieldID, field);
1780 GET_CHAR_ARG (signature_type);
1781 ARG (jvalue, new_value);
1782 env->callbacks.FieldModification (env, jni_env, event_thread, method,
1783 location, field_class, object,
1784 field, signature_type, new_value);
1785 }
1786 break;
1787
1788 case JVMTI_EVENT_METHOD_ENTRY:
1789 if (env->callbacks.MethodEntry != NULL)
1790 {
1791 ARG (JNIEnv *, jni_env);
1792 ARG (jmethodID, method);
1793 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
1794 }
1795 break;
1796
1797 case JVMTI_EVENT_METHOD_EXIT:
1798 if (env->callbacks.MethodExit != NULL)
1799 {
1800 ARG (JNIEnv *, jni_env);
1801 ARG (jmethodID, method);
1802 GET_BOOLEAN_ARG (was_popped_by_exception);
1803 ARG (jvalue, return_value);
1804 env->callbacks.MethodExit (env, jni_env, event_thread, method,
1805 was_popped_by_exception, return_value);
1806 }
1807 break;
1808
1809 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1810 if (env->callbacks.NativeMethodBind != NULL)
1811 {
1812 ARG (JNIEnv *, jni_env);
1813 ARG (jmethodID, method);
1814 ARG (void *, address);
1815 ARG (void **, new_address_ptr);
1816 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
1817 address, new_address_ptr);
1818 }
1819 break;
1820
1821 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1822 if (env->callbacks.CompiledMethodLoad != NULL)
1823 {
1824 ARG (jmethodID, method);
1825 ARG (jint, code_size);
1826 ARG (const void *, code_addr);
1827 ARG (jint, map_length);
1828 ARG (const jvmtiAddrLocationMap *, map);
1829 ARG (const void *, compile_info);
1830 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
1831 map_length, map, compile_info);
1832 }
1833 break;
1834
1835 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1836 if (env->callbacks.CompiledMethodUnload != NULL)
1837 {
1838 ARG (jmethodID, method);
1839 ARG (const void *, code_addr);
1840 env->callbacks.CompiledMethodUnload (env, method, code_addr);
1841 }
1842 break;
1843
1844 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1845 if (env->callbacks.DynamicCodeGenerated != NULL)
1846 {
1847 ARG (const char *, name);
1848 ARG (const void *, address);
1849 ARG (jint, length);
1850 env->callbacks.DynamicCodeGenerated (env, name, address, length);
1851 }
1852 break;
1853
1854 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1855 if (env->callbacks.DataDumpRequest != NULL)
1856 {
1857 env->callbacks.DataDumpRequest (env);
1858 }
1859 break;
1860
1861 case JVMTI_EVENT_MONITOR_WAIT:
1862 if (env->callbacks.MonitorWait != NULL)
1863 {
1864 ARG (JNIEnv *, jni_env);
1865 ARG (jobject, object);
1866 ARG (jlong, timeout);
1867 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
1868 timeout);
1869 }
1870 break;
1871
1872 case JVMTI_EVENT_MONITOR_WAITED:
1873 if (env->callbacks.MonitorWaited != NULL)
1874 {
1875 ARG (JNIEnv *, jni_env);
1876 ARG (jobject, object);
1877 GET_BOOLEAN_ARG (timed_out);
1878 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
1879 timed_out);
1880 }
1881 break;
1882
1883 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1884 if (env->callbacks.MonitorContendedEnter != NULL)
1885 {
1886 ARG (JNIEnv *, jni_env);
1887 ARG (jobject, object);
1888 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
1889 object);
1890 }
1891 break;
1892
1893 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1894 if (env->callbacks.MonitorContendedEntered != NULL)
1895 {
1896 ARG (JNIEnv *, jni_env);
1897 ARG (jobject, object);
1898 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
1899 object);
1900 }
1901 break;
1902
1903 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1904 if (env->callbacks.GarbageCollectionStart != NULL)
1905 {
1906 env->callbacks.GarbageCollectionStart (env);
1907 }
1908 break;
1909
1910 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1911 if (env->callbacks.GarbageCollectionFinish != NULL)
1912 {
1913 env->callbacks.GarbageCollectionFinish (env);
1914 }
1915 break;
1916
1917 case JVMTI_EVENT_OBJECT_FREE:
1918 if (env->callbacks.ObjectFree != NULL)
1919 {
1920 ARG (jlong, tag);
1921 env->callbacks.ObjectFree (env, tag);
1922 }
1923 break;
1924
1925 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1926 if (env->callbacks.VMObjectAlloc != NULL)
1927 {
1928 ARG (JNIEnv *, jni_env);
1929 ARG (jobject, object);
1930 ARG (jclass, object_class);
1931 ARG (jlong, size);
1932 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
1933 object, object_class, size);
1934 }
1935 break;
1936
1937 default:
1938 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
1939 (int) type);
1940 break;
1941 }
1942 va_end (args);
1943 #undef ARG
1944 #undef GET_BOOLEAN_ARG
1945 #undef GET_CHAR_ARG
1946 }
1947
1948 /* Post an event to requesting JVMTI environments
1949 *
1950 * This function should not be called without consulting the
1951 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
1952 * harm (other than kill speed), since this function will still
1953 * only send the event if it was properly requested by an environment.
1954 */
1955 void
1956 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
1957 {
1958 va_list args;
1959 va_start (args, event_thread);
1960
1961 JvSynchronize dummy (_envListLock);
1962 struct jvmti_env_list *e;
1963 FOREACH_ENVIRONMENT (e)
1964 {
1965 /* Events are only posted if the event was explicitly enabled,
1966 it has a registered event handler, and the event thread
1967 matches (either globally or restricted to a specific thread).
1968 Here we check all but the event handler, which will be handled
1969 by post_event. */
1970 if (e->env->enabled[EVENT_INDEX(type)]
1971 && (e->env->thread[EVENT_INDEX(type)] == NULL
1972 || e->env->thread[EVENT_INDEX(type)] == event_thread))
1973 {
1974 post_event (e->env, type, event_thread, args);
1975 }
1976 }
1977
1978 va_end (args);
1979 }