OSDN Git Service

2006-08-15 Kyle Galloway <kgallowa@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / jvmti.cc
1 // jvmti.cc - JVMTI implementation
2
3 /* Copyright (C) 2006 Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12 #include <platform.h>
13
14 #include <jvm.h>
15 #include <java-threads.h>
16 #include <java-gc.h>
17 #include <jvmti.h>
18
19 #include <gcj/method.h>
20
21 #include <gnu/classpath/SystemProperties.h>
22 #include <gnu/gcj/runtime/BootClassLoader.h>
23 #include <java/lang/Class.h>
24 #include <java/lang/ClassLoader.h>
25 #include <java/lang/Thread.h>
26 #include <java/lang/Throwable.h>
27 #include <java/lang/VMClassLoader.h>
28 #include <java/lang/reflect/Field.h>
29 #include <java/lang/reflect/Modifier.h>
30 #include <java/util/Collection.h>
31 #include <java/util/HashMap.h>
32 #include <java/net/URL.h>
33
34 extern struct JNINativeInterface _Jv_JNIFunctions;
35
36 struct _Jv_rawMonitorID
37 {
38   _Jv_Mutex_t mutex;
39   _Jv_ConditionVariable_t condition;
40 };
41
42 // Some commonly-used checks
43
44 #define THREAD_DEFAULT_TO_CURRENT(jthread)                              \
45   if (jthread == NULL) jthread = java::lang::Thread::currentThread ();
46
47 #define THREAD_CHECK_VALID(jthread)                                     \
48   if (!java::lang::Thread::class$.isAssignableFrom (&(jthread->class$))) \
49     return JVMTI_ERROR_INVALID_THREAD;
50
51 #define THREAD_CHECK_IS_ALIVE(thread)                           \
52   if (!thread->isAlive ()) return JVMTI_ERROR_THREAD_NOT_ALIVE;
53
54 // FIXME: if current phase is not set in Phases,
55 // return JVMTI_ERROR_WRONG_PHASE
56 #define REQUIRE_PHASE(Env, Phases)
57
58 #define NULL_CHECK(Ptr)                                 \
59   if (Ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
60
61 static jvmtiError JNICALL
62 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
63 {
64   using namespace java::lang;
65
66   THREAD_DEFAULT_TO_CURRENT (thread);
67   THREAD_CHECK_VALID (thread);
68
69   Thread *t = reinterpret_cast<Thread *> (thread);
70   THREAD_CHECK_IS_ALIVE (t);
71
72   _Jv_Thread_t *data = _Jv_ThreadGetData (t);
73   _Jv_SuspendThread (data);
74   return JVMTI_ERROR_NONE;
75 }
76
77 static jvmtiError JNICALL
78 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
79 {
80   using namespace java::lang;
81
82   THREAD_DEFAULT_TO_CURRENT (thread);
83   THREAD_CHECK_VALID (thread);
84
85   Thread *t = reinterpret_cast<Thread *> (thread);
86   THREAD_CHECK_IS_ALIVE (t);
87
88   _Jv_Thread_t *data = _Jv_ThreadGetData (t);
89   _Jv_ResumeThread (data);
90   return JVMTI_ERROR_NONE;
91 }
92
93 static jvmtiError JNICALL
94 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
95 {
96   using namespace java::lang;
97
98   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
99   // FIXME: capability handling?  'can_signal_thread'
100   if (thread == NULL)
101     return JVMTI_ERROR_INVALID_THREAD;
102   THREAD_CHECK_VALID (thread);
103   Thread *real_thread = reinterpret_cast<Thread *> (thread);
104   THREAD_CHECK_IS_ALIVE (real_thread);
105   real_thread->interrupt();
106   return JVMTI_ERROR_NONE;
107 }
108
109 static jvmtiError JNICALL
110 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
111                             jrawMonitorID *result)
112 {
113   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
114   NULL_CHECK (name);
115   NULL_CHECK (result);
116   *result = (jrawMonitorID) _Jv_Malloc (sizeof (_Jv_rawMonitorID));
117   _Jv_MutexInit (&(*result)->mutex);
118   _Jv_CondInit (&(*result)->condition);
119   return JVMTI_ERROR_NONE;
120 }
121
122 static jvmtiError JNICALL
123 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
124 {
125   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
126   // Note we have no better way of knowing whether this object is
127   // really a raw monitor.
128   if (monitor == NULL)
129     return JVMTI_ERROR_INVALID_MONITOR;
130   // FIXME: perform checks on monitor, release it if this thread owns
131   // it.
132 #ifdef _Jv_HaveMutexDestroy
133   _Jv_MutexDestroy (&monitor->mutex);
134 #endif
135   _Jv_Free (monitor);
136   return JVMTI_ERROR_NONE;
137 }
138
139 static jvmtiError JNICALL
140 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
141 {
142   if (monitor == NULL)
143     return JVMTI_ERROR_INVALID_MONITOR;
144   _Jv_MutexLock (&monitor->mutex);
145   return JVMTI_ERROR_NONE;
146 }
147
148 static jvmtiError JNICALL
149 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
150 {
151   if (monitor == NULL)
152     return JVMTI_ERROR_INVALID_MONITOR;
153   if (_Jv_MutexUnlock (&monitor->mutex))
154     return JVMTI_ERROR_NOT_MONITOR_OWNER;
155   return JVMTI_ERROR_NONE;
156 }
157
158 static jvmtiError JNICALL
159 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
160 {
161   if (monitor == NULL)
162     return JVMTI_ERROR_INVALID_MONITOR;
163   int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, 0, 0);
164   if (r == _JV_NOT_OWNER)
165     return JVMTI_ERROR_NOT_MONITOR_OWNER;
166   if (r == _JV_INTERRUPTED)
167     return JVMTI_ERROR_INTERRUPT;
168   return JVMTI_ERROR_NONE;
169 }
170
171 static jvmtiError JNICALL
172 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
173 {
174   if (monitor == NULL)
175     return JVMTI_ERROR_INVALID_MONITOR;
176   if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
177     return JVMTI_ERROR_NOT_MONITOR_OWNER;
178   return JVMTI_ERROR_NONE;
179 }
180
181 static jvmtiError JNICALL
182 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
183                                jrawMonitorID monitor)
184 {
185   if (monitor == NULL)
186     return JVMTI_ERROR_INVALID_MONITOR;
187   if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
188       == _JV_NOT_OWNER)
189     return JVMTI_ERROR_NOT_MONITOR_OWNER;
190   return JVMTI_ERROR_NONE;
191 }
192
193 static jvmtiError JNICALL
194 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
195                     unsigned char **result)
196 {
197   if (size < 0)
198     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
199   NULL_CHECK (result);
200   if (size == 0)
201     *result = NULL;
202   else
203     {
204       *result = (unsigned char *) _Jv_MallocUnchecked (size);
205       if (*result == NULL)
206         return JVMTI_ERROR_OUT_OF_MEMORY;
207     }
208   return JVMTI_ERROR_NONE;
209 }
210
211 static jvmtiError JNICALL
212 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
213 {
214   if (mem != NULL)
215     _Jv_Free (mem);
216   return JVMTI_ERROR_NONE;
217 }
218
219 static jvmtiError JNICALL
220 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
221                              jint *mods)
222 {
223   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
224   // Don't bother checking KLASS' type.
225   if (klass == NULL)
226     return JVMTI_ERROR_INVALID_CLASS;
227   NULL_CHECK (mods);
228   *mods = klass->getModifiers();
229   return JVMTI_ERROR_NONE;
230 }
231
232 static jvmtiError JNICALL
233 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
234                            jint *count_ptr, jmethodID **methods_ptr)
235 {
236   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
237   // FIXME: capability can_maintain_original_method_order
238   // Don't bother checking KLASS' type.
239   if (klass == NULL)
240     return JVMTI_ERROR_INVALID_CLASS;
241   NULL_CHECK (count_ptr);
242   NULL_CHECK (methods_ptr);
243   *count_ptr = JvNumMethods(klass);
244
245   *methods_ptr = (jmethodID *) _Jv_Malloc (*count_ptr * sizeof (jmethodID));
246   jmethodID start = JvGetFirstMethod (klass);
247   for (jint i = 0; i < *count_ptr; ++i)
248     // FIXME: correct?
249     (*methods_ptr)[i] = start + i;
250
251   return JVMTI_ERROR_NONE;
252 }
253
254 static jvmtiError JNICALL
255 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
256                        jboolean *result)
257 {
258   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
259   if (klass == NULL)
260     return JVMTI_ERROR_INVALID_CLASS;
261   NULL_CHECK (result);
262   *result = klass->isInterface();
263   return JVMTI_ERROR_NONE;
264 }
265
266 static jvmtiError JNICALL
267 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
268                         jboolean *result)
269 {
270   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
271   if (klass == NULL)
272     return JVMTI_ERROR_INVALID_CLASS;
273   NULL_CHECK (result);
274   *result = klass->isArray();
275   return JVMTI_ERROR_NONE;
276 }
277
278 static jvmtiError JNICALL
279 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
280                           jobject *result)
281 {
282   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
283   if (klass == NULL)
284     return JVMTI_ERROR_INVALID_CLASS;
285   NULL_CHECK (result);
286   *result = klass->getClassLoaderInternal();
287   return JVMTI_ERROR_NONE;
288 }
289
290 static jvmtiError JNICALL
291 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
292                              jint *result)
293 {
294   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
295   if (obj == NULL)
296     return JVMTI_ERROR_INVALID_OBJECT;
297   NULL_CHECK (result);
298   *result = _Jv_HashCode (obj);
299   return JVMTI_ERROR_NONE;
300 }
301
302 static jvmtiError JNICALL
303 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
304                              jfieldID field, jint *result)
305 {
306   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
307   if (klass == NULL)
308     return JVMTI_ERROR_INVALID_CLASS;
309   if (field == NULL)
310     return JVMTI_ERROR_INVALID_FIELDID;
311   NULL_CHECK (result);
312   *result = field->getModifiers();
313   return JVMTI_ERROR_NONE;
314 }
315
316 static jvmtiError JNICALL
317 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
318                             jfieldID field, jboolean *result)
319 {
320   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
321   if (klass == NULL)
322     return JVMTI_ERROR_INVALID_CLASS;
323   if (field == NULL)
324     return JVMTI_ERROR_INVALID_FIELDID;
325   NULL_CHECK (result);
326
327   // FIXME: capability can_get_synthetic_attribute
328   *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
329              != 0);
330   return JVMTI_ERROR_NONE;
331 }
332
333 static jvmtiError JNICALL
334 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
335                               jint *result)
336 {
337   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
338   if (method == NULL)
339     return JVMTI_ERROR_INVALID_METHODID;
340   NULL_CHECK (result);
341
342   // FIXME: mask off some internal bits...
343   *result = method->accflags;
344   return JVMTI_ERROR_NONE;
345 }
346
347 static jvmtiError JNICALL
348 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
349                           jboolean *result)
350 {
351   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
352   if (method == NULL)
353     return JVMTI_ERROR_INVALID_METHODID;
354   NULL_CHECK (result);
355
356   *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
357   return JVMTI_ERROR_NONE;
358 }
359
360 static jvmtiError JNICALL
361 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
362                              jboolean *result)
363 {
364   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
365   if (method == NULL)
366     return JVMTI_ERROR_INVALID_METHODID;
367   NULL_CHECK (result);
368
369   // FIXME capability can_get_synthetic_attribute
370
371   *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
372              != 0);
373   return JVMTI_ERROR_NONE;
374 }
375
376 static jvmtiError JNICALL
377 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
378                                  jobject init_loader,
379                                  jint *count_ptr,
380                                  jclass **result_ptr)
381 {
382   using namespace java::lang;
383   using namespace java::util;
384
385   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
386   NULL_CHECK (count_ptr);
387   NULL_CHECK (result_ptr);
388
389   ClassLoader *loader = (ClassLoader *) init_loader;
390   if (loader == NULL)
391     loader = VMClassLoader::bootLoader;
392
393   Collection *values = loader->loadedClasses->values();
394   jobjectArray array = values->toArray();
395   *count_ptr = array->length;
396   jobject *elts = elements (array);
397   jclass *result = (jclass *) _Jv_Malloc (*count_ptr * sizeof (jclass));
398   // FIXME: JNI references...
399   memcpy (result, elts, *count_ptr * sizeof (jclass));
400
401   *result_ptr = result;
402
403   return JVMTI_ERROR_NONE;
404 }
405
406 static jvmtiError JNICALL
407 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
408 {
409   REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
410   _Jv_RunGC();
411   return JVMTI_ERROR_NONE;
412 }
413
414 static jvmtiError JNICALL
415 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
416                                const jniNativeInterface *function_table)
417 {
418   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
419   NULL_CHECK (function_table);
420   memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
421   return JVMTI_ERROR_NONE;
422 }
423
424 static jvmtiError JNICALL
425 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
426                                jniNativeInterface **function_table)
427 {
428   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
429   NULL_CHECK (function_table);
430   *function_table
431     = (jniNativeInterface *) _Jv_Malloc (sizeof (jniNativeInterface));
432   memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
433   return JVMTI_ERROR_NONE;
434 }
435
436 static jvmtiError JNICALL
437 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
438 {
439   // All we need to do is free memory allocated by _Jv_GetJVMTIEnv
440   _Jv_Free (env);
441   return JVMTI_ERROR_NONE;
442 }
443
444 static jvmtiError JNICALL
445 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
446                              char **result)
447 {
448   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
449   NULL_CHECK (property);
450   NULL_CHECK (result);
451
452   jstring name = JvNewStringUTF(property);
453   jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
454
455   if (result_str == NULL)
456     return JVMTI_ERROR_NOT_AVAILABLE;
457
458   int len = JvGetStringUTFLength (result_str);
459   *result = (char *) _Jv_Malloc (len + 1);
460   JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
461   (*result)[len] = '\0';
462
463   return JVMTI_ERROR_NONE;
464 }
465
466 static jvmtiError JNICALL
467 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
468                              const char *value)
469 {
470   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
471
472   NULL_CHECK (property);
473   if (value == NULL)
474     {
475       // FIXME: When would a property not be writeable?
476       return JVMTI_ERROR_NONE;
477     }
478
479   jstring prop_str = JvNewStringUTF(property);
480   jstring value_str = JvNewStringUTF(value);
481   gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
482   return JVMTI_ERROR_NONE;
483 }
484
485 static jvmtiError JNICALL
486 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
487 {
488   NULL_CHECK (nanos_ptr);
489   *nanos_ptr = _Jv_platform_nanotime();
490   return JVMTI_ERROR_NONE;
491 }
492
493 static jvmtiError JNICALL
494 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
495                                   jint *nprocessors_ptr)
496 {
497   NULL_CHECK (nprocessors_ptr);
498 #ifdef _SC_NPROCESSORS_ONLN
499   *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
500 #else
501   *nprocessors_ptr = 1;
502 #endif
503   return JVMTI_ERROR_NONE;
504 }
505
506 static jvmtiError JNICALL
507 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
508                                            const char *segment)
509 {
510   using namespace java::lang;
511   using namespace java::net;
512   using namespace gnu::gcj::runtime;
513
514   REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
515   NULL_CHECK (segment);
516
517   jstring str_segment = JvNewStringUTF(segment);
518   URL *url;
519   try
520     {
521       url = new URL(JvNewStringUTF("file"), NULL, str_segment);
522     }
523   catch (jthrowable ignore)
524     {
525       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
526     }
527
528   BootClassLoader *loader = VMClassLoader::bootLoader;
529   // Don't call this too early.
530   // assert (loader != NULL);
531   loader->addURL(url);
532   return JVMTI_ERROR_NONE;
533 }
534
535 static jvmtiError JNICALL
536 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
537                           jboolean value)
538 {
539   switch (flag)
540     {
541     case JVMTI_VERBOSE_OTHER:
542     case JVMTI_VERBOSE_GC:
543     case JVMTI_VERBOSE_JNI:
544       // Ignore.
545       break;
546     case JVMTI_VERBOSE_CLASS:
547       gcj::verbose_class_flag = value;
548       break;
549     default:
550       return JVMTI_ERROR_ILLEGAL_ARGUMENT;
551     }
552   return JVMTI_ERROR_NONE;
553 }
554
555 static jvmtiError JNICALL
556 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
557                          jlong *result)
558 {
559   REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
560   if (object == NULL)
561     return JVMTI_ERROR_INVALID_OBJECT;
562   NULL_CHECK (result);
563
564   jclass klass = object->getClass();
565   if (klass->isArray())
566     {
567       jclass comp = klass->getComponentType();
568       jint base
569         = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
570                                                                     klass->getComponentType());
571       // FIXME: correct for primitive types?
572       jint compSize = comp->size();
573       __JArray *array = (__JArray *) object;
574       *result = base + array->length * compSize;
575     }
576   else
577     {
578       // Note that if OBJECT is a String then it may (if
579       // str->data==str) take more space.  Do we care?
580       *result = klass->size();
581     }
582   return JVMTI_ERROR_NONE;
583 }
584
585 #define RESERVED NULL
586 #define UNIMPLEMENTED NULL
587
588 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
589 {
590   RESERVED,                     // reserved1
591   UNIMPLEMENTED,                // SetEventNotification
592   RESERVED,                     // reserved3
593   UNIMPLEMENTED,                // GetAllThreads
594   _Jv_JVMTI_SuspendThread,      // SuspendThread
595   _Jv_JVMTI_ResumeThread,       // ResumeThread
596   UNIMPLEMENTED,                // StopThread
597   _Jv_JVMTI_InterruptThread,    // InterruptThread
598   UNIMPLEMENTED,                // GetThreadInfo
599   UNIMPLEMENTED,                // GetOwnedMonitorInfo
600   UNIMPLEMENTED,                // GetCurrentContendedMonitor
601   UNIMPLEMENTED,                // RunAgentThread
602   UNIMPLEMENTED,                // GetTopThreadGroups
603   UNIMPLEMENTED,                // GetThreadGroupInfo
604   UNIMPLEMENTED,                // GetThreadGroupChildren
605   UNIMPLEMENTED,                // GetFrameCount
606   UNIMPLEMENTED,                // GetThreadState
607   RESERVED,                     // reserved18
608   UNIMPLEMENTED,                // GetFrameLocation
609   UNIMPLEMENTED,                // NotifyPopFrame
610   UNIMPLEMENTED,                // GetLocalObject
611   UNIMPLEMENTED,                // GetLocalInt
612   UNIMPLEMENTED,                // GetLocalLong
613   UNIMPLEMENTED,                // GetLocalFloat
614   UNIMPLEMENTED,                // GetLocalDouble
615   UNIMPLEMENTED,                // SetLocalObject
616   UNIMPLEMENTED,                // SetLocalInt
617   UNIMPLEMENTED,                // SetLocalLong
618   UNIMPLEMENTED,                // SetLocalFloat
619   UNIMPLEMENTED,                // SetLocalDouble
620   _Jv_JVMTI_CreateRawMonitor,   // CreateRawMonitor
621   _Jv_JVMTI_DestroyRawMonitor,  // DestroyRawMonitor
622   _Jv_JVMTI_RawMonitorEnter,    // RawMonitorEnter
623   _Jv_JVMTI_RawMonitorExit,     // RawMonitorExit
624   _Jv_JVMTI_RawMonitorWait,     // RawMonitorWait
625   _Jv_JVMTI_RawMonitorNotify,   // RawMonitorNotify
626   _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
627   UNIMPLEMENTED,                // SetBreakpoint
628   UNIMPLEMENTED,                // ClearBreakpoint
629   RESERVED,                     // reserved40
630   UNIMPLEMENTED,                // SetFieldAccessWatch
631   UNIMPLEMENTED,                // ClearFieldAccessWatch
632   UNIMPLEMENTED,                // SetFieldModificationWatch
633   UNIMPLEMENTED,                // ClearFieldModificationWatch
634   RESERVED,                     // reserved45
635   _Jv_JVMTI_Allocate,           // Allocate
636   _Jv_JVMTI_Deallocate,         // Deallocate
637   UNIMPLEMENTED,                // GetClassSignature
638   UNIMPLEMENTED,                // GetClassStatus
639   UNIMPLEMENTED,                // GetSourceFileName
640   _Jv_JVMTI_GetClassModifiers,  // GetClassModifiers
641   _Jv_JVMTI_GetClassMethods,    // GetClassMethods
642   UNIMPLEMENTED,                // GetClassFields
643   UNIMPLEMENTED,                // GetImplementedInterfaces
644   _Jv_JVMTI_IsInterface,        // IsInterface
645   _Jv_JVMTI_IsArrayClass,       // IsArrayClass
646   _Jv_JVMTI_GetClassLoader,     // GetClassLoader
647   _Jv_JVMTI_GetObjectHashCode,  // GetObjectHashCode
648   UNIMPLEMENTED,                // GetObjectMonitorUsage
649   UNIMPLEMENTED,                // GetFieldName
650   UNIMPLEMENTED,                // GetFieldDeclaringClass
651   _Jv_JVMTI_GetFieldModifiers,  // GetFieldModifiers
652   _Jv_JVMTI_IsFieldSynthetic,   // IsFieldSynthetic
653   UNIMPLEMENTED,                // GetMethodName
654   UNIMPLEMENTED,                // GetMethodDeclaringClass
655   _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
656   RESERVED,                     // reserved67
657   UNIMPLEMENTED,                // GetMaxLocals
658   UNIMPLEMENTED,                // GetArgumentsSize
659   UNIMPLEMENTED,                // GetLineNumberTable
660   UNIMPLEMENTED,                // GetMethodLocation
661   UNIMPLEMENTED,                // GetLocalVariableTable
662   RESERVED,                     // reserved73
663   RESERVED,                     // reserved74
664   UNIMPLEMENTED,                // GetBytecodes
665   _Jv_JVMTI_IsMethodNative,     // IsMethodNative
666   _Jv_JVMTI_IsMethodSynthetic,  // IsMethodSynthetic
667   UNIMPLEMENTED,                // GetLoadedClasses
668   _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
669   UNIMPLEMENTED,                // PopFrame
670   RESERVED,                     // reserved81
671   RESERVED,                     // reserved82
672   RESERVED,                     // reserved83
673   RESERVED,                     // reserved84
674   RESERVED,                     // reserved85
675   RESERVED,                     // reserved86
676   UNIMPLEMENTED,                // RedefineClasses
677   UNIMPLEMENTED,                // GetVersionNumber
678   UNIMPLEMENTED,                // GetCapabilities
679   UNIMPLEMENTED,                // GetSourceDebugExtension
680   UNIMPLEMENTED,                // IsMethodObsolete
681   UNIMPLEMENTED,                // SuspendThreadList
682   UNIMPLEMENTED,                // ResumeThreadList
683   RESERVED,                     // reserved94
684   RESERVED,                     // reserved95
685   RESERVED,                     // reserved96
686   RESERVED,                     // reserved97
687   RESERVED,                     // reserved98
688   RESERVED,                     // reserved99
689   UNIMPLEMENTED,                // GetAllStackTraces
690   UNIMPLEMENTED,                // GetThreadListStackTraces
691   UNIMPLEMENTED,                // GetThreadLocalStorage
692   UNIMPLEMENTED,                // SetThreadLocalStorage
693   UNIMPLEMENTED,                // GetStackTrace
694   RESERVED,                     // reserved105
695   UNIMPLEMENTED,                // GetTag
696   UNIMPLEMENTED,                // SetTag
697   _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
698   UNIMPLEMENTED,                // IterateOverObjectsReachable
699   UNIMPLEMENTED,                // IterateOverReachableObjects
700   UNIMPLEMENTED,                // IterateOverHeap
701   UNIMPLEMENTED,                // IterateOverInstanceOfClass
702   RESERVED,                     // reserved113
703   UNIMPLEMENTED,                // GetObjectsWithTags
704   RESERVED,                     // reserved115
705   RESERVED,                     // reserved116
706   RESERVED,                     // reserved117
707   RESERVED,                     // reserved118
708   RESERVED,                     // reserved119
709   _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
710   _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
711   UNIMPLEMENTED,                // SetEventCallbacks
712   UNIMPLEMENTED,                // GenerateEvents
713   UNIMPLEMENTED,                // GetExtensionFunctions
714   UNIMPLEMENTED,                // GetExtensionEvents
715   UNIMPLEMENTED,                // SetExtensionEventCallback
716   _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
717   UNIMPLEMENTED,                // GetErrorName
718   UNIMPLEMENTED,                // GetJLocationFormat
719   UNIMPLEMENTED,                // GetSystemProperties
720   _Jv_JVMTI_GetSystemProperty,  // GetSystemProperty
721   _Jv_JVMTI_SetSystemProperty,  // SetSystemProperty
722   UNIMPLEMENTED,                // GetPhase
723   UNIMPLEMENTED,                // GetCurrentThreadCpuTimerInfo
724   UNIMPLEMENTED,                // GetCurrentThreadCpuTime
725   UNIMPLEMENTED,                // GetThreadCpuTimerInfo
726   UNIMPLEMENTED,                // GetThreadCpuTime
727   UNIMPLEMENTED,                // GetTimerInfo
728   _Jv_JVMTI_GetTime,            // GetTime
729   UNIMPLEMENTED,                // GetPotentialCapabilities
730   RESERVED,                     // reserved141
731   UNIMPLEMENTED,                // AddCapabilities
732   UNIMPLEMENTED,                // RelinquishCapabilities
733   _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
734   RESERVED,                     // reserved145
735   RESERVED,                     // reserved146
736   UNIMPLEMENTED,                // GetEnvironmentLocalStorage
737   UNIMPLEMENTED,                // SetEnvironmentLocalStorage
738   _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
739   _Jv_JVMTI_SetVerboseFlag,     // SetVerboseFlag
740   RESERVED,                     // reserved151
741   RESERVED,                     // reserved152
742   RESERVED,                     // reserved153
743   _Jv_JVMTI_GetObjectSize       // GetObjectSize
744 };
745
746 _Jv_JVMTIEnv *
747 _Jv_GetJVMTIEnv (void)
748 {
749   _Jv_JVMTIEnv *env
750     = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
751   env->p = &_Jv_JVMTI_Interface;
752   return env;
753 }