OSDN Git Service

f73298417470e8b3dff6f7c63dec20e11e702f0f
[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_GetMethodName (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
572                          char **name_ptr, char **signature_ptr,
573                          char **generic_ptr)
574 {
575   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
576
577   if (method == NULL)
578     return JVMTI_ERROR_INVALID_METHODID;
579
580   if (name_ptr != NULL)
581     {
582       int len = static_cast<int> (method->name->len ());
583       *name_ptr = (char *) _Jv_MallocUnchecked (len + 1);
584       if (*name_ptr == NULL)
585         return JVMTI_ERROR_OUT_OF_MEMORY;
586       strncpy (*name_ptr, method->name->chars (), len);
587       (*name_ptr)[len] = '\0';
588     }
589
590   if (signature_ptr != NULL)
591     {
592       int len = static_cast<int> (method->signature->len ());
593       *signature_ptr = (char *) _Jv_MallocUnchecked (len + 1);
594       if (*signature_ptr == NULL)
595         {
596           if (name_ptr != NULL)
597             _Jv_Free (*name_ptr);
598           return JVMTI_ERROR_OUT_OF_MEMORY;
599         }
600       strncpy (*signature_ptr, method->signature->chars (), len);
601       (*signature_ptr)[len] = '\0';
602     }
603
604   if (generic_ptr != NULL)
605     {
606       *generic_ptr = NULL;
607     }
608
609   return JVMTI_ERROR_NONE;
610 }
611
612 static jvmtiError JNICALL
613 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
614                               jint *result)
615 {
616   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
617   if (method == NULL)
618     return JVMTI_ERROR_INVALID_METHODID;
619   NULL_CHECK (result);
620
621   // FIXME: mask off some internal bits...
622   *result = method->accflags;
623   return JVMTI_ERROR_NONE;
624 }
625
626 static jvmtiError JNICALL
627 _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
628                               jint *entry_count_ptr,
629                               jvmtiLineNumberEntry **table_ptr)
630 {
631   NULL_CHECK (entry_count_ptr);
632   NULL_CHECK (table_ptr);
633
634   jclass klass;
635   jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
636   if (jerr != JVMTI_ERROR_NONE)
637     return jerr;
638
639   _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
640   if (base == NULL)
641     return JVMTI_ERROR_INVALID_METHODID;
642
643   if (java::lang::reflect::Modifier::isNative (method->accflags)
644       || !_Jv_IsInterpretedClass (klass))
645     return JVMTI_ERROR_NATIVE_METHOD;
646
647   _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
648   jlong start, end;
649   jintArray lines = NULL;
650   jlongArray indices = NULL;
651   imeth->get_line_table (start, end, lines, indices);
652   if (lines == NULL)
653     return JVMTI_ERROR_ABSENT_INFORMATION;
654
655   jvmtiLineNumberEntry *table;
656   jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
657   table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
658   if (table == NULL)
659     return JVMTI_ERROR_OUT_OF_MEMORY;
660   
661   jint *line = elements (lines);
662   jlong *index = elements (indices);
663   for (int i = 0; i < lines->length; ++i)
664     {
665       table[i].start_location = index[i];
666       table[i].line_number = line[i];
667     }
668
669   *table_ptr = table;
670   *entry_count_ptr = lines->length;
671   return JVMTI_ERROR_NONE;
672 }
673
674 static jvmtiError JNICALL
675 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
676                           jboolean *result)
677 {
678   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
679   if (method == NULL)
680     return JVMTI_ERROR_INVALID_METHODID;
681   NULL_CHECK (result);
682
683   *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
684   return JVMTI_ERROR_NONE;
685 }
686
687 static jvmtiError JNICALL
688 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
689                              jboolean *result)
690 {
691   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
692   if (method == NULL)
693     return JVMTI_ERROR_INVALID_METHODID;
694   NULL_CHECK (result);
695
696   // FIXME capability can_get_synthetic_attribute
697
698   *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
699              != 0);
700   return JVMTI_ERROR_NONE;
701 }
702
703 static jvmtiError JNICALL
704 _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
705                                    jmethodID method,
706                                    jclass *declaring_class_ptr)
707 {
708   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
709   NULL_CHECK (declaring_class_ptr);
710
711   jclass klass = _Jv_GetMethodDeclaringClass (method);
712   if (klass != NULL)
713     {
714       *declaring_class_ptr = klass;
715       return JVMTI_ERROR_NONE;
716     }
717
718   return JVMTI_ERROR_INVALID_METHODID;
719 }
720
721 static jvmtiError JNICALL
722 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
723                                  jobject init_loader,
724                                  jint *count_ptr,
725                                  jclass **result_ptr)
726 {
727   using namespace java::lang;
728   using namespace java::util;
729
730   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
731   NULL_CHECK (count_ptr);
732   NULL_CHECK (result_ptr);
733
734   ClassLoader *loader = (ClassLoader *) init_loader;
735   if (loader == NULL)
736     loader = VMClassLoader::bootLoader;
737
738   Collection *values = loader->loadedClasses->values();
739   jobjectArray array = values->toArray();
740   *count_ptr = array->length;
741   jobject *elts = elements (array);
742   jclass *result
743     = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
744   if (result == NULL)
745     return JVMTI_ERROR_OUT_OF_MEMORY;
746
747   // FIXME: JNI references...
748   memcpy (result, elts, *count_ptr * sizeof (jclass));
749
750   *result_ptr = result;
751
752   return JVMTI_ERROR_NONE;
753 }
754
755 static jvmtiError JNICALL
756 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
757 {
758   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
759   _Jv_RunGC();
760   return JVMTI_ERROR_NONE;
761 }
762
763 static jvmtiError JNICALL
764 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
765                                const jniNativeInterface *function_table)
766 {
767   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
768   NULL_CHECK (function_table);
769   memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
770   return JVMTI_ERROR_NONE;
771 }
772
773 static jvmtiError JNICALL
774 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
775                                jniNativeInterface **function_table)
776 {
777   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
778   NULL_CHECK (function_table);
779   *function_table
780     = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
781   if (*function_table == NULL)
782     return JVMTI_ERROR_OUT_OF_MEMORY;
783   memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
784   return JVMTI_ERROR_NONE;
785 }
786
787 static jvmtiError JNICALL
788 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
789 {
790   NULL_CHECK (env);
791
792   if (_jvmtiEnvironments == NULL)
793     return JVMTI_ERROR_INVALID_ENVIRONMENT;
794   else
795     {
796       JvSynchronize dummy (_envListLock);
797       if (_jvmtiEnvironments->env == env)
798         {
799           struct jvmti_env_list *next = _jvmtiEnvironments->next;
800           _Jv_Free (_jvmtiEnvironments);
801           _jvmtiEnvironments = next;
802         }
803       else
804         {
805           struct jvmti_env_list *e = _jvmtiEnvironments; 
806           while (e->next != NULL && e->next->env != env)
807             e = e->next;
808           if (e->next == NULL)
809             return JVMTI_ERROR_INVALID_ENVIRONMENT;
810
811           struct jvmti_env_list *next = e->next->next;
812           _Jv_Free (e->next);
813           e->next = next;
814         }
815     }
816
817   _Jv_Free (env);
818
819   check_enabled_events ();
820
821   return JVMTI_ERROR_NONE;
822 }
823
824 static jvmtiError JNICALL
825 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
826                              char **result)
827 {
828   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
829   NULL_CHECK (property);
830   NULL_CHECK (result);
831
832   jstring name = JvNewStringUTF(property);
833   jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
834
835   if (result_str == NULL)
836     return JVMTI_ERROR_NOT_AVAILABLE;
837
838   int len = JvGetStringUTFLength (result_str);
839   *result = (char *) _Jv_MallocUnchecked (len + 1);
840   if (*result == NULL)
841     return JVMTI_ERROR_OUT_OF_MEMORY;
842   JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
843   (*result)[len] = '\0';
844
845   return JVMTI_ERROR_NONE;
846 }
847
848 static jvmtiError JNICALL
849 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
850                              const char *value)
851 {
852   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
853
854   NULL_CHECK (property);
855   if (value == NULL)
856     {
857       // FIXME: When would a property not be writeable?
858       return JVMTI_ERROR_NONE;
859     }
860
861   jstring prop_str = JvNewStringUTF(property);
862   jstring value_str = JvNewStringUTF(value);
863   gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
864   return JVMTI_ERROR_NONE;
865 }
866
867 static jvmtiError JNICALL
868 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
869 {
870   NULL_CHECK (nanos_ptr);
871   *nanos_ptr = _Jv_platform_nanotime();
872   return JVMTI_ERROR_NONE;
873 }
874
875 static jvmtiError JNICALL
876 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
877                                   jint *nprocessors_ptr)
878 {
879   NULL_CHECK (nprocessors_ptr);
880 #ifdef _SC_NPROCESSORS_ONLN
881   *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
882 #else
883   *nprocessors_ptr = 1;
884 #endif
885   return JVMTI_ERROR_NONE;
886 }
887
888 static jvmtiError JNICALL
889 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
890                                            const char *segment)
891 {
892   using namespace java::lang;
893   using namespace java::net;
894   using namespace gnu::gcj::runtime;
895
896   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
897   NULL_CHECK (segment);
898
899   jstring str_segment = JvNewStringUTF(segment);
900   URL *url;
901   try
902     {
903       url = new URL(JvNewStringUTF("file"), NULL, str_segment);
904     }
905   catch (jthrowable ignore)
906     {
907       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
908     }
909
910   BootClassLoader *loader = VMClassLoader::bootLoader;
911   // Don't call this too early.
912   // assert (loader != NULL);
913   loader->addURL(url);
914   return JVMTI_ERROR_NONE;
915 }
916
917 static jvmtiError JNICALL
918 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
919                           jboolean value)
920 {
921   switch (flag)
922     {
923     case JVMTI_VERBOSE_OTHER:
924     case JVMTI_VERBOSE_GC:
925     case JVMTI_VERBOSE_JNI:
926       // Ignore.
927       break;
928     case JVMTI_VERBOSE_CLASS:
929       gcj::verbose_class_flag = value;
930       break;
931     default:
932       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
933     }
934   return JVMTI_ERROR_NONE;
935 }
936
937 static jvmtiError JNICALL
938 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
939                          jlong *result)
940 {
941   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
942   if (object == NULL)
943     return JVMTI_ERROR_INVALID_OBJECT;
944   NULL_CHECK (result);
945
946   jclass klass = object->getClass();
947   if (klass->isArray())
948     {
949       jclass comp = klass->getComponentType();
950       jint base
951         = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
952                                                                     klass->getComponentType());
953       // FIXME: correct for primitive types?
954       jint compSize = comp->size();
955       __JArray *array = (__JArray *) object;
956       *result = base + array->length * compSize;
957     }
958   else
959     {
960       // Note that if OBJECT is a String then it may (if
961       // str->data==str) take more space.  Do we care?
962       *result = klass->size();
963     }
964   return JVMTI_ERROR_NONE;
965 }
966
967 /* An event is enabled only if it has both an event handler
968    and it is enabled in the environment. */
969 static void
970 check_enabled_event (jvmtiEvent type)
971 {
972   bool *enabled;
973   int offset;
974
975 #define GET_OFFSET(Event)                               \
976   do                                                    \
977     {                                                   \
978       enabled = &JVMTI::Event;                          \
979       offset = offsetof (jvmtiEventCallbacks, Event);   \
980     }                                                   \
981   while (0)
982
983   switch (type)
984     {
985     case JVMTI_EVENT_VM_INIT:
986       GET_OFFSET (VMInit);
987       break;
988
989     case JVMTI_EVENT_VM_DEATH:
990       GET_OFFSET (VMDeath);
991       break;
992
993     case JVMTI_EVENT_THREAD_START:
994       GET_OFFSET (ThreadStart);
995       break;
996
997     case JVMTI_EVENT_THREAD_END:
998       GET_OFFSET (ThreadEnd);
999       break;
1000
1001     case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1002       GET_OFFSET (ClassFileLoadHook);
1003       break;
1004
1005     case JVMTI_EVENT_CLASS_LOAD:
1006       GET_OFFSET (ClassLoad);
1007       break;
1008
1009     case JVMTI_EVENT_CLASS_PREPARE:
1010       GET_OFFSET (ClassPrepare);
1011       break;
1012
1013     case JVMTI_EVENT_VM_START:
1014       GET_OFFSET (VMStart);
1015       break;
1016
1017     case JVMTI_EVENT_EXCEPTION:
1018       GET_OFFSET (Exception);
1019       break;
1020
1021     case JVMTI_EVENT_EXCEPTION_CATCH:
1022       GET_OFFSET (ExceptionCatch);
1023       break;
1024
1025     case JVMTI_EVENT_SINGLE_STEP:
1026       GET_OFFSET (SingleStep);
1027       break;
1028
1029     case JVMTI_EVENT_FRAME_POP:
1030       GET_OFFSET (FramePop);
1031       break;
1032
1033     case JVMTI_EVENT_BREAKPOINT:
1034       GET_OFFSET (Breakpoint);
1035       break;
1036
1037     case JVMTI_EVENT_FIELD_ACCESS:
1038       GET_OFFSET (FieldAccess);
1039       break;
1040
1041     case JVMTI_EVENT_FIELD_MODIFICATION:
1042       GET_OFFSET (FieldModification);
1043       break;
1044
1045     case JVMTI_EVENT_METHOD_ENTRY:
1046       GET_OFFSET (MethodEntry);
1047       break;
1048
1049     case JVMTI_EVENT_METHOD_EXIT:
1050       GET_OFFSET (MethodExit);
1051       break;
1052
1053     case JVMTI_EVENT_NATIVE_METHOD_BIND:
1054       GET_OFFSET (NativeMethodBind);
1055       break;
1056
1057     case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1058       GET_OFFSET (CompiledMethodLoad);
1059       break;
1060
1061     case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1062       GET_OFFSET (CompiledMethodUnload);
1063       break;
1064
1065     case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1066       GET_OFFSET (DynamicCodeGenerated);
1067       break;
1068
1069     case JVMTI_EVENT_DATA_DUMP_REQUEST:
1070       GET_OFFSET (DataDumpRequest);
1071       break;
1072
1073     case JVMTI_EVENT_MONITOR_WAIT:
1074       GET_OFFSET (MonitorWait);
1075       break;
1076
1077     case JVMTI_EVENT_MONITOR_WAITED:
1078       GET_OFFSET (MonitorWaited);
1079       break;
1080
1081     case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1082       GET_OFFSET (MonitorContendedEnter);
1083       break;
1084
1085     case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1086       GET_OFFSET (MonitorContendedEntered);
1087       break;
1088
1089     case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1090       GET_OFFSET (GarbageCollectionStart);
1091       break;
1092
1093     case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1094       GET_OFFSET (GarbageCollectionFinish);
1095       break;
1096
1097     case JVMTI_EVENT_OBJECT_FREE:
1098       GET_OFFSET (ObjectFree);
1099       break;
1100
1101     case JVMTI_EVENT_VM_OBJECT_ALLOC:
1102       GET_OFFSET (VMObjectAlloc);
1103       break;
1104
1105     default:
1106       fprintf (stderr,
1107                "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
1108                (int) type);
1109       return;
1110     }
1111 #undef GET_OFFSET
1112
1113   int index = EVENT_INDEX (type); // safe since caller checks this
1114
1115   JvSynchronize dummy (_envListLock);
1116   struct jvmti_env_list *e;
1117   FOREACH_ENVIRONMENT (e)
1118     {
1119       char *addr
1120         = reinterpret_cast<char *> (&e->env->callbacks) + offset;
1121       void **callback = reinterpret_cast<void **> (addr);
1122       if (e->env->enabled[index] && *callback != NULL)
1123         {
1124           *enabled = true;
1125           return;
1126         }
1127     }
1128
1129   *enabled = false;
1130 }
1131
1132 static void
1133 check_enabled_events ()
1134 {
1135   check_enabled_event (JVMTI_EVENT_VM_INIT);
1136   check_enabled_event (JVMTI_EVENT_VM_DEATH);
1137   check_enabled_event (JVMTI_EVENT_THREAD_START);
1138   check_enabled_event (JVMTI_EVENT_THREAD_END);
1139   check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
1140   check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
1141   check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
1142   check_enabled_event (JVMTI_EVENT_VM_START);
1143   check_enabled_event (JVMTI_EVENT_EXCEPTION);
1144   check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
1145   check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
1146   check_enabled_event (JVMTI_EVENT_FRAME_POP);
1147   check_enabled_event (JVMTI_EVENT_BREAKPOINT);
1148   check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
1149   check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
1150   check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
1151   check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
1152   check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
1153   check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
1154   check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
1155   check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
1156   check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
1157   check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
1158   check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
1159   check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
1160   check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
1161   check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
1162   check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
1163   check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
1164   check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
1165 }
1166
1167 static jvmtiError JNICALL
1168 _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
1169                                     jvmtiEvent type, jthread event_thread, ...)
1170 {
1171   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1172
1173   if (event_thread != NULL)
1174     {
1175       using namespace java::lang;
1176       Thread *t = reinterpret_cast<Thread *> (event_thread);
1177       THREAD_CHECK_VALID (t);
1178       THREAD_CHECK_IS_ALIVE (t);
1179     }
1180
1181   bool enabled;
1182   switch (mode)
1183     {
1184     case JVMTI_DISABLE:
1185       enabled = false;
1186       break;
1187     case JVMTI_ENABLE:
1188       enabled = true;
1189       break;
1190
1191     default:
1192       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1193     }
1194
1195   switch (type)
1196     {
1197     case JVMTI_EVENT_VM_INIT:
1198     case JVMTI_EVENT_VM_DEATH:
1199     case JVMTI_EVENT_THREAD_START:
1200     case JVMTI_EVENT_VM_START:
1201     case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1202     case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1203     case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1204     case JVMTI_EVENT_DATA_DUMP_REQUEST:
1205       ILLEGAL_ARGUMENT (event_thread != NULL);
1206       break;
1207
1208     case JVMTI_EVENT_THREAD_END:
1209     case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1210     case JVMTI_EVENT_CLASS_LOAD:
1211     case JVMTI_EVENT_CLASS_PREPARE:
1212     case JVMTI_EVENT_EXCEPTION:
1213     case JVMTI_EVENT_EXCEPTION_CATCH:
1214     case JVMTI_EVENT_SINGLE_STEP:
1215     case JVMTI_EVENT_FRAME_POP:
1216     case JVMTI_EVENT_BREAKPOINT:
1217     case JVMTI_EVENT_FIELD_ACCESS:
1218     case JVMTI_EVENT_FIELD_MODIFICATION:
1219     case JVMTI_EVENT_METHOD_ENTRY:
1220     case JVMTI_EVENT_METHOD_EXIT:
1221     case JVMTI_EVENT_NATIVE_METHOD_BIND:
1222     case JVMTI_EVENT_MONITOR_WAIT:
1223     case JVMTI_EVENT_MONITOR_WAITED:
1224     case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1225     case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1226     case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1227     case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1228     case JVMTI_EVENT_OBJECT_FREE:
1229     case JVMTI_EVENT_VM_OBJECT_ALLOC:
1230       break;
1231
1232     default:
1233       return JVMTI_ERROR_INVALID_EVENT_TYPE;
1234     }
1235
1236   env->thread[EVENT_INDEX(type)] = event_thread;
1237   env->enabled[EVENT_INDEX(type)] = enabled;
1238   check_enabled_event (type);
1239   return JVMTI_ERROR_NONE;
1240 }
1241
1242 static jvmtiError JNICALL
1243 _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
1244                              const jvmtiEventCallbacks *callbacks,
1245                              jint size_of_callbacks)
1246 {
1247   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
1248   ILLEGAL_ARGUMENT (size_of_callbacks < 0);
1249
1250   // Copy the list of callbacks into the environment
1251   memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
1252
1253   /* Check which events are now enabeld (JVMTI makes no requirements
1254      about the order in which SetEventCallbacks and SetEventNotifications
1255      are called. So we must check all events here. */
1256   check_enabled_events ();
1257
1258   return JVMTI_ERROR_NONE;
1259 }
1260
1261 static jvmtiError JNICALL
1262 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
1263                         char **name_ptr)
1264 {
1265   NULL_CHECK (name_ptr);
1266
1267   const char *name;
1268   switch (error)
1269     {
1270     case JVMTI_ERROR_NONE:
1271       name = "none";
1272       break;
1273
1274     case JVMTI_ERROR_NULL_POINTER:
1275       name = "null pointer";
1276       break;
1277
1278     case JVMTI_ERROR_OUT_OF_MEMORY:
1279       name = "out of memory";
1280       break;
1281
1282     case JVMTI_ERROR_ACCESS_DENIED:
1283       name = "access denied";
1284       break;
1285
1286     case JVMTI_ERROR_WRONG_PHASE:
1287       name = "wrong phase";
1288       break;
1289
1290     case JVMTI_ERROR_INTERNAL:
1291       name = "internal error";
1292       break;
1293
1294     case JVMTI_ERROR_UNATTACHED_THREAD:
1295       name = "unattached thread";
1296       break;
1297
1298     case JVMTI_ERROR_INVALID_ENVIRONMENT:
1299       name = "invalid environment";
1300       break;
1301
1302     case JVMTI_ERROR_INVALID_PRIORITY:
1303       name = "invalid priority";
1304       break;
1305
1306     case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
1307       name = "thread not suspended";
1308       break;
1309
1310     case JVMTI_ERROR_THREAD_SUSPENDED:
1311       name = "thread suspended";
1312       break;
1313
1314     case JVMTI_ERROR_THREAD_NOT_ALIVE:
1315       name = "thread not alive";
1316       break;
1317
1318     case JVMTI_ERROR_CLASS_NOT_PREPARED:
1319       name = "class not prepared";
1320       break;
1321
1322     case JVMTI_ERROR_NO_MORE_FRAMES:
1323       name = "no more frames";
1324       break;
1325
1326     case JVMTI_ERROR_OPAQUE_FRAME:
1327       name = "opaque frame";
1328       break;
1329
1330     case JVMTI_ERROR_DUPLICATE:
1331       name = "duplicate";
1332       break;
1333
1334     case JVMTI_ERROR_NOT_FOUND:
1335       name = "not found";
1336       break;
1337
1338     case JVMTI_ERROR_NOT_MONITOR_OWNER:
1339       name = "not monitor owner";
1340       break;
1341
1342     case JVMTI_ERROR_INTERRUPT:
1343       name = "interrupted";
1344       break;
1345
1346     case JVMTI_ERROR_UNMODIFIABLE_CLASS:
1347       name = "unmodifiable class";
1348       break;
1349
1350     case JVMTI_ERROR_NOT_AVAILABLE:
1351       name = "not available";
1352       break;
1353
1354     case JVMTI_ERROR_ABSENT_INFORMATION:
1355       name = "absent information";
1356       break;
1357
1358     case JVMTI_ERROR_INVALID_EVENT_TYPE:
1359       name = "invalid event type";
1360       break;
1361
1362     case JVMTI_ERROR_NATIVE_METHOD:
1363       name = "native method";
1364       break;
1365
1366     case JVMTI_ERROR_INVALID_THREAD:
1367       name = "invalid thread";
1368       break;
1369
1370     case JVMTI_ERROR_INVALID_THREAD_GROUP:
1371       name = "invalid thread group";
1372       break;
1373
1374     case JVMTI_ERROR_INVALID_OBJECT:
1375       name = "invalid object";
1376       break;
1377
1378     case JVMTI_ERROR_INVALID_CLASS:
1379       name = "invalid class";
1380       break;
1381
1382     case JVMTI_ERROR_INVALID_METHODID:
1383       name = "invalid method ID";
1384       break;
1385
1386     case JVMTI_ERROR_INVALID_LOCATION:
1387       name = "invalid location";
1388       break;
1389
1390     case JVMTI_ERROR_INVALID_FIELDID:
1391       name = "invalid field ID";
1392       break;
1393
1394     case JVMTI_ERROR_TYPE_MISMATCH:
1395       name = "type mismatch";
1396       break;
1397
1398     case JVMTI_ERROR_INVALID_SLOT:
1399       name = "invalid slot";
1400       break;
1401
1402     case JVMTI_ERROR_INVALID_MONITOR:
1403       name = "invalid monitor";
1404       break;
1405
1406     case JVMTI_ERROR_INVALID_CLASS_FORMAT:
1407       name = "invalid class format";
1408       break;
1409
1410     case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
1411       name = "circular class definition";
1412       break;
1413
1414     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
1415       name = "unsupported redefinition: method added";
1416       break;
1417
1418     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
1419       name = "unsupported redefinition: schema changed";
1420       break;
1421
1422     case JVMTI_ERROR_INVALID_TYPESTATE:
1423       name = "invalid type state";
1424       break;
1425
1426     case JVMTI_ERROR_FAILS_VERIFICATION:
1427       name = "fails verification";
1428       break;
1429
1430     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
1431       name = "unsupported redefinition: hierarchy changed";
1432       break;
1433
1434     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
1435       name = "unsupported redefinition: method deleted";
1436       break;
1437
1438     case JVMTI_ERROR_UNSUPPORTED_VERSION:
1439       name = "unsupported version";
1440       break;
1441
1442     case JVMTI_ERROR_NAMES_DONT_MATCH:
1443       name = "names do not match";
1444       break;
1445
1446     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
1447       name = "unsupported redefinition: class modifiers changed";
1448       break;
1449
1450     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
1451       name = "unsupported redefinition: method modifiers changed";
1452       break;
1453
1454     case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
1455       name = "must possess capability";
1456       break;
1457
1458     case JVMTI_ERROR_ILLEGAL_ARGUMENT:
1459       name = "illegal argument";
1460       break;
1461
1462     default:
1463       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1464     }
1465
1466   *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
1467   if (*name_ptr == NULL)
1468     return JVMTI_ERROR_OUT_OF_MEMORY;
1469
1470   strcpy (*name_ptr, name);
1471   return JVMTI_ERROR_NONE;
1472 }
1473
1474 #define RESERVED NULL
1475 #define UNIMPLEMENTED NULL
1476
1477 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
1478 {
1479   RESERVED,                     // reserved1
1480   _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
1481   RESERVED,                     // reserved3
1482   _Jv_JVMTI_GetAllThreads,              // GetAllThreads
1483   _Jv_JVMTI_SuspendThread,      // SuspendThread
1484   _Jv_JVMTI_ResumeThread,       // ResumeThread
1485   UNIMPLEMENTED,                // StopThread
1486   _Jv_JVMTI_InterruptThread,    // InterruptThread
1487   UNIMPLEMENTED,                // GetThreadInfo
1488   UNIMPLEMENTED,                // GetOwnedMonitorInfo
1489   UNIMPLEMENTED,                // GetCurrentContendedMonitor
1490   UNIMPLEMENTED,                // RunAgentThread
1491   UNIMPLEMENTED,                // GetTopThreadGroups
1492   UNIMPLEMENTED,                // GetThreadGroupInfo
1493   UNIMPLEMENTED,                // GetThreadGroupChildren
1494   UNIMPLEMENTED,                // GetFrameCount
1495   UNIMPLEMENTED,                // GetThreadState
1496   RESERVED,                     // reserved18
1497   UNIMPLEMENTED,                // GetFrameLocation
1498   UNIMPLEMENTED,                // NotifyPopFrame
1499   UNIMPLEMENTED,                // GetLocalObject
1500   UNIMPLEMENTED,                // GetLocalInt
1501   UNIMPLEMENTED,                // GetLocalLong
1502   UNIMPLEMENTED,                // GetLocalFloat
1503   UNIMPLEMENTED,                // GetLocalDouble
1504   UNIMPLEMENTED,                // SetLocalObject
1505   UNIMPLEMENTED,                // SetLocalInt
1506   UNIMPLEMENTED,                // SetLocalLong
1507   UNIMPLEMENTED,                // SetLocalFloat
1508   UNIMPLEMENTED,                // SetLocalDouble
1509   _Jv_JVMTI_CreateRawMonitor,   // CreateRawMonitor
1510   _Jv_JVMTI_DestroyRawMonitor,  // DestroyRawMonitor
1511   _Jv_JVMTI_RawMonitorEnter,    // RawMonitorEnter
1512   _Jv_JVMTI_RawMonitorExit,     // RawMonitorExit
1513   _Jv_JVMTI_RawMonitorWait,     // RawMonitorWait
1514   _Jv_JVMTI_RawMonitorNotify,   // RawMonitorNotify
1515   _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
1516   _Jv_JVMTI_SetBreakpoint,      // SetBreakpoint
1517   _Jv_JVMTI_ClearBreakpoint,    // ClearBreakpoint
1518   RESERVED,                     // reserved40
1519   UNIMPLEMENTED,                // SetFieldAccessWatch
1520   UNIMPLEMENTED,                // ClearFieldAccessWatch
1521   UNIMPLEMENTED,                // SetFieldModificationWatch
1522   UNIMPLEMENTED,                // ClearFieldModificationWatch
1523   RESERVED,                     // reserved45
1524   _Jv_JVMTI_Allocate,           // Allocate
1525   _Jv_JVMTI_Deallocate,         // Deallocate
1526   UNIMPLEMENTED,                // GetClassSignature
1527   _Jv_JVMTI_GetClassStatus,     // GetClassStatus
1528   UNIMPLEMENTED,                // GetSourceFileName
1529   _Jv_JVMTI_GetClassModifiers,  // GetClassModifiers
1530   _Jv_JVMTI_GetClassMethods,    // GetClassMethods
1531   UNIMPLEMENTED,                // GetClassFields
1532   UNIMPLEMENTED,                // GetImplementedInterfaces
1533   _Jv_JVMTI_IsInterface,        // IsInterface
1534   _Jv_JVMTI_IsArrayClass,       // IsArrayClass
1535   _Jv_JVMTI_GetClassLoader,     // GetClassLoader
1536   _Jv_JVMTI_GetObjectHashCode,  // GetObjectHashCode
1537   UNIMPLEMENTED,                // GetObjectMonitorUsage
1538   UNIMPLEMENTED,                // GetFieldName
1539   UNIMPLEMENTED,                // GetFieldDeclaringClass
1540   _Jv_JVMTI_GetFieldModifiers,  // GetFieldModifiers
1541   _Jv_JVMTI_IsFieldSynthetic,   // IsFieldSynthetic
1542   _Jv_JVMTI_GetMethodName,      // GetMethodName
1543   _Jv_JVMTI_GetMethodDeclaringClass,  // GetMethodDeclaringClass
1544   _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
1545   RESERVED,                     // reserved67
1546   UNIMPLEMENTED,                // GetMaxLocals
1547   UNIMPLEMENTED,                // GetArgumentsSize
1548   _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
1549   UNIMPLEMENTED,                // GetMethodLocation
1550   UNIMPLEMENTED,                // GetLocalVariableTable
1551   RESERVED,                     // reserved73
1552   RESERVED,                     // reserved74
1553   UNIMPLEMENTED,                // GetBytecodes
1554   _Jv_JVMTI_IsMethodNative,     // IsMethodNative
1555   _Jv_JVMTI_IsMethodSynthetic,  // IsMethodSynthetic
1556   UNIMPLEMENTED,                // GetLoadedClasses
1557   _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
1558   UNIMPLEMENTED,                // PopFrame
1559   RESERVED,                     // reserved81
1560   RESERVED,                     // reserved82
1561   RESERVED,                     // reserved83
1562   RESERVED,                     // reserved84
1563   RESERVED,                     // reserved85
1564   RESERVED,                     // reserved86
1565   UNIMPLEMENTED,                // RedefineClasses
1566   UNIMPLEMENTED,                // GetVersionNumber
1567   UNIMPLEMENTED,                // GetCapabilities
1568   UNIMPLEMENTED,                // GetSourceDebugExtension
1569   UNIMPLEMENTED,                // IsMethodObsolete
1570   UNIMPLEMENTED,                // SuspendThreadList
1571   UNIMPLEMENTED,                // ResumeThreadList
1572   RESERVED,                     // reserved94
1573   RESERVED,                     // reserved95
1574   RESERVED,                     // reserved96
1575   RESERVED,                     // reserved97
1576   RESERVED,                     // reserved98
1577   RESERVED,                     // reserved99
1578   UNIMPLEMENTED,                // GetAllStackTraces
1579   UNIMPLEMENTED,                // GetThreadListStackTraces
1580   UNIMPLEMENTED,                // GetThreadLocalStorage
1581   UNIMPLEMENTED,                // SetThreadLocalStorage
1582   UNIMPLEMENTED,                // GetStackTrace
1583   RESERVED,                     // reserved105
1584   UNIMPLEMENTED,                // GetTag
1585   UNIMPLEMENTED,                // SetTag
1586   _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
1587   UNIMPLEMENTED,                // IterateOverObjectsReachable
1588   UNIMPLEMENTED,                // IterateOverReachableObjects
1589   UNIMPLEMENTED,                // IterateOverHeap
1590   UNIMPLEMENTED,                // IterateOverInstanceOfClass
1591   RESERVED,                     // reserved113
1592   UNIMPLEMENTED,                // GetObjectsWithTags
1593   RESERVED,                     // reserved115
1594   RESERVED,                     // reserved116
1595   RESERVED,                     // reserved117
1596   RESERVED,                     // reserved118
1597   RESERVED,                     // reserved119
1598   _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
1599   _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
1600   _Jv_JVMTI_SetEventCallbacks,  // SetEventCallbacks
1601   UNIMPLEMENTED,                // GenerateEvents
1602   UNIMPLEMENTED,                // GetExtensionFunctions
1603   UNIMPLEMENTED,                // GetExtensionEvents
1604   UNIMPLEMENTED,                // SetExtensionEventCallback
1605   _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
1606   _Jv_JVMTI_GetErrorName,       // GetErrorName
1607   UNIMPLEMENTED,                // GetJLocationFormat
1608   UNIMPLEMENTED,                // GetSystemProperties
1609   _Jv_JVMTI_GetSystemProperty,  // GetSystemProperty
1610   _Jv_JVMTI_SetSystemProperty,  // SetSystemProperty
1611   UNIMPLEMENTED,                // GetPhase
1612   UNIMPLEMENTED,                // GetCurrentThreadCpuTimerInfo
1613   UNIMPLEMENTED,                // GetCurrentThreadCpuTime
1614   UNIMPLEMENTED,                // GetThreadCpuTimerInfo
1615   UNIMPLEMENTED,                // GetThreadCpuTime
1616   UNIMPLEMENTED,                // GetTimerInfo
1617   _Jv_JVMTI_GetTime,            // GetTime
1618   UNIMPLEMENTED,                // GetPotentialCapabilities
1619   RESERVED,                     // reserved141
1620   UNIMPLEMENTED,                // AddCapabilities
1621   UNIMPLEMENTED,                // RelinquishCapabilities
1622   _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
1623   RESERVED,                     // reserved145
1624   RESERVED,                     // reserved146
1625   UNIMPLEMENTED,                // GetEnvironmentLocalStorage
1626   UNIMPLEMENTED,                // SetEnvironmentLocalStorage
1627   _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
1628   _Jv_JVMTI_SetVerboseFlag,     // SetVerboseFlag
1629   RESERVED,                     // reserved151
1630   RESERVED,                     // reserved152
1631   RESERVED,                     // reserved153
1632   _Jv_JVMTI_GetObjectSize       // GetObjectSize
1633 };
1634
1635 _Jv_JVMTIEnv *
1636 _Jv_GetJVMTIEnv (void)
1637 {
1638   _Jv_JVMTIEnv *env
1639     = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1640   env->p = &_Jv_JVMTI_Interface;
1641
1642   {
1643     JvSynchronize dummy (_envListLock);
1644     struct jvmti_env_list *element
1645       = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
1646     element->env = env;
1647     element->next = NULL;
1648
1649     if (_jvmtiEnvironments == NULL)
1650       _jvmtiEnvironments = element;
1651     else
1652       {
1653         struct jvmti_env_list *e;
1654         for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1655           ;
1656         e->next = element;
1657       }
1658   }
1659
1660   return env;
1661 }
1662
1663 void
1664 _Jv_JVMTI_Init ()
1665 {
1666   _jvmtiEnvironments = NULL;
1667   _envListLock = new java::lang::Object ();
1668
1669   // No environments, so this should set all JVMTI:: members to false
1670   check_enabled_events ();
1671 }
1672
1673 static void
1674 post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
1675 {
1676 #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
1677
1678 #define GET_BOOLEAN_ARG(Name)                   \
1679   ARG (int, b);                                 \
1680   jboolean Name = (b == 0) ? false : true
1681
1682 #define GET_CHAR_ARG(Name)                      \
1683   ARG (int, c);                                 \
1684   char Name = static_cast<char> (c)
1685
1686   switch (type)
1687     {
1688     case JVMTI_EVENT_VM_INIT:
1689       if (env->callbacks.VMInit != NULL)
1690         {
1691           ARG (JNIEnv *, jni_env);
1692           env->callbacks.VMInit (env, jni_env, event_thread);
1693         }
1694       break;
1695
1696     case JVMTI_EVENT_VM_DEATH:
1697       if (env->callbacks.VMDeath != NULL)
1698         {
1699           ARG (JNIEnv *, jni_env);
1700           env->callbacks.VMDeath (env, jni_env);
1701         }
1702       break;
1703
1704     case JVMTI_EVENT_THREAD_START:
1705       if (env->callbacks.ThreadStart != NULL)
1706         {
1707           ARG (JNIEnv *, jni_env);
1708           env->callbacks.ThreadStart (env, jni_env, event_thread);
1709         }
1710       break;
1711
1712     case JVMTI_EVENT_THREAD_END:
1713       if (env->callbacks.ThreadEnd != NULL)
1714         {
1715           ARG (JNIEnv *, jni_env);
1716           env->callbacks.ThreadEnd (env, jni_env, event_thread);
1717         }
1718       break;
1719
1720     case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
1721       if (env->callbacks.ClassFileLoadHook != NULL)
1722         {
1723           ARG (JNIEnv *, jni_env);
1724           ARG (jclass, class_being_redefined);
1725           ARG (jobject, loader);
1726           ARG (const char *, name);
1727           ARG (jobject, protection_domain);
1728           ARG (jint, class_data_len);
1729           ARG (const unsigned char *, class_data);
1730           ARG (jint *, new_class_data_len);
1731           ARG (unsigned char **, new_class_data);
1732           env->callbacks.ClassFileLoadHook (env, jni_env,
1733                                             class_being_redefined, loader,
1734                                             name, protection_domain,
1735                                             class_data_len, class_data,
1736                                             new_class_data_len,
1737                                             new_class_data);
1738         }
1739       break;
1740
1741     case JVMTI_EVENT_CLASS_LOAD:
1742       if (env->callbacks.ClassLoad != NULL)
1743         {
1744           ARG (JNIEnv *, jni_env);
1745           ARG (jclass, klass);
1746           env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
1747         }
1748       break;
1749
1750     case JVMTI_EVENT_CLASS_PREPARE:
1751       if (env->callbacks.ClassPrepare != NULL)
1752         {
1753           ARG (JNIEnv *, jni_env);
1754           ARG (jclass, klass);
1755           env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
1756         }
1757       break;
1758
1759     case JVMTI_EVENT_VM_START:
1760       if (env->callbacks.VMStart != NULL)
1761         {
1762           ARG (JNIEnv *, jni_env);
1763           env->callbacks.VMStart (env, jni_env);
1764         }
1765       break;
1766
1767     case JVMTI_EVENT_EXCEPTION:
1768       if (env->callbacks.Exception != NULL)
1769         {
1770           ARG (JNIEnv *, jni_env);
1771           ARG (jmethodID, method);
1772           ARG (jlocation, location);
1773           ARG (jobject, exception);
1774           ARG (jmethodID, catch_method);
1775           ARG (jlocation, catch_location);
1776           env->callbacks.Exception (env, jni_env, event_thread, method,
1777                                     location, exception, catch_method,
1778                                     catch_location);
1779         }
1780       break;
1781
1782     case JVMTI_EVENT_EXCEPTION_CATCH:
1783       if (env->callbacks.ExceptionCatch != NULL)
1784         {
1785           ARG (JNIEnv *, jni_env);
1786           ARG (jmethodID, method);
1787           ARG (jlocation, location);
1788           ARG (jobject, exception);
1789           env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
1790                                          location, exception);
1791         }
1792       break;
1793
1794     case JVMTI_EVENT_SINGLE_STEP:
1795       if (env->callbacks.SingleStep != NULL)
1796         {
1797           ARG (JNIEnv *, jni_env);
1798           ARG (jmethodID, method);
1799           ARG (jlocation, location);
1800           env->callbacks.SingleStep (env, jni_env, event_thread, method,
1801                                      location);
1802         }
1803       break;
1804
1805     case JVMTI_EVENT_FRAME_POP:
1806       if (env->callbacks.FramePop != NULL)
1807         {
1808           ARG (JNIEnv *, jni_env);
1809           ARG (jmethodID, method);
1810           GET_BOOLEAN_ARG (was_popped_by_exception);
1811           env->callbacks.FramePop (env, jni_env, event_thread, method,
1812                                    was_popped_by_exception);
1813         }
1814       break;
1815
1816     case JVMTI_EVENT_BREAKPOINT:
1817       if (env->callbacks.Breakpoint != NULL)
1818         {
1819           ARG (JNIEnv *, jni_env);
1820           ARG (jmethodID, method);
1821           ARG (jlocation, location);
1822           env->callbacks.Breakpoint (env, jni_env, event_thread, method,
1823                                      location);
1824         }
1825       break;
1826
1827     case JVMTI_EVENT_FIELD_ACCESS:
1828       if (env->callbacks.FieldAccess != NULL)
1829         {
1830           ARG (JNIEnv *, jni_env);
1831           ARG (jmethodID, method);
1832           ARG (jlocation, location);
1833           ARG (jclass, field_class);
1834           ARG (jobject, object);
1835           ARG (jfieldID, field);
1836           env->callbacks.FieldAccess (env, jni_env, event_thread, method,
1837                                       location, field_class, object, field);
1838         }
1839       break;
1840
1841     case JVMTI_EVENT_FIELD_MODIFICATION:
1842       if (env->callbacks.FieldModification != NULL)
1843         {
1844           ARG (JNIEnv *, jni_env);
1845           ARG (jmethodID, method);
1846           ARG (jlocation, location);
1847           ARG (jclass, field_class);
1848           ARG (jobject, object);
1849           ARG (jfieldID, field);
1850           GET_CHAR_ARG (signature_type);
1851           ARG (jvalue, new_value);
1852           env->callbacks.FieldModification (env, jni_env, event_thread, method,
1853                                             location, field_class, object,
1854                                             field, signature_type, new_value);
1855         }
1856       break;
1857
1858     case JVMTI_EVENT_METHOD_ENTRY:
1859       if (env->callbacks.MethodEntry != NULL)
1860         {
1861           ARG (JNIEnv *, jni_env);
1862           ARG (jmethodID, method);
1863           env->callbacks.MethodEntry (env, jni_env, event_thread, method);
1864         }
1865       break;
1866
1867     case JVMTI_EVENT_METHOD_EXIT:
1868       if (env->callbacks.MethodExit != NULL)
1869         {
1870           ARG (JNIEnv *, jni_env);
1871           ARG (jmethodID, method);
1872           GET_BOOLEAN_ARG (was_popped_by_exception);
1873           ARG (jvalue, return_value);
1874           env->callbacks.MethodExit (env, jni_env, event_thread, method,
1875                                      was_popped_by_exception, return_value);
1876         }
1877       break;
1878
1879     case JVMTI_EVENT_NATIVE_METHOD_BIND:
1880       if (env->callbacks.NativeMethodBind != NULL)
1881         {
1882           ARG (JNIEnv *, jni_env);
1883           ARG (jmethodID, method);
1884           ARG (void *, address);
1885           ARG (void **, new_address_ptr);
1886           env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
1887                                            address, new_address_ptr);
1888         }
1889       break;
1890
1891     case JVMTI_EVENT_COMPILED_METHOD_LOAD:
1892       if (env->callbacks.CompiledMethodLoad != NULL)
1893         {
1894           ARG (jmethodID, method);
1895           ARG (jint, code_size);
1896           ARG (const void *, code_addr);
1897           ARG (jint, map_length);
1898           ARG (const jvmtiAddrLocationMap *, map);
1899           ARG (const void *, compile_info);
1900           env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
1901                                              map_length, map, compile_info);
1902         }
1903       break;
1904
1905     case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
1906       if (env->callbacks.CompiledMethodUnload != NULL)
1907         {
1908           ARG (jmethodID, method);
1909           ARG (const void *, code_addr);
1910           env->callbacks.CompiledMethodUnload (env, method, code_addr);
1911         }
1912       break;
1913
1914     case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
1915       if (env->callbacks.DynamicCodeGenerated != NULL)
1916         {
1917           ARG (const char *, name);
1918           ARG (const void *, address);
1919           ARG (jint, length);
1920           env->callbacks.DynamicCodeGenerated (env, name, address, length);
1921         }
1922       break;
1923
1924     case JVMTI_EVENT_DATA_DUMP_REQUEST:
1925       if (env->callbacks.DataDumpRequest != NULL)
1926         {
1927           env->callbacks.DataDumpRequest (env);
1928         }
1929       break;
1930
1931     case JVMTI_EVENT_MONITOR_WAIT:
1932       if (env->callbacks.MonitorWait != NULL)
1933         {
1934           ARG (JNIEnv *, jni_env);
1935           ARG (jobject, object);
1936           ARG (jlong, timeout);
1937           env->callbacks.MonitorWait (env, jni_env, event_thread, object,
1938                                       timeout);
1939         }
1940       break;
1941
1942     case JVMTI_EVENT_MONITOR_WAITED:
1943       if (env->callbacks.MonitorWaited != NULL)
1944         {
1945           ARG (JNIEnv *, jni_env);
1946           ARG (jobject, object);
1947           GET_BOOLEAN_ARG (timed_out);
1948           env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
1949                                         timed_out);
1950         }
1951       break;
1952
1953     case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
1954       if (env->callbacks.MonitorContendedEnter != NULL)
1955         {
1956           ARG (JNIEnv *, jni_env);
1957           ARG (jobject, object);
1958           env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
1959                                                 object);
1960         }
1961       break;
1962
1963     case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
1964       if (env->callbacks.MonitorContendedEntered != NULL)
1965         {
1966           ARG (JNIEnv *, jni_env);
1967           ARG (jobject, object);
1968           env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
1969                                                   object);
1970         }
1971       break;
1972
1973     case JVMTI_EVENT_GARBAGE_COLLECTION_START:
1974       if (env->callbacks.GarbageCollectionStart != NULL)
1975         {
1976           env->callbacks.GarbageCollectionStart (env);
1977         }
1978       break;
1979
1980     case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
1981       if (env->callbacks.GarbageCollectionFinish != NULL)
1982         {
1983           env->callbacks.GarbageCollectionFinish (env);
1984         }
1985       break;
1986
1987     case JVMTI_EVENT_OBJECT_FREE:
1988       if (env->callbacks.ObjectFree != NULL)
1989         {
1990           ARG (jlong, tag);
1991           env->callbacks.ObjectFree (env, tag);
1992         }
1993       break;
1994
1995     case JVMTI_EVENT_VM_OBJECT_ALLOC:
1996       if (env->callbacks.VMObjectAlloc != NULL)
1997         {
1998           ARG (JNIEnv *, jni_env);
1999           ARG (jobject, object);
2000           ARG (jclass, object_class);
2001           ARG (jlong, size);
2002           env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2003                                         object, object_class, size);
2004         }
2005       break;
2006
2007     default:
2008       fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2009                (int) type);
2010       break;
2011     }
2012   va_end (args);
2013 #undef ARG
2014 #undef GET_BOOLEAN_ARG
2015 #undef GET_CHAR_ARG
2016 }
2017
2018 /* Post an event to requesting JVMTI environments
2019  *
2020  * This function should not be called without consulting the
2021  * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2022  * harm (other than kill speed), since this function will still
2023  * only send the event if it was properly requested by an environment.
2024  */ 
2025 void
2026 _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2027 {
2028   va_list args;
2029   va_start (args, event_thread);
2030
2031   JvSynchronize dummy (_envListLock);
2032   struct jvmti_env_list *e;
2033   FOREACH_ENVIRONMENT (e)
2034     {
2035       /* Events are only posted if the event was explicitly enabled,
2036          it has a registered event handler, and the event thread
2037          matches (either globally or restricted to a specific thread).
2038          Here we check all but the event handler, which will be handled
2039          by post_event. */
2040       if (e->env->enabled[EVENT_INDEX(type)]
2041           && (e->env->thread[EVENT_INDEX(type)] == NULL
2042               || e->env->thread[EVENT_INDEX(type)] == event_thread))
2043         {
2044           post_event (e->env, type, event_thread, args);
2045         }
2046     }
2047
2048   va_end (args);
2049 }