* error.c (show_locus): Remove always-false test.
[official-gcc.git] / libjava / jvmti.cc
blob716e96ae6828d4fc67e4c69bd7e37d27d90528c6
1 // jvmti.cc - JVMTI implementation
3 /* Copyright (C) 2006, 2007 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/OutOfMemoryError.h>
31 #include <java/lang/Thread.h>
32 #include <java/lang/ThreadGroup.h>
33 #include <java/lang/Throwable.h>
34 #include <java/lang/VMClassLoader.h>
35 #include <java/lang/reflect/Field.h>
36 #include <java/lang/reflect/Modifier.h>
37 #include <java/util/Collection.h>
38 #include <java/util/HashMap.h>
39 #include <java/util/concurrent/locks/Lock.h>
40 #include <java/util/concurrent/locks/ReentrantReadWriteLock.h>
41 #include <java/net/URL.h>
43 static void check_enabled_events (void);
44 static void check_enabled_event (jvmtiEvent);
46 namespace JVMTI
48 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
49 bool enabled;
51 // Event notifications
52 bool VMInit = false;
53 bool VMDeath = false;
54 bool ThreadStart = false;
55 bool ThreadEnd = false;
56 bool ClassFileLoadHook = false;
57 bool ClassLoad = false;
58 bool ClassPrepare = false;
59 bool VMStart = false;
60 bool Exception = false;
61 bool ExceptionCatch = false;
62 bool SingleStep = false;
63 bool FramePop = false;
64 bool Breakpoint = false;
65 bool FieldAccess = false;
66 bool FieldModification = false;
67 bool MethodEntry = false;
68 bool MethodExit = false;
69 bool NativeMethodBind = false;
70 bool CompiledMethodLoad = false;
71 bool CompiledMethodUnload = false;
72 bool DynamicCodeGenerated = false;
73 bool DataDumpRequest = false;
74 bool reserved72 = false;
75 bool MonitorWait = false;
76 bool MonitorWaited = false;
77 bool MonitorContendedEnter = false;
78 bool MonitorContendedEntered = false;
79 bool reserved77 = false;
80 bool reserved78 = false;
81 bool reserved79 = false;
82 bool reserved80 = false;
83 bool GarbageCollectionStart = false;
84 bool GarbageCollectionFinish = false;
85 bool ObjectFree = false;
86 bool VMObjectAlloc = false;
89 extern struct JNINativeInterface _Jv_JNIFunctions;
91 struct _Jv_rawMonitorID
93 _Jv_Mutex_t mutex;
94 _Jv_ConditionVariable_t condition;
97 /* A simple linked list of all JVMTI environments. Since
98 events must be delivered to environments in the order
99 in which the environments were created, new environments
100 are added to the end of the list. */
101 struct jvmti_env_list
103 jvmtiEnv *env;
104 struct jvmti_env_list *next;
106 static struct jvmti_env_list *_jvmtiEnvironments = NULL;
107 static java::util::concurrent::locks::
108 ReentrantReadWriteLock *_envListLock = NULL;
109 #define FOREACH_ENVIRONMENT(Ele) \
110 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
112 // Some commonly-used checks
114 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
115 do \
117 if (Ajthread == NULL) \
118 Ajthread = java::lang::Thread::currentThread (); \
120 while (0)
122 #define THREAD_CHECK_VALID(Athread) \
123 do \
125 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
126 return JVMTI_ERROR_INVALID_THREAD; \
128 while (0)
130 #define THREAD_CHECK_IS_ALIVE(Athread) \
131 do \
133 if (!Athread->isAlive ()) \
134 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
136 while (0)
138 // FIXME: if current phase is not set in Phases,
139 // return JVMTI_ERROR_WRONG_PHASE
140 #define REQUIRE_PHASE(Env, Phases)
142 #define NULL_CHECK(Ptr) \
143 do \
145 if (Ptr == NULL) \
146 return JVMTI_ERROR_NULL_POINTER; \
148 while (0)
150 #define ILLEGAL_ARGUMENT(Cond) \
151 do \
153 if ((Cond)) \
154 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
156 while (0)
158 #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
159 do \
161 jboolean is_native; \
162 jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
163 if (jerr != JVMTI_ERROR_NONE) \
164 return jerr; \
165 if (is_native) \
166 return JVMTI_ERROR_NATIVE_METHOD; \
168 while (0)
170 static jvmtiError JNICALL
171 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
173 using namespace java::lang;
175 THREAD_DEFAULT_TO_CURRENT (thread);
176 THREAD_CHECK_VALID (thread);
177 THREAD_CHECK_IS_ALIVE (thread);
179 _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
180 _Jv_SuspendThread (data);
181 return JVMTI_ERROR_NONE;
184 static jvmtiError JNICALL
185 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
187 using namespace java::lang;
189 THREAD_DEFAULT_TO_CURRENT (thread);
190 THREAD_CHECK_VALID (thread);
191 THREAD_CHECK_IS_ALIVE (thread);
193 _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
194 _Jv_ResumeThread (data);
195 return JVMTI_ERROR_NONE;
198 static jvmtiError JNICALL
199 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
201 using namespace java::lang;
203 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
204 // FIXME: capability handling? 'can_signal_thread'
205 if (thread == NULL)
206 return JVMTI_ERROR_INVALID_THREAD;
208 THREAD_CHECK_VALID (thread);
209 THREAD_CHECK_IS_ALIVE (thread);
210 thread->interrupt();
211 return JVMTI_ERROR_NONE;
214 // This method performs the common tasks to get and set variables of all types.
215 // It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods.
216 static jvmtiError
217 getLocalFrame (jvmtiEnv *env, jthread thread, jint depth, jint slot, char type,
218 _Jv_InterpFrame **iframe)
220 using namespace java::lang;
222 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
224 ILLEGAL_ARGUMENT (depth < 0);
226 THREAD_DEFAULT_TO_CURRENT (thread);
227 THREAD_CHECK_VALID (thread);
228 THREAD_CHECK_IS_ALIVE (thread);
230 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
232 for (int i = 0; i < depth; i++)
234 frame = frame->next;
236 if (frame == NULL)
237 return JVMTI_ERROR_NO_MORE_FRAMES;
240 if (frame->frame_type == frame_native)
241 return JVMTI_ERROR_OPAQUE_FRAME;
243 jint max_locals;
244 jvmtiError jerr = env->GetMaxLocals (reinterpret_cast<jmethodID>
245 (frame->self->get_method ()),
246 &max_locals);
247 if (jerr != JVMTI_ERROR_NONE)
248 return jerr;
250 _Jv_InterpFrame *tmp_iframe = reinterpret_cast<_Jv_InterpFrame *> (frame);
252 // The second slot taken up by a long type is marked as type 'x' meaning it
253 // is not valid for access since it holds only the 4 low bytes of the value.
254 if (tmp_iframe->locals_type[slot] == 'x')
255 return JVMTI_ERROR_INVALID_SLOT;
257 if (tmp_iframe->locals_type[slot] != type)
258 return JVMTI_ERROR_TYPE_MISMATCH;
260 // Check for invalid slots, if the type is a long type, we must check that
261 // the next slot is valid as well.
262 if (slot < 0 || slot >= max_locals
263 || ((type == 'l' || type == 'd') && slot + 1 >= max_locals))
264 return JVMTI_ERROR_INVALID_SLOT;
266 *iframe = tmp_iframe;
268 return JVMTI_ERROR_NONE;
271 static jvmtiError JNICALL
272 _Jv_JVMTI_GetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
273 jobject *value)
275 NULL_CHECK (value);
277 _Jv_InterpFrame *frame;
278 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
280 if (jerr != JVMTI_ERROR_NONE)
281 return jerr;
283 *value = frame->locals[slot].o;
285 return JVMTI_ERROR_NONE;
288 static jvmtiError JNICALL
289 _Jv_JVMTI_SetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
290 jobject value)
292 _Jv_InterpFrame *frame;
293 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
295 if (jerr != JVMTI_ERROR_NONE)
296 return jerr;
298 frame->locals[slot].o = value;
300 return JVMTI_ERROR_NONE;
303 static jvmtiError JNICALL
304 _Jv_JVMTI_GetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
305 jint *value)
307 NULL_CHECK (value);
309 _Jv_InterpFrame *frame;
310 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
312 if (jerr != JVMTI_ERROR_NONE)
313 return jerr;
315 *value = frame->locals[slot].i;
317 return JVMTI_ERROR_NONE;
320 static jvmtiError JNICALL
321 _Jv_JVMTI_SetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
322 jint value)
324 _Jv_InterpFrame *frame;
325 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
327 if (jerr != JVMTI_ERROR_NONE)
328 return jerr;
330 frame->locals[slot].i = value;
332 return JVMTI_ERROR_NONE;
335 static jvmtiError JNICALL
336 _Jv_JVMTI_GetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
337 jlong *value)
339 NULL_CHECK (value);
341 _Jv_InterpFrame *frame;
342 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
344 if (jerr != JVMTI_ERROR_NONE)
345 return jerr;
347 #if SIZEOF_VOID_P==8
348 *value = frame->locals[slot].l;
349 #else
350 _Jv_word2 val;
351 val.ia[0] = frame->locals[slot].ia[0];
352 val.ia[1] = frame->locals[slot + 1].ia[0];
353 *value = val.l;
354 #endif
356 return JVMTI_ERROR_NONE;
359 static jvmtiError JNICALL
360 _Jv_JVMTI_SetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
361 jlong value)
363 _Jv_InterpFrame *frame;
364 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
366 if (jerr != JVMTI_ERROR_NONE)
367 return jerr;
369 #if SIZEOF_VOID_P==8
370 frame->locals[slot].l = value;
371 #else
372 _Jv_word2 val;
373 val.l = value;
374 frame->locals[slot].ia[0] = val.ia[0];
375 frame->locals[slot + 1].ia[0] = val.ia[1];
376 #endif
378 return JVMTI_ERROR_NONE;
382 static jvmtiError JNICALL
383 _Jv_JVMTI_GetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
384 jfloat *value)
386 NULL_CHECK (value);
388 _Jv_InterpFrame *frame;
389 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
391 if (jerr != JVMTI_ERROR_NONE)
392 return jerr;
394 *value = frame->locals[slot].f;
396 return JVMTI_ERROR_NONE;
399 static jvmtiError JNICALL
400 _Jv_JVMTI_SetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
401 jfloat value)
403 _Jv_InterpFrame *frame;
404 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
406 if (jerr != JVMTI_ERROR_NONE)
407 return jerr;
409 frame->locals[slot].f = value;
411 return JVMTI_ERROR_NONE;
415 static jvmtiError JNICALL
416 _Jv_JVMTI_GetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
417 jdouble *value)
419 NULL_CHECK (value);
421 _Jv_InterpFrame *frame;
422 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
424 if (jerr != JVMTI_ERROR_NONE)
425 return jerr;
427 #if SIZEOF_VOID_P==8
428 *value = frame->locals[slot].d;
429 #else
430 _Jv_word2 val;
431 val.ia[0] = frame->locals[slot].ia[0];
432 val.ia[1] = frame->locals[slot + 1].ia[0];
433 *value = val.d;
434 #endif
436 return JVMTI_ERROR_NONE;
439 static jvmtiError JNICALL
440 _Jv_JVMTI_SetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
441 jdouble value)
443 _Jv_InterpFrame *frame;
444 jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
446 if (jerr != JVMTI_ERROR_NONE)
447 return jerr;
449 #if SIZEOF_VOID_P==8
450 frame->locals[slot].d = value;
451 #else
452 _Jv_word2 val;
453 val.d = value;
454 frame->locals[slot].ia[0] = val.ia[0];
455 frame->locals[slot + 1].ia[0] = val.ia[1];
456 #endif
458 return JVMTI_ERROR_NONE;
461 static jvmtiError JNICALL
462 _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
463 jthread **threads)
465 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
466 NULL_CHECK (thread_cnt);
467 NULL_CHECK (threads);
469 using namespace java::lang;
471 ThreadGroup *root_grp = ThreadGroup::root;
472 jint estimate = root_grp->activeCount ();
474 JArray<Thread *> *thr_arr;
476 // Allocate some extra space since threads can be created between calls
479 thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
480 ((estimate * 2),
481 &Thread::class$, NULL));
483 catch (java::lang::OutOfMemoryError *err)
485 return JVMTI_ERROR_OUT_OF_MEMORY;
488 *thread_cnt = root_grp->enumerate (thr_arr);
490 jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)),
491 (unsigned char **) threads);
493 if (jerr != JVMTI_ERROR_NONE)
494 return jerr;
496 // Transfer the threads to the result array
497 jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr));
499 memcpy ((*threads), tmp_arr, (*thread_cnt));
501 return JVMTI_ERROR_NONE;
504 static jvmtiError JNICALL
505 _Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
506 jint *frame_count)
508 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
510 NULL_CHECK (frame_count);
512 using namespace java::lang;
514 THREAD_DEFAULT_TO_CURRENT (thread);
515 THREAD_CHECK_VALID (thread);
516 THREAD_CHECK_IS_ALIVE (thread);
518 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
519 (*frame_count) = frame->depth ();
520 return JVMTI_ERROR_NONE;
523 static jvmtiError JNICALL
524 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
525 jrawMonitorID *result)
527 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
528 NULL_CHECK (name);
529 NULL_CHECK (result);
530 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
531 if (*result == NULL)
532 return JVMTI_ERROR_OUT_OF_MEMORY;
533 _Jv_MutexInit (&(*result)->mutex);
534 _Jv_CondInit (&(*result)->condition);
535 return JVMTI_ERROR_NONE;
538 static jvmtiError JNICALL
539 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
541 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
542 // Note we have no better way of knowing whether this object is
543 // really a raw monitor.
544 if (monitor == NULL)
545 return JVMTI_ERROR_INVALID_MONITOR;
546 // FIXME: perform checks on monitor, release it if this thread owns
547 // it.
548 #ifdef _Jv_HaveMutexDestroy
549 _Jv_MutexDestroy (&monitor->mutex);
550 #endif
551 _Jv_Free (monitor);
552 return JVMTI_ERROR_NONE;
555 static jvmtiError JNICALL
556 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
558 if (monitor == NULL)
559 return JVMTI_ERROR_INVALID_MONITOR;
560 _Jv_MutexLock (&monitor->mutex);
561 return JVMTI_ERROR_NONE;
564 static jvmtiError JNICALL
565 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
567 if (monitor == NULL)
568 return JVMTI_ERROR_INVALID_MONITOR;
569 if (_Jv_MutexUnlock (&monitor->mutex))
570 return JVMTI_ERROR_NOT_MONITOR_OWNER;
571 return JVMTI_ERROR_NONE;
574 static jvmtiError JNICALL
575 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
576 jlong millis)
578 if (monitor == NULL)
579 return JVMTI_ERROR_INVALID_MONITOR;
580 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
581 if (r == _JV_NOT_OWNER)
582 return JVMTI_ERROR_NOT_MONITOR_OWNER;
583 if (r == _JV_INTERRUPTED)
584 return JVMTI_ERROR_INTERRUPT;
585 return JVMTI_ERROR_NONE;
588 static jvmtiError JNICALL
589 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
591 if (monitor == NULL)
592 return JVMTI_ERROR_INVALID_MONITOR;
593 if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
594 return JVMTI_ERROR_NOT_MONITOR_OWNER;
595 return JVMTI_ERROR_NONE;
598 static jvmtiError JNICALL
599 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
600 jrawMonitorID monitor)
602 if (monitor == NULL)
603 return JVMTI_ERROR_INVALID_MONITOR;
604 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
605 == _JV_NOT_OWNER)
606 return JVMTI_ERROR_NOT_MONITOR_OWNER;
607 return JVMTI_ERROR_NONE;
610 static jvmtiError JNICALL
611 _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
613 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
615 using namespace gnu::gcj::jvmti;
616 Breakpoint *bp
617 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
618 location);
619 if (bp == NULL)
621 jclass klass;
622 jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
623 if (err != JVMTI_ERROR_NONE)
624 return err;
626 if (!_Jv_IsInterpretedClass (klass))
627 return JVMTI_ERROR_INVALID_CLASS;
629 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
630 if (base == NULL)
631 return JVMTI_ERROR_INVALID_METHODID;
633 jint flags;
634 err = env->GetMethodModifiers (method, &flags);
635 if (err != JVMTI_ERROR_NONE)
636 return err;
638 if (flags & java::lang::reflect::Modifier::NATIVE)
639 return JVMTI_ERROR_NATIVE_METHOD;
641 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
642 if (imeth->get_insn (location) == NULL)
643 return JVMTI_ERROR_INVALID_LOCATION;
645 // Now the breakpoint can be safely installed
646 bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
647 location);
649 else
651 // Duplicate breakpoints are not permitted by JVMTI
652 return JVMTI_ERROR_DUPLICATE;
655 return JVMTI_ERROR_NONE;
658 static jvmtiError JNICALL
659 _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
660 jlocation location)
662 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
664 using namespace gnu::gcj::jvmti;
666 Breakpoint *bp
667 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
668 location);
669 if (bp == NULL)
670 return JVMTI_ERROR_NOT_FOUND;
672 BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
673 return JVMTI_ERROR_NONE;
676 static jvmtiError JNICALL
677 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
678 unsigned char **result)
680 ILLEGAL_ARGUMENT (size < 0);
681 NULL_CHECK (result);
682 if (size == 0)
683 *result = NULL;
684 else
686 *result = (unsigned char *) _Jv_MallocUnchecked (size);
687 if (*result == NULL)
688 return JVMTI_ERROR_OUT_OF_MEMORY;
690 return JVMTI_ERROR_NONE;
693 static jvmtiError JNICALL
694 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
696 if (mem != NULL)
697 _Jv_Free (mem);
698 return JVMTI_ERROR_NONE;
701 static jvmtiError JNICALL
702 _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
703 jint *status_ptr)
705 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
706 NULL_CHECK (status_ptr);
707 if (klass == NULL)
708 return JVMTI_ERROR_INVALID_CLASS;
710 if (klass->isArray ())
711 *status_ptr = JVMTI_CLASS_STATUS_ARRAY;
712 else if (klass->isPrimitive ())
713 *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE;
714 else
716 jbyte state = _Jv_GetClassState (klass);
717 *status_ptr = 0;
718 if (state >= JV_STATE_LINKED)
719 (*status_ptr) |= JVMTI_CLASS_STATUS_VERIFIED;
720 if (state >= JV_STATE_PREPARED)
721 (*status_ptr) |= JVMTI_CLASS_STATUS_PREPARED;
722 if (state == JV_STATE_ERROR || state == JV_STATE_PHANTOM)
723 (*status_ptr) |= JVMTI_CLASS_STATUS_ERROR;
724 else if (state == JV_STATE_DONE)
725 (*status_ptr) |= JVMTI_CLASS_STATUS_INITIALIZED;
728 return JVMTI_ERROR_NONE;
731 static jvmtiError JNICALL
732 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
733 jint *mods)
735 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
736 // Don't bother checking KLASS' type.
737 if (klass == NULL)
738 return JVMTI_ERROR_INVALID_CLASS;
739 NULL_CHECK (mods);
740 *mods = klass->getModifiers();
741 return JVMTI_ERROR_NONE;
744 static jvmtiError JNICALL
745 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
746 jint *count_ptr, jmethodID **methods_ptr)
748 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
749 // FIXME: capability can_maintain_original_method_order
750 // Don't bother checking KLASS' type.
751 if (klass == NULL)
752 return JVMTI_ERROR_INVALID_CLASS;
753 NULL_CHECK (count_ptr);
754 NULL_CHECK (methods_ptr);
755 *count_ptr = JvNumMethods(klass);
757 *methods_ptr
758 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
759 if (*methods_ptr == NULL)
760 return JVMTI_ERROR_OUT_OF_MEMORY;
762 jmethodID start = JvGetFirstMethod (klass);
763 for (jint i = 0; i < *count_ptr; ++i)
764 // FIXME: correct?
765 (*methods_ptr)[i] = start + i;
767 return JVMTI_ERROR_NONE;
770 static jvmtiError JNICALL
771 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
772 jboolean *result)
774 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
775 if (klass == NULL)
776 return JVMTI_ERROR_INVALID_CLASS;
777 NULL_CHECK (result);
778 *result = klass->isInterface();
779 return JVMTI_ERROR_NONE;
782 static jvmtiError JNICALL
783 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
784 jboolean *result)
786 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
787 if (klass == NULL)
788 return JVMTI_ERROR_INVALID_CLASS;
789 NULL_CHECK (result);
790 *result = klass->isArray();
791 return JVMTI_ERROR_NONE;
794 static jvmtiError JNICALL
795 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
796 jobject *result)
798 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
799 if (klass == NULL)
800 return JVMTI_ERROR_INVALID_CLASS;
801 NULL_CHECK (result);
802 *result = klass->getClassLoaderInternal();
803 return JVMTI_ERROR_NONE;
806 static jvmtiError JNICALL
807 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
808 jint *result)
810 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
811 if (obj == NULL)
812 return JVMTI_ERROR_INVALID_OBJECT;
813 NULL_CHECK (result);
814 *result = _Jv_HashCode (obj);
815 return JVMTI_ERROR_NONE;
818 static jvmtiError JNICALL
819 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
820 jfieldID field, jint *result)
822 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
823 if (klass == NULL)
824 return JVMTI_ERROR_INVALID_CLASS;
825 if (field == NULL)
826 return JVMTI_ERROR_INVALID_FIELDID;
827 NULL_CHECK (result);
828 *result = field->getModifiers();
829 return JVMTI_ERROR_NONE;
832 static jvmtiError JNICALL
833 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
834 jfieldID field, jboolean *result)
836 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
837 if (klass == NULL)
838 return JVMTI_ERROR_INVALID_CLASS;
839 if (field == NULL)
840 return JVMTI_ERROR_INVALID_FIELDID;
841 NULL_CHECK (result);
843 // FIXME: capability can_get_synthetic_attribute
844 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
845 != 0);
846 return JVMTI_ERROR_NONE;
849 static jvmtiError JNICALL
850 _Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
851 char **name_ptr, char **signature_ptr,
852 char **generic_ptr)
854 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
856 if (method == NULL)
857 return JVMTI_ERROR_INVALID_METHODID;
859 if (name_ptr != NULL)
861 int len = static_cast<int> (method->name->len ());
862 *name_ptr = (char *) _Jv_MallocUnchecked (len + 1);
863 if (*name_ptr == NULL)
864 return JVMTI_ERROR_OUT_OF_MEMORY;
865 strncpy (*name_ptr, method->name->chars (), len);
866 (*name_ptr)[len] = '\0';
869 if (signature_ptr != NULL)
871 int len = static_cast<int> (method->signature->len ());
872 *signature_ptr = (char *) _Jv_MallocUnchecked (len + 1);
873 if (*signature_ptr == NULL)
875 if (name_ptr != NULL)
876 _Jv_Free (*name_ptr);
877 return JVMTI_ERROR_OUT_OF_MEMORY;
879 strncpy (*signature_ptr, method->signature->chars (), len);
880 (*signature_ptr)[len] = '\0';
883 if (generic_ptr != NULL)
885 *generic_ptr = NULL;
888 return JVMTI_ERROR_NONE;
891 static jvmtiError JNICALL
892 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
893 jint *result)
895 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
896 if (method == NULL)
897 return JVMTI_ERROR_INVALID_METHODID;
898 NULL_CHECK (result);
900 // FIXME: mask off some internal bits...
901 *result = method->accflags;
902 return JVMTI_ERROR_NONE;
905 static jvmtiError JNICALL
906 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
907 jint *entry_count_ptr,
908 jvmtiLineNumberEntry **table_ptr)
910 NULL_CHECK (entry_count_ptr);
911 NULL_CHECK (table_ptr);
913 jclass klass;
914 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
915 if (jerr != JVMTI_ERROR_NONE)
916 return jerr;
918 _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
919 if (base == NULL)
920 return JVMTI_ERROR_INVALID_METHODID;
922 if (java::lang::reflect::Modifier::isNative (method->accflags)
923 || !_Jv_IsInterpretedClass (klass))
924 return JVMTI_ERROR_NATIVE_METHOD;
926 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
927 jlong start, end;
928 jintArray lines = NULL;
929 jlongArray indices = NULL;
930 imeth->get_line_table (start, end, lines, indices);
931 if (lines == NULL)
932 return JVMTI_ERROR_ABSENT_INFORMATION;
934 jvmtiLineNumberEntry *table;
935 jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
936 table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
937 if (table == NULL)
938 return JVMTI_ERROR_OUT_OF_MEMORY;
940 jint *line = elements (lines);
941 jlong *index = elements (indices);
942 for (int i = 0; i < lines->length; ++i)
944 table[i].start_location = index[i];
945 table[i].line_number = line[i];
948 *table_ptr = table;
949 *entry_count_ptr = lines->length;
950 return JVMTI_ERROR_NONE;
953 static jvmtiError JNICALL
954 _Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
955 jint *num_locals,
956 jvmtiLocalVariableEntry **locals)
958 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
959 NULL_CHECK (num_locals);
960 NULL_CHECK (locals);
962 CHECK_FOR_NATIVE_METHOD(method);
964 jclass klass;
965 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
966 if (jerr != JVMTI_ERROR_NONE)
967 return jerr;
969 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
970 (_Jv_FindInterpreterMethod (klass, method));
972 if (imeth == NULL)
973 return JVMTI_ERROR_INVALID_METHODID;
975 jerr = env->GetMaxLocals (method, num_locals);
976 if (jerr != JVMTI_ERROR_NONE)
977 return jerr;
979 jerr = env->Allocate (static_cast<jlong>
980 ((*num_locals) * sizeof (jvmtiLocalVariableEntry)),
981 reinterpret_cast<unsigned char **> (locals));
983 if (jerr != JVMTI_ERROR_NONE)
984 return jerr;
986 //the slot in the methods local_var_table to get
987 int table_slot = 0;
988 char *name;
989 char *sig;
990 char *generic_sig;
992 while (table_slot < *num_locals
993 && imeth->get_local_var_table (&name, &sig, &generic_sig,
994 &((((*locals)[table_slot].start_location))),
995 &((*locals)[table_slot].length),
996 &((*locals)[table_slot].slot),
997 table_slot)
998 >= 0)
1000 char **str_ptr = &(*locals)[table_slot].name;
1001 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
1002 reinterpret_cast<unsigned char **> (str_ptr));
1003 if (jerr != JVMTI_ERROR_NONE)
1004 return jerr;
1005 strcpy ((*locals)[table_slot].name, name);
1007 str_ptr = &(*locals)[table_slot].signature;
1008 jerr = env->Allocate (static_cast<jlong> (strlen (sig) + 1),
1009 reinterpret_cast<unsigned char **> (str_ptr));
1010 if (jerr != JVMTI_ERROR_NONE)
1011 return jerr;
1012 strcpy ((*locals)[table_slot].signature, sig);
1014 str_ptr = &(*locals)[table_slot].generic_signature;
1015 jerr = env->Allocate (static_cast<jlong> (strlen (generic_sig) + 1),
1016 reinterpret_cast<unsigned char **> (str_ptr));
1017 if (jerr != JVMTI_ERROR_NONE)
1018 return jerr;
1019 strcpy ((*locals)[table_slot].generic_signature, generic_sig);
1021 table_slot++;
1024 if (table_slot == 0)
1025 return JVMTI_ERROR_ABSENT_INFORMATION;
1027 // If there are double or long variables in the table, the the table will be
1028 // smaller than the max number of slots, so correct for this here.
1029 if ((table_slot) < *num_locals)
1030 *num_locals = table_slot;
1032 return JVMTI_ERROR_NONE;
1035 static jvmtiError JNICALL
1036 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
1037 jboolean *result)
1039 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1040 if (method == NULL)
1041 return JVMTI_ERROR_INVALID_METHODID;
1042 NULL_CHECK (result);
1044 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
1045 return JVMTI_ERROR_NONE;
1048 static jvmtiError JNICALL
1049 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
1050 jboolean *result)
1052 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1053 if (method == NULL)
1054 return JVMTI_ERROR_INVALID_METHODID;
1055 NULL_CHECK (result);
1057 // FIXME capability can_get_synthetic_attribute
1059 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
1060 != 0);
1061 return JVMTI_ERROR_NONE;
1064 static jvmtiError JNICALL
1065 _Jv_JVMTI_GetMaxLocals (jvmtiEnv *env, jmethodID method, jint *max_locals)
1067 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1068 NULL_CHECK (max_locals);
1070 CHECK_FOR_NATIVE_METHOD (method);
1072 jclass klass;
1073 jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
1074 if (jerr != JVMTI_ERROR_NONE)
1075 return jerr;
1077 _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
1078 (_Jv_FindInterpreterMethod (klass, method));
1080 if (imeth == NULL)
1081 return JVMTI_ERROR_INVALID_METHODID;
1083 *max_locals = imeth->get_max_locals ();
1085 return JVMTI_ERROR_NONE;
1088 static jvmtiError JNICALL
1089 _Jv_JVMTI_GetArgumentsSize (jvmtiEnv *env, jmethodID method, jint *size)
1091 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1092 NULL_CHECK (size);
1094 CHECK_FOR_NATIVE_METHOD (method);
1096 jvmtiError jerr;
1097 char *sig;
1098 jint num_slots = 0;
1100 jerr = env->GetMethodName (method, NULL, &sig, NULL);
1101 if (jerr != JVMTI_ERROR_NONE)
1102 return jerr;
1104 // If the method is non-static add a slot for the "this" pointer.
1105 if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
1106 num_slots++;
1108 for (int i = 0; sig[i] != ')'; i++)
1110 if (sig[i] == 'Z' || sig[i] == 'B' || sig[i] == 'C' || sig[i] == 'S'
1111 || sig[i] == 'I' || sig[i] == 'F')
1112 num_slots++;
1113 else if (sig[i] == 'J' || sig[i] == 'D')
1115 // If this is an array of wide types it uses a single slot
1116 if (i > 0 && sig[i - 1] == '[')
1117 num_slots++;
1118 else
1119 num_slots += 2;
1121 else if (sig[i] == 'L')
1123 num_slots++;
1124 while (sig[i] != ';')
1125 i++;
1129 *size = num_slots;
1130 return JVMTI_ERROR_NONE;
1133 static jvmtiError JNICALL
1134 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
1135 jmethodID method,
1136 jclass *declaring_class_ptr)
1138 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1139 NULL_CHECK (declaring_class_ptr);
1141 jclass klass = _Jv_GetMethodDeclaringClass (method);
1142 if (klass != NULL)
1144 *declaring_class_ptr = klass;
1145 return JVMTI_ERROR_NONE;
1148 return JVMTI_ERROR_INVALID_METHODID;
1151 static jvmtiError JNICALL
1152 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
1153 jobject init_loader,
1154 jint *count_ptr,
1155 jclass **result_ptr)
1157 using namespace java::lang;
1158 using namespace java::util;
1160 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1161 NULL_CHECK (count_ptr);
1162 NULL_CHECK (result_ptr);
1164 ClassLoader *loader = (ClassLoader *) init_loader;
1165 if (loader == NULL)
1166 loader = VMClassLoader::bootLoader;
1168 Collection *values = loader->loadedClasses->values();
1169 jobjectArray array = values->toArray();
1170 *count_ptr = array->length;
1171 jobject *elts = elements (array);
1172 jclass *result
1173 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
1174 if (result == NULL)
1175 return JVMTI_ERROR_OUT_OF_MEMORY;
1177 // FIXME: JNI references...
1178 memcpy (result, elts, *count_ptr * sizeof (jclass));
1180 *result_ptr = result;
1182 return JVMTI_ERROR_NONE;
1185 static jvmtiError JNICALL
1186 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
1187 jint start_depth, jint max_frames,
1188 jvmtiFrameInfo *frames, jint *frame_count)
1190 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1192 ILLEGAL_ARGUMENT (max_frames < 0);
1194 NULL_CHECK (frames);
1195 NULL_CHECK (frame_count);
1197 using namespace java::lang;
1199 THREAD_DEFAULT_TO_CURRENT (thread);
1200 THREAD_CHECK_VALID (thread);
1201 THREAD_CHECK_IS_ALIVE (thread);
1203 jvmtiError jerr = env->GetFrameCount (thread, frame_count);
1204 if (jerr != JVMTI_ERROR_NONE)
1205 return jerr;
1207 // start_depth can be either a positive number, indicating the depth of the
1208 // stack at which to begin the trace, or a negative number indicating the
1209 // number of frames at the bottom of the stack to exclude. These checks
1210 // ensure that it is a valid value in either case
1212 ILLEGAL_ARGUMENT (start_depth >= (*frame_count));
1213 ILLEGAL_ARGUMENT (start_depth < (-(*frame_count)));
1215 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
1217 // If start_depth is negative use this to determine at what depth to start
1218 // the trace by adding it to the length of the call stack. This allows the
1219 // use of the same frame "discarding" mechanism as for a positive start_depth
1220 if (start_depth < 0)
1221 start_depth = *frame_count + start_depth;
1223 // If start_depth > 0 "remove" start_depth frames from the beginning
1224 // of the stack before beginning the trace by moving along the frame list.
1225 while (start_depth > 0)
1227 frame = frame->next;
1228 start_depth--;
1229 (*frame_count)--;
1232 // Now check to see if the array supplied by the agent is large enough to
1233 // hold frame_count frames, after adjustment for start_depth.
1234 if ((*frame_count) > max_frames)
1235 (*frame_count) = max_frames;
1237 for (int i = 0; i < (*frame_count); i++)
1239 frames[i].method = frame->self->get_method ();
1241 // Set the location in the frame, native frames have location = -1
1242 if (frame->frame_type == frame_interpreter)
1244 _Jv_InterpMethod *imeth
1245 = static_cast<_Jv_InterpMethod *> (frame->self);
1246 _Jv_InterpFrame *interp_frame
1247 = static_cast<_Jv_InterpFrame *> (frame);
1248 frames[i].location = imeth->insn_index (interp_frame->pc);
1250 else
1251 frames[i].location = -1;
1253 frame = frame->next;
1256 return JVMTI_ERROR_NONE;
1259 static jvmtiError JNICALL
1260 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
1262 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1263 _Jv_RunGC();
1264 return JVMTI_ERROR_NONE;
1267 static jvmtiError JNICALL
1268 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
1269 const jniNativeInterface *function_table)
1271 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1272 NULL_CHECK (function_table);
1273 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
1274 return JVMTI_ERROR_NONE;
1277 static jvmtiError JNICALL
1278 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
1279 jniNativeInterface **function_table)
1281 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1282 NULL_CHECK (function_table);
1283 *function_table
1284 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
1285 if (*function_table == NULL)
1286 return JVMTI_ERROR_OUT_OF_MEMORY;
1287 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
1288 return JVMTI_ERROR_NONE;
1291 static jvmtiError JNICALL
1292 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
1294 NULL_CHECK (env);
1296 if (_jvmtiEnvironments == NULL)
1297 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1298 else
1300 _envListLock->writeLock ()->lock ();
1301 if (_jvmtiEnvironments->env == env)
1303 struct jvmti_env_list *next = _jvmtiEnvironments->next;
1304 _Jv_Free (_jvmtiEnvironments);
1305 _jvmtiEnvironments = next;
1307 else
1309 struct jvmti_env_list *e = _jvmtiEnvironments;
1310 while (e->next != NULL && e->next->env != env)
1311 e = e->next;
1312 if (e->next == NULL)
1314 _envListLock->writeLock ()->unlock ();
1315 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1318 struct jvmti_env_list *next = e->next->next;
1319 _Jv_Free (e->next);
1320 e->next = next;
1322 _envListLock->writeLock ()->unlock ();
1325 _Jv_Free (env);
1327 check_enabled_events ();
1329 return JVMTI_ERROR_NONE;
1332 static jvmtiError JNICALL
1333 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1334 char **result)
1336 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1337 NULL_CHECK (property);
1338 NULL_CHECK (result);
1340 jstring name = JvNewStringUTF(property);
1341 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
1343 if (result_str == NULL)
1344 return JVMTI_ERROR_NOT_AVAILABLE;
1346 int len = JvGetStringUTFLength (result_str);
1347 *result = (char *) _Jv_MallocUnchecked (len + 1);
1348 if (*result == NULL)
1349 return JVMTI_ERROR_OUT_OF_MEMORY;
1350 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
1351 (*result)[len] = '\0';
1353 return JVMTI_ERROR_NONE;
1356 static jvmtiError JNICALL
1357 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1358 const char *value)
1360 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1362 NULL_CHECK (property);
1363 if (value == NULL)
1365 // FIXME: When would a property not be writeable?
1366 return JVMTI_ERROR_NONE;
1369 jstring prop_str = JvNewStringUTF(property);
1370 jstring value_str = JvNewStringUTF(value);
1371 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
1372 return JVMTI_ERROR_NONE;
1375 static jvmtiError JNICALL
1376 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
1378 NULL_CHECK (nanos_ptr);
1379 *nanos_ptr = _Jv_platform_nanotime();
1380 return JVMTI_ERROR_NONE;
1383 static jvmtiError JNICALL
1384 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
1385 jint *nprocessors_ptr)
1387 NULL_CHECK (nprocessors_ptr);
1388 #ifdef _SC_NPROCESSORS_ONLN
1389 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
1390 #else
1391 *nprocessors_ptr = 1;
1392 #endif
1393 return JVMTI_ERROR_NONE;
1396 static jvmtiError JNICALL
1397 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
1398 const char *segment)
1400 using namespace java::lang;
1401 using namespace java::net;
1402 using namespace gnu::gcj::runtime;
1404 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1405 NULL_CHECK (segment);
1407 jstring str_segment = JvNewStringUTF(segment);
1408 URL *url;
1411 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
1413 catch (jthrowable ignore)
1415 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1418 BootClassLoader *loader = VMClassLoader::bootLoader;
1419 // Don't call this too early.
1420 // assert (loader != NULL);
1421 loader->addURL(url);
1422 return JVMTI_ERROR_NONE;
1425 static jvmtiError JNICALL
1426 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
1427 jboolean value)
1429 switch (flag)
1431 case JVMTI_VERBOSE_OTHER:
1432 case JVMTI_VERBOSE_GC:
1433 case JVMTI_VERBOSE_JNI:
1434 // Ignore.
1435 break;
1436 case JVMTI_VERBOSE_CLASS:
1437 gcj::verbose_class_flag = value;
1438 break;
1439 default:
1440 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1442 return JVMTI_ERROR_NONE;
1445 static jvmtiError JNICALL
1446 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
1447 jlong *result)
1449 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1450 if (object == NULL)
1451 return JVMTI_ERROR_INVALID_OBJECT;
1452 NULL_CHECK (result);
1454 jclass klass = object->getClass();
1455 if (klass->isArray())
1457 jclass comp = klass->getComponentType();
1458 jint base
1459 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
1460 klass->getComponentType());
1461 // FIXME: correct for primitive types?
1462 jint compSize = comp->size();
1463 __JArray *array = (__JArray *) object;
1464 *result = base + array->length * compSize;
1466 else
1468 // Note that if OBJECT is a String then it may (if
1469 // str->data==str) take more space. Do we care?
1470 *result = klass->size();
1472 return JVMTI_ERROR_NONE;
1475 /* An event is enabled only if it has both an event handler
1476 and it is enabled in the environment. */
1477 static void
1478 check_enabled_event (jvmtiEvent type)
1480 bool *enabled;
1481 int offset;
1483 #define GET_OFFSET(Event) \
1484 do \
1486 enabled = &JVMTI::Event; \
1487 offset = offsetof (jvmtiEventCallbacks, Event); \
1489 while (0)
1491 switch (type)
1493 case JVMTI_EVENT_VM_INIT:
1494 GET_OFFSET (VMInit);
1495 break;
1497 case JVMTI_EVENT_VM_DEATH:
1498 GET_OFFSET (VMDeath);
1499 break;
1501 case JVMTI_EVENT_THREAD_START:
1502 GET_OFFSET (ThreadStart);
1503 break;
1505 case JVMTI_EVENT_THREAD_END:
1506 GET_OFFSET (ThreadEnd);
1507 break;
1509 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1510 GET_OFFSET (ClassFileLoadHook);
1511 break;
1513 case JVMTI_EVENT_CLASS_LOAD:
1514 GET_OFFSET (ClassLoad);
1515 break;
1517 case JVMTI_EVENT_CLASS_PREPARE:
1518 GET_OFFSET (ClassPrepare);
1519 break;
1521 case JVMTI_EVENT_VM_START:
1522 GET_OFFSET (VMStart);
1523 break;
1525 case JVMTI_EVENT_EXCEPTION:
1526 GET_OFFSET (Exception);
1527 break;
1529 case JVMTI_EVENT_EXCEPTION_CATCH:
1530 GET_OFFSET (ExceptionCatch);
1531 break;
1533 case JVMTI_EVENT_SINGLE_STEP:
1534 GET_OFFSET (SingleStep);
1535 break;
1537 case JVMTI_EVENT_FRAME_POP:
1538 GET_OFFSET (FramePop);
1539 break;
1541 case JVMTI_EVENT_BREAKPOINT:
1542 GET_OFFSET (Breakpoint);
1543 break;
1545 case JVMTI_EVENT_FIELD_ACCESS:
1546 GET_OFFSET (FieldAccess);
1547 break;
1549 case JVMTI_EVENT_FIELD_MODIFICATION:
1550 GET_OFFSET (FieldModification);
1551 break;
1553 case JVMTI_EVENT_METHOD_ENTRY:
1554 GET_OFFSET (MethodEntry);
1555 break;
1557 case JVMTI_EVENT_METHOD_EXIT:
1558 GET_OFFSET (MethodExit);
1559 break;
1561 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1562 GET_OFFSET (NativeMethodBind);
1563 break;
1565 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1566 GET_OFFSET (CompiledMethodLoad);
1567 break;
1569 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1570 GET_OFFSET (CompiledMethodUnload);
1571 break;
1573 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1574 GET_OFFSET (DynamicCodeGenerated);
1575 break;
1577 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1578 GET_OFFSET (DataDumpRequest);
1579 break;
1581 case JVMTI_EVENT_MONITOR_WAIT:
1582 GET_OFFSET (MonitorWait);
1583 break;
1585 case JVMTI_EVENT_MONITOR_WAITED:
1586 GET_OFFSET (MonitorWaited);
1587 break;
1589 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1590 GET_OFFSET (MonitorContendedEnter);
1591 break;
1593 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1594 GET_OFFSET (MonitorContendedEntered);
1595 break;
1597 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1598 GET_OFFSET (GarbageCollectionStart);
1599 break;
1601 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1602 GET_OFFSET (GarbageCollectionFinish);
1603 break;
1605 case JVMTI_EVENT_OBJECT_FREE:
1606 GET_OFFSET (ObjectFree);
1607 break;
1609 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1610 GET_OFFSET (VMObjectAlloc);
1611 break;
1613 default:
1614 fprintf (stderr,
1615 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1616 (int) type);
1617 return;
1619 #undef GET_OFFSET
1621 int index = EVENT_INDEX (type); // safe since caller checks this
1623 if (_jvmtiEnvironments != NULL)
1625 _envListLock->readLock ()->lock ();
1626 struct jvmti_env_list *e;
1627 FOREACH_ENVIRONMENT (e)
1629 char *addr
1630 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1631 void **callback = reinterpret_cast<void **> (addr);
1632 if (e->env->enabled[index] && *callback != NULL)
1634 *enabled = true;
1635 _envListLock->readLock ()->unlock ();
1636 return;
1640 _envListLock->readLock ()->unlock ();
1643 *enabled = false;
1646 static void
1647 check_enabled_events ()
1649 check_enabled_event (JVMTI_EVENT_VM_INIT);
1650 check_enabled_event (JVMTI_EVENT_VM_DEATH);
1651 check_enabled_event (JVMTI_EVENT_THREAD_START);
1652 check_enabled_event (JVMTI_EVENT_THREAD_END);
1653 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1654 check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1655 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1656 check_enabled_event (JVMTI_EVENT_VM_START);
1657 check_enabled_event (JVMTI_EVENT_EXCEPTION);
1658 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1659 check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1660 check_enabled_event (JVMTI_EVENT_FRAME_POP);
1661 check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1662 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1663 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1664 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1665 check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1666 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1667 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1668 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1669 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1670 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1671 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1672 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1673 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1674 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1675 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1676 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1677 check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1678 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1681 static jvmtiError JNICALL
1682 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1683 jvmtiEvent type, jthread event_thread, ...)
1685 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1687 if (event_thread != NULL)
1689 THREAD_CHECK_VALID (event_thread);
1690 THREAD_CHECK_IS_ALIVE (event_thread);
1693 bool enabled;
1694 switch (mode)
1696 case JVMTI_DISABLE:
1697 enabled = false;
1698 break;
1699 case JVMTI_ENABLE:
1700 enabled = true;
1701 break;
1703 default:
1704 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1707 switch (type)
1709 case JVMTI_EVENT_VM_INIT:
1710 case JVMTI_EVENT_VM_DEATH:
1711 case JVMTI_EVENT_THREAD_START:
1712 case JVMTI_EVENT_VM_START:
1713 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1714 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1715 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1716 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1717 ILLEGAL_ARGUMENT (event_thread != NULL);
1718 break;
1720 case JVMTI_EVENT_THREAD_END:
1721 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1722 case JVMTI_EVENT_CLASS_LOAD:
1723 case JVMTI_EVENT_CLASS_PREPARE:
1724 case JVMTI_EVENT_EXCEPTION:
1725 case JVMTI_EVENT_EXCEPTION_CATCH:
1726 case JVMTI_EVENT_SINGLE_STEP:
1727 case JVMTI_EVENT_FRAME_POP:
1728 case JVMTI_EVENT_BREAKPOINT:
1729 case JVMTI_EVENT_FIELD_ACCESS:
1730 case JVMTI_EVENT_FIELD_MODIFICATION:
1731 case JVMTI_EVENT_METHOD_ENTRY:
1732 case JVMTI_EVENT_METHOD_EXIT:
1733 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1734 case JVMTI_EVENT_MONITOR_WAIT:
1735 case JVMTI_EVENT_MONITOR_WAITED:
1736 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1737 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1738 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1739 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1740 case JVMTI_EVENT_OBJECT_FREE:
1741 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1742 break;
1744 default:
1745 return JVMTI_ERROR_INVALID_EVENT_TYPE;
1748 env->thread[EVENT_INDEX(type)] = event_thread;
1749 env->enabled[EVENT_INDEX(type)] = enabled;
1750 check_enabled_event (type);
1751 return JVMTI_ERROR_NONE;
1754 static jvmtiError JNICALL
1755 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1756 const jvmtiEventCallbacks *callbacks,
1757 jint size_of_callbacks)
1759 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1760 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1762 // Copy the list of callbacks into the environment
1763 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1765 /* Check which events are now enabeld (JVMTI makes no requirements
1766 about the order in which SetEventCallbacks and SetEventNotifications
1767 are called. So we must check all events here. */
1768 check_enabled_events ();
1770 return JVMTI_ERROR_NONE;
1773 static jvmtiError JNICALL
1774 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1775 char **name_ptr)
1777 NULL_CHECK (name_ptr);
1779 const char *name;
1780 switch (error)
1782 case JVMTI_ERROR_NONE:
1783 name = "none";
1784 break;
1786 case JVMTI_ERROR_NULL_POINTER:
1787 name = "null pointer";
1788 break;
1790 case JVMTI_ERROR_OUT_OF_MEMORY:
1791 name = "out of memory";
1792 break;
1794 case JVMTI_ERROR_ACCESS_DENIED:
1795 name = "access denied";
1796 break;
1798 case JVMTI_ERROR_WRONG_PHASE:
1799 name = "wrong phase";
1800 break;
1802 case JVMTI_ERROR_INTERNAL:
1803 name = "internal error";
1804 break;
1806 case JVMTI_ERROR_UNATTACHED_THREAD:
1807 name = "unattached thread";
1808 break;
1810 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1811 name = "invalid environment";
1812 break;
1814 case JVMTI_ERROR_INVALID_PRIORITY:
1815 name = "invalid priority";
1816 break;
1818 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1819 name = "thread not suspended";
1820 break;
1822 case JVMTI_ERROR_THREAD_SUSPENDED:
1823 name = "thread suspended";
1824 break;
1826 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1827 name = "thread not alive";
1828 break;
1830 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1831 name = "class not prepared";
1832 break;
1834 case JVMTI_ERROR_NO_MORE_FRAMES:
1835 name = "no more frames";
1836 break;
1838 case JVMTI_ERROR_OPAQUE_FRAME:
1839 name = "opaque frame";
1840 break;
1842 case JVMTI_ERROR_DUPLICATE:
1843 name = "duplicate";
1844 break;
1846 case JVMTI_ERROR_NOT_FOUND:
1847 name = "not found";
1848 break;
1850 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1851 name = "not monitor owner";
1852 break;
1854 case JVMTI_ERROR_INTERRUPT:
1855 name = "interrupted";
1856 break;
1858 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1859 name = "unmodifiable class";
1860 break;
1862 case JVMTI_ERROR_NOT_AVAILABLE:
1863 name = "not available";
1864 break;
1866 case JVMTI_ERROR_ABSENT_INFORMATION:
1867 name = "absent information";
1868 break;
1870 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1871 name = "invalid event type";
1872 break;
1874 case JVMTI_ERROR_NATIVE_METHOD:
1875 name = "native method";
1876 break;
1878 case JVMTI_ERROR_INVALID_THREAD:
1879 name = "invalid thread";
1880 break;
1882 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1883 name = "invalid thread group";
1884 break;
1886 case JVMTI_ERROR_INVALID_OBJECT:
1887 name = "invalid object";
1888 break;
1890 case JVMTI_ERROR_INVALID_CLASS:
1891 name = "invalid class";
1892 break;
1894 case JVMTI_ERROR_INVALID_METHODID:
1895 name = "invalid method ID";
1896 break;
1898 case JVMTI_ERROR_INVALID_LOCATION:
1899 name = "invalid location";
1900 break;
1902 case JVMTI_ERROR_INVALID_FIELDID:
1903 name = "invalid field ID";
1904 break;
1906 case JVMTI_ERROR_TYPE_MISMATCH:
1907 name = "type mismatch";
1908 break;
1910 case JVMTI_ERROR_INVALID_SLOT:
1911 name = "invalid slot";
1912 break;
1914 case JVMTI_ERROR_INVALID_MONITOR:
1915 name = "invalid monitor";
1916 break;
1918 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1919 name = "invalid class format";
1920 break;
1922 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1923 name = "circular class definition";
1924 break;
1926 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1927 name = "unsupported redefinition: method added";
1928 break;
1930 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1931 name = "unsupported redefinition: schema changed";
1932 break;
1934 case JVMTI_ERROR_INVALID_TYPESTATE:
1935 name = "invalid type state";
1936 break;
1938 case JVMTI_ERROR_FAILS_VERIFICATION:
1939 name = "fails verification";
1940 break;
1942 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1943 name = "unsupported redefinition: hierarchy changed";
1944 break;
1946 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1947 name = "unsupported redefinition: method deleted";
1948 break;
1950 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1951 name = "unsupported version";
1952 break;
1954 case JVMTI_ERROR_NAMES_DONT_MATCH:
1955 name = "names do not match";
1956 break;
1958 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1959 name = "unsupported redefinition: class modifiers changed";
1960 break;
1962 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1963 name = "unsupported redefinition: method modifiers changed";
1964 break;
1966 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1967 name = "must possess capability";
1968 break;
1970 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1971 name = "illegal argument";
1972 break;
1974 default:
1975 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1978 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1979 if (*name_ptr == NULL)
1980 return JVMTI_ERROR_OUT_OF_MEMORY;
1982 strcpy (*name_ptr, name);
1983 return JVMTI_ERROR_NONE;
1986 #define RESERVED NULL
1987 #define UNIMPLEMENTED NULL
1989 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1991 RESERVED, // reserved1
1992 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1993 RESERVED, // reserved3
1994 _Jv_JVMTI_GetAllThreads, // GetAllThreads
1995 _Jv_JVMTI_SuspendThread, // SuspendThread
1996 _Jv_JVMTI_ResumeThread, // ResumeThread
1997 UNIMPLEMENTED, // StopThread
1998 _Jv_JVMTI_InterruptThread, // InterruptThread
1999 UNIMPLEMENTED, // GetThreadInfo
2000 UNIMPLEMENTED, // GetOwnedMonitorInfo
2001 UNIMPLEMENTED, // GetCurrentContendedMonitor
2002 UNIMPLEMENTED, // RunAgentThread
2003 UNIMPLEMENTED, // GetTopThreadGroups
2004 UNIMPLEMENTED, // GetThreadGroupInfo
2005 UNIMPLEMENTED, // GetThreadGroupChildren
2006 _Jv_JVMTI_GetFrameCount, // GetFrameCount
2007 UNIMPLEMENTED, // GetThreadState
2008 RESERVED, // reserved18
2009 UNIMPLEMENTED, // GetFrameLocation
2010 UNIMPLEMENTED, // NotifyPopFrame
2011 _Jv_JVMTI_GetLocalObject, // GetLocalObject
2012 _Jv_JVMTI_GetLocalInt, // GetLocalInt
2013 _Jv_JVMTI_GetLocalLong, // GetLocalLong
2014 _Jv_JVMTI_GetLocalFloat, // GetLocalFloat
2015 _Jv_JVMTI_GetLocalDouble, // GetLocalDouble
2016 _Jv_JVMTI_SetLocalObject, // SetLocalObject
2017 _Jv_JVMTI_SetLocalInt, // SetLocalInt
2018 _Jv_JVMTI_SetLocalLong, // SetLocalLong
2019 _Jv_JVMTI_SetLocalFloat, // SetLocalFloat
2020 _Jv_JVMTI_SetLocalDouble, // SetLocalDouble
2021 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
2022 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
2023 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
2024 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
2025 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
2026 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
2027 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
2028 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
2029 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
2030 RESERVED, // reserved40
2031 UNIMPLEMENTED, // SetFieldAccessWatch
2032 UNIMPLEMENTED, // ClearFieldAccessWatch
2033 UNIMPLEMENTED, // SetFieldModificationWatch
2034 UNIMPLEMENTED, // ClearFieldModificationWatch
2035 RESERVED, // reserved45
2036 _Jv_JVMTI_Allocate, // Allocate
2037 _Jv_JVMTI_Deallocate, // Deallocate
2038 UNIMPLEMENTED, // GetClassSignature
2039 _Jv_JVMTI_GetClassStatus, // GetClassStatus
2040 UNIMPLEMENTED, // GetSourceFileName
2041 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
2042 _Jv_JVMTI_GetClassMethods, // GetClassMethods
2043 UNIMPLEMENTED, // GetClassFields
2044 UNIMPLEMENTED, // GetImplementedInterfaces
2045 _Jv_JVMTI_IsInterface, // IsInterface
2046 _Jv_JVMTI_IsArrayClass, // IsArrayClass
2047 _Jv_JVMTI_GetClassLoader, // GetClassLoader
2048 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
2049 UNIMPLEMENTED, // GetObjectMonitorUsage
2050 UNIMPLEMENTED, // GetFieldName
2051 UNIMPLEMENTED, // GetFieldDeclaringClass
2052 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
2053 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
2054 _Jv_JVMTI_GetMethodName, // GetMethodName
2055 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
2056 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
2057 RESERVED, // reserved67
2058 _Jv_JVMTI_GetMaxLocals, // GetMaxLocals
2059 _Jv_JVMTI_GetArgumentsSize, // GetArgumentsSize
2060 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
2061 UNIMPLEMENTED, // GetMethodLocation
2062 _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable
2063 RESERVED, // reserved73
2064 RESERVED, // reserved74
2065 UNIMPLEMENTED, // GetBytecodes
2066 _Jv_JVMTI_IsMethodNative, // IsMethodNative
2067 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
2068 UNIMPLEMENTED, // GetLoadedClasses
2069 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
2070 UNIMPLEMENTED, // PopFrame
2071 RESERVED, // reserved81
2072 RESERVED, // reserved82
2073 RESERVED, // reserved83
2074 RESERVED, // reserved84
2075 RESERVED, // reserved85
2076 RESERVED, // reserved86
2077 UNIMPLEMENTED, // RedefineClasses
2078 UNIMPLEMENTED, // GetVersionNumber
2079 UNIMPLEMENTED, // GetCapabilities
2080 UNIMPLEMENTED, // GetSourceDebugExtension
2081 UNIMPLEMENTED, // IsMethodObsolete
2082 UNIMPLEMENTED, // SuspendThreadList
2083 UNIMPLEMENTED, // ResumeThreadList
2084 RESERVED, // reserved94
2085 RESERVED, // reserved95
2086 RESERVED, // reserved96
2087 RESERVED, // reserved97
2088 RESERVED, // reserved98
2089 RESERVED, // reserved99
2090 UNIMPLEMENTED, // GetAllStackTraces
2091 UNIMPLEMENTED, // GetThreadListStackTraces
2092 UNIMPLEMENTED, // GetThreadLocalStorage
2093 UNIMPLEMENTED, // SetThreadLocalStorage
2094 _Jv_JVMTI_GetStackTrace, // GetStackTrace
2095 RESERVED, // reserved105
2096 UNIMPLEMENTED, // GetTag
2097 UNIMPLEMENTED, // SetTag
2098 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
2099 UNIMPLEMENTED, // IterateOverObjectsReachable
2100 UNIMPLEMENTED, // IterateOverReachableObjects
2101 UNIMPLEMENTED, // IterateOverHeap
2102 UNIMPLEMENTED, // IterateOverInstanceOfClass
2103 RESERVED, // reserved113
2104 UNIMPLEMENTED, // GetObjectsWithTags
2105 RESERVED, // reserved115
2106 RESERVED, // reserved116
2107 RESERVED, // reserved117
2108 RESERVED, // reserved118
2109 RESERVED, // reserved119
2110 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
2111 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
2112 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
2113 UNIMPLEMENTED, // GenerateEvents
2114 UNIMPLEMENTED, // GetExtensionFunctions
2115 UNIMPLEMENTED, // GetExtensionEvents
2116 UNIMPLEMENTED, // SetExtensionEventCallback
2117 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
2118 _Jv_JVMTI_GetErrorName, // GetErrorName
2119 UNIMPLEMENTED, // GetJLocationFormat
2120 UNIMPLEMENTED, // GetSystemProperties
2121 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
2122 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
2123 UNIMPLEMENTED, // GetPhase
2124 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
2125 UNIMPLEMENTED, // GetCurrentThreadCpuTime
2126 UNIMPLEMENTED, // GetThreadCpuTimerInfo
2127 UNIMPLEMENTED, // GetThreadCpuTime
2128 UNIMPLEMENTED, // GetTimerInfo
2129 _Jv_JVMTI_GetTime, // GetTime
2130 UNIMPLEMENTED, // GetPotentialCapabilities
2131 RESERVED, // reserved141
2132 UNIMPLEMENTED, // AddCapabilities
2133 UNIMPLEMENTED, // RelinquishCapabilities
2134 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
2135 RESERVED, // reserved145
2136 RESERVED, // reserved146
2137 UNIMPLEMENTED, // GetEnvironmentLocalStorage
2138 UNIMPLEMENTED, // SetEnvironmentLocalStorage
2139 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
2140 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
2141 RESERVED, // reserved151
2142 RESERVED, // reserved152
2143 RESERVED, // reserved153
2144 _Jv_JVMTI_GetObjectSize // GetObjectSize
2147 _Jv_JVMTIEnv *
2148 _Jv_GetJVMTIEnv (void)
2150 _Jv_JVMTIEnv *env
2151 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
2152 env->p = &_Jv_JVMTI_Interface;
2153 struct jvmti_env_list *element
2154 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
2155 element->env = env;
2156 element->next = NULL;
2158 _envListLock->writeLock ()->lock ();
2159 if (_jvmtiEnvironments == NULL)
2160 _jvmtiEnvironments = element;
2161 else
2163 struct jvmti_env_list *e;
2164 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
2166 e->next = element;
2168 _envListLock->writeLock ()->unlock ();
2170 /* Mark JVMTI active. This is used to force the interpreter
2171 to use either debugging or non-debugging code. Once JVMTI
2172 has been enabled, the non-debug interpreter cannot be used. */
2173 JVMTI::enabled = true;
2174 return env;
2177 void
2178 _Jv_JVMTI_Init ()
2180 _jvmtiEnvironments = NULL;
2181 _envListLock
2182 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2184 // No environments, so this should set all JVMTI:: members to false
2185 check_enabled_events ();
2188 static void
2189 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
2191 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2193 #define GET_BOOLEAN_ARG(Name) \
2194 ARG (int, b); \
2195 jboolean Name = (b == 0) ? false : true
2197 #define GET_CHAR_ARG(Name) \
2198 ARG (int, c); \
2199 char Name = static_cast<char> (c)
2201 switch (type)
2203 case JVMTI_EVENT_VM_INIT:
2204 if (env->callbacks.VMInit != NULL)
2206 ARG (JNIEnv *, jni_env);
2207 env->callbacks.VMInit (env, jni_env, event_thread);
2209 break;
2211 case JVMTI_EVENT_VM_DEATH:
2212 if (env->callbacks.VMDeath != NULL)
2214 ARG (JNIEnv *, jni_env);
2215 env->callbacks.VMDeath (env, jni_env);
2217 break;
2219 case JVMTI_EVENT_THREAD_START:
2220 if (env->callbacks.ThreadStart != NULL)
2222 ARG (JNIEnv *, jni_env);
2223 env->callbacks.ThreadStart (env, jni_env, event_thread);
2225 break;
2227 case JVMTI_EVENT_THREAD_END:
2228 if (env->callbacks.ThreadEnd != NULL)
2230 ARG (JNIEnv *, jni_env);
2231 env->callbacks.ThreadEnd (env, jni_env, event_thread);
2233 break;
2235 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
2236 if (env->callbacks.ClassFileLoadHook != NULL)
2238 ARG (JNIEnv *, jni_env);
2239 ARG (jclass, class_being_redefined);
2240 ARG (jobject, loader);
2241 ARG (const char *, name);
2242 ARG (jobject, protection_domain);
2243 ARG (jint, class_data_len);
2244 ARG (const unsigned char *, class_data);
2245 ARG (jint *, new_class_data_len);
2246 ARG (unsigned char **, new_class_data);
2247 env->callbacks.ClassFileLoadHook (env, jni_env,
2248 class_being_redefined, loader,
2249 name, protection_domain,
2250 class_data_len, class_data,
2251 new_class_data_len,
2252 new_class_data);
2254 break;
2256 case JVMTI_EVENT_CLASS_LOAD:
2257 if (env->callbacks.ClassLoad != NULL)
2259 ARG (JNIEnv *, jni_env);
2260 ARG (jclass, klass);
2261 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
2263 break;
2265 case JVMTI_EVENT_CLASS_PREPARE:
2266 if (env->callbacks.ClassPrepare != NULL)
2268 ARG (JNIEnv *, jni_env);
2269 ARG (jclass, klass);
2270 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
2272 break;
2274 case JVMTI_EVENT_VM_START:
2275 if (env->callbacks.VMStart != NULL)
2277 ARG (JNIEnv *, jni_env);
2278 env->callbacks.VMStart (env, jni_env);
2280 break;
2282 case JVMTI_EVENT_EXCEPTION:
2283 if (env->callbacks.Exception != NULL)
2285 ARG (JNIEnv *, jni_env);
2286 ARG (jmethodID, method);
2287 ARG (jlocation, location);
2288 ARG (jobject, exception);
2289 ARG (jmethodID, catch_method);
2290 ARG (jlocation, catch_location);
2291 env->callbacks.Exception (env, jni_env, event_thread, method,
2292 location, exception, catch_method,
2293 catch_location);
2295 break;
2297 case JVMTI_EVENT_EXCEPTION_CATCH:
2298 if (env->callbacks.ExceptionCatch != NULL)
2300 ARG (JNIEnv *, jni_env);
2301 ARG (jmethodID, method);
2302 ARG (jlocation, location);
2303 ARG (jobject, exception);
2304 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
2305 location, exception);
2307 break;
2309 case JVMTI_EVENT_SINGLE_STEP:
2310 if (env->callbacks.SingleStep != NULL)
2312 ARG (JNIEnv *, jni_env);
2313 ARG (jmethodID, method);
2314 ARG (jlocation, location);
2315 env->callbacks.SingleStep (env, jni_env, event_thread, method,
2316 location);
2318 break;
2320 case JVMTI_EVENT_FRAME_POP:
2321 if (env->callbacks.FramePop != NULL)
2323 ARG (JNIEnv *, jni_env);
2324 ARG (jmethodID, method);
2325 GET_BOOLEAN_ARG (was_popped_by_exception);
2326 env->callbacks.FramePop (env, jni_env, event_thread, method,
2327 was_popped_by_exception);
2329 break;
2331 case JVMTI_EVENT_BREAKPOINT:
2332 if (env->callbacks.Breakpoint != NULL)
2334 ARG (JNIEnv *, jni_env);
2335 ARG (jmethodID, method);
2336 ARG (jlocation, location);
2337 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
2338 location);
2340 break;
2342 case JVMTI_EVENT_FIELD_ACCESS:
2343 if (env->callbacks.FieldAccess != NULL)
2345 ARG (JNIEnv *, jni_env);
2346 ARG (jmethodID, method);
2347 ARG (jlocation, location);
2348 ARG (jclass, field_class);
2349 ARG (jobject, object);
2350 ARG (jfieldID, field);
2351 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
2352 location, field_class, object, field);
2354 break;
2356 case JVMTI_EVENT_FIELD_MODIFICATION:
2357 if (env->callbacks.FieldModification != NULL)
2359 ARG (JNIEnv *, jni_env);
2360 ARG (jmethodID, method);
2361 ARG (jlocation, location);
2362 ARG (jclass, field_class);
2363 ARG (jobject, object);
2364 ARG (jfieldID, field);
2365 GET_CHAR_ARG (signature_type);
2366 ARG (jvalue, new_value);
2367 env->callbacks.FieldModification (env, jni_env, event_thread, method,
2368 location, field_class, object,
2369 field, signature_type, new_value);
2371 break;
2373 case JVMTI_EVENT_METHOD_ENTRY:
2374 if (env->callbacks.MethodEntry != NULL)
2376 ARG (JNIEnv *, jni_env);
2377 ARG (jmethodID, method);
2378 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
2380 break;
2382 case JVMTI_EVENT_METHOD_EXIT:
2383 if (env->callbacks.MethodExit != NULL)
2385 ARG (JNIEnv *, jni_env);
2386 ARG (jmethodID, method);
2387 GET_BOOLEAN_ARG (was_popped_by_exception);
2388 ARG (jvalue, return_value);
2389 env->callbacks.MethodExit (env, jni_env, event_thread, method,
2390 was_popped_by_exception, return_value);
2392 break;
2394 case JVMTI_EVENT_NATIVE_METHOD_BIND:
2395 if (env->callbacks.NativeMethodBind != NULL)
2397 ARG (JNIEnv *, jni_env);
2398 ARG (jmethodID, method);
2399 ARG (void *, address);
2400 ARG (void **, new_address_ptr);
2401 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
2402 address, new_address_ptr);
2404 break;
2406 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
2407 if (env->callbacks.CompiledMethodLoad != NULL)
2409 ARG (jmethodID, method);
2410 ARG (jint, code_size);
2411 ARG (const void *, code_addr);
2412 ARG (jint, map_length);
2413 ARG (const jvmtiAddrLocationMap *, map);
2414 ARG (const void *, compile_info);
2415 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
2416 map_length, map, compile_info);
2418 break;
2420 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
2421 if (env->callbacks.CompiledMethodUnload != NULL)
2423 ARG (jmethodID, method);
2424 ARG (const void *, code_addr);
2425 env->callbacks.CompiledMethodUnload (env, method, code_addr);
2427 break;
2429 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
2430 if (env->callbacks.DynamicCodeGenerated != NULL)
2432 ARG (const char *, name);
2433 ARG (const void *, address);
2434 ARG (jint, length);
2435 env->callbacks.DynamicCodeGenerated (env, name, address, length);
2437 break;
2439 case JVMTI_EVENT_DATA_DUMP_REQUEST:
2440 if (env->callbacks.DataDumpRequest != NULL)
2442 env->callbacks.DataDumpRequest (env);
2444 break;
2446 case JVMTI_EVENT_MONITOR_WAIT:
2447 if (env->callbacks.MonitorWait != NULL)
2449 ARG (JNIEnv *, jni_env);
2450 ARG (jobject, object);
2451 ARG (jlong, timeout);
2452 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
2453 timeout);
2455 break;
2457 case JVMTI_EVENT_MONITOR_WAITED:
2458 if (env->callbacks.MonitorWaited != NULL)
2460 ARG (JNIEnv *, jni_env);
2461 ARG (jobject, object);
2462 GET_BOOLEAN_ARG (timed_out);
2463 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
2464 timed_out);
2466 break;
2468 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2469 if (env->callbacks.MonitorContendedEnter != NULL)
2471 ARG (JNIEnv *, jni_env);
2472 ARG (jobject, object);
2473 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
2474 object);
2476 break;
2478 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2479 if (env->callbacks.MonitorContendedEntered != NULL)
2481 ARG (JNIEnv *, jni_env);
2482 ARG (jobject, object);
2483 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
2484 object);
2486 break;
2488 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
2489 if (env->callbacks.GarbageCollectionStart != NULL)
2491 env->callbacks.GarbageCollectionStart (env);
2493 break;
2495 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2496 if (env->callbacks.GarbageCollectionFinish != NULL)
2498 env->callbacks.GarbageCollectionFinish (env);
2500 break;
2502 case JVMTI_EVENT_OBJECT_FREE:
2503 if (env->callbacks.ObjectFree != NULL)
2505 ARG (jlong, tag);
2506 env->callbacks.ObjectFree (env, tag);
2508 break;
2510 case JVMTI_EVENT_VM_OBJECT_ALLOC:
2511 if (env->callbacks.VMObjectAlloc != NULL)
2513 ARG (JNIEnv *, jni_env);
2514 ARG (jobject, object);
2515 ARG (jclass, object_class);
2516 ARG (jlong, size);
2517 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2518 object, object_class, size);
2520 break;
2522 default:
2523 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2524 (int) type);
2525 break;
2527 va_end (args);
2528 #undef ARG
2529 #undef GET_BOOLEAN_ARG
2530 #undef GET_CHAR_ARG
2533 /* Post an event to requesting JVMTI environments
2535 * This function should not be called without consulting the
2536 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2537 * harm (other than kill speed), since this function will still
2538 * only send the event if it was properly requested by an environment.
2540 void
2541 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2543 va_list args;
2544 va_start (args, event_thread);
2546 _envListLock->readLock ()->lock ();
2547 struct jvmti_env_list *e;
2548 FOREACH_ENVIRONMENT (e)
2550 /* Events are only posted if the event was explicitly enabled,
2551 it has a registered event handler, and the event thread
2552 matches (either globally or restricted to a specific thread).
2553 Here we check all but the event handler, which will be handled
2554 by post_event. */
2555 if (e->env->enabled[EVENT_INDEX(type)]
2556 && (e->env->thread[EVENT_INDEX(type)] == NULL
2557 || e->env->thread[EVENT_INDEX(type)] == event_thread))
2559 post_event (e->env, type, event_thread, args);
2562 _envListLock->readLock ()->unlock ();
2563 va_end (args);