jvmti.cc (_Jv_JVMTI_CreateRawMonitor): Use _Jv_MallocUnchked and return JVMTI_ERROR_O...
[gcc.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/Object.h>
26 #include <java/lang/Thread.h>
27 #include <java/lang/Throwable.h>
28 #include <java/lang/VMClassLoader.h>
29 #include <java/lang/reflect/Field.h>
30 #include <java/lang/reflect/Modifier.h>
31 #include <java/util/Collection.h>
32 #include <java/util/HashMap.h>
33 #include <java/net/URL.h>
34
35 extern struct JNINativeInterface _Jv_JNIFunctions;
36
37 struct _Jv_rawMonitorID
38 {
39 _Jv_Mutex_t mutex;
40 _Jv_ConditionVariable_t condition;
41 };
42
43 /* A simple linked list of all JVMTI environments. Since
44 events must be delivered to environments in the order
45 in which the environments were created, new environments
46 are added to the end of the list. */
47 struct jvmti_env_list
48 {
49 jvmtiEnv *env;
50 struct jvmti_env_list *next;
51 };
52 static struct jvmti_env_list *_jvmtiEnvironments = NULL;
53 static java::lang::Object *_envListLock = NULL;
54 #define FOREACH_ENVIRONMENT(Ele) \
55 for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
56
57 // Some commonly-used checks
58
59 #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
60 do \
61 { \
62 if (Ajthread == NULL) \
63 Ajthread = java::lang::Thread::currentThread (); \
64 } \
65 while (0)
66
67 #define THREAD_CHECK_VALID(Athread) \
68 do \
69 { \
70 if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
71 return JVMTI_ERROR_INVALID_THREAD; \
72 } \
73 while (0)
74
75 #define THREAD_CHECK_IS_ALIVE(Athread) \
76 do \
77 { \
78 if (!Athread->isAlive ()) \
79 return JVMTI_ERROR_THREAD_NOT_ALIVE; \
80 } \
81 while (0)
82
83 // FIXME: if current phase is not set in Phases,
84 // return JVMTI_ERROR_WRONG_PHASE
85 #define REQUIRE_PHASE(Env, Phases)
86
87 #define NULL_CHECK(Ptr) \
88 do \
89 { \
90 if (Ptr == NULL) \
91 return JVMTI_ERROR_NULL_POINTER; \
92 } \
93 while (0)
94
95 #define ILLEGAL_ARGUMENT(Cond) \
96 do \
97 { \
98 if ((Cond)) \
99 return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
100 } \
101 while (0)
102
103 static jvmtiError JNICALL
104 _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
105 {
106 using namespace java::lang;
107
108 THREAD_DEFAULT_TO_CURRENT (thread);
109
110 Thread *t = reinterpret_cast<Thread *> (thread);
111 THREAD_CHECK_VALID (t);
112 THREAD_CHECK_IS_ALIVE (t);
113
114 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
115 _Jv_SuspendThread (data);
116 return JVMTI_ERROR_NONE;
117 }
118
119 static jvmtiError JNICALL
120 _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
121 {
122 using namespace java::lang;
123
124 THREAD_DEFAULT_TO_CURRENT (thread);
125
126 Thread *t = reinterpret_cast<Thread *> (thread);
127 THREAD_CHECK_VALID (t);
128 THREAD_CHECK_IS_ALIVE (t);
129
130 _Jv_Thread_t *data = _Jv_ThreadGetData (t);
131 _Jv_ResumeThread (data);
132 return JVMTI_ERROR_NONE;
133 }
134
135 static jvmtiError JNICALL
136 _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
137 {
138 using namespace java::lang;
139
140 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
141 // FIXME: capability handling? 'can_signal_thread'
142 if (thread == NULL)
143 return JVMTI_ERROR_INVALID_THREAD;
144
145 Thread *real_thread = reinterpret_cast<Thread *> (thread);
146 THREAD_CHECK_VALID (real_thread);
147 THREAD_CHECK_IS_ALIVE (real_thread);
148 real_thread->interrupt();
149 return JVMTI_ERROR_NONE;
150 }
151
152 static jvmtiError JNICALL
153 _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
154 jrawMonitorID *result)
155 {
156 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
157 NULL_CHECK (name);
158 NULL_CHECK (result);
159 *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
160 if (*result == NULL)
161 return JVMTI_ERROR_OUT_OF_MEMORY;
162 _Jv_MutexInit (&(*result)->mutex);
163 _Jv_CondInit (&(*result)->condition);
164 return JVMTI_ERROR_NONE;
165 }
166
167 static jvmtiError JNICALL
168 _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
169 {
170 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
171 // Note we have no better way of knowing whether this object is
172 // really a raw monitor.
173 if (monitor == NULL)
174 return JVMTI_ERROR_INVALID_MONITOR;
175 // FIXME: perform checks on monitor, release it if this thread owns
176 // it.
177 #ifdef _Jv_HaveMutexDestroy
178 _Jv_MutexDestroy (&monitor->mutex);
179 #endif
180 _Jv_Free (monitor);
181 return JVMTI_ERROR_NONE;
182 }
183
184 static jvmtiError JNICALL
185 _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
186 {
187 if (monitor == NULL)
188 return JVMTI_ERROR_INVALID_MONITOR;
189 _Jv_MutexLock (&monitor->mutex);
190 return JVMTI_ERROR_NONE;
191 }
192
193 static jvmtiError JNICALL
194 _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
195 {
196 if (monitor == NULL)
197 return JVMTI_ERROR_INVALID_MONITOR;
198 if (_Jv_MutexUnlock (&monitor->mutex))
199 return JVMTI_ERROR_NOT_MONITOR_OWNER;
200 return JVMTI_ERROR_NONE;
201 }
202
203 static jvmtiError JNICALL
204 _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
205 jlong millis)
206 {
207 if (monitor == NULL)
208 return JVMTI_ERROR_INVALID_MONITOR;
209 int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
210 if (r == _JV_NOT_OWNER)
211 return JVMTI_ERROR_NOT_MONITOR_OWNER;
212 if (r == _JV_INTERRUPTED)
213 return JVMTI_ERROR_INTERRUPT;
214 return JVMTI_ERROR_NONE;
215 }
216
217 static jvmtiError JNICALL
218 _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
219 {
220 if (monitor == NULL)
221 return JVMTI_ERROR_INVALID_MONITOR;
222 if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
223 return JVMTI_ERROR_NOT_MONITOR_OWNER;
224 return JVMTI_ERROR_NONE;
225 }
226
227 static jvmtiError JNICALL
228 _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
229 jrawMonitorID monitor)
230 {
231 if (monitor == NULL)
232 return JVMTI_ERROR_INVALID_MONITOR;
233 if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
234 == _JV_NOT_OWNER)
235 return JVMTI_ERROR_NOT_MONITOR_OWNER;
236 return JVMTI_ERROR_NONE;
237 }
238
239 static jvmtiError JNICALL
240 _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
241 unsigned char **result)
242 {
243 ILLEGAL_ARGUMENT (size < 0);
244 NULL_CHECK (result);
245 if (size == 0)
246 *result = NULL;
247 else
248 {
249 *result = (unsigned char *) _Jv_MallocUnchecked (size);
250 if (*result == NULL)
251 return JVMTI_ERROR_OUT_OF_MEMORY;
252 }
253 return JVMTI_ERROR_NONE;
254 }
255
256 static jvmtiError JNICALL
257 _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
258 {
259 if (mem != NULL)
260 _Jv_Free (mem);
261 return JVMTI_ERROR_NONE;
262 }
263
264 static jvmtiError JNICALL
265 _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
266 jint *mods)
267 {
268 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
269 // Don't bother checking KLASS' type.
270 if (klass == NULL)
271 return JVMTI_ERROR_INVALID_CLASS;
272 NULL_CHECK (mods);
273 *mods = klass->getModifiers();
274 return JVMTI_ERROR_NONE;
275 }
276
277 static jvmtiError JNICALL
278 _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
279 jint *count_ptr, jmethodID **methods_ptr)
280 {
281 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
282 // FIXME: capability can_maintain_original_method_order
283 // Don't bother checking KLASS' type.
284 if (klass == NULL)
285 return JVMTI_ERROR_INVALID_CLASS;
286 NULL_CHECK (count_ptr);
287 NULL_CHECK (methods_ptr);
288 *count_ptr = JvNumMethods(klass);
289
290 *methods_ptr
291 = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
292 if (*methods_ptr == NULL)
293 return JVMTI_ERROR_OUT_OF_MEMORY;
294
295 jmethodID start = JvGetFirstMethod (klass);
296 for (jint i = 0; i < *count_ptr; ++i)
297 // FIXME: correct?
298 (*methods_ptr)[i] = start + i;
299
300 return JVMTI_ERROR_NONE;
301 }
302
303 static jvmtiError JNICALL
304 _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
305 jboolean *result)
306 {
307 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
308 if (klass == NULL)
309 return JVMTI_ERROR_INVALID_CLASS;
310 NULL_CHECK (result);
311 *result = klass->isInterface();
312 return JVMTI_ERROR_NONE;
313 }
314
315 static jvmtiError JNICALL
316 _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
317 jboolean *result)
318 {
319 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
320 if (klass == NULL)
321 return JVMTI_ERROR_INVALID_CLASS;
322 NULL_CHECK (result);
323 *result = klass->isArray();
324 return JVMTI_ERROR_NONE;
325 }
326
327 static jvmtiError JNICALL
328 _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
329 jobject *result)
330 {
331 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
332 if (klass == NULL)
333 return JVMTI_ERROR_INVALID_CLASS;
334 NULL_CHECK (result);
335 *result = klass->getClassLoaderInternal();
336 return JVMTI_ERROR_NONE;
337 }
338
339 static jvmtiError JNICALL
340 _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
341 jint *result)
342 {
343 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
344 if (obj == NULL)
345 return JVMTI_ERROR_INVALID_OBJECT;
346 NULL_CHECK (result);
347 *result = _Jv_HashCode (obj);
348 return JVMTI_ERROR_NONE;
349 }
350
351 static jvmtiError JNICALL
352 _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
353 jfieldID field, jint *result)
354 {
355 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
356 if (klass == NULL)
357 return JVMTI_ERROR_INVALID_CLASS;
358 if (field == NULL)
359 return JVMTI_ERROR_INVALID_FIELDID;
360 NULL_CHECK (result);
361 *result = field->getModifiers();
362 return JVMTI_ERROR_NONE;
363 }
364
365 static jvmtiError JNICALL
366 _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
367 jfieldID field, jboolean *result)
368 {
369 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
370 if (klass == NULL)
371 return JVMTI_ERROR_INVALID_CLASS;
372 if (field == NULL)
373 return JVMTI_ERROR_INVALID_FIELDID;
374 NULL_CHECK (result);
375
376 // FIXME: capability can_get_synthetic_attribute
377 *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
378 != 0);
379 return JVMTI_ERROR_NONE;
380 }
381
382 static jvmtiError JNICALL
383 _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
384 jint *result)
385 {
386 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
387 if (method == NULL)
388 return JVMTI_ERROR_INVALID_METHODID;
389 NULL_CHECK (result);
390
391 // FIXME: mask off some internal bits...
392 *result = method->accflags;
393 return JVMTI_ERROR_NONE;
394 }
395
396 static jvmtiError JNICALL
397 _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
398 jboolean *result)
399 {
400 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
401 if (method == NULL)
402 return JVMTI_ERROR_INVALID_METHODID;
403 NULL_CHECK (result);
404
405 *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
406 return JVMTI_ERROR_NONE;
407 }
408
409 static jvmtiError JNICALL
410 _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
411 jboolean *result)
412 {
413 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
414 if (method == NULL)
415 return JVMTI_ERROR_INVALID_METHODID;
416 NULL_CHECK (result);
417
418 // FIXME capability can_get_synthetic_attribute
419
420 *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
421 != 0);
422 return JVMTI_ERROR_NONE;
423 }
424
425 static jvmtiError JNICALL
426 _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
427 jobject init_loader,
428 jint *count_ptr,
429 jclass **result_ptr)
430 {
431 using namespace java::lang;
432 using namespace java::util;
433
434 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
435 NULL_CHECK (count_ptr);
436 NULL_CHECK (result_ptr);
437
438 ClassLoader *loader = (ClassLoader *) init_loader;
439 if (loader == NULL)
440 loader = VMClassLoader::bootLoader;
441
442 Collection *values = loader->loadedClasses->values();
443 jobjectArray array = values->toArray();
444 *count_ptr = array->length;
445 jobject *elts = elements (array);
446 jclass *result
447 = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
448 if (result == NULL)
449 return JVMTI_ERROR_OUT_OF_MEMORY;
450
451 // FIXME: JNI references...
452 memcpy (result, elts, *count_ptr * sizeof (jclass));
453
454 *result_ptr = result;
455
456 return JVMTI_ERROR_NONE;
457 }
458
459 static jvmtiError JNICALL
460 _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
461 {
462 REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
463 _Jv_RunGC();
464 return JVMTI_ERROR_NONE;
465 }
466
467 static jvmtiError JNICALL
468 _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
469 const jniNativeInterface *function_table)
470 {
471 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
472 NULL_CHECK (function_table);
473 memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
474 return JVMTI_ERROR_NONE;
475 }
476
477 static jvmtiError JNICALL
478 _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
479 jniNativeInterface **function_table)
480 {
481 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
482 NULL_CHECK (function_table);
483 *function_table
484 = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
485 if (*function_table == NULL)
486 return JVMTI_ERROR_OUT_OF_MEMORY;
487 memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
488 return JVMTI_ERROR_NONE;
489 }
490
491 static jvmtiError JNICALL
492 _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
493 {
494 NULL_CHECK (env);
495
496 if (_jvmtiEnvironments == NULL)
497 return JVMTI_ERROR_INVALID_ENVIRONMENT;
498 else
499 {
500 JvSynchronize dummy (_envListLock);
501 if (_jvmtiEnvironments->env == env)
502 {
503 struct jvmti_env_list *next = _jvmtiEnvironments->next;
504 _Jv_Free (_jvmtiEnvironments);
505 _jvmtiEnvironments = next;
506 }
507 else
508 {
509 struct jvmti_env_list *e = _jvmtiEnvironments;
510 while (e->next != NULL && e->next->env != env)
511 e = e->next;
512 if (e->next == NULL)
513 return JVMTI_ERROR_INVALID_ENVIRONMENT;
514
515 struct jvmti_env_list *next = e->next->next;
516 _Jv_Free (e->next);
517 e->next = next;
518 }
519 }
520
521 _Jv_Free (env);
522 return JVMTI_ERROR_NONE;
523 }
524
525 static jvmtiError JNICALL
526 _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
527 char **result)
528 {
529 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
530 NULL_CHECK (property);
531 NULL_CHECK (result);
532
533 jstring name = JvNewStringUTF(property);
534 jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
535
536 if (result_str == NULL)
537 return JVMTI_ERROR_NOT_AVAILABLE;
538
539 int len = JvGetStringUTFLength (result_str);
540 *result = (char *) _Jv_MallocUnchecked (len + 1);
541 if (*result == NULL)
542 return JVMTI_ERROR_OUT_OF_MEMORY;
543 JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
544 (*result)[len] = '\0';
545
546 return JVMTI_ERROR_NONE;
547 }
548
549 static jvmtiError JNICALL
550 _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
551 const char *value)
552 {
553 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
554
555 NULL_CHECK (property);
556 if (value == NULL)
557 {
558 // FIXME: When would a property not be writeable?
559 return JVMTI_ERROR_NONE;
560 }
561
562 jstring prop_str = JvNewStringUTF(property);
563 jstring value_str = JvNewStringUTF(value);
564 gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
565 return JVMTI_ERROR_NONE;
566 }
567
568 static jvmtiError JNICALL
569 _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
570 {
571 NULL_CHECK (nanos_ptr);
572 *nanos_ptr = _Jv_platform_nanotime();
573 return JVMTI_ERROR_NONE;
574 }
575
576 static jvmtiError JNICALL
577 _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
578 jint *nprocessors_ptr)
579 {
580 NULL_CHECK (nprocessors_ptr);
581 #ifdef _SC_NPROCESSORS_ONLN
582 *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
583 #else
584 *nprocessors_ptr = 1;
585 #endif
586 return JVMTI_ERROR_NONE;
587 }
588
589 static jvmtiError JNICALL
590 _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
591 const char *segment)
592 {
593 using namespace java::lang;
594 using namespace java::net;
595 using namespace gnu::gcj::runtime;
596
597 REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
598 NULL_CHECK (segment);
599
600 jstring str_segment = JvNewStringUTF(segment);
601 URL *url;
602 try
603 {
604 url = new URL(JvNewStringUTF("file"), NULL, str_segment);
605 }
606 catch (jthrowable ignore)
607 {
608 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
609 }
610
611 BootClassLoader *loader = VMClassLoader::bootLoader;
612 // Don't call this too early.
613 // assert (loader != NULL);
614 loader->addURL(url);
615 return JVMTI_ERROR_NONE;
616 }
617
618 static jvmtiError JNICALL
619 _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
620 jboolean value)
621 {
622 switch (flag)
623 {
624 case JVMTI_VERBOSE_OTHER:
625 case JVMTI_VERBOSE_GC:
626 case JVMTI_VERBOSE_JNI:
627 // Ignore.
628 break;
629 case JVMTI_VERBOSE_CLASS:
630 gcj::verbose_class_flag = value;
631 break;
632 default:
633 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
634 }
635 return JVMTI_ERROR_NONE;
636 }
637
638 static jvmtiError JNICALL
639 _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
640 jlong *result)
641 {
642 REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
643 if (object == NULL)
644 return JVMTI_ERROR_INVALID_OBJECT;
645 NULL_CHECK (result);
646
647 jclass klass = object->getClass();
648 if (klass->isArray())
649 {
650 jclass comp = klass->getComponentType();
651 jint base
652 = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
653 klass->getComponentType());
654 // FIXME: correct for primitive types?
655 jint compSize = comp->size();
656 __JArray *array = (__JArray *) object;
657 *result = base + array->length * compSize;
658 }
659 else
660 {
661 // Note that if OBJECT is a String then it may (if
662 // str->data==str) take more space. Do we care?
663 *result = klass->size();
664 }
665 return JVMTI_ERROR_NONE;
666 }
667
668 jvmtiError
669 _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
670 char **name_ptr)
671 {
672 NULL_CHECK (name_ptr);
673
674 const char *name;
675 switch (error)
676 {
677 case JVMTI_ERROR_NONE:
678 name = "none";
679 break;
680
681 case JVMTI_ERROR_NULL_POINTER:
682 name = "null pointer";
683 break;
684
685 case JVMTI_ERROR_OUT_OF_MEMORY:
686 name = "out of memory";
687 break;
688
689 case JVMTI_ERROR_ACCESS_DENIED:
690 name = "access denied";
691 break;
692
693 case JVMTI_ERROR_WRONG_PHASE:
694 name = "wrong phase";
695 break;
696
697 case JVMTI_ERROR_INTERNAL:
698 name = "internal error";
699 break;
700
701 case JVMTI_ERROR_UNATTACHED_THREAD:
702 name = "unattached thread";
703 break;
704
705 case JVMTI_ERROR_INVALID_ENVIRONMENT:
706 name = "invalid environment";
707 break;
708
709 case JVMTI_ERROR_INVALID_PRIORITY:
710 name = "invalid priority";
711 break;
712
713 case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
714 name = "thread not suspended";
715 break;
716
717 case JVMTI_ERROR_THREAD_SUSPENDED:
718 name = "thread suspended";
719 break;
720
721 case JVMTI_ERROR_THREAD_NOT_ALIVE:
722 name = "thread not alive";
723 break;
724
725 case JVMTI_ERROR_CLASS_NOT_PREPARED:
726 name = "class not prepared";
727 break;
728
729 case JVMTI_ERROR_NO_MORE_FRAMES:
730 name = "no more frames";
731 break;
732
733 case JVMTI_ERROR_OPAQUE_FRAME:
734 name = "opaque frame";
735 break;
736
737 case JVMTI_ERROR_DUPLICATE:
738 name = "duplicate";
739 break;
740
741 case JVMTI_ERROR_NOT_FOUND:
742 name = "not found";
743 break;
744
745 case JVMTI_ERROR_NOT_MONITOR_OWNER:
746 name = "not monitor owner";
747 break;
748
749 case JVMTI_ERROR_INTERRUPT:
750 name = "interrupted";
751 break;
752
753 case JVMTI_ERROR_UNMODIFIABLE_CLASS:
754 name = "unmodifiable class";
755 break;
756
757 case JVMTI_ERROR_NOT_AVAILABLE:
758 name = "not available";
759 break;
760
761 case JVMTI_ERROR_ABSENT_INFORMATION:
762 name = "absent information";
763 break;
764
765 case JVMTI_ERROR_INVALID_EVENT_TYPE:
766 name = "invalid event type";
767 break;
768
769 case JVMTI_ERROR_NATIVE_METHOD:
770 name = "native method";
771 break;
772
773 case JVMTI_ERROR_INVALID_THREAD:
774 name = "invalid thread";
775 break;
776
777 case JVMTI_ERROR_INVALID_THREAD_GROUP:
778 name = "invalid thread group";
779 break;
780
781 case JVMTI_ERROR_INVALID_OBJECT:
782 name = "invalid object";
783 break;
784
785 case JVMTI_ERROR_INVALID_CLASS:
786 name = "invalid class";
787 break;
788
789 case JVMTI_ERROR_INVALID_METHODID:
790 name = "invalid method ID";
791 break;
792
793 case JVMTI_ERROR_INVALID_LOCATION:
794 name = "invalid location";
795 break;
796
797 case JVMTI_ERROR_INVALID_FIELDID:
798 name = "invalid field ID";
799 break;
800
801 case JVMTI_ERROR_TYPE_MISMATCH:
802 name = "type mismatch";
803 break;
804
805 case JVMTI_ERROR_INVALID_SLOT:
806 name = "invalid slot";
807 break;
808
809 case JVMTI_ERROR_INVALID_MONITOR:
810 name = "invalid monitor";
811 break;
812
813 case JVMTI_ERROR_INVALID_CLASS_FORMAT:
814 name = "invalid class format";
815 break;
816
817 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
818 name = "circular class definition";
819 break;
820
821 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
822 name = "unsupported redefinition: method added";
823 break;
824
825 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
826 name = "unsupported redefinition: schema changed";
827 break;
828
829 case JVMTI_ERROR_INVALID_TYPESTATE:
830 name = "invalid type state";
831 break;
832
833 case JVMTI_ERROR_FAILS_VERIFICATION:
834 name = "fails verification";
835 break;
836
837 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
838 name = "unsupported redefinition: hierarchy changed";
839 break;
840
841 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
842 name = "unsupported redefinition: method deleted";
843 break;
844
845 case JVMTI_ERROR_UNSUPPORTED_VERSION:
846 name = "unsupported version";
847 break;
848
849 case JVMTI_ERROR_NAMES_DONT_MATCH:
850 name = "names do not match";
851 break;
852
853 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
854 name = "unsupported redefinition: class modifiers changed";
855 break;
856
857 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
858 name = "unsupported redefinition: method modifiers changed";
859 break;
860
861 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
862 name = "must possess capability";
863 break;
864
865 case JVMTI_ERROR_ILLEGAL_ARGUMENT:
866 name = "illegal argument";
867 break;
868
869 default:
870 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
871 }
872
873 *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
874 if (*name_ptr == NULL)
875 return JVMTI_ERROR_OUT_OF_MEMORY;
876
877 strcpy (*name_ptr, name);
878 return JVMTI_ERROR_NONE;
879 }
880
881 #define RESERVED NULL
882 #define UNIMPLEMENTED NULL
883
884 struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
885 {
886 RESERVED, // reserved1
887 UNIMPLEMENTED, // SetEventNotification
888 RESERVED, // reserved3
889 UNIMPLEMENTED, // GetAllThreads
890 _Jv_JVMTI_SuspendThread, // SuspendThread
891 _Jv_JVMTI_ResumeThread, // ResumeThread
892 UNIMPLEMENTED, // StopThread
893 _Jv_JVMTI_InterruptThread, // InterruptThread
894 UNIMPLEMENTED, // GetThreadInfo
895 UNIMPLEMENTED, // GetOwnedMonitorInfo
896 UNIMPLEMENTED, // GetCurrentContendedMonitor
897 UNIMPLEMENTED, // RunAgentThread
898 UNIMPLEMENTED, // GetTopThreadGroups
899 UNIMPLEMENTED, // GetThreadGroupInfo
900 UNIMPLEMENTED, // GetThreadGroupChildren
901 UNIMPLEMENTED, // GetFrameCount
902 UNIMPLEMENTED, // GetThreadState
903 RESERVED, // reserved18
904 UNIMPLEMENTED, // GetFrameLocation
905 UNIMPLEMENTED, // NotifyPopFrame
906 UNIMPLEMENTED, // GetLocalObject
907 UNIMPLEMENTED, // GetLocalInt
908 UNIMPLEMENTED, // GetLocalLong
909 UNIMPLEMENTED, // GetLocalFloat
910 UNIMPLEMENTED, // GetLocalDouble
911 UNIMPLEMENTED, // SetLocalObject
912 UNIMPLEMENTED, // SetLocalInt
913 UNIMPLEMENTED, // SetLocalLong
914 UNIMPLEMENTED, // SetLocalFloat
915 UNIMPLEMENTED, // SetLocalDouble
916 _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
917 _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
918 _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
919 _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
920 _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
921 _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
922 _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
923 UNIMPLEMENTED, // SetBreakpoint
924 UNIMPLEMENTED, // ClearBreakpoint
925 RESERVED, // reserved40
926 UNIMPLEMENTED, // SetFieldAccessWatch
927 UNIMPLEMENTED, // ClearFieldAccessWatch
928 UNIMPLEMENTED, // SetFieldModificationWatch
929 UNIMPLEMENTED, // ClearFieldModificationWatch
930 RESERVED, // reserved45
931 _Jv_JVMTI_Allocate, // Allocate
932 _Jv_JVMTI_Deallocate, // Deallocate
933 UNIMPLEMENTED, // GetClassSignature
934 UNIMPLEMENTED, // GetClassStatus
935 UNIMPLEMENTED, // GetSourceFileName
936 _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
937 _Jv_JVMTI_GetClassMethods, // GetClassMethods
938 UNIMPLEMENTED, // GetClassFields
939 UNIMPLEMENTED, // GetImplementedInterfaces
940 _Jv_JVMTI_IsInterface, // IsInterface
941 _Jv_JVMTI_IsArrayClass, // IsArrayClass
942 _Jv_JVMTI_GetClassLoader, // GetClassLoader
943 _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
944 UNIMPLEMENTED, // GetObjectMonitorUsage
945 UNIMPLEMENTED, // GetFieldName
946 UNIMPLEMENTED, // GetFieldDeclaringClass
947 _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
948 _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
949 UNIMPLEMENTED, // GetMethodName
950 UNIMPLEMENTED, // GetMethodDeclaringClass
951 _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
952 RESERVED, // reserved67
953 UNIMPLEMENTED, // GetMaxLocals
954 UNIMPLEMENTED, // GetArgumentsSize
955 UNIMPLEMENTED, // GetLineNumberTable
956 UNIMPLEMENTED, // GetMethodLocation
957 UNIMPLEMENTED, // GetLocalVariableTable
958 RESERVED, // reserved73
959 RESERVED, // reserved74
960 UNIMPLEMENTED, // GetBytecodes
961 _Jv_JVMTI_IsMethodNative, // IsMethodNative
962 _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
963 UNIMPLEMENTED, // GetLoadedClasses
964 _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
965 UNIMPLEMENTED, // PopFrame
966 RESERVED, // reserved81
967 RESERVED, // reserved82
968 RESERVED, // reserved83
969 RESERVED, // reserved84
970 RESERVED, // reserved85
971 RESERVED, // reserved86
972 UNIMPLEMENTED, // RedefineClasses
973 UNIMPLEMENTED, // GetVersionNumber
974 UNIMPLEMENTED, // GetCapabilities
975 UNIMPLEMENTED, // GetSourceDebugExtension
976 UNIMPLEMENTED, // IsMethodObsolete
977 UNIMPLEMENTED, // SuspendThreadList
978 UNIMPLEMENTED, // ResumeThreadList
979 RESERVED, // reserved94
980 RESERVED, // reserved95
981 RESERVED, // reserved96
982 RESERVED, // reserved97
983 RESERVED, // reserved98
984 RESERVED, // reserved99
985 UNIMPLEMENTED, // GetAllStackTraces
986 UNIMPLEMENTED, // GetThreadListStackTraces
987 UNIMPLEMENTED, // GetThreadLocalStorage
988 UNIMPLEMENTED, // SetThreadLocalStorage
989 UNIMPLEMENTED, // GetStackTrace
990 RESERVED, // reserved105
991 UNIMPLEMENTED, // GetTag
992 UNIMPLEMENTED, // SetTag
993 _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
994 UNIMPLEMENTED, // IterateOverObjectsReachable
995 UNIMPLEMENTED, // IterateOverReachableObjects
996 UNIMPLEMENTED, // IterateOverHeap
997 UNIMPLEMENTED, // IterateOverInstanceOfClass
998 RESERVED, // reserved113
999 UNIMPLEMENTED, // GetObjectsWithTags
1000 RESERVED, // reserved115
1001 RESERVED, // reserved116
1002 RESERVED, // reserved117
1003 RESERVED, // reserved118
1004 RESERVED, // reserved119
1005 _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
1006 _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
1007 UNIMPLEMENTED, // SetEventCallbacks
1008 UNIMPLEMENTED, // GenerateEvents
1009 UNIMPLEMENTED, // GetExtensionFunctions
1010 UNIMPLEMENTED, // GetExtensionEvents
1011 UNIMPLEMENTED, // SetExtensionEventCallback
1012 _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
1013 _Jv_JVMTI_GetErrorName, // GetErrorName
1014 UNIMPLEMENTED, // GetJLocationFormat
1015 UNIMPLEMENTED, // GetSystemProperties
1016 _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
1017 _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
1018 UNIMPLEMENTED, // GetPhase
1019 UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
1020 UNIMPLEMENTED, // GetCurrentThreadCpuTime
1021 UNIMPLEMENTED, // GetThreadCpuTimerInfo
1022 UNIMPLEMENTED, // GetThreadCpuTime
1023 UNIMPLEMENTED, // GetTimerInfo
1024 _Jv_JVMTI_GetTime, // GetTime
1025 UNIMPLEMENTED, // GetPotentialCapabilities
1026 RESERVED, // reserved141
1027 UNIMPLEMENTED, // AddCapabilities
1028 UNIMPLEMENTED, // RelinquishCapabilities
1029 _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
1030 RESERVED, // reserved145
1031 RESERVED, // reserved146
1032 UNIMPLEMENTED, // GetEnvironmentLocalStorage
1033 UNIMPLEMENTED, // SetEnvironmentLocalStorage
1034 _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
1035 _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
1036 RESERVED, // reserved151
1037 RESERVED, // reserved152
1038 RESERVED, // reserved153
1039 _Jv_JVMTI_GetObjectSize // GetObjectSize
1040 };
1041
1042 _Jv_JVMTIEnv *
1043 _Jv_GetJVMTIEnv (void)
1044 {
1045 _Jv_JVMTIEnv *env
1046 = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
1047 env->p = &_Jv_JVMTI_Interface;
1048
1049 {
1050 JvSynchronize dummy (_envListLock);
1051 struct jvmti_env_list *element
1052 = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
1053 element->env = env;
1054 element->next = NULL;
1055
1056 if (_jvmtiEnvironments == NULL)
1057 _jvmtiEnvironments = element;
1058 else
1059 {
1060 struct jvmti_env_list *e;
1061 for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
1062 ;
1063 e->next = element;
1064 }
1065 }
1066
1067 return env;
1068 }
1069
1070 void
1071 _Jv_JVMTI_Init ()
1072 {
1073 _jvmtiEnvironments = NULL;
1074 _envListLock = new java::lang::Object ();
1075 }