]> git.ipfire.org Git - thirdparty/gcc.git/blame - libjava/jvmti.cc
* MAINTAINERS: Update my email address.
[thirdparty/gcc.git] / libjava / jvmti.cc
CommitLineData
94f473ee
KS
1// jvmti.cc - JVMTI implementation
2
70686a71 3/* Copyright (C) 2006, 2007 Free Software Foundation
94f473ee
KS
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11#include <config.h>
224aaa41 12#include <platform.h>
94f473ee
KS
13
14#include <jvm.h>
303f32cc
KS
15#include <java-threads.h>
16#include <java-gc.h>
444dd946 17#include <java-interp.h>
94f473ee 18#include <jvmti.h>
ebf29cf6 19#include "jvmti-int.h"
94f473ee 20
76b63f3c
MW
21#include <gcj/method.h>
22
224aaa41
TT
23#include <gnu/classpath/SystemProperties.h>
24#include <gnu/gcj/runtime/BootClassLoader.h>
444dd946
KS
25#include <gnu/gcj/jvmti/Breakpoint.h>
26#include <gnu/gcj/jvmti/BreakpointManager.h>
27
224aaa41
TT
28#include <java/lang/Class.h>
29#include <java/lang/ClassLoader.h>
05794ce8 30#include <java/lang/OutOfMemoryError.h>
303f32cc 31#include <java/lang/Thread.h>
05794ce8 32#include <java/lang/ThreadGroup.h>
22099c59 33#include <java/lang/Thread$State.h>
224aaa41
TT
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>
d6df67ef
KS
40#include <java/util/concurrent/locks/Lock.h>
41#include <java/util/concurrent/locks/ReentrantReadWriteLock.h>
224aaa41
TT
42#include <java/net/URL.h>
43
ebf29cf6
KS
44static void check_enabled_events (void);
45static void check_enabled_event (jvmtiEvent);
46
dc0aeb60
KS
47namespace JVMTI
48{
c6923d93
KS
49 // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
50 bool enabled;
51
52 // Event notifications
dc0aeb60
KS
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
224aaa41
TT
90extern struct JNINativeInterface _Jv_JNIFunctions;
91
92struct _Jv_rawMonitorID
93{
94 _Jv_Mutex_t mutex;
95 _Jv_ConditionVariable_t condition;
96};
303f32cc 97
e6789bef
KS
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. */
102struct jvmti_env_list
103{
104 jvmtiEnv *env;
105 struct jvmti_env_list *next;
106};
107static struct jvmti_env_list *_jvmtiEnvironments = NULL;
d6df67ef
KS
108static java::util::concurrent::locks::
109ReentrantReadWriteLock *_envListLock = NULL;
e6789bef
KS
110#define FOREACH_ENVIRONMENT(Ele) \
111 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
112
303f32cc
KS
113// Some commonly-used checks
114
af91f02d 115#define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
a56913dd
KS
116 do \
117 { \
af91f02d
KS
118 if (Ajthread == NULL) \
119 Ajthread = java::lang::Thread::currentThread (); \
a56913dd
KS
120 } \
121 while (0)
303f32cc 122
af91f02d 123#define THREAD_CHECK_VALID(Athread) \
a56913dd
KS
124 do \
125 { \
af91f02d 126 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
a56913dd
KS
127 return JVMTI_ERROR_INVALID_THREAD; \
128 } \
129 while (0)
130
af91f02d 131#define THREAD_CHECK_IS_ALIVE(Athread) \
a56913dd
KS
132 do \
133 { \
af91f02d 134 if (!Athread->isAlive ()) \
a56913dd
KS
135 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
136 } \
137 while (0)
303f32cc 138
224aaa41
TT
139// FIXME: if current phase is not set in Phases,
140// return JVMTI_ERROR_WRONG_PHASE
141#define REQUIRE_PHASE(Env, Phases)
142
a56913dd
KS
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)
e6789bef 158
04ab4573
KG
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
3201e73d 171static jvmtiError JNICALL
303f32cc
KS
172_Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
173{
174 using namespace java::lang;
175
176 THREAD_DEFAULT_TO_CURRENT (thread);
68254f23
KS
177 THREAD_CHECK_VALID (thread);
178 THREAD_CHECK_IS_ALIVE (thread);
303f32cc 179
68254f23 180 _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
303f32cc
KS
181 _Jv_SuspendThread (data);
182 return JVMTI_ERROR_NONE;
183}
184
3201e73d 185static jvmtiError JNICALL
303f32cc
KS
186_Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
187{
188 using namespace java::lang;
189
190 THREAD_DEFAULT_TO_CURRENT (thread);
68254f23
KS
191 THREAD_CHECK_VALID (thread);
192 THREAD_CHECK_IS_ALIVE (thread);
303f32cc 193
68254f23 194 _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
303f32cc
KS
195 _Jv_ResumeThread (data);
196 return JVMTI_ERROR_NONE;
197}
198
224aaa41
TT
199static 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;
af91f02d 208
68254f23
KS
209 THREAD_CHECK_VALID (thread);
210 THREAD_CHECK_IS_ALIVE (thread);
211 thread->interrupt();
224aaa41
TT
212 return JVMTI_ERROR_NONE;
213}
214
ce359ed9
KG
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.
217static jvmtiError
218getLocalFrame (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
272static 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
289static 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
304static 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
321static 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
336static 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
360static 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
383static 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
400static 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
416static 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
440static 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
70686a71 462static jvmtiError JNICALL
05794ce8
KG
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;
05794ce8
KG
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 {
70686a71
MT
480 thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
481 ((estimate * 2),
482 &Thread::class$, NULL));
05794ce8
KG
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
39273131
KG
505static jvmtiError JNICALL
506_Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
9606c9dd 507 jint *frame_count)
39273131
KG
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);
9606c9dd
KS
516 THREAD_CHECK_VALID (thread);
517 THREAD_CHECK_IS_ALIVE (thread);
39273131 518
9606c9dd 519 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
896b1c87 520 (*frame_count) = frame->depth ();
39273131
KG
521 return JVMTI_ERROR_NONE;
522}
523
22099c59
KS
524static 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
224aaa41
TT
584static 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);
e853e26e
KS
591 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
592 if (*result == NULL)
593 return JVMTI_ERROR_OUT_OF_MEMORY;
224aaa41
TT
594 _Jv_MutexInit (&(*result)->mutex);
595 _Jv_CondInit (&(*result)->condition);
596 return JVMTI_ERROR_NONE;
597}
598
599static 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
616static 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
625static 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
635static jvmtiError JNICALL
59294c2b
KS
636_Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
637 jlong millis)
224aaa41
TT
638{
639 if (monitor == NULL)
640 return JVMTI_ERROR_INVALID_MONITOR;
59294c2b 641 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
224aaa41
TT
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
649static 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
659static 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
444dd946
KS
671static 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
719static 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
224aaa41
TT
737static jvmtiError JNICALL
738_Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
739 unsigned char **result)
740{
e6789bef 741 ILLEGAL_ARGUMENT (size < 0);
224aaa41
TT
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
754static 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
2b3c6788
KS
762static 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
224aaa41 792static jvmtiError JNICALL
cb86b2b6
TT
793_Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
794 jint *mods)
224aaa41
TT
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
805static jvmtiError JNICALL
cb86b2b6
TT
806_Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
807 jint *count_ptr, jmethodID **methods_ptr)
224aaa41
TT
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
e853e26e
KS
818 *methods_ptr
819 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
820 if (*methods_ptr == NULL)
821 return JVMTI_ERROR_OUT_OF_MEMORY;
822
224aaa41
TT
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
831static jvmtiError JNICALL
cb86b2b6
TT
832_Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
833 jboolean *result)
224aaa41
TT
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
843static jvmtiError JNICALL
cb86b2b6
TT
844_Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
845 jboolean *result)
224aaa41
TT
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
855static jvmtiError JNICALL
cb86b2b6
TT
856_Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
857 jobject *result)
224aaa41
TT
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
867static jvmtiError JNICALL
cb86b2b6
TT
868_Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
869 jint *result)
224aaa41
TT
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
879static jvmtiError JNICALL
cb86b2b6
TT
880_Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
881 jfieldID field, jint *result)
224aaa41
TT
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
893static jvmtiError JNICALL
cb86b2b6
TT
894_Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
895 jfieldID field, jboolean *result)
224aaa41
TT
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
ff393407
KS
910static 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
224aaa41 952static jvmtiError JNICALL
cb86b2b6
TT
953_Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
954 jint *result)
224aaa41
TT
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
08107015
KS
966static 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
fe60528e
KG
1014static 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 {
61a36e0d 1061 char **str_ptr = &(*locals)[table_slot].name;
fe60528e 1062 jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
61a36e0d 1063 reinterpret_cast<unsigned char **> (str_ptr));
fe60528e
KG
1064 if (jerr != JVMTI_ERROR_NONE)
1065 return jerr;
1066 strcpy ((*locals)[table_slot].name, name);
61a36e0d
KG
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));
fe60528e
KG
1071 if (jerr != JVMTI_ERROR_NONE)
1072 return jerr;
1073 strcpy ((*locals)[table_slot].signature, sig);
61a36e0d
KG
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));
fe60528e
KG
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
224aaa41 1096static jvmtiError JNICALL
cb86b2b6
TT
1097_Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
1098 jboolean *result)
224aaa41
TT
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
1109static jvmtiError JNICALL
cb86b2b6
TT
1110_Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
1111 jboolean *result)
224aaa41
TT
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
04ab4573 1125static jvmtiError JNICALL
fe60528e 1126_Jv_JVMTI_GetMaxLocals (jvmtiEnv *env, jmethodID method, jint *max_locals)
04ab4573
KG
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
532e9fe7
KG
1149static 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')
b389f63b
KG
1175 {
1176 // If this is an array of wide types it uses a single slot
814bcb14 1177 if (i > 0 && sig[i - 1] == '[')
b389f63b
KG
1178 num_slots++;
1179 else
1180 num_slots += 2;
1181 }
532e9fe7
KG
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
f356a436
KS
1194static 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
224aaa41 1212static jvmtiError JNICALL
cb86b2b6 1213_Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
224aaa41
TT
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);
e853e26e
KS
1233 jclass *result
1234 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
1235 if (result == NULL)
1236 return JVMTI_ERROR_OUT_OF_MEMORY;
1237
224aaa41
TT
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
39273131
KG
1246static 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);
9606c9dd
KS
1261 THREAD_CHECK_VALID (thread);
1262 THREAD_CHECK_IS_ALIVE (thread);
39273131
KG
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
9606c9dd 1276 _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
39273131
KG
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);
d7647361 1309 frames[i].location = imeth->insn_index (interp_frame->get_pc ());
39273131
KG
1310 }
1311 else
1312 frames[i].location = -1;
1313
1314 frame = frame->next;
1315 }
1316
1317 return JVMTI_ERROR_NONE;
1318}
1319
224aaa41 1320static jvmtiError JNICALL
cb86b2b6 1321_Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
224aaa41
TT
1322{
1323 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
1324 _Jv_RunGC();
1325 return JVMTI_ERROR_NONE;
1326}
1327
1328static jvmtiError JNICALL
cb86b2b6 1329_Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
224aaa41
TT
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
1338static jvmtiError JNICALL
cb86b2b6 1339_Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
224aaa41
TT
1340 jniNativeInterface **function_table)
1341{
1342 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
1343 NULL_CHECK (function_table);
1344 *function_table
e853e26e
KS
1345 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
1346 if (*function_table == NULL)
1347 return JVMTI_ERROR_OUT_OF_MEMORY;
224aaa41
TT
1348 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
1349 return JVMTI_ERROR_NONE;
1350}
94f473ee 1351
3201e73d 1352static jvmtiError JNICALL
326d5132
KS
1353_Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
1354{
e6789bef
KS
1355 NULL_CHECK (env);
1356
1357 if (_jvmtiEnvironments == NULL)
1358 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1359 else
1360 {
d6df67ef 1361 _envListLock->writeLock ()->lock ();
e6789bef
KS
1362 if (_jvmtiEnvironments->env == env)
1363 {
af91f02d 1364 struct jvmti_env_list *next = _jvmtiEnvironments->next;
e6789bef 1365 _Jv_Free (_jvmtiEnvironments);
af91f02d 1366 _jvmtiEnvironments = next;
e6789bef
KS
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)
d6df67ef
KS
1374 {
1375 _envListLock->writeLock ()->unlock ();
1376 return JVMTI_ERROR_INVALID_ENVIRONMENT;
1377 }
e6789bef
KS
1378
1379 struct jvmti_env_list *next = e->next->next;
1380 _Jv_Free (e->next);
1381 e->next = next;
1382 }
d6df67ef 1383 _envListLock->writeLock ()->unlock ();
e6789bef
KS
1384 }
1385
326d5132 1386 _Jv_Free (env);
ebf29cf6
KS
1387
1388 check_enabled_events ();
1389
326d5132
KS
1390 return JVMTI_ERROR_NONE;
1391}
1392
224aaa41 1393static jvmtiError JNICALL
cb86b2b6 1394_Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
224aaa41
TT
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);
e853e26e
KS
1408 *result = (char *) _Jv_MallocUnchecked (len + 1);
1409 if (*result == NULL)
1410 return JVMTI_ERROR_OUT_OF_MEMORY;
224aaa41
TT
1411 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
1412 (*result)[len] = '\0';
1413
1414 return JVMTI_ERROR_NONE;
1415}
1416
1417static jvmtiError JNICALL
cb86b2b6 1418_Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
224aaa41
TT
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
1436static 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
1444static 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
1457static jvmtiError JNICALL
cb86b2b6
TT
1458_Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
1459 const char *segment)
224aaa41
TT
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
1486static 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
1506static jvmtiError JNICALL
cb86b2b6
TT
1507_Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
1508 jlong *result)
224aaa41
TT
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
cb86b2b6
TT
1520 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
1521 klass->getComponentType());
224aaa41
TT
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
ebf29cf6
KS
1536/* An event is enabled only if it has both an event handler
1537 and it is enabled in the environment. */
1538static void
1539check_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
d6df67ef 1684 if (_jvmtiEnvironments != NULL)
ebf29cf6 1685 {
d6df67ef
KS
1686 _envListLock->readLock ()->lock ();
1687 struct jvmti_env_list *e;
1688 FOREACH_ENVIRONMENT (e)
ebf29cf6 1689 {
d6df67ef
KS
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 }
ebf29cf6 1699 }
d6df67ef
KS
1700
1701 _envListLock->readLock ()->unlock ();
ebf29cf6
KS
1702 }
1703
1704 *enabled = false;
1705}
1706
1707static void
1708check_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
1742static 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 {
68254f23
KS
1750 THREAD_CHECK_VALID (event_thread);
1751 THREAD_CHECK_IS_ALIVE (event_thread);
ebf29cf6
KS
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
1815static 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
f8e04884 1834static jvmtiError JNICALL
19289614
KS
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
224aaa41
TT
2047#define RESERVED NULL
2048#define UNIMPLEMENTED NULL
2049
94f473ee
KS
2050struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
2051{
2052 RESERVED, // reserved1
ebf29cf6 2053 _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
94f473ee 2054 RESERVED, // reserved3
05794ce8 2055 _Jv_JVMTI_GetAllThreads, // GetAllThreads
303f32cc
KS
2056 _Jv_JVMTI_SuspendThread, // SuspendThread
2057 _Jv_JVMTI_ResumeThread, // ResumeThread
94f473ee 2058 UNIMPLEMENTED, // StopThread
224aaa41 2059 _Jv_JVMTI_InterruptThread, // InterruptThread
94f473ee
KS
2060 UNIMPLEMENTED, // GetThreadInfo
2061 UNIMPLEMENTED, // GetOwnedMonitorInfo
2062 UNIMPLEMENTED, // GetCurrentContendedMonitor
2063 UNIMPLEMENTED, // RunAgentThread
2064 UNIMPLEMENTED, // GetTopThreadGroups
2065 UNIMPLEMENTED, // GetThreadGroupInfo
2066 UNIMPLEMENTED, // GetThreadGroupChildren
39273131 2067 _Jv_JVMTI_GetFrameCount, // GetFrameCount
22099c59 2068 _Jv_JVMTI_GetThreadState, // GetThreadState
94f473ee
KS
2069 RESERVED, // reserved18
2070 UNIMPLEMENTED, // GetFrameLocation
2071 UNIMPLEMENTED, // NotifyPopFrame
ce359ed9
KG
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
224aaa41
TT
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
444dd946
KS
2089 _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
2090 _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
94f473ee
KS
2091 RESERVED, // reserved40
2092 UNIMPLEMENTED, // SetFieldAccessWatch
2093 UNIMPLEMENTED, // ClearFieldAccessWatch
2094 UNIMPLEMENTED, // SetFieldModificationWatch
2095 UNIMPLEMENTED, // ClearFieldModificationWatch
2096 RESERVED, // reserved45
224aaa41
TT
2097 _Jv_JVMTI_Allocate, // Allocate
2098 _Jv_JVMTI_Deallocate, // Deallocate
94f473ee 2099 UNIMPLEMENTED, // GetClassSignature
2b3c6788 2100 _Jv_JVMTI_GetClassStatus, // GetClassStatus
94f473ee 2101 UNIMPLEMENTED, // GetSourceFileName
224aaa41
TT
2102 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
2103 _Jv_JVMTI_GetClassMethods, // GetClassMethods
94f473ee
KS
2104 UNIMPLEMENTED, // GetClassFields
2105 UNIMPLEMENTED, // GetImplementedInterfaces
224aaa41
TT
2106 _Jv_JVMTI_IsInterface, // IsInterface
2107 _Jv_JVMTI_IsArrayClass, // IsArrayClass
2108 _Jv_JVMTI_GetClassLoader, // GetClassLoader
2109 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
94f473ee
KS
2110 UNIMPLEMENTED, // GetObjectMonitorUsage
2111 UNIMPLEMENTED, // GetFieldName
2112 UNIMPLEMENTED, // GetFieldDeclaringClass
224aaa41
TT
2113 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
2114 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
ff393407 2115 _Jv_JVMTI_GetMethodName, // GetMethodName
f356a436 2116 _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
224aaa41 2117 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
94f473ee 2118 RESERVED, // reserved67
04ab4573 2119 _Jv_JVMTI_GetMaxLocals, // GetMaxLocals
532e9fe7 2120 _Jv_JVMTI_GetArgumentsSize, // GetArgumentsSize
08107015 2121 _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
94f473ee 2122 UNIMPLEMENTED, // GetMethodLocation
fe60528e 2123 _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable
94f473ee
KS
2124 RESERVED, // reserved73
2125 RESERVED, // reserved74
2126 UNIMPLEMENTED, // GetBytecodes
224aaa41
TT
2127 _Jv_JVMTI_IsMethodNative, // IsMethodNative
2128 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
94f473ee 2129 UNIMPLEMENTED, // GetLoadedClasses
224aaa41 2130 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
94f473ee
KS
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
39273131 2155 _Jv_JVMTI_GetStackTrace, // GetStackTrace
94f473ee
KS
2156 RESERVED, // reserved105
2157 UNIMPLEMENTED, // GetTag
2158 UNIMPLEMENTED, // SetTag
224aaa41 2159 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
94f473ee
KS
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
224aaa41
TT
2171 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
2172 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
ebf29cf6 2173 _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
94f473ee
KS
2174 UNIMPLEMENTED, // GenerateEvents
2175 UNIMPLEMENTED, // GetExtensionFunctions
2176 UNIMPLEMENTED, // GetExtensionEvents
2177 UNIMPLEMENTED, // SetExtensionEventCallback
326d5132 2178 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
19289614 2179 _Jv_JVMTI_GetErrorName, // GetErrorName
94f473ee
KS
2180 UNIMPLEMENTED, // GetJLocationFormat
2181 UNIMPLEMENTED, // GetSystemProperties
224aaa41
TT
2182 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
2183 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
94f473ee
KS
2184 UNIMPLEMENTED, // GetPhase
2185 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
2186 UNIMPLEMENTED, // GetCurrentThreadCpuTime
2187 UNIMPLEMENTED, // GetThreadCpuTimerInfo
2188 UNIMPLEMENTED, // GetThreadCpuTime
2189 UNIMPLEMENTED, // GetTimerInfo
224aaa41 2190 _Jv_JVMTI_GetTime, // GetTime
94f473ee
KS
2191 UNIMPLEMENTED, // GetPotentialCapabilities
2192 RESERVED, // reserved141
2193 UNIMPLEMENTED, // AddCapabilities
2194 UNIMPLEMENTED, // RelinquishCapabilities
224aaa41 2195 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
94f473ee
KS
2196 RESERVED, // reserved145
2197 RESERVED, // reserved146
2198 UNIMPLEMENTED, // GetEnvironmentLocalStorage
2199 UNIMPLEMENTED, // SetEnvironmentLocalStorage
224aaa41
TT
2200 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
2201 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
94f473ee
KS
2202 RESERVED, // reserved151
2203 RESERVED, // reserved152
2204 RESERVED, // reserved153
224aaa41 2205 _Jv_JVMTI_GetObjectSize // GetObjectSize
94f473ee
KS
2206};
2207
2208_Jv_JVMTIEnv *
2209_Jv_GetJVMTIEnv (void)
2210{
2211 _Jv_JVMTIEnv *env
2212 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
2213 env->p = &_Jv_JVMTI_Interface;
d6df67ef
KS
2214 struct jvmti_env_list *element
2215 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
2216 element->env = env;
2217 element->next = NULL;
e6789bef 2218
d6df67ef
KS
2219 _envListLock->writeLock ()->lock ();
2220 if (_jvmtiEnvironments == NULL)
2221 _jvmtiEnvironments = element;
2222 else
2223 {
2224 struct jvmti_env_list *e;
2225 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
2226 ;
2227 e->next = element;
2228 }
2229 _envListLock->writeLock ()->unlock ();
e6789bef 2230
c6923d93
KS
2231 /* Mark JVMTI active. This is used to force the interpreter
2232 to use either debugging or non-debugging code. Once JVMTI
2233 has been enabled, the non-debug interpreter cannot be used. */
2234 JVMTI::enabled = true;
94f473ee
KS
2235 return env;
2236}
e6789bef
KS
2237
2238void
2239_Jv_JVMTI_Init ()
2240{
2241 _jvmtiEnvironments = NULL;
d6df67ef
KS
2242 _envListLock
2243 = new java::util::concurrent::locks::ReentrantReadWriteLock ();
ebf29cf6
KS
2244
2245 // No environments, so this should set all JVMTI:: members to false
2246 check_enabled_events ();
2247}
2248
2249static void
2250post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
2251{
2252#define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
2253
2254#define GET_BOOLEAN_ARG(Name) \
2255 ARG (int, b); \
2256 jboolean Name = (b == 0) ? false : true
2257
2258#define GET_CHAR_ARG(Name) \
2259 ARG (int, c); \
2260 char Name = static_cast<char> (c)
2261
2262 switch (type)
2263 {
2264 case JVMTI_EVENT_VM_INIT:
2265 if (env->callbacks.VMInit != NULL)
2266 {
2267 ARG (JNIEnv *, jni_env);
2268 env->callbacks.VMInit (env, jni_env, event_thread);
2269 }
2270 break;
2271
2272 case JVMTI_EVENT_VM_DEATH:
2273 if (env->callbacks.VMDeath != NULL)
2274 {
2275 ARG (JNIEnv *, jni_env);
2276 env->callbacks.VMDeath (env, jni_env);
2277 }
2278 break;
2279
2280 case JVMTI_EVENT_THREAD_START:
2281 if (env->callbacks.ThreadStart != NULL)
2282 {
2283 ARG (JNIEnv *, jni_env);
2284 env->callbacks.ThreadStart (env, jni_env, event_thread);
2285 }
2286 break;
2287
2288 case JVMTI_EVENT_THREAD_END:
2289 if (env->callbacks.ThreadEnd != NULL)
2290 {
2291 ARG (JNIEnv *, jni_env);
2292 env->callbacks.ThreadEnd (env, jni_env, event_thread);
2293 }
2294 break;
2295
2296 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
2297 if (env->callbacks.ClassFileLoadHook != NULL)
2298 {
2299 ARG (JNIEnv *, jni_env);
2300 ARG (jclass, class_being_redefined);
2301 ARG (jobject, loader);
2302 ARG (const char *, name);
2303 ARG (jobject, protection_domain);
2304 ARG (jint, class_data_len);
2305 ARG (const unsigned char *, class_data);
2306 ARG (jint *, new_class_data_len);
2307 ARG (unsigned char **, new_class_data);
2308 env->callbacks.ClassFileLoadHook (env, jni_env,
2309 class_being_redefined, loader,
2310 name, protection_domain,
2311 class_data_len, class_data,
2312 new_class_data_len,
2313 new_class_data);
2314 }
2315 break;
2316
2317 case JVMTI_EVENT_CLASS_LOAD:
2318 if (env->callbacks.ClassLoad != NULL)
2319 {
2320 ARG (JNIEnv *, jni_env);
2321 ARG (jclass, klass);
2322 env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
2323 }
2324 break;
2325
2326 case JVMTI_EVENT_CLASS_PREPARE:
2327 if (env->callbacks.ClassPrepare != NULL)
2328 {
2329 ARG (JNIEnv *, jni_env);
2330 ARG (jclass, klass);
2331 env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
2332 }
2333 break;
2334
2335 case JVMTI_EVENT_VM_START:
2336 if (env->callbacks.VMStart != NULL)
2337 {
2338 ARG (JNIEnv *, jni_env);
2339 env->callbacks.VMStart (env, jni_env);
2340 }
2341 break;
2342
2343 case JVMTI_EVENT_EXCEPTION:
2344 if (env->callbacks.Exception != NULL)
2345 {
2346 ARG (JNIEnv *, jni_env);
2347 ARG (jmethodID, method);
2348 ARG (jlocation, location);
2349 ARG (jobject, exception);
2350 ARG (jmethodID, catch_method);
2351 ARG (jlocation, catch_location);
2352 env->callbacks.Exception (env, jni_env, event_thread, method,
2353 location, exception, catch_method,
2354 catch_location);
2355 }
2356 break;
2357
2358 case JVMTI_EVENT_EXCEPTION_CATCH:
2359 if (env->callbacks.ExceptionCatch != NULL)
2360 {
2361 ARG (JNIEnv *, jni_env);
2362 ARG (jmethodID, method);
2363 ARG (jlocation, location);
2364 ARG (jobject, exception);
2365 env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
2366 location, exception);
2367 }
2368 break;
2369
2370 case JVMTI_EVENT_SINGLE_STEP:
2371 if (env->callbacks.SingleStep != NULL)
2372 {
2373 ARG (JNIEnv *, jni_env);
2374 ARG (jmethodID, method);
2375 ARG (jlocation, location);
2376 env->callbacks.SingleStep (env, jni_env, event_thread, method,
2377 location);
2378 }
2379 break;
2380
2381 case JVMTI_EVENT_FRAME_POP:
2382 if (env->callbacks.FramePop != NULL)
2383 {
2384 ARG (JNIEnv *, jni_env);
2385 ARG (jmethodID, method);
2386 GET_BOOLEAN_ARG (was_popped_by_exception);
2387 env->callbacks.FramePop (env, jni_env, event_thread, method,
2388 was_popped_by_exception);
2389 }
2390 break;
2391
2392 case JVMTI_EVENT_BREAKPOINT:
2393 if (env->callbacks.Breakpoint != NULL)
2394 {
2395 ARG (JNIEnv *, jni_env);
2396 ARG (jmethodID, method);
2397 ARG (jlocation, location);
2398 env->callbacks.Breakpoint (env, jni_env, event_thread, method,
2399 location);
2400 }
2401 break;
2402
2403 case JVMTI_EVENT_FIELD_ACCESS:
2404 if (env->callbacks.FieldAccess != NULL)
2405 {
2406 ARG (JNIEnv *, jni_env);
2407 ARG (jmethodID, method);
2408 ARG (jlocation, location);
2409 ARG (jclass, field_class);
2410 ARG (jobject, object);
2411 ARG (jfieldID, field);
2412 env->callbacks.FieldAccess (env, jni_env, event_thread, method,
2413 location, field_class, object, field);
2414 }
2415 break;
2416
2417 case JVMTI_EVENT_FIELD_MODIFICATION:
2418 if (env->callbacks.FieldModification != NULL)
2419 {
2420 ARG (JNIEnv *, jni_env);
2421 ARG (jmethodID, method);
2422 ARG (jlocation, location);
2423 ARG (jclass, field_class);
2424 ARG (jobject, object);
2425 ARG (jfieldID, field);
2426 GET_CHAR_ARG (signature_type);
2427 ARG (jvalue, new_value);
2428 env->callbacks.FieldModification (env, jni_env, event_thread, method,
2429 location, field_class, object,
2430 field, signature_type, new_value);
2431 }
2432 break;
2433
2434 case JVMTI_EVENT_METHOD_ENTRY:
2435 if (env->callbacks.MethodEntry != NULL)
2436 {
2437 ARG (JNIEnv *, jni_env);
2438 ARG (jmethodID, method);
2439 env->callbacks.MethodEntry (env, jni_env, event_thread, method);
2440 }
2441 break;
2442
2443 case JVMTI_EVENT_METHOD_EXIT:
2444 if (env->callbacks.MethodExit != NULL)
2445 {
2446 ARG (JNIEnv *, jni_env);
2447 ARG (jmethodID, method);
2448 GET_BOOLEAN_ARG (was_popped_by_exception);
2449 ARG (jvalue, return_value);
2450 env->callbacks.MethodExit (env, jni_env, event_thread, method,
2451 was_popped_by_exception, return_value);
2452 }
2453 break;
2454
2455 case JVMTI_EVENT_NATIVE_METHOD_BIND:
2456 if (env->callbacks.NativeMethodBind != NULL)
2457 {
2458 ARG (JNIEnv *, jni_env);
2459 ARG (jmethodID, method);
2460 ARG (void *, address);
2461 ARG (void **, new_address_ptr);
2462 env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
2463 address, new_address_ptr);
2464 }
2465 break;
2466
2467 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
2468 if (env->callbacks.CompiledMethodLoad != NULL)
2469 {
2470 ARG (jmethodID, method);
2471 ARG (jint, code_size);
2472 ARG (const void *, code_addr);
2473 ARG (jint, map_length);
2474 ARG (const jvmtiAddrLocationMap *, map);
2475 ARG (const void *, compile_info);
2476 env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
2477 map_length, map, compile_info);
2478 }
2479 break;
2480
2481 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
2482 if (env->callbacks.CompiledMethodUnload != NULL)
2483 {
2484 ARG (jmethodID, method);
2485 ARG (const void *, code_addr);
2486 env->callbacks.CompiledMethodUnload (env, method, code_addr);
2487 }
2488 break;
2489
2490 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
2491 if (env->callbacks.DynamicCodeGenerated != NULL)
2492 {
2493 ARG (const char *, name);
2494 ARG (const void *, address);
2495 ARG (jint, length);
2496 env->callbacks.DynamicCodeGenerated (env, name, address, length);
2497 }
2498 break;
2499
2500 case JVMTI_EVENT_DATA_DUMP_REQUEST:
2501 if (env->callbacks.DataDumpRequest != NULL)
2502 {
2503 env->callbacks.DataDumpRequest (env);
2504 }
2505 break;
2506
2507 case JVMTI_EVENT_MONITOR_WAIT:
2508 if (env->callbacks.MonitorWait != NULL)
2509 {
2510 ARG (JNIEnv *, jni_env);
2511 ARG (jobject, object);
2512 ARG (jlong, timeout);
2513 env->callbacks.MonitorWait (env, jni_env, event_thread, object,
2514 timeout);
2515 }
2516 break;
2517
2518 case JVMTI_EVENT_MONITOR_WAITED:
2519 if (env->callbacks.MonitorWaited != NULL)
2520 {
2521 ARG (JNIEnv *, jni_env);
2522 ARG (jobject, object);
2523 GET_BOOLEAN_ARG (timed_out);
2524 env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
2525 timed_out);
2526 }
2527 break;
2528
2529 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
2530 if (env->callbacks.MonitorContendedEnter != NULL)
2531 {
2532 ARG (JNIEnv *, jni_env);
2533 ARG (jobject, object);
2534 env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
2535 object);
2536 }
2537 break;
2538
2539 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
2540 if (env->callbacks.MonitorContendedEntered != NULL)
2541 {
2542 ARG (JNIEnv *, jni_env);
2543 ARG (jobject, object);
2544 env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
2545 object);
2546 }
2547 break;
2548
2549 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
2550 if (env->callbacks.GarbageCollectionStart != NULL)
2551 {
2552 env->callbacks.GarbageCollectionStart (env);
2553 }
2554 break;
2555
2556 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
2557 if (env->callbacks.GarbageCollectionFinish != NULL)
2558 {
2559 env->callbacks.GarbageCollectionFinish (env);
2560 }
2561 break;
2562
2563 case JVMTI_EVENT_OBJECT_FREE:
2564 if (env->callbacks.ObjectFree != NULL)
2565 {
2566 ARG (jlong, tag);
2567 env->callbacks.ObjectFree (env, tag);
2568 }
2569 break;
2570
2571 case JVMTI_EVENT_VM_OBJECT_ALLOC:
2572 if (env->callbacks.VMObjectAlloc != NULL)
2573 {
2574 ARG (JNIEnv *, jni_env);
2575 ARG (jobject, object);
2576 ARG (jclass, object_class);
2577 ARG (jlong, size);
2578 env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
2579 object, object_class, size);
2580 }
2581 break;
2582
2583 default:
2584 fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
2585 (int) type);
2586 break;
2587 }
2588 va_end (args);
2589#undef ARG
2590#undef GET_BOOLEAN_ARG
2591#undef GET_CHAR_ARG
2592}
2593
2594/* Post an event to requesting JVMTI environments
2595 *
2596 * This function should not be called without consulting the
2597 * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
2598 * harm (other than kill speed), since this function will still
2599 * only send the event if it was properly requested by an environment.
2600 */
2601void
2602_Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
2603{
2604 va_list args;
2605 va_start (args, event_thread);
2606
d6df67ef 2607 _envListLock->readLock ()->lock ();
ebf29cf6
KS
2608 struct jvmti_env_list *e;
2609 FOREACH_ENVIRONMENT (e)
2610 {
2611 /* Events are only posted if the event was explicitly enabled,
2612 it has a registered event handler, and the event thread
2613 matches (either globally or restricted to a specific thread).
2614 Here we check all but the event handler, which will be handled
2615 by post_event. */
2616 if (e->env->enabled[EVENT_INDEX(type)]
2617 && (e->env->thread[EVENT_INDEX(type)] == NULL
2618 || e->env->thread[EVENT_INDEX(type)] == event_thread))
2619 {
2620 post_event (e->env, type, event_thread, args);
2621 }
2622 }
d6df67ef 2623 _envListLock->readLock ()->unlock ();
ebf29cf6 2624 va_end (args);
e6789bef 2625}