PR tree-optimization/29902
[official-gcc.git] / libjava / jvmti.cc
blob8584c333d6d1c20afeed9a7e6f1c77fb766f7c53
1 // jvmti.cc - JVMTI implementation
3 /* Copyright (C) 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
12 #include <platform.h>
14 #include <jvm.h>
15 #include <java-threads.h>
16 #include <java-gc.h>
17 #include <java-interp.h>
18 #include <jvmti.h>
19 #include "jvmti-int.h"
21 #include <gcj/method.h>
23 #include <gnu/classpath/SystemProperties.h>
24 #include <gnu/gcj/runtime/BootClassLoader.h>
25 #include <gnu/gcj/jvmti/Breakpoint.h>
26 #include <gnu/gcj/jvmti/BreakpointManager.h>
28 #include <java/lang/Class.h>
29 #include <java/lang/ClassLoader.h>
30 #include <java/lang/Object.h>
31 #include <java/lang/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>
40 static void check_enabled_events (void);
41 static void check_enabled_event (jvmtiEvent);
43 namespace JVMTI
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;
82 extern struct JNINativeInterface _Jv_JNIFunctions;
84 struct _Jv_rawMonitorID
86 _Jv_Mutex_t mutex;
87 _Jv_ConditionVariable_t condition;
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
96 jvmtiEnv *env;
97 struct jvmti_env_list *next;
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)
104 // Some commonly-used checks
106 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
107 do \
109 if (Ajthread == NULL) \
110 Ajthread = java::lang::Thread::currentThread (); \
112 while (0)
114 #define THREAD_CHECK_VALID(Athread) \
115 do \
117 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
118 return JVMTI_ERROR_INVALID_THREAD; \
120 while (0)
122 #define THREAD_CHECK_IS_ALIVE(Athread) \
123 do \
125 if (!Athread->isAlive ()) \
126 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
128 while (0)
130 // FIXME: if current phase is not set in Phases,
131 // return JVMTI_ERROR_WRONG_PHASE
132 #define REQUIRE_PHASE(Env, Phases)
134 #define NULL_CHECK(Ptr) \
135 do \
137 if (Ptr == NULL) \
138 return JVMTI_ERROR_NULL_POINTER; \
140 while (0)
142 #define ILLEGAL_ARGUMENT(Cond) \
143 do \
145 if ((Cond)) \
146 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
148 while (0)
150 static jvmtiError JNICALL
151 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
153 using namespace java::lang;
155 THREAD_DEFAULT_TO_CURRENT (thread);
157 Thread *t = reinterpret_cast<Thread *> (thread);
158 THREAD_CHECK_VALID (t);
159 THREAD_CHECK_IS_ALIVE (t);
161 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
162 _Jv_SuspendThread (data);
163 return JVMTI_ERROR_NONE;
166 static jvmtiError JNICALL
167 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
169 using namespace java::lang;
171 THREAD_DEFAULT_TO_CURRENT (thread);
173 Thread *t = reinterpret_cast<Thread *> (thread);
174 THREAD_CHECK_VALID (t);
175 THREAD_CHECK_IS_ALIVE (t);
177 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
178 _Jv_ResumeThread (data);
179 return JVMTI_ERROR_NONE;
182 static jvmtiError JNICALL
183 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
185 using namespace java::lang;
187 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
188 // FIXME: capability handling? 'can_signal_thread'
189 if (thread == NULL)
190 return JVMTI_ERROR_INVALID_THREAD;
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;
199 static jvmtiError JNICALL
200 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
201 jrawMonitorID *result)
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;
214 static jvmtiError JNICALL
215 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
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;
231 static jvmtiError JNICALL
232 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
234 if (monitor == NULL)
235 return JVMTI_ERROR_INVALID_MONITOR;
236 _Jv_MutexLock (&monitor->mutex);
237 return JVMTI_ERROR_NONE;
240 static jvmtiError JNICALL
241 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
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;
250 static jvmtiError JNICALL
251 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
252 jlong millis)
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;
264 static jvmtiError JNICALL
265 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
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;
274 static jvmtiError JNICALL
275 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
276 jrawMonitorID monitor)
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;
286 static jvmtiError JNICALL
287 _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
289 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
291 using namespace gnu::gcj::jvmti;
292 Breakpoint *bp
293 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
294 location);
295 if (bp == NULL)
297 jclass klass;
298 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
299 if (err != JVMTI_ERROR_NONE)
300 return err;
302 if (!_Jv_IsInterpretedClass (klass))
303 return JVMTI_ERROR_INVALID_CLASS;
305 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
306 if (base == NULL)
307 return JVMTI_ERROR_INVALID_METHODID;
309 jint flags;
310 err = env->GetMethodModifiers (method, &flags);
311 if (err != JVMTI_ERROR_NONE)
312 return err;
314 if (flags & java::lang::reflect::Modifier::NATIVE)
315 return JVMTI_ERROR_NATIVE_METHOD;
317 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
318 if (imeth->get_insn (location) == NULL)
319 return JVMTI_ERROR_INVALID_LOCATION;
321 // Now the breakpoint can be safely installed
322 bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
323 location);
325 else
327 // Duplicate breakpoints are not permitted by JVMTI
328 return JVMTI_ERROR_DUPLICATE;
331 return JVMTI_ERROR_NONE;
334 static jvmtiError JNICALL
335 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
336 jlocation location)
338 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
340 using namespace gnu::gcj::jvmti;
342 Breakpoint *bp
343 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
344 location);
345 if (bp == NULL)
346 return JVMTI_ERROR_NOT_FOUND;
348 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
349 return JVMTI_ERROR_NONE;
352 static jvmtiError JNICALL
353 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
354 unsigned char **result)
356 ILLEGAL_ARGUMENT (size < 0);
357 NULL_CHECK (result);
358 if (size == 0)
359 *result = NULL;
360 else
362 *result = (unsigned char *) _Jv_MallocUnchecked (size);
363 if (*result == NULL)
364 return JVMTI_ERROR_OUT_OF_MEMORY;
366 return JVMTI_ERROR_NONE;
369 static jvmtiError JNICALL
370 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
372 if (mem != NULL)
373 _Jv_Free (mem);
374 return JVMTI_ERROR_NONE;
377 static jvmtiError JNICALL
378 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
379 jint *mods)
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;
390 static jvmtiError JNICALL
391 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
392 jint *count_ptr, jmethodID **methods_ptr)
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);
403 *methods_ptr
404 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
405 if (*methods_ptr == NULL)
406 return JVMTI_ERROR_OUT_OF_MEMORY;
408 jmethodID start = JvGetFirstMethod (klass);
409 for (jint i = 0; i < *count_ptr; ++i)
410 // FIXME: correct?
411 (*methods_ptr)[i] = start + i;
413 return JVMTI_ERROR_NONE;
416 static jvmtiError JNICALL
417 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
418 jboolean *result)
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;
428 static jvmtiError JNICALL
429 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
430 jboolean *result)
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;
440 static jvmtiError JNICALL
441 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
442 jobject *result)
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;
452 static jvmtiError JNICALL
453 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
454 jint *result)
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;
464 static jvmtiError JNICALL
465 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
466 jfieldID field, jint *result)
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;
478 static jvmtiError JNICALL
479 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
480 jfieldID field, jboolean *result)
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);
489 // FIXME: capability can_get_synthetic_attribute
490 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
491 != 0);
492 return JVMTI_ERROR_NONE;
495 static jvmtiError JNICALL
496 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
497 jint *result)
499 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
500 if (method == NULL)
501 return JVMTI_ERROR_INVALID_METHODID;
502 NULL_CHECK (result);
504 // FIXME: mask off some internal bits...
505 *result = method->accflags;
506 return JVMTI_ERROR_NONE;
509 static jvmtiError JNICALL
510 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
511 jint *entry_count_ptr,
512 jvmtiLineNumberEntry **table_ptr)
514 NULL_CHECK (entry_count_ptr);
515 NULL_CHECK (table_ptr);
517 jclass klass;
518 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
519 if (jerr != JVMTI_ERROR_NONE)
520 return jerr;
522 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
523 if (base == NULL)
524 return JVMTI_ERROR_INVALID_METHODID;
526 if (java::lang::reflect::Modifier::isNative (method->accflags)
527 || !_Jv_IsInterpretedClass (klass))
528 return JVMTI_ERROR_NATIVE_METHOD;
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;
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;
544 jint *line = elements (lines);
545 jlong *index = elements (indices);
546 for (int i = 0; i < lines->length; ++i)
548 table[i].start_location = index[i];
549 table[i].line_number = line[i];
552 *table_ptr = table;
553 *entry_count_ptr = lines->length;
554 return JVMTI_ERROR_NONE;
557 static jvmtiError JNICALL
558 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
559 jboolean *result)
561 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
562 if (method == NULL)
563 return JVMTI_ERROR_INVALID_METHODID;
564 NULL_CHECK (result);
566 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
567 return JVMTI_ERROR_NONE;
570 static jvmtiError JNICALL
571 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
572 jboolean *result)
574 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
575 if (method == NULL)
576 return JVMTI_ERROR_INVALID_METHODID;
577 NULL_CHECK (result);
579 // FIXME capability can_get_synthetic_attribute
581 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
582 != 0);
583 return JVMTI_ERROR_NONE;
586 static jvmtiError JNICALL
587 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
588 jmethodID method,
589 jclass *declaring_class_ptr)
591 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
592 NULL_CHECK (declaring_class_ptr);
594 jclass klass = _Jv_GetMethodDeclaringClass (method);
595 if (klass != NULL)
597 *declaring_class_ptr = klass;
598 return JVMTI_ERROR_NONE;
601 return JVMTI_ERROR_INVALID_METHODID;
604 static jvmtiError JNICALL
605 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
606 jobject init_loader,
607 jint *count_ptr,
608 jclass **result_ptr)
610 using namespace java::lang;
611 using namespace java::util;
613 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
614 NULL_CHECK (count_ptr);
615 NULL_CHECK (result_ptr);
617 ClassLoader *loader = (ClassLoader *) init_loader;
618 if (loader == NULL)
619 loader = VMClassLoader::bootLoader;
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;
630 // FIXME: JNI references...
631 memcpy (result, elts, *count_ptr * sizeof (jclass));
633 *result_ptr = result;
635 return JVMTI_ERROR_NONE;
638 static jvmtiError JNICALL
639 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
641 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
642 _Jv_RunGC();
643 return JVMTI_ERROR_NONE;
646 static jvmtiError JNICALL
647 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
648 const jniNativeInterface *function_table)
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;
656 static jvmtiError JNICALL
657 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
658 jniNativeInterface **function_table)
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;
670 static jvmtiError JNICALL
671 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
673 NULL_CHECK (env);
675 if (_jvmtiEnvironments == NULL)
676 return JVMTI_ERROR_INVALID_ENVIRONMENT;
677 else
679 JvSynchronize dummy (_envListLock);
680 if (_jvmtiEnvironments->env == env)
682 struct jvmti_env_list *next = _jvmtiEnvironments->next;
683 _Jv_Free (_jvmtiEnvironments);
684 _jvmtiEnvironments = next;
686 else
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;
694 struct jvmti_env_list *next = e->next->next;
695 _Jv_Free (e->next);
696 e->next = next;
700 _Jv_Free (env);
702 check_enabled_events ();
704 return JVMTI_ERROR_NONE;
707 static jvmtiError JNICALL
708 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
709 char **result)
711 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
712 NULL_CHECK (property);
713 NULL_CHECK (result);
715 jstring name = JvNewStringUTF(property);
716 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
718 if (result_str == NULL)
719 return JVMTI_ERROR_NOT_AVAILABLE;
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';
728 return JVMTI_ERROR_NONE;
731 static jvmtiError JNICALL
732 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
733 const char *value)
735 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
737 NULL_CHECK (property);
738 if (value == NULL)
740 // FIXME: When would a property not be writeable?
741 return JVMTI_ERROR_NONE;
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;
750 static jvmtiError JNICALL
751 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
753 NULL_CHECK (nanos_ptr);
754 *nanos_ptr = _Jv_platform_nanotime();
755 return JVMTI_ERROR_NONE;
758 static jvmtiError JNICALL
759 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
760 jint *nprocessors_ptr)
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;
771 static jvmtiError JNICALL
772 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
773 const char *segment)
775 using namespace java::lang;
776 using namespace java::net;
777 using namespace gnu::gcj::runtime;
779 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
780 NULL_CHECK (segment);
782 jstring str_segment = JvNewStringUTF(segment);
783 URL *url;
786 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
788 catch (jthrowable ignore)
790 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
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;
800 static jvmtiError JNICALL
801 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
802 jboolean value)
804 switch (flag)
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;
817 return JVMTI_ERROR_NONE;
820 static jvmtiError JNICALL
821 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
822 jlong *result)
824 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
825 if (object == NULL)
826 return JVMTI_ERROR_INVALID_OBJECT;
827 NULL_CHECK (result);
829 jclass klass = object->getClass();
830 if (klass->isArray())
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;
841 else
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();
847 return JVMTI_ERROR_NONE;
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)
855 bool *enabled;
856 int offset;
858 #define GET_OFFSET(Event) \
859 do \
861 enabled = &JVMTI::Event; \
862 offset = offsetof (jvmtiEventCallbacks, Event); \
864 while (0)
866 switch (type)
868 case JVMTI_EVENT_VM_INIT:
869 GET_OFFSET (VMInit);
870 break;
872 case JVMTI_EVENT_VM_DEATH:
873 GET_OFFSET (VMDeath);
874 break;
876 case JVMTI_EVENT_THREAD_START:
877 GET_OFFSET (ThreadStart);
878 break;
880 case JVMTI_EVENT_THREAD_END:
881 GET_OFFSET (ThreadEnd);
882 break;
884 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
885 GET_OFFSET (ClassFileLoadHook);
886 break;
888 case JVMTI_EVENT_CLASS_LOAD:
889 GET_OFFSET (ClassLoad);
890 break;
892 case JVMTI_EVENT_CLASS_PREPARE:
893 GET_OFFSET (ClassPrepare);
894 break;
896 case JVMTI_EVENT_VM_START:
897 GET_OFFSET (VMStart);
898 break;
900 case JVMTI_EVENT_EXCEPTION:
901 GET_OFFSET (Exception);
902 break;
904 case JVMTI_EVENT_EXCEPTION_CATCH:
905 GET_OFFSET (ExceptionCatch);
906 break;
908 case JVMTI_EVENT_SINGLE_STEP:
909 GET_OFFSET (SingleStep);
910 break;
912 case JVMTI_EVENT_FRAME_POP:
913 GET_OFFSET (FramePop);
914 break;
916 case JVMTI_EVENT_BREAKPOINT:
917 GET_OFFSET (Breakpoint);
918 break;
920 case JVMTI_EVENT_FIELD_ACCESS:
921 GET_OFFSET (FieldAccess);
922 break;
924 case JVMTI_EVENT_FIELD_MODIFICATION:
925 GET_OFFSET (FieldModification);
926 break;
928 case JVMTI_EVENT_METHOD_ENTRY:
929 GET_OFFSET (MethodEntry);
930 break;
932 case JVMTI_EVENT_METHOD_EXIT:
933 GET_OFFSET (MethodExit);
934 break;
936 case JVMTI_EVENT_NATIVE_METHOD_BIND:
937 GET_OFFSET (NativeMethodBind);
938 break;
940 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
941 GET_OFFSET (CompiledMethodLoad);
942 break;
944 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
945 GET_OFFSET (CompiledMethodUnload);
946 break;
948 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
949 GET_OFFSET (DynamicCodeGenerated);
950 break;
952 case JVMTI_EVENT_DATA_DUMP_REQUEST:
953 GET_OFFSET (DataDumpRequest);
954 break;
956 case JVMTI_EVENT_MONITOR_WAIT:
957 GET_OFFSET (MonitorWait);
958 break;
960 case JVMTI_EVENT_MONITOR_WAITED:
961 GET_OFFSET (MonitorWaited);
962 break;
964 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
965 GET_OFFSET (MonitorContendedEnter);
966 break;
968 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
969 GET_OFFSET (MonitorContendedEntered);
970 break;
972 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
973 GET_OFFSET (GarbageCollectionStart);
974 break;
976 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
977 GET_OFFSET (GarbageCollectionFinish);
978 break;
980 case JVMTI_EVENT_OBJECT_FREE:
981 GET_OFFSET (ObjectFree);
982 break;
984 case JVMTI_EVENT_VM_OBJECT_ALLOC:
985 GET_OFFSET (VMObjectAlloc);
986 break;
988 default:
989 fprintf (stderr,
990 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
991 (int) type);
992 return;
994 #undef GET_OFFSET
996 int index = EVENT_INDEX (type); // safe since caller checks this
998 JvSynchronize dummy (_envListLock);
999 struct jvmti_env_list *e;
1000 FOREACH_ENVIRONMENT (e)
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)
1007 *enabled = true;
1008 return;
1012 *enabled = false;
1015 static void
1016 check_enabled_events ()
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);
1050 static jvmtiError JNICALL
1051 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1052 jvmtiEvent type, jthread event_thread, ...)
1054 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1056 if (event_thread != NULL)
1058 using namespace java::lang;
1059 Thread *t = reinterpret_cast<Thread *> (event_thread);
1060 THREAD_CHECK_VALID (t);
1061 THREAD_CHECK_IS_ALIVE (t);
1064 bool enabled;
1065 switch (mode)
1067 case JVMTI_DISABLE:
1068 enabled = false;
1069 break;
1070 case JVMTI_ENABLE:
1071 enabled = true;
1072 break;
1074 default:
1075 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1078 switch (type)
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;
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;
1115 default:
1116 return JVMTI_ERROR_INVALID_EVENT_TYPE;
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;
1125 static jvmtiError JNICALL
1126 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1127 const jvmtiEventCallbacks *callbacks,
1128 jint size_of_callbacks)
1130 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1131 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1133 // Copy the list of callbacks into the environment
1134 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
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 ();
1141 return JVMTI_ERROR_NONE;
1144 static jvmtiError JNICALL
1145 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1146 char **name_ptr)
1148 NULL_CHECK (name_ptr);
1150 const char *name;
1151 switch (error)
1153 case JVMTI_ERROR_NONE:
1154 name = "none";
1155 break;
1157 case JVMTI_ERROR_NULL_POINTER:
1158 name = "null pointer";
1159 break;
1161 case JVMTI_ERROR_OUT_OF_MEMORY:
1162 name = "out of memory";
1163 break;
1165 case JVMTI_ERROR_ACCESS_DENIED:
1166 name = "access denied";
1167 break;
1169 case JVMTI_ERROR_WRONG_PHASE:
1170 name = "wrong phase";
1171 break;
1173 case JVMTI_ERROR_INTERNAL:
1174 name = "internal error";
1175 break;
1177 case JVMTI_ERROR_UNATTACHED_THREAD:
1178 name = "unattached thread";
1179 break;
1181 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1182 name = "invalid environment";
1183 break;
1185 case JVMTI_ERROR_INVALID_PRIORITY:
1186 name = "invalid priority";
1187 break;
1189 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1190 name = "thread not suspended";
1191 break;
1193 case JVMTI_ERROR_THREAD_SUSPENDED:
1194 name = "thread suspended";
1195 break;
1197 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1198 name = "thread not alive";
1199 break;
1201 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1202 name = "class not prepared";
1203 break;
1205 case JVMTI_ERROR_NO_MORE_FRAMES:
1206 name = "no more frames";
1207 break;
1209 case JVMTI_ERROR_OPAQUE_FRAME:
1210 name = "opaque frame";
1211 break;
1213 case JVMTI_ERROR_DUPLICATE:
1214 name = "duplicate";
1215 break;
1217 case JVMTI_ERROR_NOT_FOUND:
1218 name = "not found";
1219 break;
1221 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1222 name = "not monitor owner";
1223 break;
1225 case JVMTI_ERROR_INTERRUPT:
1226 name = "interrupted";
1227 break;
1229 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1230 name = "unmodifiable class";
1231 break;
1233 case JVMTI_ERROR_NOT_AVAILABLE:
1234 name = "not available";
1235 break;
1237 case JVMTI_ERROR_ABSENT_INFORMATION:
1238 name = "absent information";
1239 break;
1241 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1242 name = "invalid event type";
1243 break;
1245 case JVMTI_ERROR_NATIVE_METHOD:
1246 name = "native method";
1247 break;
1249 case JVMTI_ERROR_INVALID_THREAD:
1250 name = "invalid thread";
1251 break;
1253 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1254 name = "invalid thread group";
1255 break;
1257 case JVMTI_ERROR_INVALID_OBJECT:
1258 name = "invalid object";
1259 break;
1261 case JVMTI_ERROR_INVALID_CLASS:
1262 name = "invalid class";
1263 break;
1265 case JVMTI_ERROR_INVALID_METHODID:
1266 name = "invalid method ID";
1267 break;
1269 case JVMTI_ERROR_INVALID_LOCATION:
1270 name = "invalid location";
1271 break;
1273 case JVMTI_ERROR_INVALID_FIELDID:
1274 name = "invalid field ID";
1275 break;
1277 case JVMTI_ERROR_TYPE_MISMATCH:
1278 name = "type mismatch";
1279 break;
1281 case JVMTI_ERROR_INVALID_SLOT:
1282 name = "invalid slot";
1283 break;
1285 case JVMTI_ERROR_INVALID_MONITOR:
1286 name = "invalid monitor";
1287 break;
1289 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1290 name = "invalid class format";
1291 break;
1293 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1294 name = "circular class definition";
1295 break;
1297 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1298 name = "unsupported redefinition: method added";
1299 break;
1301 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1302 name = "unsupported redefinition: schema changed";
1303 break;
1305 case JVMTI_ERROR_INVALID_TYPESTATE:
1306 name = "invalid type state";
1307 break;
1309 case JVMTI_ERROR_FAILS_VERIFICATION:
1310 name = "fails verification";
1311 break;
1313 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1314 name = "unsupported redefinition: hierarchy changed";
1315 break;
1317 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1318 name = "unsupported redefinition: method deleted";
1319 break;
1321 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1322 name = "unsupported version";
1323 break;
1325 case JVMTI_ERROR_NAMES_DONT_MATCH:
1326 name = "names do not match";
1327 break;
1329 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1330 name = "unsupported redefinition: class modifiers changed";
1331 break;
1333 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1334 name = "unsupported redefinition: method modifiers changed";
1335 break;
1337 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1338 name = "must possess capability";
1339 break;
1341 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1342 name = "illegal argument";
1343 break;
1345 default:
1346 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1349 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1350 if (*name_ptr == NULL)
1351 return JVMTI_ERROR_OUT_OF_MEMORY;
1353 strcpy (*name_ptr, name);
1354 return JVMTI_ERROR_NONE;
1357 #define RESERVED NULL
1358 #define UNIMPLEMENTED NULL
1360 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
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
1518 _Jv_JVMTIEnv *
1519 _Jv_GetJVMTIEnv (void)
1521 _Jv_JVMTIEnv *env
1522 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1523 env->p = &_Jv_JVMTI_Interface;
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;
1532 if (_jvmtiEnvironments == NULL)
1533 _jvmtiEnvironments = element;
1534 else
1536 struct jvmti_env_list *e;
1537 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1539 e->next = element;
1543 return env;
1546 void
1547 _Jv_JVMTI_Init ()
1549 _jvmtiEnvironments = NULL;
1550 _envListLock = new java::lang::Object ();
1552 // No environments, so this should set all JVMTI:: members to false
1553 check_enabled_events ();
1556 static void
1557 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
1559 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
1561 #define GET_BOOLEAN_ARG(Name) \
1562 ARG (int, b); \
1563 jboolean Name = (b == 0) ? false : true
1565 #define GET_CHAR_ARG(Name) \
1566 ARG (int, c); \
1567 char Name = static_cast<char> (c)
1569 switch (type)
1571 case JVMTI_EVENT_VM_INIT:
1572 if (env->callbacks.VMInit != NULL)
1574 ARG (JNIEnv *, jni_env);
1575 env->callbacks.VMInit (env, jni_env, event_thread);
1577 break;
1579 case JVMTI_EVENT_VM_DEATH:
1580 if (env->callbacks.VMDeath != NULL)
1582 ARG (JNIEnv *, jni_env);
1583 env->callbacks.VMDeath (env, jni_env);
1585 break;
1587 case JVMTI_EVENT_THREAD_START:
1588 if (env->callbacks.ThreadStart != NULL)
1590 ARG (JNIEnv *, jni_env);
1591 env->callbacks.ThreadStart (env, jni_env, event_thread);
1593 break;
1595 case JVMTI_EVENT_THREAD_END:
1596 if (env->callbacks.ThreadEnd != NULL)
1598 ARG (JNIEnv *, jni_env);
1599 env->callbacks.ThreadEnd (env, jni_env, event_thread);
1601 break;
1603 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1604 if (env->callbacks.ClassFileLoadHook != NULL)
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);
1622 break;
1624 case JVMTI_EVENT_CLASS_LOAD:
1625 if (env->callbacks.ClassLoad != NULL)
1627 ARG (JNIEnv *, jni_env);
1628 ARG (jclass, klass);
1629 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
1631 break;
1633 case JVMTI_EVENT_CLASS_PREPARE:
1634 if (env->callbacks.ClassPrepare != NULL)
1636 ARG (JNIEnv *, jni_env);
1637 ARG (jclass, klass);
1638 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
1640 break;
1642 case JVMTI_EVENT_VM_START:
1643 if (env->callbacks.VMStart != NULL)
1645 ARG (JNIEnv *, jni_env);
1646 env->callbacks.VMStart (env, jni_env);
1648 break;
1650 case JVMTI_EVENT_EXCEPTION:
1651 if (env->callbacks.Exception != NULL)
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);
1663 break;
1665 case JVMTI_EVENT_EXCEPTION_CATCH:
1666 if (env->callbacks.ExceptionCatch != NULL)
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);
1675 break;
1677 case JVMTI_EVENT_SINGLE_STEP:
1678 if (env->callbacks.SingleStep != NULL)
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);
1686 break;
1688 case JVMTI_EVENT_FRAME_POP:
1689 if (env->callbacks.FramePop != NULL)
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);
1697 break;
1699 case JVMTI_EVENT_BREAKPOINT:
1700 if (env->callbacks.Breakpoint != NULL)
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);
1708 break;
1710 case JVMTI_EVENT_FIELD_ACCESS:
1711 if (env->callbacks.FieldAccess != NULL)
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);
1722 break;
1724 case JVMTI_EVENT_FIELD_MODIFICATION:
1725 if (env->callbacks.FieldModification != NULL)
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);
1739 break;
1741 case JVMTI_EVENT_METHOD_ENTRY:
1742 if (env->callbacks.MethodEntry != NULL)
1744 ARG (JNIEnv *, jni_env);
1745 ARG (jmethodID, method);
1746 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
1748 break;
1750 case JVMTI_EVENT_METHOD_EXIT:
1751 if (env->callbacks.MethodExit != NULL)
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);
1760 break;
1762 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1763 if (env->callbacks.NativeMethodBind != NULL)
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);
1772 break;
1774 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1775 if (env->callbacks.CompiledMethodLoad != NULL)
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);
1786 break;
1788 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1789 if (env->callbacks.CompiledMethodUnload != NULL)
1791 ARG (jmethodID, method);
1792 ARG (const void *, code_addr);
1793 env->callbacks.CompiledMethodUnload (env, method, code_addr);
1795 break;
1797 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1798 if (env->callbacks.DynamicCodeGenerated != NULL)
1800 ARG (const char *, name);
1801 ARG (const void *, address);
1802 ARG (jint, length);
1803 env->callbacks.DynamicCodeGenerated (env, name, address, length);
1805 break;
1807 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1808 if (env->callbacks.DataDumpRequest != NULL)
1810 env->callbacks.DataDumpRequest (env);
1812 break;
1814 case JVMTI_EVENT_MONITOR_WAIT:
1815 if (env->callbacks.MonitorWait != NULL)
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);
1823 break;
1825 case JVMTI_EVENT_MONITOR_WAITED:
1826 if (env->callbacks.MonitorWaited != NULL)
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);
1834 break;
1836 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1837 if (env->callbacks.MonitorContendedEnter != NULL)
1839 ARG (JNIEnv *, jni_env);
1840 ARG (jobject, object);
1841 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
1842 object);
1844 break;
1846 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1847 if (env->callbacks.MonitorContendedEntered != NULL)
1849 ARG (JNIEnv *, jni_env);
1850 ARG (jobject, object);
1851 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
1852 object);
1854 break;
1856 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1857 if (env->callbacks.GarbageCollectionStart != NULL)
1859 env->callbacks.GarbageCollectionStart (env);
1861 break;
1863 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1864 if (env->callbacks.GarbageCollectionFinish != NULL)
1866 env->callbacks.GarbageCollectionFinish (env);
1868 break;
1870 case JVMTI_EVENT_OBJECT_FREE:
1871 if (env->callbacks.ObjectFree != NULL)
1873 ARG (jlong, tag);
1874 env->callbacks.ObjectFree (env, tag);
1876 break;
1878 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1879 if (env->callbacks.VMObjectAlloc != NULL)
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);
1888 break;
1890 default:
1891 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
1892 (int) type);
1893 break;
1895 va_end (args);
1896 #undef ARG
1897 #undef GET_BOOLEAN_ARG
1898 #undef GET_CHAR_ARG
1901 /* Post an event to requesting JVMTI environments
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.
1908 void
1909 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
1911 va_list args;
1912 va_start (args, event_thread);
1914 JvSynchronize dummy (_envListLock);
1915 struct jvmti_env_list *e;
1916 FOREACH_ENVIRONMENT (e)
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))
1927 post_event (e->env, type, event_thread, args);
1931 va_end (args);