1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine Tool
4 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
5 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
6 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
7 Institut f. Computersprachen - TU Wien
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Author: Martin Platter
33 $Id: jvmti.c 3588 2005-11-06 14:01:10Z motse $
39 #include "native/jni.h"
40 #include "native/jvmti/jvmti.h"
41 #include "vm/global.h"
42 #include "vm/loader.h"
43 #include "vm/builtin.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/classcache.h"
47 #include "toolbox/logging.h"
48 #include "vm/options.h"
49 #include "cacao/cacao.h"
50 #include "vm/stringlocal.h"
51 #include "mm/memory.h"
52 #include "threads/native/threads.h"
53 #include "vm/exceptions.h"
54 #include "native/include/java_util_Vector.h"
55 #include "native/include/java_io_PrintStream.h"
56 #include "native/include/java_io_InputStream.h"
57 #include "native/include/java_lang_Cloneable.h"
58 #include "native/include/java_lang_ThreadGroup.h"
59 #include "native/include/java_lang_VMObject.h"
60 #include "native/include/java_lang_VMSystem.h"
61 #include "native/include/java_lang_VMClass.h"
62 #include "vm/jit/stacktrace.h"
65 #include <linux/unistd.h>
67 #include "toolbox/logging.h"
69 #include <sys/types.h>
74 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
75 #include "threads/native/threads.h"
82 typedef struct _environment environment;
83 environment *envs=NULL;
85 extern const struct JNIInvokeInterface JNI_JavaVMTable;
87 static jvmtiPhase phase;
88 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
89 struct _jvmtiEventModeLL {
92 jvmtiEventModeLL *next;
95 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
96 struct _jvmtiThreadLocalStorage{
98 jvmtiThreadLocalStorage *next;
102 struct _environment {
104 jvmtiEventCallbacks callbacks;
105 /* table for enabled/disabled jvmtiEvents - first element contains global
107 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
108 jvmtiCapabilities capabilities;
109 void *EnvironmentLocalStorage;
110 jvmtiThreadLocalStorage *tls;
115 static jvmtiEnv JVMTI_EnvTable;
116 static jvmtiCapabilities JVMTI_Capabilities;
117 static lt_ptr unload;
119 #define CHECK_PHASE_START if (!(0
120 #define CHECK_PHASE(chkphase) || (phase == chkphase)
121 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
122 #define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
123 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
124 #define CHECK_THREAD_IS_ALIVE(t) if((((java_lang_Thread*)t)->vmThread==NULL)&& \
125 (((java_lang_Thread*)t)->group==NULL)) \
126 return JVMTI_ERROR_THREAD_NOT_ALIVE;
130 static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
131 JNIEnv* jni_env = ptr_env;
134 case JVMTI_EVENT_VM_INIT:
135 case JVMTI_EVENT_THREAD_START:
136 case JVMTI_EVENT_THREAD_END:
137 ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
141 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
142 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
147 data->protection_domain,
150 data->new_class_data_len,
151 data->new_class_data);
155 case JVMTI_EVENT_CLASS_PREPARE:
156 case JVMTI_EVENT_CLASS_LOAD:
157 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
158 data->thread, data->klass);
161 case JVMTI_EVENT_VM_DEATH:
162 case JVMTI_EVENT_VM_START:
163 ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
166 case JVMTI_EVENT_EXCEPTION:
167 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
173 data->catch_location);
176 case JVMTI_EVENT_EXCEPTION_CATCH:
177 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
184 case JVMTI_EVENT_BREAKPOINT:
185 case JVMTI_EVENT_SINGLE_STEP:
186 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
192 case JVMTI_EVENT_FRAME_POP:
193 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
199 case JVMTI_EVENT_FIELD_ACCESS:
200 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
209 case JVMTI_EVENT_FIELD_MODIFICATION:
210 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
217 data->signature_type,
221 case JVMTI_EVENT_METHOD_ENTRY:
222 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
227 case JVMTI_EVENT_METHOD_EXIT:
228 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
235 case JVMTI_EVENT_NATIVE_METHOD_BIND:
236 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
240 data->new_address_ptr);
243 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
244 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
253 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
254 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
259 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
260 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
266 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
267 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
268 case JVMTI_EVENT_DATA_DUMP_REQUEST:
269 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
272 case JVMTI_EVENT_MONITOR_WAIT:
273 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
279 case JVMTI_EVENT_MONITOR_WAITED:
280 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
287 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
288 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
289 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
294 case JVMTI_EVENT_OBJECT_FREE:
295 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
298 case JVMTI_EVENT_VM_OBJECT_ALLOC:
299 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
308 log_text ("unknown event");
312 /* fireEvent **************************************************************
314 fire event callback with data arguments.
316 *******************************************************************************/
318 void fireEvent(jvmtiEvent e, genericEventData* data) {
320 jvmtiEventModeLL *evm;
324 /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
326 thread = (jthread)THREADOBJECT;
328 data->thread = thread;
333 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
334 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
335 /* test if the event is enable for some threads */
337 if (evm->mode == JVMTI_ENABLE) {
338 data->jvmti_env=&env->env;
339 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
340 execcallback(e, ec, data);
344 } else { /* event enabled globally */
345 data->jvmti_env=&env->env;
346 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
347 execcallback(e, ec, data);
356 /* getchildproc ***************************************************************
358 Get data from child process
360 *******************************************************************************/
361 static long getchildproc (void *ptr) {
363 /* get data from child process */
364 return GETMEM(debuggee,ptr);
366 return *((long*)ptr);
372 /* SetEventNotificationMode ****************************************************
374 Control the generation of events
376 *******************************************************************************/
379 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
380 jvmtiEvent event_type, jthread event_thread, ...)
382 environment* cacao_env;
383 jvmtiEventModeLL *ll;
386 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
387 CHECK_PHASE(JVMTI_PHASE_LIVE)
390 if((event_thread != NULL)&&
391 (!builtin_instanceof(event_thread,class_java_lang_Thread)))
392 return JVMTI_ERROR_INVALID_THREAD;
394 CHECK_THREAD_IS_ALIVE(event_thread);
396 cacao_env = (environment*) env;
397 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
398 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
400 if ((event_type < JVMTI_EVENT_START_ENUM) ||
401 (event_type > JVMTI_EVENT_END_ENUM))
402 return JVMTI_ERROR_INVALID_EVENT_TYPE;
405 switch (event_type) { /* check capability */
406 case JVMTI_EVENT_EXCEPTION:
407 case JVMTI_EVENT_EXCEPTION_CATCH:
408 CHECK_CAPABILITY(env,can_generate_exception_events)
410 case JVMTI_EVENT_SINGLE_STEP:
411 CHECK_CAPABILITY(env,can_generate_single_step_events)
413 case JVMTI_EVENT_FRAME_POP:
414 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
416 case JVMTI_EVENT_BREAKPOINT:
417 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
419 case JVMTI_EVENT_FIELD_ACCESS:
420 CHECK_CAPABILITY(env,can_generate_field_access_events)
422 case JVMTI_EVENT_FIELD_MODIFICATION:
423 CHECK_CAPABILITY(env,can_generate_field_modification_events)
425 case JVMTI_EVENT_METHOD_ENTRY:
426 CHECK_CAPABILITY(env,can_generate_method_entry_events)
428 case JVMTI_EVENT_METHOD_EXIT:
429 CHECK_CAPABILITY(env, can_generate_method_exit_events)
431 case JVMTI_EVENT_NATIVE_METHOD_BIND:
432 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
434 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
435 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
436 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
438 case JVMTI_EVENT_MONITOR_WAIT:
439 case JVMTI_EVENT_MONITOR_WAITED:
440 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
441 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
442 CHECK_CAPABILITY(env,can_generate_monitor_events)
444 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
445 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
446 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
448 case JVMTI_EVENT_OBJECT_FREE:
449 CHECK_CAPABILITY(env,can_generate_object_free_events)
451 case JVMTI_EVENT_VM_OBJECT_ALLOC:
452 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
455 /* all other events are required */
459 if (event_thread != NULL) {
460 /* thread level control */
461 if ((JVMTI_EVENT_VM_INIT == mode) ||
462 (JVMTI_EVENT_VM_DEATH == mode) ||
463 (JVMTI_EVENT_VM_START == mode) ||
464 (JVMTI_EVENT_THREAD_START == mode) ||
465 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
466 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
467 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
468 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
469 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
470 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
471 while (ll->next != NULL) {
473 if (ll->event_thread == event_thread) {
475 return JVMTI_ERROR_NONE;
478 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
482 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
486 return JVMTI_ERROR_NONE;
490 /* GetAllThreads ***************************************************************
494 *******************************************************************************/
497 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
498 jthread ** threads_ptr)
501 threadobject* thread;
504 CHECK_PHASE(JVMTI_PHASE_LIVE)
507 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
508 return JVMTI_ERROR_NULL_POINTER;
510 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
511 thread = mainthreadobj;
513 if((thread->o.thread->vmThread==NULL)&& (thread->o.thread->group==NULL))
514 i++; /* count only live threads */
515 thread = thread->info.prev;
516 } while (thread != mainthreadobj);
518 *threads_count_ptr = i;
520 *threads_ptr = (jthread*) heap_allocate(sizeof(jthread) * i,true,NULL);
523 memcpy(*threads_ptr[i],thread,sizeof(jthread));
524 thread = thread->info.prev;
526 } while (thread != mainthreadobj);
528 return JVMTI_ERROR_NOT_AVAILABLE;
531 return JVMTI_ERROR_NONE;
535 /* SuspendThread ***************************************************************
537 Suspend specified thread
539 *******************************************************************************/
542 SuspendThread (jvmtiEnv * env, jthread thread)
545 CHECK_PHASE(JVMTI_PHASE_LIVE)
547 CHECK_CAPABILITY(env,can_suspend)
549 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
550 suspendThread((thread *) thread->thread);
553 return JVMTI_ERROR_NONE;
556 /* ResumeThread ***************************************************************
558 Resume a suspended thread
560 *******************************************************************************/
563 ResumeThread (jvmtiEnv * env, jthread thread)
566 CHECK_PHASE(JVMTI_PHASE_LIVE)
568 CHECK_CAPABILITY(env,can_suspend)
570 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
571 resumeThread((thread *) this->thread);
574 return JVMTI_ERROR_NONE;
577 /* StopThread *****************************************************************
579 Send asynchronous exception to the specified thread. Similar to
580 java.lang.Thread.stop(). Used to kill thread.
582 *******************************************************************************/
585 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
588 CHECK_PHASE(JVMTI_PHASE_LIVE)
590 CHECK_CAPABILITY(env,can_signal_thread)
592 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
593 return JVMTI_ERROR_NONE;
596 /* InterruptThread ************************************************************
598 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
600 *******************************************************************************/
603 InterruptThread (jvmtiEnv * env, jthread thread)
606 CHECK_PHASE(JVMTI_PHASE_LIVE)
608 CHECK_CAPABILITY(env,can_signal_thread)
610 if(!builtin_instanceof(thread,class_java_lang_Thread))
611 return JVMTI_ERROR_INVALID_THREAD;
613 CHECK_THREAD_IS_ALIVE(thread);
615 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
616 interruptThread((java_lang_VMThread*)thread);
618 return JVMTI_ERROR_NOT_AVAILABLE;
621 return JVMTI_ERROR_NONE;
624 /* GetThreadInfo ***************************************************************
626 Get thread information. Details of the specified thread are stored in the
627 jvmtiThreadInfo structure.
629 *******************************************************************************/
632 GetThreadInfo (jvmtiEnv * env, jthread th, jvmtiThreadInfo * info_ptr)
634 java_lang_Thread* t = (java_lang_Thread*)th;
639 CHECK_PHASE(JVMTI_PHASE_LIVE)
642 name = javastring_tochar((java_objectheader*)t->name);
644 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
645 strncpy(info_ptr->name,name,size);
646 info_ptr->priority=(jint)t->priority;
647 info_ptr->is_daemon=(jboolean)t->daemon;
648 info_ptr->thread_group=(jthreadGroup)t->group;
649 info_ptr->context_class_loader=(jobject)t->contextClassLoader;
651 return JVMTI_ERROR_NONE;
654 /* GetOwnedMonitorInfo *********************************************************
656 Get information about the monitors owned by the specified thread
658 *******************************************************************************/
661 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
662 jint * owned_monitor_count_ptr,
663 jobject ** owned_monitors_ptr)
670 CHECK_PHASE(JVMTI_PHASE_LIVE)
672 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
674 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
675 return JVMTI_ERROR_NULL_POINTER;
677 if(!builtin_instanceof(thread,class_java_lang_Thread))
678 return JVMTI_ERROR_INVALID_THREAD;
680 CHECK_THREAD_IS_ALIVE(thread);
682 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
684 om=MNEW(java_objectheader*,size);
686 pthread_mutex_lock(&pool_lock);
690 while (lrp != NULL) {
691 for (j=0; j<lrp->header.size; j++) {
692 if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
693 (!lrp->lr[j].waiting)) {
695 MREALLOC(om,java_objectheader*,size,size*2);
702 lrp=lrp->header.next;
705 pthread_mutex_unlock(&pool_lock);
707 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
708 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
709 MFREE(om,java_objectheader*,size);
711 *owned_monitor_count_ptr = i;
715 return JVMTI_ERROR_NONE;
718 /* GetCurrentContendedMonitor *************************************************
720 Get the object the specified thread waits for.
722 *******************************************************************************/
725 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
726 jobject * monitor_ptr)
730 java_objectheader* monitor;
733 CHECK_PHASE(JVMTI_PHASE_LIVE)
735 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
737 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
740 if(!builtin_instanceof(thread,class_java_lang_Thread))
741 return JVMTI_ERROR_INVALID_THREAD;
743 CHECK_THREAD_IS_ALIVE(thread);
746 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
748 pthread_mutex_lock(&pool_lock);
752 while ((lrp != NULL)&&(monitor==NULL)) {
753 for (j=0; j<lrp->header.size; j++) {
754 if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
755 monitor=lrp->lr[j].o;
759 lrp=lrp->header.next;
762 pthread_mutex_unlock(&pool_lock);
765 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
766 *monitor_ptr = (jobject)monitor;
770 return JVMTI_ERROR_NONE;
774 jvmtiStartFunction sf;
780 static void *threadstartup(void *t) {
781 runagentparam *rap = (runagentparam*)t;
782 rap->sf(rap->jvmti_env,ptr_env,rap->arg);
786 /* RunAgentThread *************************************************************
788 Starts the execution of an agent thread of the specified native function
789 within the specified thread
791 *******************************************************************************/
794 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
795 const void *arg, jint priority)
797 pthread_attr_t threadattr;
798 struct sched_param sp;
802 CHECK_PHASE(JVMTI_PHASE_LIVE)
805 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
806 return JVMTI_ERROR_INVALID_THREAD;
807 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
808 if ((priority < JVMTI_THREAD_MIN_PRIORITY) || (priority > JVMTI_THREAD_MAX_PRIORITY))
809 return JVMTI_ERROR_INVALID_PRIORITY;
812 rap.arg = (void*)arg;
815 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
816 pthread_attr_init(&threadattr);
817 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
818 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
819 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
821 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
822 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
824 pthread_attr_setschedparam(&threadattr,&sp);
825 if (pthread_create(&((threadobject*) thread)->info.tid, &threadattr, &threadstartup, &rap)) {
826 log_text("pthread_create failed");
831 return JVMTI_ERROR_NONE;
835 /* GetTopThreadGroups *********************************************************
837 Get all top-level thread groups in the VM.
839 *******************************************************************************/
842 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
843 jthreadGroup ** groups_ptr)
845 jint threads_count_ptr;
846 threadobject *threads_ptr;
848 jthreadGroup **tg,*ttgp;
851 CHECK_PHASE(JVMTI_PHASE_LIVE)
854 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
855 return JVMTI_ERROR_NULL_POINTER;
857 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
858 tg = MNEW(jthreadGroup*,size);
860 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
861 return JVMTI_ERROR_INTERNAL;
863 for (i=0;i<threads_count_ptr;i++){
864 if (threads_ptr[i].o.thread->group == NULL) {
865 log_text("threadgroup not set");
866 return JVMTI_ERROR_INTERNAL;
868 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
871 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
877 MREALLOC(tg,jthreadGroup*,size,size*2);
886 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
887 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
888 MFREE(tg,jthreadGroup*,size);
890 *group_count_ptr = x;
893 return JVMTI_ERROR_NOT_AVAILABLE;
895 return JVMTI_ERROR_NONE;
899 /* GetThreadGroupInfo *********************************************************
901 Get information about the specified thread group.
903 *******************************************************************************/
906 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
907 jvmtiThreadGroupInfo * info_ptr)
911 java_lang_ThreadGroup* grp;
914 CHECK_PHASE(JVMTI_PHASE_LIVE)
917 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
918 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
919 return JVMTI_ERROR_INVALID_THREAD_GROUP;
921 grp = (java_lang_ThreadGroup*)group;
923 info_ptr->parent = (jthreadGroup)
924 Java_java_lang_VMObject_clone(NULL,
925 (jclass)grp->header.vftbl->class,
926 (java_lang_Cloneable*) &grp->parent);
928 name = javastring_tochar((java_objectheader*)grp->name);
930 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
931 strncpy(info_ptr->name,name,size);
932 info_ptr->max_priority= (jint)grp->maxpri;
933 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
935 return JVMTI_ERROR_NONE;
939 /* GetThreadGroupChildren *****************************************************
941 Get the live threads and active subgroups in this thread group.
943 *******************************************************************************/
946 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
947 jint * thread_count_ptr, jthread ** threads_ptr,
948 jint * group_count_ptr, jthreadGroup ** groups_ptr)
950 java_lang_ThreadGroup* tgp;
953 CHECK_PHASE(JVMTI_PHASE_LIVE)
956 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
957 (group_count_ptr == NULL) || (groups_ptr == NULL))
958 return JVMTI_ERROR_NULL_POINTER;
960 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
961 return JVMTI_ERROR_INVALID_THREAD_GROUP;
963 tgp = (java_lang_ThreadGroup*)group;
965 *thread_count_ptr = (jint)tgp->threads->elementCount;
967 *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
969 memcpy(*threads_ptr, &tgp->threads->elementData,
970 (*thread_count_ptr)*sizeof(jthread*));
972 *group_count_ptr = (jint) tgp->groups->elementCount;
974 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
976 memcpy(*groups_ptr, &tgp->threads->elementData,
977 (*group_count_ptr)*sizeof(jthreadGroup*));
979 return JVMTI_ERROR_NONE;
983 /* getcacaostacktrace *********************************************************
985 Helper function that retrives stack trace for specified thread.
986 Has to take care of suspend/resume issuses
988 *******************************************************************************/
990 static jvmtiError getcacaostacktrace(stackTraceBuffer** trace, jthread thread) {
992 /* todo: suspend specified thread */
994 if (!cacao_stacktrace_fillInStackTrace((void**)trace,&stackTraceCollector, (threadobject*)thread))
995 return JVMTI_ERROR_INTERNAL;
997 /* todo: resume specified thread */
998 log_text("todo: stacktraces");
999 return JVMTI_ERROR_NONE;
1003 /* GetFrameCount **************************************************************
1005 Get the number of frames in the specified thread's stack.
1007 *******************************************************************************/
1010 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1012 stackTraceBuffer* trace;
1016 CHECK_PHASE(JVMTI_PHASE_LIVE)
1019 if(!builtin_instanceof(thread,class_java_lang_Thread))
1020 return JVMTI_ERROR_INVALID_THREAD;
1022 CHECK_THREAD_IS_ALIVE(thread);
1024 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1026 er = getcacaostacktrace(&trace, thread);
1027 if (er==JVMTI_ERROR_NONE) return er;
1029 *count_ptr = trace->size;
1031 return JVMTI_ERROR_NONE;
1035 /* GetThreadState **************************************************************
1037 Get the state of a thread.
1039 *******************************************************************************/
1042 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1044 java_lang_Thread* th = (java_lang_Thread*)thread;
1046 CHECK_PHASE(JVMTI_PHASE_LIVE)
1049 if(!builtin_instanceof(thread,class_java_lang_Thread))
1050 return JVMTI_ERROR_INVALID_THREAD;
1052 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1054 *thread_state_ptr = 0;
1055 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1056 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1058 if (((threadobject*)th->vmThread)->info.tid == 0)
1059 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1062 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1063 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED; /* todo */
1067 return JVMTI_ERROR_INTERNAL;
1070 return JVMTI_ERROR_NONE;
1074 /* GetFrameLocation ************************************************************
1076 Get the location of the instruction currently executing
1078 *******************************************************************************/
1081 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1082 jmethodID * method_ptr, jlocation * location_ptr)
1084 stackframeinfo *sfi;
1088 CHECK_PHASE(JVMTI_PHASE_LIVE)
1091 if(!builtin_instanceof(thread,class_java_lang_Thread))
1092 return JVMTI_ERROR_INVALID_THREAD;
1094 CHECK_THREAD_IS_ALIVE(thread);
1096 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1098 if ((method_ptr == NULL)&&(location_ptr == NULL))
1099 return JVMTI_ERROR_NULL_POINTER;
1101 sfi = ((threadobject*)thread)->info._stackframeinfo;
1104 while ((sfi != NULL) && (i<depth)) {
1109 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1111 *method_ptr=(jmethodID)sfi->method;
1112 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1114 return JVMTI_ERROR_NONE;
1118 /* NotifyFramePop *************************************************************
1122 *******************************************************************************/
1125 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1128 CHECK_PHASE(JVMTI_PHASE_LIVE)
1130 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1132 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1133 return JVMTI_ERROR_NONE;
1136 /* GetLocalObject *************************************************************
1140 *******************************************************************************/
1143 GetLocalObject (jvmtiEnv * env,
1144 jthread thread, jint depth, jint slot, jobject * value_ptr)
1147 CHECK_PHASE(JVMTI_PHASE_LIVE)
1149 CHECK_CAPABILITY(env,can_access_local_variables)
1151 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1152 return JVMTI_ERROR_NONE;
1155 /* GetLocalInt ****************************************************************
1159 *******************************************************************************/
1162 GetLocalInt (jvmtiEnv * env,
1163 jthread thread, jint depth, jint slot, jint * value_ptr)
1166 CHECK_PHASE(JVMTI_PHASE_LIVE)
1168 CHECK_CAPABILITY(env,can_access_local_variables)
1169 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1170 return JVMTI_ERROR_NONE;
1173 /* *****************************************************************************
1177 *******************************************************************************/
1180 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1184 CHECK_PHASE(JVMTI_PHASE_LIVE)
1186 CHECK_CAPABILITY(env,can_access_local_variables)
1188 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1189 return JVMTI_ERROR_NONE;
1193 /* *****************************************************************************
1197 *******************************************************************************/
1200 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1204 CHECK_PHASE(JVMTI_PHASE_LIVE)
1206 CHECK_CAPABILITY(env,can_access_local_variables)
1208 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1209 return JVMTI_ERROR_NONE;
1213 /* *****************************************************************************
1217 *******************************************************************************/
1220 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1221 jdouble * value_ptr)
1224 CHECK_PHASE(JVMTI_PHASE_LIVE)
1226 CHECK_CAPABILITY(env,can_access_local_variables)
1228 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1229 return JVMTI_ERROR_NONE;
1233 /* *****************************************************************************
1237 *******************************************************************************/
1240 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1244 CHECK_PHASE(JVMTI_PHASE_LIVE)
1246 CHECK_CAPABILITY(env,can_access_local_variables)
1248 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1249 return JVMTI_ERROR_NONE;
1253 /* *****************************************************************************
1257 *******************************************************************************/
1260 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1264 CHECK_PHASE(JVMTI_PHASE_LIVE)
1266 CHECK_CAPABILITY(env,can_access_local_variables)
1268 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1269 return JVMTI_ERROR_NONE;
1273 /* *****************************************************************************
1277 *******************************************************************************/
1280 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1284 CHECK_PHASE(JVMTI_PHASE_LIVE)
1286 CHECK_CAPABILITY(env,can_access_local_variables)
1288 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1289 return JVMTI_ERROR_NONE;
1293 /* *****************************************************************************
1297 *******************************************************************************/
1300 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1304 CHECK_PHASE(JVMTI_PHASE_LIVE)
1306 CHECK_CAPABILITY(env,can_access_local_variables)
1308 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1309 return JVMTI_ERROR_NONE;
1313 /* *****************************************************************************
1317 *******************************************************************************/
1320 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1324 CHECK_PHASE(JVMTI_PHASE_LIVE)
1326 CHECK_CAPABILITY(env,can_access_local_variables)
1328 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1329 return JVMTI_ERROR_NONE;
1333 /* CreateRawMonitor ***********************************************************
1335 This function creates a new raw monitor.
1337 *******************************************************************************/
1340 CreateRawMonitor (jvmtiEnv * env, const char *name,
1341 jrawMonitorID * monitor_ptr)
1343 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1346 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1347 CHECK_PHASE(JVMTI_PHASE_LIVE)
1350 if ((name == NULL) || (monitor_ptr == NULL))
1351 return JVMTI_ERROR_NULL_POINTER;
1353 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1354 monitor->name=javastring_new_char(name);
1356 log_text ("CreateRawMonitor not supported");
1359 return JVMTI_ERROR_NONE;
1363 /* DestroyRawMonitor **********************************************************
1365 This function destroys a raw monitor.
1367 *******************************************************************************/
1370 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1373 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1374 CHECK_PHASE(JVMTI_PHASE_LIVE)
1377 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1378 return JVMTI_ERROR_INVALID_MONITOR;
1380 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1381 if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1382 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1384 monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1386 /* GC will clean monitor up */
1388 log_text ("DestroyRawMonitor not supported");
1391 return JVMTI_ERROR_NONE;
1395 /* RawMonitorEnter ************************************************************
1397 Gain exclusive ownership of a raw monitor
1399 *******************************************************************************/
1402 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1404 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1405 return JVMTI_ERROR_INVALID_MONITOR;
1407 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1408 builtin_monitorenter((java_objectheader*)monitor->name);
1410 log_text ("RawMonitorEnter not supported");
1413 return JVMTI_ERROR_NONE;
1417 /* RawMonitorExit *************************************************************
1421 *******************************************************************************/
1424 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1426 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1427 return JVMTI_ERROR_INVALID_MONITOR;
1429 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1430 /* assure current thread owns this monitor */
1431 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1432 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1434 builtin_monitorexit((java_objectheader*)monitor->name);
1436 log_text ("RawMonitorExit not supported");
1439 return JVMTI_ERROR_NONE;
1443 /* RawMonitorWait *************************************************************
1445 Wait for notification of the raw monitor.
1447 *******************************************************************************/
1450 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1452 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1453 return JVMTI_ERROR_INVALID_MONITOR;
1455 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1456 /* assure current thread owns this monitor */
1457 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1458 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1460 wait_cond_for_object(&monitor->name->header, millis,0);
1461 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1462 return JVMTI_ERROR_INTERRUPT;
1465 log_text ("RawMonitorWait not supported");
1468 return JVMTI_ERROR_NONE;
1472 /* RawMonitorNotify ***********************************************************
1474 Notify one thread waiting on the given monitor.
1476 *******************************************************************************/
1479 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1481 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1482 return JVMTI_ERROR_INVALID_MONITOR;
1484 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1485 /* assure current thread owns this monitor */
1486 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1487 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1489 signal_cond_for_object((java_objectheader*)&monitor->name);
1491 log_text ("RawMonitorNotify not supported");
1494 return JVMTI_ERROR_NONE;
1498 /* RawMonitorNotifyAll *********************************************************
1500 Notify all threads waiting on the given monitor.
1502 *******************************************************************************/
1505 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1507 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1508 return JVMTI_ERROR_INVALID_MONITOR;
1510 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1511 /* assure current thread owns this monitor */
1512 if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1513 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1515 broadcast_cond_for_object((java_objectheader*)&monitor->name);
1517 log_text ("RawMonitorNotifyAll not supported");
1520 return JVMTI_ERROR_NONE;
1524 /* SetBreakpoint **************************************************************
1528 *******************************************************************************/
1531 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1534 CHECK_PHASE(JVMTI_PHASE_LIVE)
1536 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1538 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1539 return JVMTI_ERROR_NONE;
1543 /* *****************************************************************************
1547 *******************************************************************************/
1550 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1553 CHECK_PHASE(JVMTI_PHASE_LIVE)
1555 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1557 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1558 return JVMTI_ERROR_NONE;
1562 /* SetFieldAccessWatch ********************************************************
1566 *******************************************************************************/
1569 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1572 CHECK_PHASE(JVMTI_PHASE_LIVE)
1574 CHECK_CAPABILITY(env,can_generate_field_access_events)
1576 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1577 return JVMTI_ERROR_NONE;
1581 /* *****************************************************************************
1585 *******************************************************************************/
1588 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1591 CHECK_PHASE(JVMTI_PHASE_LIVE)
1593 CHECK_CAPABILITY(env,can_generate_field_access_events)
1595 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1596 return JVMTI_ERROR_NONE;
1600 /* *****************************************************************************
1604 *******************************************************************************/
1607 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1610 CHECK_PHASE(JVMTI_PHASE_LIVE)
1612 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1614 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1615 return JVMTI_ERROR_NONE;
1619 /* *****************************************************************************
1623 *******************************************************************************/
1626 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1629 CHECK_PHASE(JVMTI_PHASE_LIVE)
1631 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1633 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1634 return JVMTI_ERROR_NONE;
1638 /* Allocate ********************************************************************
1640 Allocate an area of memory through the JVM TI allocator. The allocated
1641 memory should be freed with Deallocate
1643 *******************************************************************************/
1646 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1649 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1650 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1652 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1653 if (*mem_ptr == NULL)
1654 return JVMTI_ERROR_OUT_OF_MEMORY;
1656 return JVMTI_ERROR_NONE;
1661 /* Deallocate ******************************************************************
1663 Deallocate mem using the JVM TI allocator.
1665 *******************************************************************************/
1668 Deallocate (jvmtiEnv * env, unsigned char *mem)
1670 /* let Boehm GC do the job */
1671 return JVMTI_ERROR_NONE;
1675 /* GetClassSignature ************************************************************
1677 For the class indicated by klass, return the JNI type signature and the
1678 generic signature of the class.
1680 *******************************************************************************/
1683 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1689 CHECK_PHASE(JVMTI_PHASE_START)
1690 CHECK_PHASE(JVMTI_PHASE_LIVE)
1693 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1694 return JVMTI_ERROR_NULL_POINTER;
1696 nsize=((classinfo*)klass)->name->blength;
1697 psize=((classinfo*)klass)->packagename->blength;
1699 *signature_ptr = (char*)
1700 heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
1702 *signature_ptr[0]='L';
1703 memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
1704 *signature_ptr[psize+2]='/';
1705 memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
1706 *signature_ptr[nsize+psize+3]=';';
1707 *signature_ptr[nsize+psize+4]='\0';
1709 *generic_ptr = NULL;
1711 return JVMTI_ERROR_NONE;
1714 /* GetClassStatus *************************************************************
1716 Get status of the class.
1718 *******************************************************************************/
1721 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1725 CHECK_PHASE(JVMTI_PHASE_START)
1726 CHECK_PHASE(JVMTI_PHASE_LIVE)
1729 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1730 return JVMTI_ERROR_INVALID_CLASS;
1732 if (status_ptr == NULL)
1733 return JVMTI_ERROR_NULL_POINTER;
1735 c = (classinfo*)klass;
1738 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1739 /* if () *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED; ? */
1742 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1744 if (c->erroneous_state)
1745 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1747 if (c->vftbl->arraydesc != NULL)
1748 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1750 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1751 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1753 return JVMTI_ERROR_NONE;
1757 /* GetSourceFileName **********************************************************
1759 For the class indicated by klass, return the source file name.
1761 *******************************************************************************/
1764 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1769 CHECK_PHASE(JVMTI_PHASE_START)
1770 CHECK_PHASE(JVMTI_PHASE_LIVE)
1772 CHECK_CAPABILITY(env,can_get_source_file_name)
1774 if ((klass == NULL)||(source_name_ptr == NULL))
1775 return JVMTI_ERROR_NULL_POINTER;
1777 size = (((classinfo*)klass)->sourcefile->blength);
1779 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1781 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1783 return JVMTI_ERROR_NONE;
1787 /* GetClassModifiers **********************************************************
1789 For class klass return the access flags
1791 *******************************************************************************/
1794 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1797 CHECK_PHASE(JVMTI_PHASE_START)
1798 CHECK_PHASE(JVMTI_PHASE_LIVE)
1801 if (modifiers_ptr == NULL)
1802 return JVMTI_ERROR_NULL_POINTER;
1804 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1805 return JVMTI_ERROR_INVALID_CLASS;
1807 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1809 return JVMTI_ERROR_NONE;
1813 /* GetClassMethods *************************************************************
1815 For class klass return a count of methods and a list of method IDs
1817 *******************************************************************************/
1820 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1821 jmethodID ** methods_ptr)
1824 CHECK_PHASE(JVMTI_PHASE_START)
1825 CHECK_PHASE(JVMTI_PHASE_LIVE)
1828 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1829 return JVMTI_ERROR_NULL_POINTER;
1831 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1832 return JVMTI_ERROR_INVALID_CLASS;
1834 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1835 *methods_ptr = (jmethodID*)
1836 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1838 memcpy (*methods_ptr, ((classinfo*)klass)->methods,
1839 sizeof(jmethodID) * (*method_count_ptr));
1841 return JVMTI_ERROR_NONE;
1845 /* GetClassFields *************************************************************
1847 For the class indicated by klass, return a count of fields and a list of
1850 *******************************************************************************/
1853 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1854 jfieldID ** fields_ptr)
1857 CHECK_PHASE(JVMTI_PHASE_START)
1858 CHECK_PHASE(JVMTI_PHASE_LIVE)
1861 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1862 return JVMTI_ERROR_NULL_POINTER;
1864 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1865 *fields_ptr = (jfieldID*)
1866 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1868 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1869 sizeof(jfieldID) * (*field_count_ptr));
1871 return JVMTI_ERROR_NONE;
1875 /* GetImplementedInterfaces ***************************************************
1877 Return the direct super-interfaces of this class.
1879 *******************************************************************************/
1882 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1883 jint * interface_count_ptr,
1884 jclass ** interfaces_ptr)
1887 classref_or_classinfo *interfaces;
1891 CHECK_PHASE(JVMTI_PHASE_START)
1892 CHECK_PHASE(JVMTI_PHASE_LIVE)
1895 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1896 return JVMTI_ERROR_NULL_POINTER;
1898 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1899 return JVMTI_ERROR_INVALID_CLASS;
1902 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1904 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1906 interfaces = ((classinfo*)klass)->interfaces;
1907 for (i=0; i<*interface_count_ptr; i++) {
1908 if (IS_CLASSREF(interfaces[i]))
1909 tmp = load_class_bootstrap(interfaces[i].ref->name);
1911 tmp = interfaces[i].cls;
1913 *interfaces_ptr[i]=tmp;
1916 return JVMTI_ERROR_NONE;
1920 /* IsInterface ****************************************************************
1922 Determines whether a class object reference represents an interface.
1924 *******************************************************************************/
1927 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1930 CHECK_PHASE(JVMTI_PHASE_START)
1931 CHECK_PHASE(JVMTI_PHASE_LIVE)
1934 if ((klass == NULL)||(is_interface_ptr == NULL))
1935 return JVMTI_ERROR_NULL_POINTER;
1937 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
1939 return JVMTI_ERROR_NONE;
1942 /* IsArrayClass ***************************************************************
1944 Determines whether a class object reference represents an array.
1946 *******************************************************************************/
1949 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
1952 CHECK_PHASE(JVMTI_PHASE_START)
1953 CHECK_PHASE(JVMTI_PHASE_LIVE)
1956 if (is_array_class_ptr == NULL)
1957 return JVMTI_ERROR_NULL_POINTER;
1959 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
1961 return JVMTI_ERROR_NONE;
1965 /* GetClassLoader *************************************************************
1967 For the class indicated by klass, return via classloader_ptr a reference to
1968 the class loader for the class.
1970 *******************************************************************************/
1973 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
1976 CHECK_PHASE(JVMTI_PHASE_START)
1977 CHECK_PHASE(JVMTI_PHASE_LIVE)
1980 if ((klass == NULL)||(classloader_ptr == NULL))
1981 return JVMTI_ERROR_NULL_POINTER;
1983 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
1985 return JVMTI_ERROR_NONE;
1989 /* GetObjectHashCode **********************************************************
1991 Return hash code for object object
1993 *******************************************************************************/
1996 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
1999 CHECK_PHASE(JVMTI_PHASE_START)
2000 CHECK_PHASE(JVMTI_PHASE_LIVE)
2003 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2004 if (!builtin_instanceof(object,class_java_lang_Object))
2005 return JVMTI_ERROR_INVALID_OBJECT;
2007 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2009 return JVMTI_ERROR_NONE;
2013 /* *****************************************************************************
2017 *******************************************************************************/
2020 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2021 jvmtiMonitorUsage * info_ptr)
2024 CHECK_PHASE(JVMTI_PHASE_LIVE)
2026 CHECK_CAPABILITY(env,can_get_monitor_info)
2028 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2029 return JVMTI_ERROR_NONE;
2033 /* GetFieldName ***************************************************************
2035 For the field indicated by klass and field, return the field name and
2038 *******************************************************************************/
2041 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2042 char **name_ptr, char **signature_ptr, char **generic_ptr)
2047 CHECK_PHASE(JVMTI_PHASE_START)
2048 CHECK_PHASE(JVMTI_PHASE_LIVE)
2051 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2052 return JVMTI_ERROR_NULL_POINTER;
2054 size = (((fieldinfo*)field)->name->blength);
2055 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2056 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2058 size = (((fieldinfo*)field)->descriptor->blength);
2059 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2060 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2062 *generic_ptr = NULL;
2064 return JVMTI_ERROR_NONE;
2068 /* GetFieldDeclaringClass *****************************************************
2070 For the field indicated by klass and field return the class that defined it
2071 The declaring class will either be klass, a superclass, or an implemented
2074 *******************************************************************************/
2077 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2078 jclass * declaring_class_ptr)
2081 CHECK_PHASE(JVMTI_PHASE_START)
2082 CHECK_PHASE(JVMTI_PHASE_LIVE)
2085 /* todo: how do I find declaring class other then iterate over all fields in all classes ?*/
2086 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
2088 return JVMTI_ERROR_NONE;
2092 /* GetFieldModifiers **********************************************************
2094 Return access flags of field field
2096 *******************************************************************************/
2099 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2100 jint * modifiers_ptr)
2103 CHECK_PHASE(JVMTI_PHASE_START)
2104 CHECK_PHASE(JVMTI_PHASE_LIVE)
2107 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2108 return JVMTI_ERROR_INVALID_OBJECT;
2110 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2112 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2114 *modifiers_ptr = ((fieldinfo*)field)->flags;
2116 return JVMTI_ERROR_NONE;
2120 /* IsFieldSynthetic ***********************************************************
2124 *******************************************************************************/
2127 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2128 jboolean * is_synthetic_ptr)
2131 CHECK_PHASE(JVMTI_PHASE_START)
2132 CHECK_PHASE(JVMTI_PHASE_LIVE)
2134 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2136 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2137 return JVMTI_ERROR_NONE;
2141 /* GetMethodName ***************************************************************
2143 For the method indicated by method, return the method name via name_ptr and
2144 method signature via signature_ptr.
2146 *******************************************************************************/
2149 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2150 char **signature_ptr, char **generic_ptr)
2152 methodinfo* m = (methodinfo*)method;
2155 CHECK_PHASE(JVMTI_PHASE_START)
2156 CHECK_PHASE(JVMTI_PHASE_LIVE)
2159 if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2160 || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2162 *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
2163 memcpy(*name_ptr, m->name->text, m->name->blength);
2165 *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
2166 memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
2168 /* there is no generic signature attribute */
2169 *generic_ptr = NULL;
2171 return JVMTI_ERROR_NONE;
2175 /* GetMethodDeclaringClass *****************************************************
2177 For the method indicated by method, return the class that defined it.
2179 *******************************************************************************/
2182 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2183 jclass * declaring_class_ptr)
2186 CHECK_PHASE(JVMTI_PHASE_START)
2187 CHECK_PHASE(JVMTI_PHASE_LIVE)
2190 if ((method == NULL) || (declaring_class_ptr == NULL))
2191 return JVMTI_ERROR_NULL_POINTER;
2193 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2195 return JVMTI_ERROR_NONE;
2199 /* GetMethodModifiers **********************************************************
2201 For the method indicated by method, return the access flags.
2203 *******************************************************************************/
2206 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2209 CHECK_PHASE(JVMTI_PHASE_START)
2210 CHECK_PHASE(JVMTI_PHASE_LIVE)
2213 if ((method == NULL) || (modifiers_ptr == NULL))
2214 return JVMTI_ERROR_NULL_POINTER;
2216 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2218 return JVMTI_ERROR_NONE;
2222 /* GetMaxLocals ****************************************************************
2224 For the method indicated by method, return the number of local variable slots
2225 used by the method, including the local variables used to pass parameters to
2226 the method on its invocation.
2228 *******************************************************************************/
2231 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2234 CHECK_PHASE(JVMTI_PHASE_START)
2235 CHECK_PHASE(JVMTI_PHASE_LIVE)
2238 if ((method == NULL)||(max_ptr == NULL))
2239 return JVMTI_ERROR_NULL_POINTER;
2241 if (((methodinfo*)method)->flags & ACC_NATIVE)
2242 return JVMTI_ERROR_NATIVE_METHOD;
2244 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2246 return JVMTI_ERROR_NONE;
2251 /* GetArgumentsSize ************************************************************
2253 Return the number of local variable slots used by the method's arguments.
2255 *******************************************************************************/
2258 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2261 CHECK_PHASE(JVMTI_PHASE_START)
2262 CHECK_PHASE(JVMTI_PHASE_LIVE)
2265 if ((method == NULL)||(size_ptr == NULL))
2266 return JVMTI_ERROR_NULL_POINTER;
2268 if (((methodinfo*)method)->flags & ACC_NATIVE)
2269 return JVMTI_ERROR_NATIVE_METHOD;
2271 *size_ptr = (jint)((methodinfo*)method)->paramcount;
2272 return JVMTI_ERROR_NONE;
2277 /* GetLineNumberTable ***********************************************************
2279 Return table of source line number entries for a given method
2281 *******************************************************************************/
2284 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2285 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2290 CHECK_PHASE(JVMTI_PHASE_START)
2291 CHECK_PHASE(JVMTI_PHASE_LIVE)
2293 CHECK_CAPABILITY(env,can_get_line_numbers)
2295 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2296 return JVMTI_ERROR_NULL_POINTER;
2297 if (((methodinfo*)method)->flags & ACC_NATIVE)
2298 return JVMTI_ERROR_NATIVE_METHOD;
2299 if (((methodinfo*)method)->linenumbers == NULL)
2300 return JVMTI_ERROR_ABSENT_INFORMATION;
2302 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2303 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2304 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2307 for (i=0; i < *entry_count_ptr; i++) {
2308 (*table_ptr[i]).start_location =
2309 (jlocation) method->linenumbers[i].start_pc;
2310 (*table_ptr[i]).line_number =
2311 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2314 return JVMTI_ERROR_NONE;
2318 /* GetMethodLocation ***********************************************************
2320 For the method indicated by method, return the beginning and ending addresses
2321 through start_location_ptr and end_location_ptr. In cacao this points to
2322 entry point in machine code and length of machine code
2324 *******************************************************************************/
2327 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2328 jlocation * start_location_ptr,
2329 jlocation * end_location_ptr)
2331 methodinfo* m = (methodinfo*)method;
2334 CHECK_PHASE(JVMTI_PHASE_START)
2335 CHECK_PHASE(JVMTI_PHASE_LIVE)
2338 if ((method == NULL) || (start_location_ptr == NULL) ||
2339 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2341 *start_location_ptr = (jlocation)m->mcode;
2342 *end_location_ptr = (jlocation)(m->mcode)+m->mcodelength;
2343 return JVMTI_ERROR_NONE;
2347 /* GetLocalVariableTable *******************************************************
2349 Return local variable information.
2351 *******************************************************************************/
2354 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2355 jint * entry_count_ptr,
2356 jvmtiLocalVariableEntry ** table_ptr)
2359 CHECK_PHASE(JVMTI_PHASE_LIVE)
2361 CHECK_CAPABILITY(env,can_access_local_variables)
2363 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2365 return JVMTI_ERROR_NONE;
2369 /* GetBytecode *****************************************************************
2371 For the method indicated by method, return the byte codes that implement the
2374 *******************************************************************************/
2377 GetBytecodes (jvmtiEnv * env, jmethodID method,
2378 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2380 methodinfo* m = (methodinfo*)method;;
2383 CHECK_PHASE(JVMTI_PHASE_START)
2384 CHECK_PHASE(JVMTI_PHASE_LIVE)
2386 CHECK_CAPABILITY(env,can_get_bytecodes)
2388 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2389 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2391 *bytecode_count_ptr = m->jcodelength;
2392 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2393 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2395 return JVMTI_ERROR_NONE;
2399 /* IsMethodNative **************************************************************
2401 For the method indicated by method, return a value indicating whether the
2402 method is a native function
2404 *******************************************************************************/
2407 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2410 CHECK_PHASE(JVMTI_PHASE_START)
2411 CHECK_PHASE(JVMTI_PHASE_LIVE)
2414 if ((method == NULL)||(is_native_ptr == NULL))
2415 return JVMTI_ERROR_NULL_POINTER;
2417 if (((methodinfo*)method)->flags & ACC_NATIVE)
2418 *is_native_ptr = JNI_TRUE;
2420 *is_native_ptr = JNI_FALSE;
2422 return JVMTI_ERROR_NONE;
2426 /* IsMethodSynthetic ***********************************************************
2428 return a value indicating whether the method is synthetic. Synthetic methods
2429 are generated by the compiler but not present in the original source code.
2431 *******************************************************************************/
2434 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2435 jboolean * is_synthetic_ptr)
2438 CHECK_PHASE(JVMTI_PHASE_START)
2439 CHECK_PHASE(JVMTI_PHASE_LIVE)
2441 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2443 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2444 return JVMTI_ERROR_NONE;
2448 /* GetLoadedClasses ************************************************************
2450 Return an array of all classes loaded in the virtual machine.
2452 *******************************************************************************/
2455 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr,
2456 jclass ** classes_ptr)
2459 classcache_name_entry *cne;
2460 classcache_class_entry *cce;
2462 CHECK_PHASE(JVMTI_PHASE_LIVE)
2465 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2466 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2470 *classes_ptr = heap_allocate(sizeof(jclass*)*classcache_hash.entries,true,NULL);
2471 *class_count_ptr = classcache_hash.entries;
2473 /* look in every slot of the hashtable */
2474 for (i=0; i<classcache_hash.size; i++) {
2475 cne =(classcache_name_entry*) classcache_hash.ptr[i];
2476 while (cne != NULL) { /* iterate over hashlink */
2478 while (cce != NULL){ /* iterate over classes with same name */
2479 if (cce->classobj != NULL) { /* get only loaded classes */
2480 assert(j<classcache_hash.entries);
2481 *classes_ptr[j]=cce->classobj;
2486 cne = cne->hashlink;
2492 return JVMTI_ERROR_NONE;
2496 /* GetClassLoaderClasses *******************************************************
2498 Returns an array of those classes for which this class loader has been
2499 recorded as an initiating loader.
2501 *******************************************************************************/
2504 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2505 jint * class_count_ptr, jclass ** classes_ptr)
2508 CHECK_PHASE(JVMTI_PHASE_LIVE)
2511 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2512 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2514 /* behave like jdk 1.1 and make no distinction between initiating and
2515 defining class loaders */
2517 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2521 /* PopFrame *******************************************************************
2525 *******************************************************************************/
2528 PopFrame (jvmtiEnv * env, jthread thread)
2531 CHECK_PHASE(JVMTI_PHASE_LIVE)
2533 CHECK_CAPABILITY(env,can_pop_frame)
2535 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2536 return JVMTI_ERROR_NONE;
2540 /* RedefineClasses ************************************************************
2544 *******************************************************************************/
2547 RedefineClasses (jvmtiEnv * env, jint class_count,
2548 const jvmtiClassDefinition * class_definitions)
2551 CHECK_PHASE(JVMTI_PHASE_START)
2552 CHECK_PHASE(JVMTI_PHASE_LIVE)
2554 CHECK_CAPABILITY(env,can_redefine_classes)
2555 CHECK_CAPABILITY(env,can_redefine_any_class)
2556 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2557 return JVMTI_ERROR_NONE;
2561 /* GetVersionNumber ***********************************************************
2563 Return the JVM TI version identifier.
2565 *******************************************************************************/
2568 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2570 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2572 *version_ptr = JVMTI_VERSION_1_0;
2574 return JVMTI_ERROR_NONE;
2578 /* GetCapabilities ************************************************************
2580 Returns the optional JVM TI features which this environment currently
2583 *******************************************************************************/
2586 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2588 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2590 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2592 return JVMTI_ERROR_NONE;
2596 /* *****************************************************************************
2600 *******************************************************************************/
2603 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2604 char **source_debug_extension_ptr)
2607 CHECK_PHASE(JVMTI_PHASE_START)
2608 CHECK_PHASE(JVMTI_PHASE_LIVE)
2610 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2612 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2613 return JVMTI_ERROR_NONE;
2617 /* IsMethodObsolete ************************************************************
2619 Determine if a method ID refers to an obsolete method version.
2621 *******************************************************************************/
2624 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2625 jboolean * is_obsolete_ptr)
2628 CHECK_PHASE(JVMTI_PHASE_START)
2629 CHECK_PHASE(JVMTI_PHASE_LIVE)
2631 CHECK_CAPABILITY(env,can_redefine_classes)
2633 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2634 return JVMTI_ERROR_NONE;
2638 /* *****************************************************************************
2642 *******************************************************************************/
2645 SuspendThreadList (jvmtiEnv * env, jint request_count,
2646 const jthread * request_list, jvmtiError * results)
2649 CHECK_PHASE(JVMTI_PHASE_START)
2650 CHECK_PHASE(JVMTI_PHASE_LIVE)
2652 CHECK_CAPABILITY(env,can_suspend)
2654 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2655 return JVMTI_ERROR_NONE;
2659 /* *****************************************************************************
2663 *******************************************************************************/
2666 ResumeThreadList (jvmtiEnv * env, jint request_count,
2667 const jthread * request_list, jvmtiError * results)
2670 CHECK_PHASE(JVMTI_PHASE_LIVE)
2672 CHECK_CAPABILITY(env,can_suspend)
2674 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2675 return JVMTI_ERROR_NONE;
2679 /* GetStackTrace **************************************************************
2681 Get information about the stack of a thread
2683 *******************************************************************************/
2686 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2687 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2690 stackTraceBuffer* trace;
2695 CHECK_PHASE(JVMTI_PHASE_LIVE)
2698 if(!builtin_instanceof(thread,class_java_lang_Thread))
2699 return JVMTI_ERROR_INVALID_THREAD;
2701 CHECK_THREAD_IS_ALIVE(thread);
2703 if((count_ptr == NULL)||(frame_buffer == NULL))
2704 return JVMTI_ERROR_NULL_POINTER;
2706 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2708 er = getcacaostacktrace(&trace, thread);
2709 if (er==JVMTI_ERROR_NONE) return er;
2711 if ((trace->size >= start_depth) || ((trace->size * -1) > start_depth))
2712 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2714 for (i=start_depth, j=0;i<trace->size;i++,j++) {
2715 frame_buffer[j].method = (jmethodID)trace[i].start->method;
2716 /* todo: location MachinePC not avilable - Linenumber not expected */
2717 frame_buffer[j].location = 0;
2720 return JVMTI_ERROR_NONE;
2724 /* GetThreadListStackTraces ***************************************************
2726 Get information about the stacks of the supplied threads.
2728 *******************************************************************************/
2731 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2732 const jthread * thread_list,
2733 jint max_frame_count,
2734 jvmtiStackInfo ** stack_info_ptr)
2740 CHECK_PHASE(JVMTI_PHASE_LIVE)
2743 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2744 return JVMTI_ERROR_NULL_POINTER;
2746 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2748 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2750 *stack_info_ptr = (jvmtiStackInfo*)
2751 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2753 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2754 (*stack_info_ptr)[i].thread=thread_list[i];
2755 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2756 (*stack_info_ptr)[i].frame_buffer =
2757 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2758 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2759 (*stack_info_ptr)[i].frame_buffer,
2760 &((*stack_info_ptr)[i].frame_count));
2762 if (er != JVMTI_ERROR_NONE) return er;
2765 return JVMTI_ERROR_NONE;
2769 /* GetAllStackTraces **********************************************************
2771 Get stack traces of all live threads
2773 *******************************************************************************/
2776 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2777 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2779 jthread *threads_ptr;
2783 CHECK_PHASE(JVMTI_PHASE_LIVE)
2786 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2788 /* todo: all threads have to be suspended */
2790 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2791 return JVMTI_ERROR_INTERNAL;
2793 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2794 max_frame_count, stack_info_ptr);
2796 /* todo: resume all threads have to be suspended */
2797 if (er != JVMTI_ERROR_NONE) return er;
2799 return JVMTI_ERROR_NONE;
2803 /* GetThreadLocalStorage ******************************************************
2805 Get the value of the JVM TI thread-local storage.
2807 *******************************************************************************/
2810 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2812 jvmtiThreadLocalStorage *tls;
2815 CHECK_PHASE(JVMTI_PHASE_START)
2816 CHECK_PHASE(JVMTI_PHASE_LIVE)
2820 thread = (jthread) THREADOBJECT;
2822 if (!builtin_instanceof(thread,class_java_lang_Thread))
2823 return JVMTI_ERROR_INVALID_THREAD;
2824 CHECK_THREAD_IS_ALIVE(thread);
2827 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2829 tls = ((environment*)env)->tls;
2830 while ((tls->thread != thread) && (tls != NULL)) {
2834 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2836 *data_ptr = tls->data;
2838 return JVMTI_ERROR_NONE;
2842 /* SetThreadLocalStorage *******************************************************
2844 Stores a pointer value associated with each environment-thread pair. The
2845 value is NULL unless set with this function. Agents can allocate memory in
2846 which they store thread specific information
2848 *******************************************************************************/
2851 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2853 jvmtiThreadLocalStorage *tls, *pre;
2854 environment* env = (environment*)jenv;
2857 CHECK_PHASE(JVMTI_PHASE_START)
2858 CHECK_PHASE(JVMTI_PHASE_LIVE)
2862 thread = (jthread) THREADOBJECT;
2864 if (!builtin_instanceof(thread,class_java_lang_Thread))
2865 return JVMTI_ERROR_INVALID_THREAD;
2866 CHECK_THREAD_IS_ALIVE(thread);
2869 if (env->tls == NULL) {
2870 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2873 while ((tls->thread != thread) && (tls->next != NULL)) {
2876 if (tls->thread != thread) {
2877 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2883 tls->data = (void*)data;
2885 /* remove current tls */
2887 while (pre->next == tls) pre = pre->next;
2888 pre->next = tls->next;
2890 return JVMTI_ERROR_NONE;
2894 /* *****************************************************************************
2898 *******************************************************************************/
2901 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
2904 CHECK_PHASE(JVMTI_PHASE_START)
2905 CHECK_PHASE(JVMTI_PHASE_LIVE)
2907 CHECK_CAPABILITY(env,can_tag_objects)
2909 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2910 return JVMTI_ERROR_NONE;
2913 /* *****************************************************************************
2917 *******************************************************************************/
2920 SetTag (jvmtiEnv * env, jobject object, jlong tag)
2923 CHECK_PHASE(JVMTI_PHASE_START)
2924 CHECK_PHASE(JVMTI_PHASE_LIVE)
2926 CHECK_CAPABILITY(env,can_tag_objects)
2928 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2929 return JVMTI_ERROR_NONE;
2933 /* ForceGarbageCollection *****************************************************
2935 Force boehm-gc to perform a garbage collection
2937 *******************************************************************************/
2940 ForceGarbageCollection (jvmtiEnv * env)
2943 CHECK_PHASE(JVMTI_PHASE_LIVE)
2948 return JVMTI_ERROR_NONE;
2952 /* IterateOverObjectsReachableFromObject **************************************
2956 *******************************************************************************/
2959 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
2960 jvmtiObjectReferenceCallback
2961 object_reference_callback,
2965 CHECK_PHASE(JVMTI_PHASE_LIVE)
2967 CHECK_CAPABILITY(env,can_tag_objects)
2969 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2970 return JVMTI_ERROR_NONE;
2974 /* IterateOverReachableObjects ************************************************
2978 *******************************************************************************/
2981 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
2983 jvmtiStackReferenceCallback
2985 jvmtiObjectReferenceCallback
2986 object_ref_callback, void *user_data)
2989 CHECK_PHASE(JVMTI_PHASE_LIVE)
2991 CHECK_CAPABILITY(env,can_tag_objects)
2993 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2994 return JVMTI_ERROR_NONE;
2998 /* IterateOverHeap ************************************************************
3002 *******************************************************************************/
3005 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3006 jvmtiHeapObjectCallback heap_object_callback,
3010 CHECK_PHASE(JVMTI_PHASE_LIVE)
3012 CHECK_CAPABILITY(env,can_tag_objects)
3014 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3015 return JVMTI_ERROR_NONE;
3019 /* IterateOverInstancesOfClass ************************************************
3023 *******************************************************************************/
3026 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3027 jvmtiHeapObjectFilter object_filter,
3028 jvmtiHeapObjectCallback
3029 heap_object_callback, void *user_data)
3032 CHECK_PHASE(JVMTI_PHASE_LIVE)
3034 CHECK_CAPABILITY(env,can_tag_objects)
3036 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3037 return JVMTI_ERROR_NONE;
3041 /* *****************************************************************************
3045 *******************************************************************************/
3048 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3049 jint * count_ptr, jobject ** object_result_ptr,
3050 jlong ** tag_result_ptr)
3053 CHECK_PHASE(JVMTI_PHASE_LIVE)
3055 CHECK_CAPABILITY(env,can_tag_objects)
3057 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3058 return JVMTI_ERROR_NONE;
3062 /* SetJNIFunctionTable **********************************************************
3064 Set the JNI function table in all current and future JNI environments
3066 *******************************************************************************/
3069 SetJNIFunctionTable (jvmtiEnv * env,
3070 const jniNativeInterface * function_table)
3073 CHECK_PHASE(JVMTI_PHASE_START)
3074 CHECK_PHASE(JVMTI_PHASE_LIVE)
3077 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3078 ptr_env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3079 memcpy(ptr_env, function_table, sizeof(jniNativeInterface));
3080 return JVMTI_ERROR_NONE;
3084 /* GetJNIFunctionTable *********************************************************
3086 Get the JNI function table. The JNI function table is copied into allocated
3089 *******************************************************************************/
3092 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3095 CHECK_PHASE(JVMTI_PHASE_START)
3096 CHECK_PHASE(JVMTI_PHASE_LIVE)
3099 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3100 *function_table = (jniNativeInterface*)
3101 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3102 memcpy(*function_table, ptr_env, sizeof(jniNativeInterface));
3103 return JVMTI_ERROR_NONE;
3107 /* SetEventCallbacks **********************************************************
3109 Set the functions to be called for each event. The callbacks are specified
3110 by supplying a replacement function table.
3112 *******************************************************************************/
3115 SetEventCallbacks (jvmtiEnv * env,
3116 const jvmtiEventCallbacks * callbacks,
3117 jint size_of_callbacks)
3120 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3121 CHECK_PHASE(JVMTI_PHASE_LIVE)
3124 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3126 if (callbacks == NULL) { /* remove the existing callbacks */
3127 memset(&(((environment* )env)->callbacks), 0,
3128 sizeof(jvmtiEventCallbacks));
3131 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3133 return JVMTI_ERROR_NONE;
3137 /* GenerateEvents *************************************************************
3139 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3140 the current state of the VM.
3142 *******************************************************************************/
3145 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3148 CHECK_PHASE(JVMTI_PHASE_LIVE)
3151 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3152 return JVMTI_ERROR_NONE;
3156 /* GetExtensionFunctions ******************************************************
3158 Returns the set of extension functions.
3160 *******************************************************************************/
3163 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3164 jvmtiExtensionFunctionInfo ** extensions)
3167 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3168 CHECK_PHASE(JVMTI_PHASE_LIVE)
3171 if ((extension_count_ptr== NULL)||(extensions == NULL))
3172 return JVMTI_ERROR_NULL_POINTER;
3174 /* cacao has no extended functions yet */
3175 *extension_count_ptr = 0;
3177 return JVMTI_ERROR_NONE;
3181 /* GetExtensionEvents *********************************************************
3183 Returns the set of extension events.
3185 *******************************************************************************/
3188 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3189 jvmtiExtensionEventInfo ** extensions)
3192 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3193 CHECK_PHASE(JVMTI_PHASE_LIVE)
3196 if ((extension_count_ptr== NULL)||(extensions == NULL))
3197 return JVMTI_ERROR_NULL_POINTER;
3199 /* cacao has no extended events yet */
3200 *extension_count_ptr = 0;
3202 return JVMTI_ERROR_NONE;
3206 /* SetExtensionEventCallback **************************************************
3208 Sets the callback function for an extension event and enables the event.
3210 *******************************************************************************/
3213 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3214 jvmtiExtensionEvent callback)
3217 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3218 CHECK_PHASE(JVMTI_PHASE_LIVE)
3221 /* cacao has no extended events yet */
3222 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3226 /* DisposeEnvironment **********************************************************
3228 Shutdown a JVM TI connection created with JNI GetEnv.
3230 *******************************************************************************/
3233 DisposeEnvironment (jvmtiEnv * env)
3235 environment* cacao_env = (environment*)env;
3236 environment* tenvs = envs;
3237 memset(&((cacao_env)->events[0]),0,sizeof(jvmtiEventModeLL)*
3238 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3239 (cacao_env)->EnvironmentLocalStorage = NULL;
3241 if (tenvs!=cacao_env) {
3242 while (tenvs->next != cacao_env) {
3243 tenvs = tenvs->next;
3245 tenvs->next = cacao_env->next;
3249 /* let Boehm GC do the rest */
3250 return JVMTI_ERROR_NONE;
3254 /* GetErrorName ***************************************************************
3256 Return the symbolic name for an error code.
3258 *******************************************************************************/
3260 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3261 memcpy(*name_ptr, &str, sizeof(str)); \
3265 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3267 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3270 case JVMTI_ERROR_NONE :
3271 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3272 case JVMTI_ERROR_NULL_POINTER :
3273 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3274 case JVMTI_ERROR_OUT_OF_MEMORY :
3275 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3276 case JVMTI_ERROR_ACCESS_DENIED :
3277 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3278 case JVMTI_ERROR_UNATTACHED_THREAD :
3279 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3280 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3281 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3282 case JVMTI_ERROR_WRONG_PHASE :
3283 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3284 case JVMTI_ERROR_INTERNAL :
3285 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3286 case JVMTI_ERROR_INVALID_PRIORITY :
3287 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3288 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3289 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3290 case JVMTI_ERROR_THREAD_SUSPENDED :
3291 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3292 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3293 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3294 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3295 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3296 case JVMTI_ERROR_NO_MORE_FRAMES :
3297 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3298 case JVMTI_ERROR_OPAQUE_FRAME :
3299 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3300 case JVMTI_ERROR_DUPLICATE :
3301 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3302 case JVMTI_ERROR_NOT_FOUND :
3303 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3304 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3305 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3306 case JVMTI_ERROR_INTERRUPT :
3307 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3308 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3309 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3310 case JVMTI_ERROR_NOT_AVAILABLE :
3311 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3312 case JVMTI_ERROR_ABSENT_INFORMATION :
3313 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3314 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3315 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3316 case JVMTI_ERROR_NATIVE_METHOD :
3317 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3318 case JVMTI_ERROR_INVALID_THREAD :
3319 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3320 case JVMTI_ERROR_INVALID_FIELDID :
3321 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3322 case JVMTI_ERROR_INVALID_METHODID :
3323 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3324 case JVMTI_ERROR_INVALID_LOCATION :
3325 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3326 case JVMTI_ERROR_INVALID_OBJECT :
3327 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3328 case JVMTI_ERROR_INVALID_CLASS :
3329 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3330 case JVMTI_ERROR_TYPE_MISMATCH :
3331 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3332 case JVMTI_ERROR_INVALID_SLOT :
3333 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3334 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3335 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3336 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3337 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3338 case JVMTI_ERROR_INVALID_MONITOR :
3339 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3340 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3341 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3342 case JVMTI_ERROR_INVALID_TYPESTATE :
3343 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3344 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3345 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3346 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3347 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3348 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3349 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3350 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3351 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3352 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3353 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3354 case JVMTI_ERROR_FAILS_VERIFICATION :
3355 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3356 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3357 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3358 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3359 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3360 case JVMTI_ERROR_NAMES_DONT_MATCH :
3361 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3362 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3363 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3364 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3365 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3367 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3369 return JVMTI_ERROR_NONE;
3372 /* GetJLocationFormat **********************************************************
3374 This function describes the representation of jlocation used in this VM.
3376 *******************************************************************************/
3379 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3381 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3382 return JVMTI_ERROR_NONE;
3386 /* GetSystemProperties ********************************************************
3388 The list of VM system property keys which may be used with GetSystemProperty
3391 *******************************************************************************/
3394 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3398 classinfo *sysclass, *propclass, *enumclass;
3399 java_objectheader *sysprop, *keys, *obj;
3404 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3405 CHECK_PHASE(JVMTI_PHASE_LIVE)
3408 if ((count_ptr == NULL) || (property_ptr == NULL))
3409 return JVMTI_ERROR_NULL_POINTER;
3411 sysclass = load_class_from_sysloader(
3412 utf_new_char_classname ("java/lang/System"));
3414 if (!sysclass) throw_main_exception_exit();
3416 mid = class_resolvemethod(sysclass,
3417 utf_new_char("getProperties"),
3418 utf_new_char("()Ljava/util/Properties;"));
3419 if (!mid) throw_main_exception_exit();
3422 sysprop = asm_calljavafunction(mid, sysclass, NULL, NULL, NULL);
3423 if (!sysprop) throw_main_exception_exit();
3425 propclass = sysprop->vftbl->class;
3427 mid = class_resolvemethod(propclass,
3428 utf_new_char("size"),
3429 utf_new_char("()I"));
3430 if (!mid) throw_main_exception_exit();
3433 JNI_JNIEnvTable.CallIntMethod(NULL, sysprop, mid);
3434 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3436 mid = class_resolvemethod(propclass,
3437 utf_new_char("keys"),
3438 utf_new_char("()Ljava/util/Enumeration;"));
3439 if (!mid) throw_main_exception_exit();
3441 keys = JNI_JNIEnvTable.CallObjectMethod(NULL, sysprop, mid);
3442 enumclass = keys->vftbl->class;
3444 moremid = class_resolvemethod(enumclass,
3445 utf_new_char("hasMoreElements"),
3446 utf_new_char("()Z"));
3447 if (!moremid) throw_main_exception_exit();
3449 mid = class_resolvemethod(propclass,
3450 utf_new_char("nextElement"),
3451 utf_new_char("()Ljava/lang/Object;"));
3452 if (!mid) throw_main_exception_exit();
3455 while (JNI_JNIEnvTable.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3456 obj = JNI_JNIEnvTable.CallObjectMethod(NULL, keys, mid);
3457 ch = javastring_tochar(obj);
3458 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3459 memcpy(*property_ptr[i], ch, strlen (ch));
3460 MFREE(ch,char,strlen(ch)+1);
3464 return JVMTI_ERROR_NONE;
3468 /* GetSystemProperty **********************************************************
3470 Return a VM system property value given the property key.
3472 *******************************************************************************/
3475 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3478 classinfo *sysclass, *propclass;
3479 java_objectheader *sysprop, *obj;
3483 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3484 CHECK_PHASE(JVMTI_PHASE_LIVE)
3487 if ((value_ptr == NULL) || (property == NULL))
3488 return JVMTI_ERROR_NULL_POINTER;
3490 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3491 if (!sysclass) throw_main_exception_exit();
3493 mid = class_resolvemethod(sysclass,
3494 utf_new_char("getProperties"),
3495 utf_new_char("()Ljava/util/Properties;"));
3496 if (!mid) throw_main_exception_exit();
3498 sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3500 propclass = sysprop->vftbl->class;
3502 mid = class_resolvemethod(propclass,
3503 utf_new_char("getProperty"),
3504 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3505 if (!mid) throw_main_exception_exit();
3507 obj = (java_objectheader*)JNI_JNIEnvTable.CallObjectMethod(
3508 NULL, sysprop, mid, javastring_new_char(property));
3509 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3511 ch = javastring_tochar(obj);
3512 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3513 memcpy(*value_ptr, ch, strlen (ch));
3514 MFREE(ch,char,strlen(ch)+1);
3516 return JVMTI_ERROR_NONE;
3520 /* SetSystemProperty **********************************************************
3522 Set a VM system property value.
3524 *******************************************************************************/
3527 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3530 classinfo *sysclass, *propclass;
3531 java_objectheader *sysprop;
3534 CHECK_PHASE(JVMTI_PHASE_START)
3537 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3538 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3540 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3541 if (!sysclass) throw_main_exception_exit();
3543 mid = class_resolvemethod(sysclass,
3544 utf_new_char("getProperties"),
3545 utf_new_char("()Ljava/util/Properties;"));
3546 if (!mid) throw_main_exception_exit();
3548 sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3550 propclass = sysprop->vftbl->class;
3552 mid = class_resolvemethod(propclass,
3553 utf_new_char("setProperty"),
3554 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3555 if (!mid) throw_main_exception_exit();
3557 JNI_JNIEnvTable.CallObjectMethod(
3558 NULL, sysprop, mid, javastring_new_char(property),javastring_new_char(value));
3560 return JVMTI_ERROR_NONE;
3563 /* GetPhase ********************************************************************
3565 Return the current phase of VM execution
3567 *******************************************************************************/
3570 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3572 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3576 return JVMTI_ERROR_NONE;
3579 /* GetCurrentThreadCpuTimerInfo ************************************************
3583 *******************************************************************************/
3586 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3589 CHECK_PHASE(JVMTI_PHASE_START)
3590 CHECK_PHASE(JVMTI_PHASE_LIVE)
3592 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3594 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3596 return JVMTI_ERROR_NONE;
3599 /* GetCurrentThreadCpuTime ****************************************************
3603 *******************************************************************************/
3606 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3609 CHECK_PHASE(JVMTI_PHASE_START)
3610 CHECK_PHASE(JVMTI_PHASE_LIVE)
3612 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3614 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3615 return JVMTI_ERROR_NONE;
3618 /* GetThreadCpuTimerInfo ******************************************************
3622 *******************************************************************************/
3625 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3628 CHECK_PHASE(JVMTI_PHASE_START)
3629 CHECK_PHASE(JVMTI_PHASE_LIVE)
3631 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3633 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3634 return JVMTI_ERROR_NONE;
3637 /* GetThreadCpuTime ***********************************************************
3641 *******************************************************************************/
3644 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3647 CHECK_PHASE(JVMTI_PHASE_LIVE)
3649 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3650 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3651 return JVMTI_ERROR_NONE;
3654 /* GetTimerInfo ***************************************************************
3656 Get information about the GetTime timer.
3658 *******************************************************************************/
3661 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3663 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3665 info_ptr->max_value = !0x0;
3666 info_ptr->may_skip_forward = true;
3667 info_ptr->may_skip_backward = true;
3668 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3670 return JVMTI_ERROR_NONE;
3673 /* GetTime ********************************************************************
3675 Return the current value of the system timer, in nanoseconds
3677 *******************************************************************************/
3680 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3682 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3685 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3687 if (gettimeofday (&tp, NULL) == -1)
3688 JNI_JNIEnvTable.FatalError (NULL, "gettimeofday call failed.");
3690 *nanos_ptr = (jlong) tp.tv_sec;
3692 *nanos_ptr += (tp.tv_usec / 1000);
3694 return JVMTI_ERROR_NONE;
3697 /* GetPotentialCapabilities ***************************************************
3699 Returns the JVM TI features that can potentially be possessed by this
3700 environment at this time.
3702 *******************************************************************************/
3705 GetPotentialCapabilities (jvmtiEnv * env,
3706 jvmtiCapabilities * capabilities_ptr)
3709 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3710 CHECK_PHASE(JVMTI_PHASE_LIVE)
3713 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3715 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3717 return JVMTI_ERROR_NONE;
3721 #define CHECK_ADD_CAPABILITY(env,CAN) \
3722 if ((capabilities_ptr->CAN == 1) && \
3723 (JVMTI_Capabilities.CAN == 0)) \
3724 return JVMTI_ERROR_NOT_AVAILABLE; \
3725 env->capabilities.CAN = 1;
3727 /* AddCapabilities ************************************************************
3729 Set new capabilities by adding the capabilities pointed to by
3730 capabilities_ptr. All previous capabilities are retained.
3732 *******************************************************************************/
3735 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3737 environment* cacao_env;
3740 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3741 CHECK_PHASE(JVMTI_PHASE_LIVE)
3744 if ((env == NULL) || (capabilities_ptr == NULL))
3745 return JVMTI_ERROR_NULL_POINTER;
3747 cacao_env = (environment*)env;
3749 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3750 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3751 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3752 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3753 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3754 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3755 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3756 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3757 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3758 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3759 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3760 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3761 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3762 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3763 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3764 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3765 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3766 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3767 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3768 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3769 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3770 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3771 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3772 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3773 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3774 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3775 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3776 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3777 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3778 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3779 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3780 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3781 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3784 return JVMTI_ERROR_NONE;
3788 #define CHECK_DEL_CAPABILITY(env,CAN) \
3789 if (capabilities_ptr->CAN == 1) \
3790 env->capabilities.CAN = 0;
3792 /* RelinquishCapabilities *****************************************************
3794 Relinquish the capabilities pointed to by capabilities_ptr.
3796 *******************************************************************************/
3799 RelinquishCapabilities (jvmtiEnv * env,
3800 const jvmtiCapabilities * capabilities_ptr)
3802 environment* cacao_env;
3805 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3806 CHECK_PHASE(JVMTI_PHASE_LIVE)
3809 if ((env == NULL) || (capabilities_ptr == NULL))
3810 return JVMTI_ERROR_NULL_POINTER;
3812 cacao_env = (environment*)env;
3814 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3815 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3816 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3817 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3818 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3819 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3820 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3821 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3822 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3823 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3824 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3825 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3826 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3827 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3828 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3829 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3830 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3831 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3832 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3833 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3834 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3835 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3836 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3837 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3838 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3839 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3840 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3841 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3842 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3843 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3844 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3845 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3846 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3848 return JVMTI_ERROR_NONE;
3851 /* *****************************************************************************
3855 *******************************************************************************/
3858 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3861 CHECK_PHASE(JVMTI_PHASE_START)
3862 CHECK_PHASE(JVMTI_PHASE_LIVE)
3865 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3867 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3869 *processor_count_ptr = 1; /* where do I get this ?*/
3871 return JVMTI_ERROR_NONE;
3874 /* GetEnvironmentLocalStorage **************************************************
3876 Called by the agent to get the value of the JVM TI environment-local storage.
3878 *******************************************************************************/
3881 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
3883 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
3885 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
3887 return JVMTI_ERROR_NONE;
3890 /* SetEnvironmentLocalStorage **************************************************
3892 The VM stores a pointer value associated with each environment. Agents can
3893 allocate memory in which they store environment specific information.
3895 *******************************************************************************/
3898 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
3900 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
3902 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
3904 return JVMTI_ERROR_NONE;
3907 /* AddToBootstrapClassLoaderSearch ********************************************
3909 After the bootstrap class loader unsuccessfully searches for a class, the
3910 specified platform-dependent search path segment will be searched as well.
3912 *******************************************************************************/
3915 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
3921 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3924 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
3926 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
3927 tmp_bcp = MNEW(char, ln);
3928 strcat(tmp_bcp, bootclasspath);
3929 strcat(tmp_bcp, ":");
3930 strcat(tmp_bcp, segment);
3931 MFREE(bootclasspath,char,ln);
3932 bootclasspath = tmp_bcp;
3934 return JVMTI_ERROR_NONE;
3937 /* SetVerboseFlag *************************************************************
3939 Control verbose output. This is the output which typically is sent to stderr
3941 *******************************************************************************/
3944 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
3947 case JVMTI_VERBOSE_OTHER:
3950 case JVMTI_VERBOSE_GC:
3951 opt_verbosegc = value;
3953 case JVMTI_VERBOSE_CLASS:
3954 loadverbose = value;
3956 case JVMTI_VERBOSE_JNI:
3959 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3961 return JVMTI_ERROR_NONE;
3964 /* GetObjectSize **************************************************************
3966 For the object object return the size.
3968 *******************************************************************************/
3971 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
3974 CHECK_PHASE(JVMTI_PHASE_START)
3975 CHECK_PHASE(JVMTI_PHASE_LIVE)
3978 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3979 if (!builtin_instanceof(object,class_java_lang_Object))
3980 return JVMTI_ERROR_INVALID_OBJECT;
3982 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
3984 return JVMTI_ERROR_NONE;
3988 /* *****************************************************************************
3990 Environment variables
3992 *******************************************************************************/
3994 static jvmtiCapabilities JVMTI_Capabilities = {
3995 0, /* can_tag_objects */
3996 0, /* can_generate_field_modification_events */
3997 0, /* can_generate_field_access_events */
3998 1, /* can_get_bytecodes */
3999 0, /* can_get_synthetic_attribute */
4001 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4002 1, /* can_get_owned_monitor_info */
4003 1, /* can_get_current_contended_monitor */
4005 0, /* can_get_owned_monitor_info */
4006 0, /* can_get_current_contended_monitor */
4009 0, /* can_get_monitor_info */
4010 0, /* can_pop_frame */
4011 0, /* can_redefine_classes */
4012 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4013 1, /* can_signal_thread */
4015 0, /* can_signal_thread */
4017 1, /* can_get_source_file_name */
4018 1, /* can_get_line_numbers */
4019 0, /* can_get_source_debug_extension */
4020 0, /* can_access_local_variables */
4021 0, /* can_maintain_original_method_order */
4022 0, /* can_generate_single_step_events */
4023 0, /* can_generate_exception_events */
4024 0, /* can_generate_frame_pop_events */
4025 0, /* can_generate_breakpoint_events */
4026 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4027 1, /* can_suspend */
4029 0, /* can_suspend */
4031 0, /* can_redefine_any_class */
4032 0, /* can_get_current_thread_cpu_time */
4033 0, /* can_get_thread_cpu_time */
4034 0, /* can_generate_method_entry_events */
4035 0, /* can_generate_method_exit_events */
4036 0, /* can_generate_all_class_hook_events */
4037 0, /* can_generate_compiled_method_load_events */
4038 0, /* can_generate_monitor_events */
4039 0, /* can_generate_vm_object_alloc_events */
4040 0, /* can_generate_native_method_bind_events */
4041 0, /* can_generate_garbage_collection_events */
4042 0, /* can_generate_object_free_events */
4045 static jvmtiEnv JVMTI_EnvTable = {
4047 &SetEventNotificationMode,
4055 &GetOwnedMonitorInfo,
4056 &GetCurrentContendedMonitor,
4058 &GetTopThreadGroups,
4059 &GetThreadGroupInfo,
4060 &GetThreadGroupChildren,
4082 &RawMonitorNotifyAll,
4086 &SetFieldAccessWatch,
4087 &ClearFieldAccessWatch,
4088 &SetFieldModificationWatch,
4089 &ClearFieldModificationWatch,
4099 &GetImplementedInterfaces,
4104 &GetObjectMonitorUsage,
4106 &GetFieldDeclaringClass,
4110 &GetMethodDeclaringClass,
4111 &GetMethodModifiers,
4115 &GetLineNumberTable,
4117 &GetLocalVariableTable,
4124 &GetClassLoaderClasses,
4135 &GetSourceDebugExtension,
4146 &GetThreadListStackTraces,
4147 &GetThreadLocalStorage,
4148 &SetThreadLocalStorage,
4153 &ForceGarbageCollection,
4154 &IterateOverObjectsReachableFromObject,
4155 &IterateOverReachableObjects,
4157 &IterateOverInstancesOfClass,
4159 &GetObjectsWithTags,
4165 &SetJNIFunctionTable,
4166 &GetJNIFunctionTable,
4169 &GetExtensionFunctions,
4170 &GetExtensionEvents,
4171 &SetExtensionEventCallback,
4172 &DisposeEnvironment,
4174 &GetJLocationFormat,
4175 &GetSystemProperties,
4179 &GetCurrentThreadCpuTimerInfo,
4180 &GetCurrentThreadCpuTime,
4181 &GetThreadCpuTimerInfo,
4185 &GetPotentialCapabilities,
4188 &RelinquishCapabilities,
4189 &GetAvailableProcessors,
4192 &GetEnvironmentLocalStorage,
4193 &SetEnvironmentLocalStorage,
4194 &AddToBootstrapClassLoaderSearch,
4202 void set_jvmti_phase(jvmtiPhase p) {
4208 case JVMTI_PHASE_ONLOAD:
4209 /* nothing to be done */
4211 case JVMTI_PHASE_PRIMORDIAL:
4212 /* nothing to be done */
4214 case JVMTI_PHASE_START:
4215 e = JVMTI_EVENT_VM_START;
4217 case JVMTI_PHASE_LIVE:
4218 e = JVMTI_EVENT_VM_INIT;
4220 case JVMTI_PHASE_DEAD:
4221 e = JVMTI_EVENT_VM_DEATH;
4228 jvmtiEnv* new_jvmtienv() {
4233 while (env->next!=NULL) {
4236 env = heap_allocate(sizeof(environment),true,NULL);
4237 memcpy(&(env->env),&JVMTI_EnvTable,sizeof(jvmtiEnv));
4238 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4239 sizeof(jvmtiEventModeLL));
4240 /* To possess a capability, the agent must add the capability.*/
4241 memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
4242 RelinquishCapabilities(&(env->env),&(env->capabilities));
4243 env->EnvironmentLocalStorage = NULL;
4248 void agentload(char* opt_arg) {
4251 char *libname, *arg;
4255 len = strlen(opt_arg);
4257 while ((opt_arg[i]!='=')&&(i<len)) i++;
4259 libname=MNEW(char,i);
4260 strncpy(libname,opt_arg,i-1);
4263 arg=MNEW(char, len-i);
4264 strcpy(arg,&opt_arg[i+1]);
4266 /* try to open the library */
4268 if (!(handle = lt_dlopen(libname)))
4271 /* resolve Agent_OnLoad function */
4272 onload = lt_dlsym(handle, "Agent_OnLoad");
4273 if (onload == NULL) {
4274 fprintf(stderr, "unable to load Agent_OnLoad function in %s\n", libname);
4278 /* resolve Agent_UnLoad function */
4279 unload = lt_dlsym(handle, "Agent_Unload");
4282 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4283 onload) ((JavaVM*) &JNI_JavaVMTable, arg, NULL);
4285 MFREE(libname,char,i);
4286 MFREE(arg,char,len-i);
4288 if (retval != 0) exit (retval);
4290 /* todo: native_library_hash_add(name, (java_objectheader *) loader, handle); */
4293 void agentunload() {
4294 if (unload != NULL) {
4295 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4296 ((JavaVM*) &JNI_JavaVMTable);
4301 * These are local overrides for various environment variables in Emacs.
4302 * Please do not remove this and leave it at the end of the file, where
4303 * Emacs will automagically detect them.
4304 * ---------------------------------------------------------------------
4307 * indent-tabs-mode: t