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