2007-03-01 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / libjava / jvmti.cc
blobfaa7401c1ce98bc01029bfc05221194c83b9d722
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 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
1001 reinterpret_cast<unsigned char **>
1002 (&(*locals)[table_slot].name));
1003 if (jerr != JVMTI_ERROR_NONE)
1004 return jerr;
1005 strcpy ((*locals)[table_slot].name, name);
1007 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
1008 reinterpret_cast<unsigned char **>
1009 (&(*locals)[table_slot].signature));
1010 if (jerr != JVMTI_ERROR_NONE)
1011 return jerr;
1012 strcpy ((*locals)[table_slot].signature, sig);
1014 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
1015 reinterpret_cast<unsigned char **>
1016 (&(*locals)[table_slot].generic_signature));
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')
1114 num_slots+=2;
1115 else if (sig[i] == 'L')
1117 num_slots++;
1118 while (sig[i] != ';')
1119 i++;
1123 *size = num_slots;
1124 return JVMTI_ERROR_NONE;
1127 static jvmtiError JNICALL
1128 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
1129 jmethodID method,
1130 jclass *declaring_class_ptr)
1132 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1133 NULL_CHECK (declaring_class_ptr);
1135 jclass klass = _Jv_GetMethodDeclaringClass (method);
1136 if (klass != NULL)
1138 *declaring_class_ptr = klass;
1139 return JVMTI_ERROR_NONE;
1142 return JVMTI_ERROR_INVALID_METHODID;
1145 static jvmtiError JNICALL
1146 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
1147 jobject init_loader,
1148 jint *count_ptr,
1149 jclass **result_ptr)
1151 using namespace java::lang;
1152 using namespace java::util;
1154 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1155 NULL_CHECK (count_ptr);
1156 NULL_CHECK (result_ptr);
1158 ClassLoader *loader = (ClassLoader *) init_loader;
1159 if (loader == NULL)
1160 loader = VMClassLoader::bootLoader;
1162 Collection *values = loader->loadedClasses->values();
1163 jobjectArray array = values->toArray();
1164 *count_ptr = array->length;
1165 jobject *elts = elements (array);
1166 jclass *result
1167 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
1168 if (result == NULL)
1169 return JVMTI_ERROR_OUT_OF_MEMORY;
1171 // FIXME: JNI references...
1172 memcpy (result, elts, *count_ptr * sizeof (jclass));
1174 *result_ptr = result;
1176 return JVMTI_ERROR_NONE;
1179 static jvmtiError JNICALL
1180 _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
1181 jint start_depth, jint max_frames,
1182 jvmtiFrameInfo *frames, jint *frame_count)
1184 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1186 ILLEGAL_ARGUMENT (max_frames < 0);
1188 NULL_CHECK (frames);
1189 NULL_CHECK (frame_count);
1191 using namespace java::lang;
1193 THREAD_DEFAULT_TO_CURRENT (thread);
1194 THREAD_CHECK_VALID (thread);
1195 THREAD_CHECK_IS_ALIVE (thread);
1197 jvmtiError jerr = env->GetFrameCount (thread, frame_count);
1198 if (jerr != JVMTI_ERROR_NONE)
1199 return jerr;
1201 // start_depth can be either a positive number, indicating the depth of the
1202 // stack at which to begin the trace, or a negative number indicating the
1203 // number of frames at the bottom of the stack to exclude. These checks
1204 // ensure that it is a valid value in either case
1206 ILLEGAL_ARGUMENT (start_depth >= (*frame_count));
1207 ILLEGAL_ARGUMENT (start_depth < (-(*frame_count)));
1209 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
1211 // If start_depth is negative use this to determine at what depth to start
1212 // the trace by adding it to the length of the call stack. This allows the
1213 // use of the same frame "discarding" mechanism as for a positive start_depth
1214 if (start_depth < 0)
1215 start_depth = *frame_count + start_depth;
1217 // If start_depth > 0 "remove" start_depth frames from the beginning
1218 // of the stack before beginning the trace by moving along the frame list.
1219 while (start_depth > 0)
1221 frame = frame->next;
1222 start_depth--;
1223 (*frame_count)--;
1226 // Now check to see if the array supplied by the agent is large enough to
1227 // hold frame_count frames, after adjustment for start_depth.
1228 if ((*frame_count) > max_frames)
1229 (*frame_count) = max_frames;
1231 for (int i = 0; i < (*frame_count); i++)
1233 frames[i].method = frame->self->get_method ();
1235 // Set the location in the frame, native frames have location = -1
1236 if (frame->frame_type == frame_interpreter)
1238 _Jv_InterpMethod *imeth
1239 = static_cast<_Jv_InterpMethod *> (frame->self);
1240 _Jv_InterpFrame *interp_frame
1241 = static_cast<_Jv_InterpFrame *> (frame);
1242 frames[i].location = imeth->insn_index (interp_frame->pc);
1244 else
1245 frames[i].location = -1;
1247 frame = frame->next;
1250 return JVMTI_ERROR_NONE;
1253 static jvmtiError JNICALL
1254 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
1256 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1257 _Jv_RunGC();
1258 return JVMTI_ERROR_NONE;
1261 static jvmtiError JNICALL
1262 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
1263 const jniNativeInterface *function_table)
1265 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1266 NULL_CHECK (function_table);
1267 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
1268 return JVMTI_ERROR_NONE;
1271 static jvmtiError JNICALL
1272 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
1273 jniNativeInterface **function_table)
1275 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1276 NULL_CHECK (function_table);
1277 *function_table
1278 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
1279 if (*function_table == NULL)
1280 return JVMTI_ERROR_OUT_OF_MEMORY;
1281 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
1282 return JVMTI_ERROR_NONE;
1285 static jvmtiError JNICALL
1286 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
1288 NULL_CHECK (env);
1290 if (_jvmtiEnvironments == NULL)
1291 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1292 else
1294 _envListLock->writeLock ()->lock ();
1295 if (_jvmtiEnvironments->env == env)
1297 struct jvmti_env_list *next = _jvmtiEnvironments->next;
1298 _Jv_Free (_jvmtiEnvironments);
1299 _jvmtiEnvironments = next;
1301 else
1303 struct jvmti_env_list *e = _jvmtiEnvironments;
1304 while (e->next != NULL && e->next->env != env)
1305 e = e->next;
1306 if (e->next == NULL)
1308 _envListLock->writeLock ()->unlock ();
1309 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1312 struct jvmti_env_list *next = e->next->next;
1313 _Jv_Free (e->next);
1314 e->next = next;
1316 _envListLock->writeLock ()->unlock ();
1319 _Jv_Free (env);
1321 check_enabled_events ();
1323 return JVMTI_ERROR_NONE;
1326 static jvmtiError JNICALL
1327 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1328 char **result)
1330 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1331 NULL_CHECK (property);
1332 NULL_CHECK (result);
1334 jstring name = JvNewStringUTF(property);
1335 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
1337 if (result_str == NULL)
1338 return JVMTI_ERROR_NOT_AVAILABLE;
1340 int len = JvGetStringUTFLength (result_str);
1341 *result = (char *) _Jv_MallocUnchecked (len + 1);
1342 if (*result == NULL)
1343 return JVMTI_ERROR_OUT_OF_MEMORY;
1344 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
1345 (*result)[len] = '\0';
1347 return JVMTI_ERROR_NONE;
1350 static jvmtiError JNICALL
1351 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
1352 const char *value)
1354 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1356 NULL_CHECK (property);
1357 if (value == NULL)
1359 // FIXME: When would a property not be writeable?
1360 return JVMTI_ERROR_NONE;
1363 jstring prop_str = JvNewStringUTF(property);
1364 jstring value_str = JvNewStringUTF(value);
1365 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
1366 return JVMTI_ERROR_NONE;
1369 static jvmtiError JNICALL
1370 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
1372 NULL_CHECK (nanos_ptr);
1373 *nanos_ptr = _Jv_platform_nanotime();
1374 return JVMTI_ERROR_NONE;
1377 static jvmtiError JNICALL
1378 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
1379 jint *nprocessors_ptr)
1381 NULL_CHECK (nprocessors_ptr);
1382 #ifdef _SC_NPROCESSORS_ONLN
1383 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
1384 #else
1385 *nprocessors_ptr = 1;
1386 #endif
1387 return JVMTI_ERROR_NONE;
1390 static jvmtiError JNICALL
1391 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
1392 const char *segment)
1394 using namespace java::lang;
1395 using namespace java::net;
1396 using namespace gnu::gcj::runtime;
1398 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
1399 NULL_CHECK (segment);
1401 jstring str_segment = JvNewStringUTF(segment);
1402 URL *url;
1405 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
1407 catch (jthrowable ignore)
1409 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1412 BootClassLoader *loader = VMClassLoader::bootLoader;
1413 // Don't call this too early.
1414 // assert (loader != NULL);
1415 loader->addURL(url);
1416 return JVMTI_ERROR_NONE;
1419 static jvmtiError JNICALL
1420 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
1421 jboolean value)
1423 switch (flag)
1425 case JVMTI_VERBOSE_OTHER:
1426 case JVMTI_VERBOSE_GC:
1427 case JVMTI_VERBOSE_JNI:
1428 // Ignore.
1429 break;
1430 case JVMTI_VERBOSE_CLASS:
1431 gcj::verbose_class_flag = value;
1432 break;
1433 default:
1434 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1436 return JVMTI_ERROR_NONE;
1439 static jvmtiError JNICALL
1440 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
1441 jlong *result)
1443 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1444 if (object == NULL)
1445 return JVMTI_ERROR_INVALID_OBJECT;
1446 NULL_CHECK (result);
1448 jclass klass = object->getClass();
1449 if (klass->isArray())
1451 jclass comp = klass->getComponentType();
1452 jint base
1453 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
1454 klass->getComponentType());
1455 // FIXME: correct for primitive types?
1456 jint compSize = comp->size();
1457 __JArray *array = (__JArray *) object;
1458 *result = base + array->length * compSize;
1460 else
1462 // Note that if OBJECT is a String then it may (if
1463 // str->data==str) take more space. Do we care?
1464 *result = klass->size();
1466 return JVMTI_ERROR_NONE;
1469 /* An event is enabled only if it has both an event handler
1470 and it is enabled in the environment. */
1471 static void
1472 check_enabled_event (jvmtiEvent type)
1474 bool *enabled;
1475 int offset;
1477 #define GET_OFFSET(Event) \
1478 do \
1480 enabled = &JVMTI::Event; \
1481 offset = offsetof (jvmtiEventCallbacks, Event); \
1483 while (0)
1485 switch (type)
1487 case JVMTI_EVENT_VM_INIT:
1488 GET_OFFSET (VMInit);
1489 break;
1491 case JVMTI_EVENT_VM_DEATH:
1492 GET_OFFSET (VMDeath);
1493 break;
1495 case JVMTI_EVENT_THREAD_START:
1496 GET_OFFSET (ThreadStart);
1497 break;
1499 case JVMTI_EVENT_THREAD_END:
1500 GET_OFFSET (ThreadEnd);
1501 break;
1503 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1504 GET_OFFSET (ClassFileLoadHook);
1505 break;
1507 case JVMTI_EVENT_CLASS_LOAD:
1508 GET_OFFSET (ClassLoad);
1509 break;
1511 case JVMTI_EVENT_CLASS_PREPARE:
1512 GET_OFFSET (ClassPrepare);
1513 break;
1515 case JVMTI_EVENT_VM_START:
1516 GET_OFFSET (VMStart);
1517 break;
1519 case JVMTI_EVENT_EXCEPTION:
1520 GET_OFFSET (Exception);
1521 break;
1523 case JVMTI_EVENT_EXCEPTION_CATCH:
1524 GET_OFFSET (ExceptionCatch);
1525 break;
1527 case JVMTI_EVENT_SINGLE_STEP:
1528 GET_OFFSET (SingleStep);
1529 break;
1531 case JVMTI_EVENT_FRAME_POP:
1532 GET_OFFSET (FramePop);
1533 break;
1535 case JVMTI_EVENT_BREAKPOINT:
1536 GET_OFFSET (Breakpoint);
1537 break;
1539 case JVMTI_EVENT_FIELD_ACCESS:
1540 GET_OFFSET (FieldAccess);
1541 break;
1543 case JVMTI_EVENT_FIELD_MODIFICATION:
1544 GET_OFFSET (FieldModification);
1545 break;
1547 case JVMTI_EVENT_METHOD_ENTRY:
1548 GET_OFFSET (MethodEntry);
1549 break;
1551 case JVMTI_EVENT_METHOD_EXIT:
1552 GET_OFFSET (MethodExit);
1553 break;
1555 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1556 GET_OFFSET (NativeMethodBind);
1557 break;
1559 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1560 GET_OFFSET (CompiledMethodLoad);
1561 break;
1563 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1564 GET_OFFSET (CompiledMethodUnload);
1565 break;
1567 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1568 GET_OFFSET (DynamicCodeGenerated);
1569 break;
1571 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1572 GET_OFFSET (DataDumpRequest);
1573 break;
1575 case JVMTI_EVENT_MONITOR_WAIT:
1576 GET_OFFSET (MonitorWait);
1577 break;
1579 case JVMTI_EVENT_MONITOR_WAITED:
1580 GET_OFFSET (MonitorWaited);
1581 break;
1583 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1584 GET_OFFSET (MonitorContendedEnter);
1585 break;
1587 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1588 GET_OFFSET (MonitorContendedEntered);
1589 break;
1591 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1592 GET_OFFSET (GarbageCollectionStart);
1593 break;
1595 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1596 GET_OFFSET (GarbageCollectionFinish);
1597 break;
1599 case JVMTI_EVENT_OBJECT_FREE:
1600 GET_OFFSET (ObjectFree);
1601 break;
1603 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1604 GET_OFFSET (VMObjectAlloc);
1605 break;
1607 default:
1608 fprintf (stderr,
1609 "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1610 (int) type);
1611 return;
1613 #undef GET_OFFSET
1615 int index = EVENT_INDEX (type); // safe since caller checks this
1617 if (_jvmtiEnvironments != NULL)
1619 _envListLock->readLock ()->lock ();
1620 struct jvmti_env_list *e;
1621 FOREACH_ENVIRONMENT (e)
1623 char *addr
1624 = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1625 void **callback = reinterpret_cast<void **> (addr);
1626 if (e->env->enabled[index] && *callback != NULL)
1628 *enabled = true;
1629 _envListLock->readLock ()->unlock ();
1630 return;
1634 _envListLock->readLock ()->unlock ();
1637 *enabled = false;
1640 static void
1641 check_enabled_events ()
1643 check_enabled_event (JVMTI_EVENT_VM_INIT);
1644 check_enabled_event (JVMTI_EVENT_VM_DEATH);
1645 check_enabled_event (JVMTI_EVENT_THREAD_START);
1646 check_enabled_event (JVMTI_EVENT_THREAD_END);
1647 check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1648 check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1649 check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1650 check_enabled_event (JVMTI_EVENT_VM_START);
1651 check_enabled_event (JVMTI_EVENT_EXCEPTION);
1652 check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1653 check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1654 check_enabled_event (JVMTI_EVENT_FRAME_POP);
1655 check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1656 check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1657 check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1658 check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1659 check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1660 check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1661 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1662 check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1663 check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1664 check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1665 check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1666 check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1667 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1668 check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1669 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1670 check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1671 check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1672 check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1675 static jvmtiError JNICALL
1676 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1677 jvmtiEvent type, jthread event_thread, ...)
1679 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1681 if (event_thread != NULL)
1683 THREAD_CHECK_VALID (event_thread);
1684 THREAD_CHECK_IS_ALIVE (event_thread);
1687 bool enabled;
1688 switch (mode)
1690 case JVMTI_DISABLE:
1691 enabled = false;
1692 break;
1693 case JVMTI_ENABLE:
1694 enabled = true;
1695 break;
1697 default:
1698 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1701 switch (type)
1703 case JVMTI_EVENT_VM_INIT:
1704 case JVMTI_EVENT_VM_DEATH:
1705 case JVMTI_EVENT_THREAD_START:
1706 case JVMTI_EVENT_VM_START:
1707 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1708 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1709 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1710 case JVMTI_EVENT_DATA_DUMP_REQUEST:
1711 ILLEGAL_ARGUMENT (event_thread != NULL);
1712 break;
1714 case JVMTI_EVENT_THREAD_END:
1715 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1716 case JVMTI_EVENT_CLASS_LOAD:
1717 case JVMTI_EVENT_CLASS_PREPARE:
1718 case JVMTI_EVENT_EXCEPTION:
1719 case JVMTI_EVENT_EXCEPTION_CATCH:
1720 case JVMTI_EVENT_SINGLE_STEP:
1721 case JVMTI_EVENT_FRAME_POP:
1722 case JVMTI_EVENT_BREAKPOINT:
1723 case JVMTI_EVENT_FIELD_ACCESS:
1724 case JVMTI_EVENT_FIELD_MODIFICATION:
1725 case JVMTI_EVENT_METHOD_ENTRY:
1726 case JVMTI_EVENT_METHOD_EXIT:
1727 case JVMTI_EVENT_NATIVE_METHOD_BIND:
1728 case JVMTI_EVENT_MONITOR_WAIT:
1729 case JVMTI_EVENT_MONITOR_WAITED:
1730 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1731 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1732 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1733 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1734 case JVMTI_EVENT_OBJECT_FREE:
1735 case JVMTI_EVENT_VM_OBJECT_ALLOC:
1736 break;
1738 default:
1739 return JVMTI_ERROR_INVALID_EVENT_TYPE;
1742 env->thread[EVENT_INDEX(type)] = event_thread;
1743 env->enabled[EVENT_INDEX(type)] = enabled;
1744 check_enabled_event (type);
1745 return JVMTI_ERROR_NONE;
1748 static jvmtiError JNICALL
1749 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1750 const jvmtiEventCallbacks *callbacks,
1751 jint size_of_callbacks)
1753 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1754 ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1756 // Copy the list of callbacks into the environment
1757 memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1759 /* Check which events are now enabeld (JVMTI makes no requirements
1760 about the order in which SetEventCallbacks and SetEventNotifications
1761 are called. So we must check all events here. */
1762 check_enabled_events ();
1764 return JVMTI_ERROR_NONE;
1767 static jvmtiError JNICALL
1768 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1769 char **name_ptr)
1771 NULL_CHECK (name_ptr);
1773 const char *name;
1774 switch (error)
1776 case JVMTI_ERROR_NONE:
1777 name = "none";
1778 break;
1780 case JVMTI_ERROR_NULL_POINTER:
1781 name = "null pointer";
1782 break;
1784 case JVMTI_ERROR_OUT_OF_MEMORY:
1785 name = "out of memory";
1786 break;
1788 case JVMTI_ERROR_ACCESS_DENIED:
1789 name = "access denied";
1790 break;
1792 case JVMTI_ERROR_WRONG_PHASE:
1793 name = "wrong phase";
1794 break;
1796 case JVMTI_ERROR_INTERNAL:
1797 name = "internal error";
1798 break;
1800 case JVMTI_ERROR_UNATTACHED_THREAD:
1801 name = "unattached thread";
1802 break;
1804 case JVMTI_ERROR_INVALID_ENVIRONMENT:
1805 name = "invalid environment";
1806 break;
1808 case JVMTI_ERROR_INVALID_PRIORITY:
1809 name = "invalid priority";
1810 break;
1812 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1813 name = "thread not suspended";
1814 break;
1816 case JVMTI_ERROR_THREAD_SUSPENDED:
1817 name = "thread suspended";
1818 break;
1820 case JVMTI_ERROR_THREAD_NOT_ALIVE:
1821 name = "thread not alive";
1822 break;
1824 case JVMTI_ERROR_CLASS_NOT_PREPARED:
1825 name = "class not prepared";
1826 break;
1828 case JVMTI_ERROR_NO_MORE_FRAMES:
1829 name = "no more frames";
1830 break;
1832 case JVMTI_ERROR_OPAQUE_FRAME:
1833 name = "opaque frame";
1834 break;
1836 case JVMTI_ERROR_DUPLICATE:
1837 name = "duplicate";
1838 break;
1840 case JVMTI_ERROR_NOT_FOUND:
1841 name = "not found";
1842 break;
1844 case JVMTI_ERROR_NOT_MONITOR_OWNER:
1845 name = "not monitor owner";
1846 break;
1848 case JVMTI_ERROR_INTERRUPT:
1849 name = "interrupted";
1850 break;
1852 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1853 name = "unmodifiable class";
1854 break;
1856 case JVMTI_ERROR_NOT_AVAILABLE:
1857 name = "not available";
1858 break;
1860 case JVMTI_ERROR_ABSENT_INFORMATION:
1861 name = "absent information";
1862 break;
1864 case JVMTI_ERROR_INVALID_EVENT_TYPE:
1865 name = "invalid event type";
1866 break;
1868 case JVMTI_ERROR_NATIVE_METHOD:
1869 name = "native method";
1870 break;
1872 case JVMTI_ERROR_INVALID_THREAD:
1873 name = "invalid thread";
1874 break;
1876 case JVMTI_ERROR_INVALID_THREAD_GROUP:
1877 name = "invalid thread group";
1878 break;
1880 case JVMTI_ERROR_INVALID_OBJECT:
1881 name = "invalid object";
1882 break;
1884 case JVMTI_ERROR_INVALID_CLASS:
1885 name = "invalid class";
1886 break;
1888 case JVMTI_ERROR_INVALID_METHODID:
1889 name = "invalid method ID";
1890 break;
1892 case JVMTI_ERROR_INVALID_LOCATION:
1893 name = "invalid location";
1894 break;
1896 case JVMTI_ERROR_INVALID_FIELDID:
1897 name = "invalid field ID";
1898 break;
1900 case JVMTI_ERROR_TYPE_MISMATCH:
1901 name = "type mismatch";
1902 break;
1904 case JVMTI_ERROR_INVALID_SLOT:
1905 name = "invalid slot";
1906 break;
1908 case JVMTI_ERROR_INVALID_MONITOR:
1909 name = "invalid monitor";
1910 break;
1912 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1913 name = "invalid class format";
1914 break;
1916 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1917 name = "circular class definition";
1918 break;
1920 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1921 name = "unsupported redefinition: method added";
1922 break;
1924 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1925 name = "unsupported redefinition: schema changed";
1926 break;
1928 case JVMTI_ERROR_INVALID_TYPESTATE:
1929 name = "invalid type state";
1930 break;
1932 case JVMTI_ERROR_FAILS_VERIFICATION:
1933 name = "fails verification";
1934 break;
1936 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1937 name = "unsupported redefinition: hierarchy changed";
1938 break;
1940 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1941 name = "unsupported redefinition: method deleted";
1942 break;
1944 case JVMTI_ERROR_UNSUPPORTED_VERSION:
1945 name = "unsupported version";
1946 break;
1948 case JVMTI_ERROR_NAMES_DONT_MATCH:
1949 name = "names do not match";
1950 break;
1952 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1953 name = "unsupported redefinition: class modifiers changed";
1954 break;
1956 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1957 name = "unsupported redefinition: method modifiers changed";
1958 break;
1960 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1961 name = "must possess capability";
1962 break;
1964 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1965 name = "illegal argument";
1966 break;
1968 default:
1969 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1972 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1973 if (*name_ptr == NULL)
1974 return JVMTI_ERROR_OUT_OF_MEMORY;
1976 strcpy (*name_ptr, name);
1977 return JVMTI_ERROR_NONE;
1980 #define RESERVED NULL
1981 #define UNIMPLEMENTED NULL
1983 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1985 RESERVED, // reserved1
1986 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1987 RESERVED, // reserved3
1988 _Jv_JVMTI_GetAllThreads, // GetAllThreads
1989 _Jv_JVMTI_SuspendThread, // SuspendThread
1990 _Jv_JVMTI_ResumeThread, // ResumeThread
1991 UNIMPLEMENTED, // StopThread
1992 _Jv_JVMTI_InterruptThread, // InterruptThread
1993 UNIMPLEMENTED, // GetThreadInfo
1994 UNIMPLEMENTED, // GetOwnedMonitorInfo
1995 UNIMPLEMENTED, // GetCurrentContendedMonitor
1996 UNIMPLEMENTED, // RunAgentThread
1997 UNIMPLEMENTED, // GetTopThreadGroups
1998 UNIMPLEMENTED, // GetThreadGroupInfo
1999 UNIMPLEMENTED, // GetThreadGroupChildren
2000 _Jv_JVMTI_GetFrameCount, // GetFrameCount
2001 UNIMPLEMENTED, // GetThreadState
2002 RESERVED, // reserved18
2003 UNIMPLEMENTED, // GetFrameLocation
2004 UNIMPLEMENTED, // NotifyPopFrame
2005 _Jv_JVMTI_GetLocalObject, // GetLocalObject
2006 _Jv_JVMTI_GetLocalInt, // GetLocalInt
2007 _Jv_JVMTI_GetLocalLong, // GetLocalLong
2008 _Jv_JVMTI_GetLocalFloat, // GetLocalFloat
2009 _Jv_JVMTI_GetLocalDouble, // GetLocalDouble
2010 _Jv_JVMTI_SetLocalObject, // SetLocalObject
2011 _Jv_JVMTI_SetLocalInt, // SetLocalInt
2012 _Jv_JVMTI_SetLocalLong, // SetLocalLong
2013 _Jv_JVMTI_SetLocalFloat, // SetLocalFloat
2014 _Jv_JVMTI_SetLocalDouble, // SetLocalDouble
2015 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
2016 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
2017 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
2018 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
2019 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
2020 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
2021 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
2022 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
2023 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
2024 RESERVED, // reserved40
2025 UNIMPLEMENTED, // SetFieldAccessWatch
2026 UNIMPLEMENTED, // ClearFieldAccessWatch
2027 UNIMPLEMENTED, // SetFieldModificationWatch
2028 UNIMPLEMENTED, // ClearFieldModificationWatch
2029 RESERVED, // reserved45
2030 _Jv_JVMTI_Allocate, // Allocate
2031 _Jv_JVMTI_Deallocate, // Deallocate
2032 UNIMPLEMENTED, // GetClassSignature
2033 _Jv_JVMTI_GetClassStatus, // GetClassStatus
2034 UNIMPLEMENTED, // GetSourceFileName
2035 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
2036 _Jv_JVMTI_GetClassMethods, // GetClassMethods
2037 UNIMPLEMENTED, // GetClassFields
2038 UNIMPLEMENTED, // GetImplementedInterfaces
2039 _Jv_JVMTI_IsInterface, // IsInterface
2040 _Jv_JVMTI_IsArrayClass, // IsArrayClass
2041 _Jv_JVMTI_GetClassLoader, // GetClassLoader
2042 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
2043 UNIMPLEMENTED, // GetObjectMonitorUsage
2044 UNIMPLEMENTED, // GetFieldName
2045 UNIMPLEMENTED, // GetFieldDeclaringClass
2046 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
2047 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
2048 _Jv_JVMTI_GetMethodName, // GetMethodName
2049 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
2050 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
2051 RESERVED, // reserved67
2052 _Jv_JVMTI_GetMaxLocals, // GetMaxLocals
2053 _Jv_JVMTI_GetArgumentsSize, // GetArgumentsSize
2054 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
2055 UNIMPLEMENTED, // GetMethodLocation
2056 _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable
2057 RESERVED, // reserved73
2058 RESERVED, // reserved74
2059 UNIMPLEMENTED, // GetBytecodes
2060 _Jv_JVMTI_IsMethodNative, // IsMethodNative
2061 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
2062 UNIMPLEMENTED, // GetLoadedClasses
2063 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
2064 UNIMPLEMENTED, // PopFrame
2065 RESERVED, // reserved81
2066 RESERVED, // reserved82
2067 RESERVED, // reserved83
2068 RESERVED, // reserved84
2069 RESERVED, // reserved85
2070 RESERVED, // reserved86
2071 UNIMPLEMENTED, // RedefineClasses
2072 UNIMPLEMENTED, // GetVersionNumber
2073 UNIMPLEMENTED, // GetCapabilities
2074 UNIMPLEMENTED, // GetSourceDebugExtension
2075 UNIMPLEMENTED, // IsMethodObsolete
2076 UNIMPLEMENTED, // SuspendThreadList
2077 UNIMPLEMENTED, // ResumeThreadList
2078 RESERVED, // reserved94
2079 RESERVED, // reserved95
2080 RESERVED, // reserved96
2081 RESERVED, // reserved97
2082 RESERVED, // reserved98
2083 RESERVED, // reserved99
2084 UNIMPLEMENTED, // GetAllStackTraces
2085 UNIMPLEMENTED, // GetThreadListStackTraces
2086 UNIMPLEMENTED, // GetThreadLocalStorage
2087 UNIMPLEMENTED, // SetThreadLocalStorage
2088 _Jv_JVMTI_GetStackTrace, // GetStackTrace
2089 RESERVED, // reserved105
2090 UNIMPLEMENTED, // GetTag
2091 UNIMPLEMENTED, // SetTag
2092 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
2093 UNIMPLEMENTED, // IterateOverObjectsReachable
2094 UNIMPLEMENTED, // IterateOverReachableObjects
2095 UNIMPLEMENTED, // IterateOverHeap
2096 UNIMPLEMENTED, // IterateOverInstanceOfClass
2097 RESERVED, // reserved113
2098 UNIMPLEMENTED, // GetObjectsWithTags
2099 RESERVED, // reserved115
2100 RESERVED, // reserved116
2101 RESERVED, // reserved117
2102 RESERVED, // reserved118
2103 RESERVED, // reserved119
2104 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
2105 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
2106 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
2107 UNIMPLEMENTED, // GenerateEvents
2108 UNIMPLEMENTED, // GetExtensionFunctions
2109 UNIMPLEMENTED, // GetExtensionEvents
2110 UNIMPLEMENTED, // SetExtensionEventCallback
2111 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
2112 _Jv_JVMTI_GetErrorName, // GetErrorName
2113 UNIMPLEMENTED, // GetJLocationFormat
2114 UNIMPLEMENTED, // GetSystemProperties
2115 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
2116 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
2117 UNIMPLEMENTED, // GetPhase
2118 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
2119 UNIMPLEMENTED, // GetCurrentThreadCpuTime
2120 UNIMPLEMENTED, // GetThreadCpuTimerInfo
2121 UNIMPLEMENTED, // GetThreadCpuTime
2122 UNIMPLEMENTED, // GetTimerInfo
2123 _Jv_JVMTI_GetTime, // GetTime
2124 UNIMPLEMENTED, // GetPotentialCapabilities
2125 RESERVED, // reserved141
2126 UNIMPLEMENTED, // AddCapabilities
2127 UNIMPLEMENTED, // RelinquishCapabilities
2128 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
2129 RESERVED, // reserved145
2130 RESERVED, // reserved146
2131 UNIMPLEMENTED, // GetEnvironmentLocalStorage
2132 UNIMPLEMENTED, // SetEnvironmentLocalStorage
2133 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
2134 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
2135 RESERVED, // reserved151
2136 RESERVED, // reserved152
2137 RESERVED, // reserved153
2138 _Jv_JVMTI_GetObjectSize // GetObjectSize
2141 _Jv_JVMTIEnv *
2142 _Jv_GetJVMTIEnv (void)
2144 _Jv_JVMTIEnv *env
2145 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
2146 env->p = &_Jv_JVMTI_Interface;
2147 struct jvmti_env_list *element
2148 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
2149 element->env = env;
2150 element->next = NULL;
2152 _envListLock->writeLock ()->lock ();
2153 if (_jvmtiEnvironments == NULL)
2154 _jvmtiEnvironments = element;
2155 else
2157 struct jvmti_env_list *e;
2158 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
2160 e->next = element;
2162 _envListLock->writeLock ()->unlock ();
2164 /* Mark JVMTI active. This is used to force the interpreter
2165 to use either debugging or non-debugging code. Once JVMTI
2166 has been enabled, the non-debug interpreter cannot be used. */
2167 JVMTI::enabled = true;
2168 return env;
2171 void
2172 _Jv_JVMTI_Init ()
2174 _jvmtiEnvironments = NULL;
2175 _envListLock
2176 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
2178 // No environments, so this should set all JVMTI:: members to false
2179 check_enabled_events ();
2182 static void
2183 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
2185 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2187 #define GET_BOOLEAN_ARG(Name) \
2188 ARG (int, b); \
2189 jboolean Name = (b == 0) ? false : true
2191 #define GET_CHAR_ARG(Name) \
2192 ARG (int, c); \
2193 char Name = static_cast<char> (c)
2195 switch (type)
2197 case JVMTI_EVENT_VM_INIT:
2198 if (env->callbacks.VMInit != NULL)
2200 ARG (JNIEnv *, jni_env);
2201 env->callbacks.VMInit (env, jni_env, event_thread);
2203 break;
2205 case JVMTI_EVENT_VM_DEATH:
2206 if (env->callbacks.VMDeath != NULL)
2208 ARG (JNIEnv *, jni_env);
2209 env->callbacks.VMDeath (env, jni_env);
2211 break;
2213 case JVMTI_EVENT_THREAD_START:
2214 if (env->callbacks.ThreadStart != NULL)
2216 ARG (JNIEnv *, jni_env);
2217 env->callbacks.ThreadStart (env, jni_env, event_thread);
2219 break;
2221 case JVMTI_EVENT_THREAD_END:
2222 if (env->callbacks.ThreadEnd != NULL)
2224 ARG (JNIEnv *, jni_env);
2225 env->callbacks.ThreadEnd (env, jni_env, event_thread);
2227 break;
2229 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
2230 if (env->callbacks.ClassFileLoadHook != NULL)
2232 ARG (JNIEnv *, jni_env);
2233 ARG (jclass, class_being_redefined);
2234 ARG (jobject, loader);
2235 ARG (const char *, name);
2236 ARG (jobject, protection_domain);
2237 ARG (jint, class_data_len);
2238 ARG (const unsigned char *, class_data);
2239 ARG (jint *, new_class_data_len);
2240 ARG (unsigned char **, new_class_data);
2241 env->callbacks.ClassFileLoadHook (env, jni_env,
2242 class_being_redefined, loader,
2243 name, protection_domain,
2244 class_data_len, class_data,
2245 new_class_data_len,
2246 new_class_data);
2248 break;
2250 case JVMTI_EVENT_CLASS_LOAD:
2251 if (env->callbacks.ClassLoad != NULL)
2253 ARG (JNIEnv *, jni_env);
2254 ARG (jclass, klass);
2255 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
2257 break;
2259 case JVMTI_EVENT_CLASS_PREPARE:
2260 if (env->callbacks.ClassPrepare != NULL)
2262 ARG (JNIEnv *, jni_env);
2263 ARG (jclass, klass);
2264 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
2266 break;
2268 case JVMTI_EVENT_VM_START:
2269 if (env->callbacks.VMStart != NULL)
2271 ARG (JNIEnv *, jni_env);
2272 env->callbacks.VMStart (env, jni_env);
2274 break;
2276 case JVMTI_EVENT_EXCEPTION:
2277 if (env->callbacks.Exception != NULL)
2279 ARG (JNIEnv *, jni_env);
2280 ARG (jmethodID, method);
2281 ARG (jlocation, location);
2282 ARG (jobject, exception);
2283 ARG (jmethodID, catch_method);
2284 ARG (jlocation, catch_location);
2285 env->callbacks.Exception (env, jni_env, event_thread, method,
2286 location, exception, catch_method,
2287 catch_location);
2289 break;
2291 case JVMTI_EVENT_EXCEPTION_CATCH:
2292 if (env->callbacks.ExceptionCatch != NULL)
2294 ARG (JNIEnv *, jni_env);
2295 ARG (jmethodID, method);
2296 ARG (jlocation, location);
2297 ARG (jobject, exception);
2298 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
2299 location, exception);
2301 break;
2303 case JVMTI_EVENT_SINGLE_STEP:
2304 if (env->callbacks.SingleStep != NULL)
2306 ARG (JNIEnv *, jni_env);
2307 ARG (jmethodID, method);
2308 ARG (jlocation, location);
2309 env->callbacks.SingleStep (env, jni_env, event_thread, method,
2310 location);
2312 break;
2314 case JVMTI_EVENT_FRAME_POP:
2315 if (env->callbacks.FramePop != NULL)
2317 ARG (JNIEnv *, jni_env);
2318 ARG (jmethodID, method);
2319 GET_BOOLEAN_ARG (was_popped_by_exception);
2320 env->callbacks.FramePop (env, jni_env, event_thread, method,
2321 was_popped_by_exception);
2323 break;
2325 case JVMTI_EVENT_BREAKPOINT:
2326 if (env->callbacks.Breakpoint != NULL)
2328 ARG (JNIEnv *, jni_env);
2329 ARG (jmethodID, method);
2330 ARG (jlocation, location);
2331 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
2332 location);
2334 break;
2336 case JVMTI_EVENT_FIELD_ACCESS:
2337 if (env->callbacks.FieldAccess != NULL)
2339 ARG (JNIEnv *, jni_env);
2340 ARG (jmethodID, method);
2341 ARG (jlocation, location);
2342 ARG (jclass, field_class);
2343 ARG (jobject, object);
2344 ARG (jfieldID, field);
2345 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
2346 location, field_class, object, field);
2348 break;
2350 case JVMTI_EVENT_FIELD_MODIFICATION:
2351 if (env->callbacks.FieldModification != NULL)
2353 ARG (JNIEnv *, jni_env);
2354 ARG (jmethodID, method);
2355 ARG (jlocation, location);
2356 ARG (jclass, field_class);
2357 ARG (jobject, object);
2358 ARG (jfieldID, field);
2359 GET_CHAR_ARG (signature_type);
2360 ARG (jvalue, new_value);
2361 env->callbacks.FieldModification (env, jni_env, event_thread, method,
2362 location, field_class, object,
2363 field, signature_type, new_value);
2365 break;
2367 case JVMTI_EVENT_METHOD_ENTRY:
2368 if (env->callbacks.MethodEntry != NULL)
2370 ARG (JNIEnv *, jni_env);
2371 ARG (jmethodID, method);
2372 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
2374 break;
2376 case JVMTI_EVENT_METHOD_EXIT:
2377 if (env->callbacks.MethodExit != NULL)
2379 ARG (JNIEnv *, jni_env);
2380 ARG (jmethodID, method);
2381 GET_BOOLEAN_ARG (was_popped_by_exception);
2382 ARG (jvalue, return_value);
2383 env->callbacks.MethodExit (env, jni_env, event_thread, method,
2384 was_popped_by_exception, return_value);
2386 break;
2388 case JVMTI_EVENT_NATIVE_METHOD_BIND:
2389 if (env->callbacks.NativeMethodBind != NULL)
2391 ARG (JNIEnv *, jni_env);
2392 ARG (jmethodID, method);
2393 ARG (void *, address);
2394 ARG (void **, new_address_ptr);
2395 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
2396 address, new_address_ptr);
2398 break;
2400 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
2401 if (env->callbacks.CompiledMethodLoad != NULL)
2403 ARG (jmethodID, method);
2404 ARG (jint, code_size);
2405 ARG (const void *, code_addr);
2406 ARG (jint, map_length);
2407 ARG (const jvmtiAddrLocationMap *, map);
2408 ARG (const void *, compile_info);
2409 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
2410 map_length, map, compile_info);
2412 break;
2414 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
2415 if (env->callbacks.CompiledMethodUnload != NULL)
2417 ARG (jmethodID, method);
2418 ARG (const void *, code_addr);
2419 env->callbacks.CompiledMethodUnload (env, method, code_addr);
2421 break;
2423 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
2424 if (env->callbacks.DynamicCodeGenerated != NULL)
2426 ARG (const char *, name);
2427 ARG (const void *, address);
2428 ARG (jint, length);
2429 env->callbacks.DynamicCodeGenerated (env, name, address, length);
2431 break;
2433 case JVMTI_EVENT_DATA_DUMP_REQUEST:
2434 if (env->callbacks.DataDumpRequest != NULL)
2436 env->callbacks.DataDumpRequest (env);
2438 break;
2440 case JVMTI_EVENT_MONITOR_WAIT:
2441 if (env->callbacks.MonitorWait != NULL)
2443 ARG (JNIEnv *, jni_env);
2444 ARG (jobject, object);
2445 ARG (jlong, timeout);
2446 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
2447 timeout);
2449 break;
2451 case JVMTI_EVENT_MONITOR_WAITED:
2452 if (env->callbacks.MonitorWaited != NULL)
2454 ARG (JNIEnv *, jni_env);
2455 ARG (jobject, object);
2456 GET_BOOLEAN_ARG (timed_out);
2457 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
2458 timed_out);
2460 break;
2462 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2463 if (env->callbacks.MonitorContendedEnter != NULL)
2465 ARG (JNIEnv *, jni_env);
2466 ARG (jobject, object);
2467 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
2468 object);
2470 break;
2472 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2473 if (env->callbacks.MonitorContendedEntered != NULL)
2475 ARG (JNIEnv *, jni_env);
2476 ARG (jobject, object);
2477 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
2478 object);
2480 break;
2482 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
2483 if (env->callbacks.GarbageCollectionStart != NULL)
2485 env->callbacks.GarbageCollectionStart (env);
2487 break;
2489 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2490 if (env->callbacks.GarbageCollectionFinish != NULL)
2492 env->callbacks.GarbageCollectionFinish (env);
2494 break;
2496 case JVMTI_EVENT_OBJECT_FREE:
2497 if (env->callbacks.ObjectFree != NULL)
2499 ARG (jlong, tag);
2500 env->callbacks.ObjectFree (env, tag);
2502 break;
2504 case JVMTI_EVENT_VM_OBJECT_ALLOC:
2505 if (env->callbacks.VMObjectAlloc != NULL)
2507 ARG (JNIEnv *, jni_env);
2508 ARG (jobject, object);
2509 ARG (jclass, object_class);
2510 ARG (jlong, size);
2511 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2512 object, object_class, size);
2514 break;
2516 default:
2517 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2518 (int) type);
2519 break;
2521 va_end (args);
2522 #undef ARG
2523 #undef GET_BOOLEAN_ARG
2524 #undef GET_CHAR_ARG
2527 /* Post an event to requesting JVMTI environments
2529 * This function should not be called without consulting the
2530 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2531 * harm (other than kill speed), since this function will still
2532 * only send the event if it was properly requested by an environment.
2534 void
2535 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2537 va_list args;
2538 va_start (args, event_thread);
2540 _envListLock->readLock ()->lock ();
2541 struct jvmti_env_list *e;
2542 FOREACH_ENVIRONMENT (e)
2544 /* Events are only posted if the event was explicitly enabled,
2545 it has a registered event handler, and the event thread
2546 matches (either globally or restricted to a specific thread).
2547 Here we check all but the event handler, which will be handled
2548 by post_event. */
2549 if (e->env->enabled[EVENT_INDEX(type)]
2550 && (e->env->thread[EVENT_INDEX(type)] == NULL
2551 || e->env->thread[EVENT_INDEX(type)] == event_thread))
2553 post_event (e->env, type, event_thread, args);
2556 _envListLock->readLock ()->unlock ();
2557 va_end (args);