OSDN Git Service

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