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