OSDN Git Service

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