OSDN Git Service

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