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