OSDN Git Service

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