OSDN Git Service

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