OSDN Git Service

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