OSDN Git Service

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