OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [jvmti.cc] - Blame information for rev 777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 753 jeremybenn
// jvmti.cc - JVMTI implementation
2
 
3
/* Copyright (C) 2006, 2007, 2010 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.