1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
5 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
6 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
7 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
26 Contact: cacao@cacaojvm.org
28 Author: Martin Platter
30 Changes: Edwin Steiner
41 #include <linux/unistd.h>
44 #include <sys/types.h>
49 #include "native/jni.h"
50 #include "native/native.h"
51 #include "native/jvmti/cacaodbg.h"
52 #include "native/jvmti/jvmti.h"
53 #include "vm/jit/stacktrace.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/builtin.h"
57 #include "vm/jit/asmpart.h"
59 #include "vm/classcache.h"
60 #include "mm/gc-common.h"
61 #include "toolbox/logging.h"
62 #include "vm/options.h"
63 #include "vm/stringlocal.h"
64 #include "mm/memory.h"
65 #include "threads/native/threads.h"
66 #include "threads/native/lock.h"
67 #include "vm/exceptions.h"
68 #include "native/include/java_util_Vector.h"
69 #include "native/include/java_io_PrintStream.h"
70 #include "native/include/java_io_InputStream.h"
71 #include "native/include/java_lang_Cloneable.h"
72 #include "native/include/java_lang_ThreadGroup.h"
73 #include "native/include/java_lang_VMObject.h"
74 #include "native/include/java_lang_VMSystem.h"
75 #include "native/include/java_lang_VMClass.h"
77 #include "boehm-gc/include/gc.h"
79 #if defined(ENABLE_THREADS)
80 #include "threads/native/threads.h"
88 typedef struct _environment environment;
89 static environment *envs=NULL;
90 pthread_mutex_t dbgcomlock;
92 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
94 static jvmtiPhase phase;
95 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
96 struct _jvmtiEventModeLL {
99 jvmtiEventModeLL *next;
102 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
103 struct _jvmtiThreadLocalStorage{
106 jvmtiThreadLocalStorage *next;
109 struct _environment {
112 jvmtiEventCallbacks callbacks;
113 /* table for enabled/disabled jvmtiEvents - first element contains global
115 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
116 jvmtiCapabilities capabilities;
117 void *EnvironmentLocalStorage;
118 jvmtiThreadLocalStorage *tls;
121 static struct jvmtiEnv_struct JVMTI_EnvTable;
122 static jvmtiCapabilities JVMTI_Capabilities;
123 static lt_ptr unload;
125 #define CHECK_PHASE_START if (!(false
126 #define CHECK_PHASE(chkphase) || (phase == chkphase)
127 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
128 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
129 env)->capabilities.CAP == 0) \
130 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
131 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
132 JVMTI_ERROR_THREAD_NOT_ALIVE) \
133 return JVMTI_ERROR_THREAD_NOT_ALIVE;
138 /* check_thread_is_alive *******************************************************
140 checks if the given thread is alive
142 *******************************************************************************/
143 static jvmtiError check_thread_is_alive(jthread t) {
144 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
145 if(((java_lang_Thread*) t)->vmThread == NULL)
146 return JVMTI_ERROR_THREAD_NOT_ALIVE;
147 return JVMTI_ERROR_NONE;
150 /* execute_callback ************************************************************
152 executes the registerd callbacks for the given jvmti event with parameter
153 in the data structure.
155 *******************************************************************************/
156 static void execute_callback(jvmtiEvent e, functionptr ec,
157 genericEventData* data) {
158 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
160 fprintf(stderr,"execcallback called (event: %d)\n",e);
163 case JVMTI_EVENT_VM_INIT:
164 if (phase != JVMTI_PHASE_LIVE) return;
165 case JVMTI_EVENT_THREAD_START:
166 case JVMTI_EVENT_THREAD_END:
167 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
168 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
171 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
172 if ((phase == JVMTI_PHASE_START) ||
173 (phase == JVMTI_PHASE_LIVE) ||
174 (phase == JVMTI_PHASE_PRIMORDIAL))
175 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
180 data->protection_domain,
183 data->new_class_data_len,
184 data->new_class_data);
186 /* if class data has been modified use it as class data for other agents
187 waiting for the same event */
188 if (data->new_class_data != NULL) {
189 data->jint1 = *(data->new_class_data_len);
190 data->class_data = *(data->new_class_data);
195 case JVMTI_EVENT_CLASS_PREPARE:
196 case JVMTI_EVENT_CLASS_LOAD:
197 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
198 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
199 data->thread, data->klass);
202 case JVMTI_EVENT_VM_DEATH:
203 if (phase != JVMTI_PHASE_LIVE) return;
204 case JVMTI_EVENT_VM_START:
205 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
206 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
209 case JVMTI_EVENT_NATIVE_METHOD_BIND:
210 if ((phase == JVMTI_PHASE_START) ||
211 (phase == JVMTI_PHASE_LIVE) ||
212 (phase == JVMTI_PHASE_PRIMORDIAL))
213 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
217 data->new_address_ptr);
221 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
222 if ((phase == JVMTI_PHASE_START) ||
223 (phase == JVMTI_PHASE_LIVE) ||
224 (phase == JVMTI_PHASE_PRIMORDIAL))
225 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
234 if (phase != JVMTI_PHASE_LIVE) return;
236 case JVMTI_EVENT_EXCEPTION:
237 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
243 data->catch_location);
246 case JVMTI_EVENT_EXCEPTION_CATCH:
247 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
254 case JVMTI_EVENT_BREAKPOINT:
255 case JVMTI_EVENT_SINGLE_STEP:
256 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
262 case JVMTI_EVENT_FRAME_POP:
263 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
270 case JVMTI_EVENT_FIELD_ACCESS:
271 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
280 case JVMTI_EVENT_FIELD_MODIFICATION:
282 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
289 data->signature_type,
293 case JVMTI_EVENT_METHOD_ENTRY:
294 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
299 case JVMTI_EVENT_METHOD_EXIT:
300 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
307 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
308 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
317 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
318 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
323 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
324 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
325 case JVMTI_EVENT_DATA_DUMP_REQUEST:
326 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
329 case JVMTI_EVENT_MONITOR_WAIT:
330 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
336 case JVMTI_EVENT_MONITOR_WAITED:
337 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
344 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
345 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
346 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
351 case JVMTI_EVENT_OBJECT_FREE:
352 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
355 case JVMTI_EVENT_VM_OBJECT_ALLOC:
356 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
363 log_text ("unknown event");
370 /* dofireEvent ******************************************************************
372 sends event if it is enabled either globally or for some threads
374 *******************************************************************************/
375 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
377 jvmtiEventModeLL *evm;
381 while (env != NULL) {
382 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
383 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
384 /* test if the event is enable for some threads */
385 while (evm != NULL) {
386 if (evm->mode == JVMTI_ENABLE) {
388 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
390 data->jvmti_env=&env->env;
391 execute_callback(e, ec, data);
396 } else { /* event enabled globally */
397 data->jvmti_env=&env->env;
398 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
399 if (ec != NULL) execute_callback(e, ec, data);
407 /* fireEvent ******************************************************************
409 fire event callback with data arguments. This function mainly fills the
412 *******************************************************************************/
413 void jvmti_fireEvent(genericEventData* d) {
415 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
417 if (d->ev == JVMTI_EVENT_VM_START)
420 thread = jvmti_get_current_thread();
424 dofireEvent(d->ev,d);
428 /* SetEventNotificationMode ****************************************************
430 Control the generation of events
432 *******************************************************************************/
435 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
436 jvmtiEvent event_type, jthread event_thread, ...)
438 environment* cacao_env;
439 jvmtiEventModeLL *ll;
442 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
443 CHECK_PHASE(JVMTI_PHASE_LIVE)
446 if(event_thread != NULL) {
447 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
448 return JVMTI_ERROR_INVALID_THREAD;
449 CHECK_THREAD_IS_ALIVE(event_thread);
452 cacao_env = (environment*) env;
453 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
454 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
456 switch (event_type) { /* check capability and set system breakpoint */
457 case JVMTI_EVENT_EXCEPTION:
458 case JVMTI_EVENT_EXCEPTION_CATCH:
459 CHECK_CAPABILITY(env,can_generate_exception_events)
461 case JVMTI_EVENT_SINGLE_STEP:
462 CHECK_CAPABILITY(env,can_generate_single_step_events)
464 case JVMTI_EVENT_FRAME_POP:
465 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
467 case JVMTI_EVENT_BREAKPOINT:
468 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
470 case JVMTI_EVENT_FIELD_ACCESS:
471 CHECK_CAPABILITY(env,can_generate_field_access_events)
473 case JVMTI_EVENT_FIELD_MODIFICATION:
474 CHECK_CAPABILITY(env,can_generate_field_modification_events)
476 case JVMTI_EVENT_METHOD_ENTRY:
477 CHECK_CAPABILITY(env,can_generate_method_entry_events)
479 case JVMTI_EVENT_METHOD_EXIT:
480 CHECK_CAPABILITY(env, can_generate_method_exit_events)
482 case JVMTI_EVENT_NATIVE_METHOD_BIND:
483 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
485 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
486 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
487 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
489 case JVMTI_EVENT_MONITOR_WAIT:
490 case JVMTI_EVENT_MONITOR_WAITED:
491 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
492 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
493 CHECK_CAPABILITY(env,can_generate_monitor_events)
495 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
496 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
497 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
499 case JVMTI_EVENT_OBJECT_FREE:
500 CHECK_CAPABILITY(env,can_generate_object_free_events)
502 case JVMTI_EVENT_VM_OBJECT_ALLOC:
503 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
506 /* all other events are required */
507 if ((event_type < JVMTI_EVENT_START_ENUM) ||
508 (event_type > JVMTI_EVENT_END_ENUM))
509 return JVMTI_ERROR_INVALID_EVENT_TYPE;
514 if (event_thread != NULL) {
515 /* thread level control */
516 if ((JVMTI_EVENT_VM_INIT == mode) ||
517 (JVMTI_EVENT_VM_DEATH == mode) ||
518 (JVMTI_EVENT_VM_START == mode) ||
519 (JVMTI_EVENT_THREAD_START == mode) ||
520 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
521 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
522 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
523 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
524 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
525 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
526 while (ll->next != NULL) {
528 if (ll->event_thread == event_thread) {
530 return JVMTI_ERROR_NONE;
533 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
537 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
541 return JVMTI_ERROR_NONE;
544 /* GetAllThreads ***************************************************************
548 *******************************************************************************/
551 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
552 jthread ** threads_ptr)
554 threadobject** threads;
559 CHECK_PHASE(JVMTI_PHASE_LIVE)
562 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
563 return JVMTI_ERROR_NULL_POINTER;
565 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
566 if (retval != JVMTI_ERROR_NONE) return retval;
569 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
571 for (i=0; i<*threads_count_ptr; i++)
572 (*threads_ptr)[i] = threads[i]->o.thread;
574 return JVMTI_ERROR_NONE;
578 /* SuspendThread ***************************************************************
580 Suspend specified thread
582 *******************************************************************************/
585 SuspendThread (jvmtiEnv * env, jthread thread)
588 CHECK_PHASE(JVMTI_PHASE_LIVE)
590 CHECK_CAPABILITY(env,can_suspend);
592 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
593 if (!builtin_instanceof(thread,class_java_lang_Thread))
594 return JVMTI_ERROR_INVALID_THREAD;
595 CHECK_THREAD_IS_ALIVE(thread);
597 /* threads_suspend_thread will implement suspend
598 threads_suspend_thread (
599 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
601 return JVMTI_ERROR_NONE;
604 /* ResumeThread ***************************************************************
606 Resume a suspended thread
608 *******************************************************************************/
611 ResumeThread (jvmtiEnv * env, jthread thread)
614 CHECK_PHASE(JVMTI_PHASE_LIVE)
616 CHECK_CAPABILITY(env,can_suspend);
618 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
619 if (!builtin_instanceof(thread,class_java_lang_Thread))
620 return JVMTI_ERROR_INVALID_THREAD;
621 CHECK_THREAD_IS_ALIVE(thread);
623 /* threads_resume_thread will implement resume
624 threads_resume_thread (
625 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
627 return JVMTI_ERROR_NONE;
630 /* StopThread *****************************************************************
632 Send asynchronous exception to the specified thread. Similar to
633 java.lang.Thread.stop(). Used to kill thread.
635 *******************************************************************************/
638 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
641 CHECK_PHASE(JVMTI_PHASE_LIVE)
643 CHECK_CAPABILITY(env,can_signal_thread);
645 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
646 return JVMTI_ERROR_NOT_AVAILABLE;
648 return JVMTI_ERROR_NONE;
651 /* InterruptThread ************************************************************
653 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
655 *******************************************************************************/
658 InterruptThread (jvmtiEnv * env, jthread thread)
661 CHECK_PHASE(JVMTI_PHASE_LIVE)
663 CHECK_CAPABILITY(env,can_signal_thread)
665 #if defined(ENABLE_THREADS)
666 if(!builtin_instanceof(thread,class_java_lang_Thread))
667 return JVMTI_ERROR_INVALID_THREAD;
669 CHECK_THREAD_IS_ALIVE(thread);
671 threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
674 return JVMTI_ERROR_NONE;
676 return JVMTI_ERROR_NOT_AVAILABLE;
680 /* GetThreadInfo ***************************************************************
682 Get thread information. Details of the specified thread are stored in the
683 jvmtiThreadInfo structure.
685 *******************************************************************************/
688 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
691 java_lang_Thread* th = (java_lang_Thread*)t;
695 CHECK_PHASE(JVMTI_PHASE_LIVE)
698 info_ptr->priority=(jint)th->priority;
699 info_ptr->is_daemon=(jboolean)th->daemon;
700 info_ptr->thread_group=(jthreadGroup)th->group;
701 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
703 name = javastring_toutf(th->name,false);
704 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
705 utf_sprint_convert_to_latin1(info_ptr->name, name);
707 return JVMTI_ERROR_NONE;
710 /* GetOwnedMonitorInfo *********************************************************
712 Gets all monitors owned by the specified thread
714 *******************************************************************************/
717 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
718 jint * owned_monitor_count_ptr,
719 jobject ** owned_monitors_ptr)
722 java_objectheader **om;
723 lock_record_pool_t* lrp;
727 CHECK_PHASE(JVMTI_PHASE_LIVE)
729 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
731 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
732 return JVMTI_ERROR_NULL_POINTER;
734 if (thread == NULL) {
735 t = jvmti_get_current_thread();
737 if(!builtin_instanceof(thread,class_java_lang_Thread))
738 return JVMTI_ERROR_INVALID_THREAD;
740 CHECK_THREAD_IS_ALIVE(thread);
741 t = (threadobject*) thread;
744 #if defined(ENABLE_THREADS)
746 om=MNEW(java_objectheader*,size);
748 pthread_mutex_lock(&lock_global_pool_lock);
749 lrp=lock_global_pool;
751 /* iterate over all lock record pools */
752 while (lrp != NULL) {
753 /* iterate over every lock record in a pool */
754 for (j=0; j<lrp->header.size; j++) {
755 /* if the lock record is owned by the given thread add it to
757 if(lrp->lr[j].owner == t) {
759 MREALLOC(om, java_objectheader*, size, size * 2);
762 om[i] = lrp->lr[j].obj;
766 lrp=lrp->header.next;
769 pthread_mutex_unlock(&lock_global_pool_lock);
771 *owned_monitors_ptr =
772 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
773 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
774 MFREE(om, java_objectheader*, size);
776 *owned_monitor_count_ptr = i;
780 return JVMTI_ERROR_NONE;
783 /* GetCurrentContendedMonitor *************************************************
785 Get the object the specified thread waits for.
787 *******************************************************************************/
790 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
791 jobject * monitor_ptr)
794 lock_record_pool_t* lrp;
796 lock_waiter_t* waiter;
799 CHECK_PHASE(JVMTI_PHASE_LIVE)
801 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
803 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
806 if (thread == NULL) {
807 t = jvmti_get_current_thread();
809 if(!builtin_instanceof(thread,class_java_lang_Thread))
810 return JVMTI_ERROR_INVALID_THREAD;
812 CHECK_THREAD_IS_ALIVE(thread);
813 t = (threadobject*) thread;
816 #if defined(ENABLE_THREADS)
818 pthread_mutex_lock(&lock_global_pool_lock);
820 lrp=lock_global_pool;
822 /* iterate over all lock record pools */
823 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
824 /* iterate over every lock record in a pool */
825 for (j=0; j<lrp->header.size; j++) {
826 /* iterate over every thread that is wait on this lock record */
827 waiter = lrp->lr[j].waiters;
828 while (waiter != NULL)
829 /* if the waiting thread equals to the given thread we are
830 done. Stop iterateting. */
831 if(waiter->waiter == t) {
832 *monitor_ptr=lrp->lr[j].obj;
836 lrp=lrp->header.next;
839 pthread_mutex_unlock(&lock_global_pool_lock);
843 return JVMTI_ERROR_NONE;
847 jvmtiStartFunction sf;
853 static void *threadstartup(void *t) {
854 runagentparam *rap = (runagentparam*)t;
855 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
859 /* RunAgentThread *************************************************************
861 Starts the execution of an agent thread of the specified native function
862 within the specified thread
864 *******************************************************************************/
867 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
868 const void *arg, jint priority)
870 pthread_attr_t threadattr;
871 struct sched_param sp;
875 CHECK_PHASE(JVMTI_PHASE_LIVE)
878 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
879 return JVMTI_ERROR_INVALID_THREAD;
880 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
881 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
882 (priority > JVMTI_THREAD_MAX_PRIORITY))
883 return JVMTI_ERROR_INVALID_PRIORITY;
885 /* XXX: Threads started with this function should not be visible to
886 Java programming language queries but are included in JVM TI queries */
889 rap.arg = (void*)arg;
892 #if defined(ENABLE_THREADS)
893 pthread_attr_init(&threadattr);
894 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
895 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
896 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
898 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
899 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
901 pthread_attr_setschedparam(&threadattr,&sp);
902 if (pthread_create(&((threadobject*)
903 thread)->tid, &threadattr, &threadstartup, &rap)) {
904 log_text("pthread_create failed");
909 return JVMTI_ERROR_NONE;
913 /* GetTopThreadGroups *********************************************************
915 Get all top-level thread groups in the VM.
917 *******************************************************************************/
920 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
921 jthreadGroup ** groups_ptr)
923 jint threads_count_ptr;
924 threadobject *threads_ptr;
926 jthreadGroup **tg,*ttgp;
929 CHECK_PHASE(JVMTI_PHASE_LIVE)
932 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
933 return JVMTI_ERROR_NULL_POINTER;
935 #if defined(ENABLE_THREADS)
936 tg = MNEW(jthreadGroup*,size);
938 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
939 return JVMTI_ERROR_INTERNAL;
941 for (i=0;i<threads_count_ptr;i++){
942 if (threads_ptr[i].o.thread->group == NULL) {
943 log_text("threadgroup not set");
944 return JVMTI_ERROR_INTERNAL;
946 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
949 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
954 MREALLOC(tg,jthreadGroup*,size,size*2);
963 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
964 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
965 MFREE(tg,jthreadGroup*,size);
967 *group_count_ptr = x;
970 return JVMTI_ERROR_NOT_AVAILABLE;
972 return JVMTI_ERROR_NONE;
976 /* GetThreadGroupInfo *********************************************************
978 Get information about the specified thread group.
980 *******************************************************************************/
983 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
984 jvmtiThreadGroupInfo * info_ptr)
988 java_lang_ThreadGroup* grp;
991 CHECK_PHASE(JVMTI_PHASE_LIVE)
994 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
995 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
996 return JVMTI_ERROR_INVALID_THREAD_GROUP;
998 grp = (java_lang_ThreadGroup*)group;
1000 info_ptr->parent = (jthreadGroup)
1001 Java_java_lang_VMObject_clone(NULL,
1002 (jclass)grp->header.vftbl->class,
1003 (java_lang_Cloneable*) &grp->parent);
1005 name = javastring_tochar((java_objectheader*)grp->name);
1006 size = strlen(name);
1007 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
1008 strncpy(info_ptr->name,name,size);
1009 info_ptr->max_priority= (jint)grp->maxpri;
1010 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1012 return JVMTI_ERROR_NONE;
1016 /* GetThreadGroupChildren *****************************************************
1018 Get the live threads and active subgroups in this thread group.
1020 *******************************************************************************/
1023 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1024 jint * thread_count_ptr, jthread ** threads_ptr,
1025 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1027 java_lang_ThreadGroup* tgp;
1030 CHECK_PHASE(JVMTI_PHASE_LIVE)
1033 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1034 (group_count_ptr == NULL) || (groups_ptr == NULL))
1035 return JVMTI_ERROR_NULL_POINTER;
1037 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1038 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1040 tgp = (java_lang_ThreadGroup*)group;
1042 *thread_count_ptr = (jint)tgp->threads->elementCount;
1045 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1047 memcpy(*threads_ptr, &tgp->threads->elementData,
1048 (*thread_count_ptr)*sizeof(java_objectarray*));
1050 *group_count_ptr = (jint) tgp->groups->elementCount;
1053 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1055 memcpy(*groups_ptr, &tgp->threads->elementData,
1056 (*group_count_ptr)*sizeof(jthreadGroup*));
1058 return JVMTI_ERROR_NONE;
1062 /* getcacaostacktrace *********************************************************
1064 Helper function that retrives stack trace for specified thread.
1066 *******************************************************************************/
1068 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1072 if (thread == NULL) {
1073 t = jvmti_get_current_thread();
1074 *trace = stacktrace_create(t);
1076 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1077 /* if (t != jvmti_get_current_thread())
1078 resume = threads_suspend_thread_if_running(thread);
1080 *trace = stacktrace_create(thread );
1083 threads_resume_thread ( thread );*/
1086 return JVMTI_ERROR_NONE;
1090 /* GetFrameCount **************************************************************
1093 Get the number of frames in the specified thread's stack. Calling function
1094 has to take care of suspending/resuming thread.
1096 *******************************************************************************/
1099 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1101 stacktracebuffer* trace;
1105 CHECK_PHASE(JVMTI_PHASE_LIVE)
1108 if (thread != NULL){
1109 if(!builtin_instanceof(thread,class_java_lang_Thread))
1110 return JVMTI_ERROR_INVALID_THREAD;
1112 CHECK_THREAD_IS_ALIVE(thread);
1115 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1117 er = getcacaostacktrace(&trace, thread);
1118 if (er == JVMTI_ERROR_NONE) {
1123 *count_ptr = trace->used;
1126 return JVMTI_ERROR_NONE;
1130 /* GetThreadState **************************************************************
1132 Get the state of a thread.
1134 *******************************************************************************/
1137 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1139 java_lang_Thread* th = (java_lang_Thread*)thread;
1140 threadobject* t = (threadobject*)th->vmThread;
1143 CHECK_PHASE(JVMTI_PHASE_LIVE)
1146 if(!builtin_instanceof(thread,class_java_lang_Thread))
1147 return JVMTI_ERROR_INVALID_THREAD;
1149 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1151 *thread_state_ptr = 0;
1152 #if defined(ENABLE_THREADS)
1153 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1155 if (((threadobject*)th->vmThread)->tid == 0)
1156 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1159 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1160 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1161 /* XXX todo - info not available */
1162 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1163 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1164 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1165 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1166 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1167 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1168 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1169 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1170 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1171 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1174 return JVMTI_ERROR_INTERNAL;
1177 return JVMTI_ERROR_NONE;
1181 /* GetFrameLocation ************************************************************
1183 Get the location of the instruction currently executing
1185 *******************************************************************************/
1188 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1189 jmethodID * method_ptr, jlocation * location_ptr)
1191 stackframeinfo *sfi;
1196 CHECK_PHASE(JVMTI_PHASE_LIVE)
1199 if (thread == NULL) {
1200 th = jvmti_get_current_thread();
1202 if(!builtin_instanceof(thread,class_java_lang_Thread))
1203 return JVMTI_ERROR_INVALID_THREAD;
1205 CHECK_THREAD_IS_ALIVE(thread);
1206 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1209 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1211 if ((method_ptr == NULL)&&(location_ptr == NULL))
1212 return JVMTI_ERROR_NULL_POINTER;
1214 sfi = th->_stackframeinfo;
1217 while ((sfi != NULL) && (i<depth)) {
1222 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1224 *method_ptr=(jmethodID)sfi->method;
1225 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1227 return JVMTI_ERROR_NONE;
1231 /* NotifyFramePop *************************************************************
1235 *******************************************************************************/
1238 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1241 CHECK_PHASE(JVMTI_PHASE_LIVE)
1243 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1245 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1246 return JVMTI_ERROR_NONE;
1249 /* GetLocalObject *************************************************************
1253 *******************************************************************************/
1256 GetLocalObject (jvmtiEnv * env,
1257 jthread thread, jint depth, jint slot, jobject * value_ptr)
1260 CHECK_PHASE(JVMTI_PHASE_LIVE)
1262 CHECK_CAPABILITY(env,can_access_local_variables)
1264 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1265 return JVMTI_ERROR_NONE;
1268 /* GetLocalInt ****************************************************************
1272 *******************************************************************************/
1275 GetLocalInt (jvmtiEnv * env,
1276 jthread thread, jint depth, jint slot, jint * value_ptr)
1279 CHECK_PHASE(JVMTI_PHASE_LIVE)
1281 CHECK_CAPABILITY(env,can_access_local_variables)
1282 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1283 return JVMTI_ERROR_NONE;
1286 /* *****************************************************************************
1290 *******************************************************************************/
1293 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1297 CHECK_PHASE(JVMTI_PHASE_LIVE)
1299 CHECK_CAPABILITY(env,can_access_local_variables)
1301 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1302 return JVMTI_ERROR_NONE;
1306 /* *****************************************************************************
1310 *******************************************************************************/
1313 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1317 CHECK_PHASE(JVMTI_PHASE_LIVE)
1319 CHECK_CAPABILITY(env,can_access_local_variables)
1321 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1322 return JVMTI_ERROR_NONE;
1326 /* *****************************************************************************
1330 *******************************************************************************/
1333 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1334 jdouble * value_ptr)
1337 CHECK_PHASE(JVMTI_PHASE_LIVE)
1339 CHECK_CAPABILITY(env,can_access_local_variables)
1341 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1342 return JVMTI_ERROR_NONE;
1346 /* *****************************************************************************
1350 *******************************************************************************/
1353 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1357 CHECK_PHASE(JVMTI_PHASE_LIVE)
1359 CHECK_CAPABILITY(env,can_access_local_variables)
1361 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1362 return JVMTI_ERROR_NONE;
1366 /* *****************************************************************************
1370 *******************************************************************************/
1373 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1377 CHECK_PHASE(JVMTI_PHASE_LIVE)
1379 CHECK_CAPABILITY(env,can_access_local_variables)
1381 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1382 return JVMTI_ERROR_NONE;
1386 /* *****************************************************************************
1390 *******************************************************************************/
1393 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1397 CHECK_PHASE(JVMTI_PHASE_LIVE)
1399 CHECK_CAPABILITY(env,can_access_local_variables)
1401 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1402 return JVMTI_ERROR_NONE;
1406 /* *****************************************************************************
1410 *******************************************************************************/
1413 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1417 CHECK_PHASE(JVMTI_PHASE_LIVE)
1419 CHECK_CAPABILITY(env,can_access_local_variables)
1421 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1422 return JVMTI_ERROR_NONE;
1426 /* *****************************************************************************
1430 *******************************************************************************/
1433 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1437 CHECK_PHASE(JVMTI_PHASE_LIVE)
1439 CHECK_CAPABILITY(env,can_access_local_variables)
1441 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1442 return JVMTI_ERROR_NONE;
1446 /* CreateRawMonitor ***********************************************************
1448 This function creates a new raw monitor.
1450 *******************************************************************************/
1453 CreateRawMonitor (jvmtiEnv * env, const char *name,
1454 jrawMonitorID * monitor_ptr)
1456 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1459 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1460 CHECK_PHASE(JVMTI_PHASE_LIVE)
1463 if ((name == NULL) || (monitor_ptr == NULL))
1464 return JVMTI_ERROR_NULL_POINTER;
1466 #if defined(ENABLE_THREADS)
1467 monitor->name=javastring_new_from_ascii(name);
1469 log_text ("CreateRawMonitor not supported");
1472 return JVMTI_ERROR_NONE;
1476 /* DestroyRawMonitor **********************************************************
1478 This function destroys a raw monitor.
1480 *******************************************************************************/
1483 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1486 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1487 CHECK_PHASE(JVMTI_PHASE_LIVE)
1490 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1491 return JVMTI_ERROR_INVALID_MONITOR;
1493 #if defined(ENABLE_THREADS)
1494 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1495 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1497 lock_monitor_exit((java_objectheader *) monitor->name);
1501 log_text ("DestroyRawMonitor not supported");
1504 return JVMTI_ERROR_NONE;
1508 /* RawMonitorEnter ************************************************************
1510 Gain exclusive ownership of a raw monitor
1512 *******************************************************************************/
1515 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1517 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1518 return JVMTI_ERROR_INVALID_MONITOR;
1520 #if defined(ENABLE_THREADS)
1521 lock_monitor_enter((java_objectheader *) monitor->name);
1523 log_text ("RawMonitorEnter not supported");
1526 return JVMTI_ERROR_NONE;
1530 /* RawMonitorExit *************************************************************
1534 *******************************************************************************/
1537 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1539 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1540 return JVMTI_ERROR_INVALID_MONITOR;
1542 #if defined(ENABLE_THREADS)
1543 /* assure current thread owns this monitor */
1544 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1545 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1547 lock_monitor_exit((java_objectheader *) monitor->name);
1549 log_text ("RawMonitorExit not supported");
1552 return JVMTI_ERROR_NONE;
1556 /* RawMonitorWait *************************************************************
1558 Wait for notification of the raw monitor.
1560 *******************************************************************************/
1563 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1565 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1566 return JVMTI_ERROR_INVALID_MONITOR;
1568 #if defined(ENABLE_THREADS)
1569 /* assure current thread owns this monitor */
1570 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1571 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1573 lock_wait_for_object(&monitor->name->header, millis,0);
1574 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1575 return JVMTI_ERROR_INTERRUPT;
1578 log_text ("RawMonitorWait not supported");
1581 return JVMTI_ERROR_NONE;
1585 /* RawMonitorNotify ***********************************************************
1587 Notify one thread waiting on the given monitor.
1589 *******************************************************************************/
1592 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1594 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1595 return JVMTI_ERROR_INVALID_MONITOR;
1597 #if defined(ENABLE_THREADS)
1598 /* assure current thread owns this monitor */
1599 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1600 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1602 lock_notify_object((java_objectheader*)&monitor->name);
1604 log_text ("RawMonitorNotify not supported");
1607 return JVMTI_ERROR_NONE;
1611 /* RawMonitorNotifyAll *********************************************************
1613 Notify all threads waiting on the given monitor.
1615 *******************************************************************************/
1618 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1620 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1621 return JVMTI_ERROR_INVALID_MONITOR;
1623 #if defined(ENABLE_THREADS)
1624 /* assure current thread owns this monitor */
1625 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1626 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1628 lock_notify_all_object((java_objectheader*)&monitor->name);
1630 log_text ("RawMonitorNotifyAll not supported");
1633 return JVMTI_ERROR_NONE;
1637 /* SetBreakpoint **************************************************************
1641 *******************************************************************************/
1644 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1647 CHECK_PHASE(JVMTI_PHASE_LIVE)
1649 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1652 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1653 return JVMTI_ERROR_NONE;
1657 /* *****************************************************************************
1661 *******************************************************************************/
1664 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1667 CHECK_PHASE(JVMTI_PHASE_LIVE)
1669 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1671 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1672 return JVMTI_ERROR_NONE;
1676 /* SetFieldAccessWatch ********************************************************
1680 *******************************************************************************/
1683 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1686 CHECK_PHASE(JVMTI_PHASE_LIVE)
1688 CHECK_CAPABILITY(env,can_generate_field_access_events)
1690 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1691 return JVMTI_ERROR_NONE;
1695 /* *****************************************************************************
1699 *******************************************************************************/
1702 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1705 CHECK_PHASE(JVMTI_PHASE_LIVE)
1707 CHECK_CAPABILITY(env,can_generate_field_access_events)
1709 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1710 return JVMTI_ERROR_NONE;
1714 /* *****************************************************************************
1718 *******************************************************************************/
1721 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1724 CHECK_PHASE(JVMTI_PHASE_LIVE)
1726 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1728 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1729 return JVMTI_ERROR_NONE;
1733 /* *****************************************************************************
1737 *******************************************************************************/
1740 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1743 CHECK_PHASE(JVMTI_PHASE_LIVE)
1745 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1747 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1748 return JVMTI_ERROR_NONE;
1752 /* Allocate ********************************************************************
1754 Allocate an area of memory through the JVM TI allocator. The allocated
1755 memory should be freed with Deallocate
1757 *******************************************************************************/
1760 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1763 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1764 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1766 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1767 if (*mem_ptr == NULL)
1768 return JVMTI_ERROR_OUT_OF_MEMORY;
1770 return JVMTI_ERROR_NONE;
1775 /* Deallocate ******************************************************************
1777 Deallocate mem using the JVM TI allocator.
1779 *******************************************************************************/
1782 Deallocate (jvmtiEnv * env, unsigned char *mem)
1784 /* let Boehm GC do the job */
1786 return JVMTI_ERROR_NONE;
1790 /* GetClassSignature ************************************************************
1792 For the class indicated by klass, return the JNI type signature and the
1793 generic signature of the class.
1795 *******************************************************************************/
1798 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1802 CHECK_PHASE(JVMTI_PHASE_START)
1803 CHECK_PHASE(JVMTI_PHASE_LIVE)
1806 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1807 if (!builtin_instanceof(klass,class_java_lang_Class))
1808 return JVMTI_ERROR_INVALID_CLASS;
1810 if (signature_ptr != NULL) {
1811 *signature_ptr = (char*)
1812 heap_allocate(sizeof(char) *
1813 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1815 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1818 if (generic_ptr!= NULL)
1819 *generic_ptr = NULL;
1821 return JVMTI_ERROR_NONE;
1824 /* GetClassStatus *************************************************************
1826 Get status of the class.
1828 *******************************************************************************/
1831 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1835 CHECK_PHASE(JVMTI_PHASE_START)
1836 CHECK_PHASE(JVMTI_PHASE_LIVE)
1839 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1840 return JVMTI_ERROR_INVALID_CLASS;
1842 if (status_ptr == NULL)
1843 return JVMTI_ERROR_NULL_POINTER;
1845 c = (classinfo*)klass;
1848 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1849 if (c->state & CLASS_LINKED)
1850 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1852 if (c->state & CLASS_INITIALIZED)
1853 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1855 if (c->state & CLASS_ERROR)
1856 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1858 if (c->vftbl->arraydesc != NULL)
1859 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1861 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1862 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1864 return JVMTI_ERROR_NONE;
1868 /* GetSourceFileName **********************************************************
1870 For the class indicated by klass, return the source file name.
1872 *******************************************************************************/
1875 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1880 CHECK_PHASE(JVMTI_PHASE_START)
1881 CHECK_PHASE(JVMTI_PHASE_LIVE)
1883 CHECK_CAPABILITY(env,can_get_source_file_name)
1885 if ((klass == NULL)||(source_name_ptr == NULL))
1886 return JVMTI_ERROR_NULL_POINTER;
1888 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1890 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1892 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1893 (*source_name_ptr)[size]='\0';
1895 return JVMTI_ERROR_NONE;
1899 /* GetClassModifiers **********************************************************
1901 For class klass return the access flags
1903 *******************************************************************************/
1906 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1909 CHECK_PHASE(JVMTI_PHASE_START)
1910 CHECK_PHASE(JVMTI_PHASE_LIVE)
1913 if (modifiers_ptr == NULL)
1914 return JVMTI_ERROR_NULL_POINTER;
1916 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1917 return JVMTI_ERROR_INVALID_CLASS;
1919 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1921 return JVMTI_ERROR_NONE;
1925 /* GetClassMethods *************************************************************
1927 For class klass return a count of methods and a list of method IDs
1929 *******************************************************************************/
1932 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1933 jmethodID ** methods_ptr)
1938 CHECK_PHASE(JVMTI_PHASE_START)
1939 CHECK_PHASE(JVMTI_PHASE_LIVE)
1942 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1943 return JVMTI_ERROR_NULL_POINTER;
1945 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1946 return JVMTI_ERROR_INVALID_CLASS;
1948 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1949 *methods_ptr = (jmethodID*)
1950 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1952 for (i=0; i<*method_count_ptr;i++)
1953 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1955 return JVMTI_ERROR_NONE;
1959 /* GetClassFields *************************************************************
1961 For the class indicated by klass, return a count of fields and a list of
1964 *******************************************************************************/
1967 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1968 jfieldID ** fields_ptr)
1971 CHECK_PHASE(JVMTI_PHASE_START)
1972 CHECK_PHASE(JVMTI_PHASE_LIVE)
1975 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1976 return JVMTI_ERROR_NULL_POINTER;
1978 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1979 *fields_ptr = (jfieldID*)
1980 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1982 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1983 sizeof(jfieldID) * (*field_count_ptr));
1985 return JVMTI_ERROR_NONE;
1989 /* GetImplementedInterfaces ***************************************************
1991 Return the direct super-interfaces of this class.
1993 *******************************************************************************/
1996 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1997 jint * interface_count_ptr,
1998 jclass ** interfaces_ptr)
2001 classref_or_classinfo *interfaces;
2005 CHECK_PHASE(JVMTI_PHASE_START)
2006 CHECK_PHASE(JVMTI_PHASE_LIVE)
2009 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
2010 return JVMTI_ERROR_NULL_POINTER;
2012 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2013 return JVMTI_ERROR_INVALID_CLASS;
2016 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2018 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2020 interfaces = ((classinfo*)klass)->interfaces;
2021 for (i=0; i<*interface_count_ptr; i++) {
2022 if (IS_CLASSREF(interfaces[i]))
2023 tmp = load_class_bootstrap(interfaces[i].ref->name);
2025 tmp = interfaces[i].cls;
2027 *interfaces_ptr[i]=tmp;
2030 return JVMTI_ERROR_NONE;
2034 /* IsInterface ****************************************************************
2036 Determines whether a class object reference represents an interface.
2038 *******************************************************************************/
2041 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2044 CHECK_PHASE(JVMTI_PHASE_START)
2045 CHECK_PHASE(JVMTI_PHASE_LIVE)
2048 if ((klass == NULL)||(is_interface_ptr == NULL))
2049 return JVMTI_ERROR_NULL_POINTER;
2051 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2053 return JVMTI_ERROR_NONE;
2056 /* IsArrayClass ***************************************************************
2058 Determines whether a class object reference represents an array.
2060 *******************************************************************************/
2063 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2066 CHECK_PHASE(JVMTI_PHASE_START)
2067 CHECK_PHASE(JVMTI_PHASE_LIVE)
2070 if (is_array_class_ptr == NULL)
2071 return JVMTI_ERROR_NULL_POINTER;
2073 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2075 return JVMTI_ERROR_NONE;
2079 /* GetClassLoader *************************************************************
2081 For the class indicated by klass, return via classloader_ptr a reference to
2082 the class loader for the class.
2084 *******************************************************************************/
2087 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2090 CHECK_PHASE(JVMTI_PHASE_START)
2091 CHECK_PHASE(JVMTI_PHASE_LIVE)
2094 if ((klass == NULL)||(classloader_ptr == NULL))
2095 return JVMTI_ERROR_NULL_POINTER;
2097 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2099 return JVMTI_ERROR_NONE;
2103 /* GetObjectHashCode **********************************************************
2105 Return hash code for object object
2107 *******************************************************************************/
2110 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2113 CHECK_PHASE(JVMTI_PHASE_START)
2114 CHECK_PHASE(JVMTI_PHASE_LIVE)
2117 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2118 if (!builtin_instanceof(object,class_java_lang_Object))
2119 return JVMTI_ERROR_INVALID_OBJECT;
2121 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2123 return JVMTI_ERROR_NONE;
2127 /* *****************************************************************************
2131 *******************************************************************************/
2134 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2135 jvmtiMonitorUsage * info_ptr)
2138 CHECK_PHASE(JVMTI_PHASE_LIVE)
2140 CHECK_CAPABILITY(env,can_get_monitor_info)
2142 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2143 return JVMTI_ERROR_NONE;
2147 /* GetFieldName ***************************************************************
2149 For the field indicated by klass and field, return the field name and
2152 *******************************************************************************/
2155 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2156 char **name_ptr, char **signature_ptr, char **generic_ptr)
2161 CHECK_PHASE(JVMTI_PHASE_START)
2162 CHECK_PHASE(JVMTI_PHASE_LIVE)
2166 return JVMTI_ERROR_INVALID_CLASS;
2168 if (!builtin_instanceof(klass,class_java_lang_Class))
2169 return JVMTI_ERROR_INVALID_CLASS;
2170 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2172 if (name_ptr != NULL) {
2173 size = utf_bytes(((fieldinfo*)field)->name)+1;
2174 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2175 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2178 if (signature_ptr != NULL) {
2179 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2180 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2181 utf_sprint_convert_to_latin1(*signature_ptr,
2182 ((fieldinfo*)field)->descriptor);
2185 if (generic_ptr != NULL)
2186 *generic_ptr = NULL;
2188 return JVMTI_ERROR_NONE;
2192 /* GetFieldDeclaringClass *****************************************************
2194 For the field indicated by klass and field return the class that defined it
2195 The declaring class will either be klass, a superclass, or an implemented
2198 *******************************************************************************/
2201 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2202 jclass * declaring_class_ptr)
2205 CHECK_PHASE(JVMTI_PHASE_START)
2206 CHECK_PHASE(JVMTI_PHASE_LIVE)
2210 return JVMTI_ERROR_INVALID_CLASS;
2212 if (!builtin_instanceof(klass,class_java_lang_Class))
2213 return JVMTI_ERROR_INVALID_CLASS;
2215 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2217 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2219 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2221 return JVMTI_ERROR_NONE;
2225 /* GetFieldModifiers **********************************************************
2227 Return access flags of field field
2229 *******************************************************************************/
2232 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2233 jint * modifiers_ptr)
2236 CHECK_PHASE(JVMTI_PHASE_START)
2237 CHECK_PHASE(JVMTI_PHASE_LIVE)
2241 return JVMTI_ERROR_INVALID_CLASS;
2243 if (!builtin_instanceof(klass,class_java_lang_Class))
2244 return JVMTI_ERROR_INVALID_CLASS;
2246 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2248 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2250 *modifiers_ptr = ((fieldinfo*)field)->flags;
2252 return JVMTI_ERROR_NONE;
2256 /* IsFieldSynthetic ***********************************************************
2260 *******************************************************************************/
2263 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2264 jboolean * is_synthetic_ptr)
2267 CHECK_PHASE(JVMTI_PHASE_START)
2268 CHECK_PHASE(JVMTI_PHASE_LIVE)
2270 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2272 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2273 return JVMTI_ERROR_NONE;
2277 /* GetMethodName ***************************************************************
2279 For the method indicated by method, return the method name via name_ptr and
2280 method signature via signature_ptr.
2282 *******************************************************************************/
2285 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2286 char **signature_ptr, char **generic_ptr)
2288 methodinfo* m = (methodinfo*)method;
2291 CHECK_PHASE(JVMTI_PHASE_START)
2292 CHECK_PHASE(JVMTI_PHASE_LIVE)
2296 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2298 if (name_ptr != NULL) {
2300 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2301 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2304 if (signature_ptr != NULL) {
2305 *signature_ptr = (char*)
2306 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2307 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2310 if (generic_ptr != NULL) {
2311 /* there is no generic signature attribute */
2312 *generic_ptr = NULL;
2315 return JVMTI_ERROR_NONE;
2319 /* GetMethodDeclaringClass *****************************************************
2321 For the method indicated by method, return the class that defined it.
2323 *******************************************************************************/
2326 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2327 jclass * declaring_class_ptr)
2330 CHECK_PHASE(JVMTI_PHASE_START)
2331 CHECK_PHASE(JVMTI_PHASE_LIVE)
2334 if ((method == NULL) || (declaring_class_ptr == NULL))
2335 return JVMTI_ERROR_NULL_POINTER;
2337 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2339 return JVMTI_ERROR_NONE;
2343 /* GetMethodModifiers **********************************************************
2345 For the method indicated by method, return the access flags.
2347 *******************************************************************************/
2350 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2353 CHECK_PHASE(JVMTI_PHASE_START)
2354 CHECK_PHASE(JVMTI_PHASE_LIVE)
2357 if ((method == NULL) || (modifiers_ptr == NULL))
2358 return JVMTI_ERROR_NULL_POINTER;
2360 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2362 return JVMTI_ERROR_NONE;
2366 /* GetMaxLocals ****************************************************************
2368 For the method indicated by method, return the number of local variable slots
2369 used by the method, including the local variables used to pass parameters to
2370 the method on its invocation.
2372 *******************************************************************************/
2375 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2378 CHECK_PHASE(JVMTI_PHASE_START)
2379 CHECK_PHASE(JVMTI_PHASE_LIVE)
2382 if ((method == NULL)||(max_ptr == NULL))
2383 return JVMTI_ERROR_NULL_POINTER;
2385 if (((methodinfo*)method)->flags & ACC_NATIVE)
2386 return JVMTI_ERROR_NATIVE_METHOD;
2388 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2390 return JVMTI_ERROR_NONE;
2395 /* GetArgumentsSize ************************************************************
2397 Return the number of local variable slots used by the method's arguments.
2399 *******************************************************************************/
2402 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2405 CHECK_PHASE(JVMTI_PHASE_START)
2406 CHECK_PHASE(JVMTI_PHASE_LIVE)
2409 if ((method == NULL)||(size_ptr == NULL))
2410 return JVMTI_ERROR_NULL_POINTER;
2412 if (((methodinfo*)method)->flags & ACC_NATIVE)
2413 return JVMTI_ERROR_NATIVE_METHOD;
2415 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2416 return JVMTI_ERROR_NONE;
2421 /* GetLineNumberTable **********************************************************
2423 Return table of source line number entries for a given method
2425 *******************************************************************************/
2428 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2429 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2434 CHECK_PHASE(JVMTI_PHASE_START)
2435 CHECK_PHASE(JVMTI_PHASE_LIVE)
2437 CHECK_CAPABILITY(env,can_get_line_numbers)
2439 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2440 return JVMTI_ERROR_NULL_POINTER;
2442 if (((methodinfo*)method)->flags & ACC_NATIVE)
2443 return JVMTI_ERROR_NATIVE_METHOD;
2445 if (((methodinfo*)method)->linenumbers == NULL)
2446 return JVMTI_ERROR_ABSENT_INFORMATION;
2448 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2449 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2450 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2453 for (i=0; i < *entry_count_ptr; i++) {
2454 (*table_ptr)[i].start_location =
2455 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2456 (*table_ptr)[i].line_number =
2457 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2460 return JVMTI_ERROR_NONE;
2464 /* GetMethodLocation ***********************************************************
2466 For the method indicated by method, return the beginning and ending addresses
2467 through start_location_ptr and end_location_ptr. In cacao this points to
2468 entry point in machine code and length of machine code
2470 *******************************************************************************/
2473 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2474 jlocation * start_location_ptr,
2475 jlocation * end_location_ptr)
2477 methodinfo* m = (methodinfo*)method;
2480 CHECK_PHASE(JVMTI_PHASE_START)
2481 CHECK_PHASE(JVMTI_PHASE_LIVE)
2484 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2486 if (((methodinfo*)method)->flags & ACC_NATIVE)
2487 return JVMTI_ERROR_NATIVE_METHOD;
2489 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2490 return JVMTI_ERROR_NULL_POINTER;
2492 /* XXX we return the location of the most recent code. Don't know
2493 * if there is a way to teach jvmti that a method can have more
2494 * than one location. -Edwin */
2496 /* XXX Don't know if that's the right way to deal with not-yet-
2497 * compiled methods. -Edwin */
2499 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2502 /* -1 states location information is not available */
2503 *start_location_ptr = (jlocation)-1;
2504 *end_location_ptr = (jlocation)-1;
2507 *start_location_ptr = (jlocation)m->code->mcode;
2508 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2509 return JVMTI_ERROR_NONE;
2513 /* GetLocalVariableTable *******************************************************
2515 Return local variable information.
2517 *******************************************************************************/
2520 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2521 jint * entry_count_ptr,
2522 jvmtiLocalVariableEntry ** table_ptr)
2525 CHECK_PHASE(JVMTI_PHASE_LIVE)
2527 CHECK_CAPABILITY(env,can_access_local_variables)
2529 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2531 return JVMTI_ERROR_NONE;
2535 /* GetBytecode *****************************************************************
2537 For the method indicated by method, return the byte codes that implement the
2540 *******************************************************************************/
2543 GetBytecodes (jvmtiEnv * env, jmethodID method,
2544 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2546 methodinfo* m = (methodinfo*)method;;
2549 CHECK_PHASE(JVMTI_PHASE_START)
2550 CHECK_PHASE(JVMTI_PHASE_LIVE)
2552 CHECK_CAPABILITY(env,can_get_bytecodes)
2554 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2555 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2557 *bytecode_count_ptr = m->jcodelength;
2558 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2559 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2561 return JVMTI_ERROR_NONE;
2565 /* IsMethodNative **************************************************************
2567 For the method indicated by method, return a value indicating whether the
2568 method is a native function
2570 *******************************************************************************/
2573 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2576 CHECK_PHASE(JVMTI_PHASE_START)
2577 CHECK_PHASE(JVMTI_PHASE_LIVE)
2580 if ((method == NULL)||(is_native_ptr == NULL))
2581 return JVMTI_ERROR_NULL_POINTER;
2583 if (((methodinfo*)method)->flags & ACC_NATIVE)
2584 *is_native_ptr = JNI_TRUE;
2586 *is_native_ptr = JNI_FALSE;
2588 return JVMTI_ERROR_NONE;
2592 /* IsMethodSynthetic ***********************************************************
2594 return a value indicating whether the method is synthetic. Synthetic methods
2595 are generated by the compiler but not present in the original source code.
2597 *******************************************************************************/
2600 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2601 jboolean * is_synthetic_ptr)
2604 CHECK_PHASE(JVMTI_PHASE_START)
2605 CHECK_PHASE(JVMTI_PHASE_LIVE)
2607 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2609 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2610 return JVMTI_ERROR_NONE;
2614 /* GetLoadedClasses ************************************************************
2616 Return an array of all classes loaded in the virtual machine.
2618 *******************************************************************************/
2621 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2624 CHECK_PHASE(JVMTI_PHASE_LIVE)
2627 if (class_count_ptr == NULL)
2628 return JVMTI_ERROR_NULL_POINTER;
2630 if (classes_ptr == NULL)
2631 return JVMTI_ERROR_NULL_POINTER;
2633 classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
2635 return JVMTI_ERROR_NONE;
2639 /* GetClassLoaderClasses *******************************************************
2641 Returns an array of those classes for which this class loader has been
2642 recorded as an initiating loader.
2644 *******************************************************************************/
2647 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2648 jint * class_count_ptr, jclass ** classes_ptr)
2650 log_text("GetClassLoaderClasses called");
2653 CHECK_PHASE(JVMTI_PHASE_LIVE)
2656 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2657 return JVMTI_ERROR_NULL_POINTER;
2659 /* behave like jdk 1.1 and make no distinction between initiating and
2660 defining class loaders */
2662 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2666 /* PopFrame *******************************************************************
2670 *******************************************************************************/
2673 PopFrame (jvmtiEnv * env, jthread thread)
2676 CHECK_PHASE(JVMTI_PHASE_LIVE)
2678 CHECK_CAPABILITY(env,can_pop_frame)
2680 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2681 return JVMTI_ERROR_NONE;
2685 /* RedefineClasses ************************************************************
2689 *******************************************************************************/
2692 RedefineClasses (jvmtiEnv * env, jint class_count,
2693 const jvmtiClassDefinition * class_definitions)
2696 CHECK_PHASE(JVMTI_PHASE_START)
2697 CHECK_PHASE(JVMTI_PHASE_LIVE)
2699 CHECK_CAPABILITY(env,can_redefine_classes)
2700 CHECK_CAPABILITY(env,can_redefine_any_class)
2702 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2703 return JVMTI_ERROR_NONE;
2707 /* GetVersionNumber ***********************************************************
2709 Return the JVM TI version identifier.
2711 *******************************************************************************/
2714 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2716 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2718 *version_ptr = JVMTI_VERSION;
2720 return JVMTI_ERROR_NONE;
2724 /* GetCapabilities ************************************************************
2726 Returns the optional JVM TI features which this environment currently
2729 *******************************************************************************/
2732 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2734 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2736 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2738 return JVMTI_ERROR_NONE;
2742 /* *****************************************************************************
2746 *******************************************************************************/
2749 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2750 char **source_debug_extension_ptr)
2753 CHECK_PHASE(JVMTI_PHASE_START)
2754 CHECK_PHASE(JVMTI_PHASE_LIVE)
2756 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2758 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2759 return JVMTI_ERROR_NONE;
2763 /* IsMethodObsolete ************************************************************
2765 Determine if a method ID refers to an obsolete method version.
2767 *******************************************************************************/
2770 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2771 jboolean * is_obsolete_ptr)
2774 CHECK_PHASE(JVMTI_PHASE_START)
2775 CHECK_PHASE(JVMTI_PHASE_LIVE)
2777 CHECK_CAPABILITY(env,can_redefine_classes)
2779 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2780 return JVMTI_ERROR_NONE;
2784 /* SuspendThreadList **********************************************************
2786 Suspend all threads in the request list.
2788 *******************************************************************************/
2791 SuspendThreadList (jvmtiEnv * env, jint request_count,
2792 const jthread * request_list, jvmtiError * results)
2799 CHECK_PHASE(JVMTI_PHASE_START)
2800 CHECK_PHASE(JVMTI_PHASE_LIVE)
2802 CHECK_CAPABILITY(env,can_suspend);
2804 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2805 if ((request_list == NULL) || (results == NULL))
2806 return JVMTI_ERROR_NULL_POINTER;
2808 me = jvmti_get_current_thread();
2810 for (i=0;i<request_count;i++) {
2811 if (request_list[i] == me)
2814 results[i]=SuspendThread(env, request_list[i]);
2817 if (suspendme != -1)
2818 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2820 return JVMTI_ERROR_NONE;
2824 /* ResumeThreadList ***********************************************************
2826 Resumes all threads in the request list.
2828 *******************************************************************************/
2831 ResumeThreadList (jvmtiEnv * env, jint request_count,
2832 const jthread * request_list, jvmtiError * results)
2837 CHECK_PHASE(JVMTI_PHASE_LIVE)
2839 CHECK_CAPABILITY(env,can_suspend);
2841 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2842 if ((request_list == NULL) || (results == NULL))
2843 return JVMTI_ERROR_NULL_POINTER;
2845 for (i=0;i<request_count;i++)
2846 results[i]=ResumeThread(env, request_list[i]);
2848 return JVMTI_ERROR_NONE;
2852 /* GetStackTrace **************************************************************
2854 Get information about the stack of a thread
2856 *******************************************************************************/
2859 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2860 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2863 stacktracebuffer* trace;
2868 CHECK_PHASE(JVMTI_PHASE_LIVE)
2871 if (thread != NULL){
2872 if(!builtin_instanceof(thread,class_java_lang_Thread))
2873 return JVMTI_ERROR_INVALID_THREAD;
2875 CHECK_THREAD_IS_ALIVE(thread);
2878 if((count_ptr == NULL)||(frame_buffer == NULL))
2879 return JVMTI_ERROR_NULL_POINTER;
2881 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2883 er = getcacaostacktrace(&trace, thread);
2884 if (er == JVMTI_ERROR_NONE) {
2889 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2890 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2892 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2893 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2894 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2895 frame_buffer[j].location = 0;
2900 return JVMTI_ERROR_NONE;
2904 /* GetThreadListStackTraces ***************************************************
2906 Get information about the stacks of the supplied threads.
2908 *******************************************************************************/
2911 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2912 const jthread * thread_list,
2913 jint max_frame_count,
2914 jvmtiStackInfo ** stack_info_ptr)
2920 CHECK_PHASE(JVMTI_PHASE_LIVE)
2923 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2924 return JVMTI_ERROR_NULL_POINTER;
2926 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2928 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2930 *stack_info_ptr = (jvmtiStackInfo*)
2931 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2933 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2934 (*stack_info_ptr)[i].thread=thread_list[i];
2935 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2936 (*stack_info_ptr)[i].frame_buffer =
2937 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2938 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2939 (*stack_info_ptr)[i].frame_buffer,
2940 &((*stack_info_ptr)[i].frame_count));
2942 if (er != JVMTI_ERROR_NONE) return er;
2945 return JVMTI_ERROR_NONE;
2949 /* GetAllStackTraces **********************************************************
2951 Get stack traces of all live threads
2953 *******************************************************************************/
2956 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2957 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2959 jthread *threads_ptr;
2963 CHECK_PHASE(JVMTI_PHASE_LIVE)
2966 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2968 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2969 return JVMTI_ERROR_INTERNAL;
2971 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2972 max_frame_count, stack_info_ptr);
2974 if (er != JVMTI_ERROR_NONE) return er;
2976 return JVMTI_ERROR_NONE;
2980 /* GetThreadLocalStorage ******************************************************
2982 Get the value of the JVM TI thread-local storage.
2984 *******************************************************************************/
2987 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2989 jvmtiThreadLocalStorage *tls;
2992 CHECK_PHASE(JVMTI_PHASE_START)
2993 CHECK_PHASE(JVMTI_PHASE_LIVE)
2997 thread = (jthread) THREADOBJECT;
2999 if (!builtin_instanceof(thread,class_java_lang_Thread))
3000 return JVMTI_ERROR_INVALID_THREAD;
3001 CHECK_THREAD_IS_ALIVE(thread);
3004 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3006 tls = ((environment*)env)->tls;
3007 while ((tls->thread != thread) && (tls != NULL)) {
3011 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3013 *data_ptr = tls->data;
3015 return JVMTI_ERROR_NONE;
3019 /* SetThreadLocalStorage *******************************************************
3021 Stores a pointer value associated with each environment-thread pair. The
3022 value is NULL unless set with this function. Agents can allocate memory in
3023 which they store thread specific information
3025 *******************************************************************************/
3028 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3030 jvmtiThreadLocalStorage *tls, *pre;
3031 environment* env = (environment*)jenv;
3034 CHECK_PHASE(JVMTI_PHASE_START)
3035 CHECK_PHASE(JVMTI_PHASE_LIVE)
3039 thread = (jthread) THREADOBJECT;
3041 if (!builtin_instanceof(thread,class_java_lang_Thread))
3042 return JVMTI_ERROR_INVALID_THREAD;
3043 CHECK_THREAD_IS_ALIVE(thread);
3046 if (env->tls == NULL) {
3047 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3050 while ((tls->thread != thread) && (tls->next != NULL)) {
3053 if (tls->thread != thread) {
3054 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3060 tls->data = (void*)data;
3062 /* remove current tls */
3064 while (pre->next == tls) pre = pre->next;
3065 pre->next = tls->next;
3067 return JVMTI_ERROR_NONE;
3071 /* *****************************************************************************
3075 *******************************************************************************/
3078 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3081 CHECK_PHASE(JVMTI_PHASE_START)
3082 CHECK_PHASE(JVMTI_PHASE_LIVE)
3084 CHECK_CAPABILITY(env,can_tag_objects)
3086 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3087 return JVMTI_ERROR_NONE;
3090 /* *****************************************************************************
3094 *******************************************************************************/
3097 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3100 CHECK_PHASE(JVMTI_PHASE_START)
3101 CHECK_PHASE(JVMTI_PHASE_LIVE)
3103 CHECK_CAPABILITY(env,can_tag_objects)
3105 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3106 return JVMTI_ERROR_NONE;
3110 /* ForceGarbageCollection *****************************************************
3112 Force boehm-gc to perform a garbage collection
3114 *******************************************************************************/
3117 ForceGarbageCollection (jvmtiEnv * env)
3120 CHECK_PHASE(JVMTI_PHASE_LIVE)
3125 return JVMTI_ERROR_NONE;
3129 /* IterateOverObjectsReachableFromObject **************************************
3133 *******************************************************************************/
3136 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3137 jvmtiObjectReferenceCallback
3138 object_reference_callback,
3142 CHECK_PHASE(JVMTI_PHASE_LIVE)
3144 CHECK_CAPABILITY(env,can_tag_objects)
3146 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3147 return JVMTI_ERROR_NONE;
3151 /* IterateOverReachableObjects ************************************************
3155 *******************************************************************************/
3158 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3160 jvmtiStackReferenceCallback
3162 jvmtiObjectReferenceCallback
3163 object_ref_callback, void *user_data)
3166 CHECK_PHASE(JVMTI_PHASE_LIVE)
3168 CHECK_CAPABILITY(env,can_tag_objects)
3170 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3171 return JVMTI_ERROR_NONE;
3175 /* IterateOverHeap ************************************************************
3179 *******************************************************************************/
3182 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3183 jvmtiHeapObjectCallback heap_object_callback,
3187 CHECK_PHASE(JVMTI_PHASE_LIVE)
3189 CHECK_CAPABILITY(env,can_tag_objects)
3191 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3192 return JVMTI_ERROR_NONE;
3196 /* IterateOverInstancesOfClass ************************************************
3200 *******************************************************************************/
3203 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3204 jvmtiHeapObjectFilter object_filter,
3205 jvmtiHeapObjectCallback
3206 heap_object_callback, void *user_data)
3209 CHECK_PHASE(JVMTI_PHASE_LIVE)
3211 CHECK_CAPABILITY(env,can_tag_objects)
3213 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3214 return JVMTI_ERROR_NONE;
3218 /* *****************************************************************************
3222 *******************************************************************************/
3225 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3226 jint * count_ptr, jobject ** object_result_ptr,
3227 jlong ** tag_result_ptr)
3230 CHECK_PHASE(JVMTI_PHASE_LIVE)
3232 CHECK_CAPABILITY(env,can_tag_objects)
3234 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3235 return JVMTI_ERROR_NONE;
3239 /* SetJNIFunctionTable **********************************************************
3241 Set the JNI function table in all current and future JNI environments
3243 *******************************************************************************/
3246 SetJNIFunctionTable (jvmtiEnv * env,
3247 const jniNativeInterface * function_table)
3250 CHECK_PHASE(JVMTI_PHASE_START)
3251 CHECK_PHASE(JVMTI_PHASE_LIVE)
3254 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3255 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3256 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3257 return JVMTI_ERROR_NONE;
3261 /* GetJNIFunctionTable *********************************************************
3263 Get the JNI function table. The JNI function table is copied into allocated
3266 *******************************************************************************/
3269 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3272 CHECK_PHASE(JVMTI_PHASE_START)
3273 CHECK_PHASE(JVMTI_PHASE_LIVE)
3276 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3277 *function_table = (jniNativeInterface*)
3278 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3279 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3280 return JVMTI_ERROR_NONE;
3284 /* SetEventCallbacks **********************************************************
3286 Set the functions to be called for each event. The callbacks are specified
3287 by supplying a replacement function table.
3289 *******************************************************************************/
3292 SetEventCallbacks (jvmtiEnv * env,
3293 const jvmtiEventCallbacks * callbacks,
3294 jint size_of_callbacks)
3297 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3298 CHECK_PHASE(JVMTI_PHASE_LIVE)
3301 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3304 if (callbacks == NULL) { /* remove the existing callbacks */
3305 memset(&(((environment* )env)->callbacks), 0,
3306 sizeof(jvmtiEventCallbacks));
3309 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3311 return JVMTI_ERROR_NONE;
3315 /* GenerateEvents *************************************************************
3317 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3318 the current state of the VM.
3320 *******************************************************************************/
3323 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3326 CHECK_PHASE(JVMTI_PHASE_LIVE)
3328 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3330 return JVMTI_ERROR_NONE;
3334 /* GetExtensionFunctions ******************************************************
3336 Returns the set of extension functions.
3338 *******************************************************************************/
3341 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3342 jvmtiExtensionFunctionInfo ** extensions)
3345 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3346 CHECK_PHASE(JVMTI_PHASE_LIVE)
3349 if ((extension_count_ptr == NULL)||(extensions == NULL))
3350 return JVMTI_ERROR_NULL_POINTER;
3352 /* cacao has no extended functions yet */
3353 *extension_count_ptr = 0;
3355 return JVMTI_ERROR_NONE;
3359 /* GetExtensionEvents *********************************************************
3361 Returns the set of extension events.
3363 *******************************************************************************/
3366 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3367 jvmtiExtensionEventInfo ** extensions)
3370 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3371 CHECK_PHASE(JVMTI_PHASE_LIVE)
3374 if ((extension_count_ptr == NULL)||(extensions == NULL))
3375 return JVMTI_ERROR_NULL_POINTER;
3377 /* cacao has no extended events yet */
3378 *extension_count_ptr = 0;
3380 return JVMTI_ERROR_NONE;
3384 /* SetExtensionEventCallback **************************************************
3386 Sets the callback function for an extension event and enables the event.
3388 *******************************************************************************/
3391 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3392 jvmtiExtensionEvent callback)
3395 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3396 CHECK_PHASE(JVMTI_PHASE_LIVE)
3399 /* cacao has no extended events yet */
3400 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3404 /* DisposeEnvironment **********************************************************
3406 Shutdown a JVM TI connection created with JNI GetEnv.
3408 *******************************************************************************/
3411 DisposeEnvironment (jvmtiEnv * env)
3413 environment* cacao_env = (environment*)env;
3414 environment* tenvs = envs;
3415 jvmtiThreadLocalStorage *jtls, *tjtls;
3417 if (tenvs != cacao_env) {
3418 while (tenvs->next != cacao_env) {
3419 tenvs = tenvs->next;
3421 tenvs->next = cacao_env->next;
3425 cacao_env->env=NULL;
3426 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3427 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3428 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3429 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3430 cacao_env->EnvironmentLocalStorage = NULL;
3432 jtls = cacao_env->tls;
3433 while (jtls != NULL) {
3438 cacao_env->tls = NULL;
3441 jvmti_cacaodbgserver_quit();
3443 /* let the GC do the rest */
3444 return JVMTI_ERROR_NONE;
3448 /* GetErrorName ***************************************************************
3450 Return the symbolic name for an error code.
3452 *******************************************************************************/
3454 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3455 memcpy(*name_ptr, &str, sizeof(str)); \
3459 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3461 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3464 case JVMTI_ERROR_NONE :
3465 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3466 case JVMTI_ERROR_NULL_POINTER :
3467 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3468 case JVMTI_ERROR_OUT_OF_MEMORY :
3469 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3470 case JVMTI_ERROR_ACCESS_DENIED :
3471 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3472 case JVMTI_ERROR_UNATTACHED_THREAD :
3473 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3474 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3475 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3476 case JVMTI_ERROR_WRONG_PHASE :
3477 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3478 case JVMTI_ERROR_INTERNAL :
3479 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3480 case JVMTI_ERROR_INVALID_PRIORITY :
3481 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3482 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3483 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3484 case JVMTI_ERROR_THREAD_SUSPENDED :
3485 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3486 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3487 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3488 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3489 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3490 case JVMTI_ERROR_NO_MORE_FRAMES :
3491 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3492 case JVMTI_ERROR_OPAQUE_FRAME :
3493 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3494 case JVMTI_ERROR_DUPLICATE :
3495 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3496 case JVMTI_ERROR_NOT_FOUND :
3497 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3498 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3499 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3500 case JVMTI_ERROR_INTERRUPT :
3501 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3502 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3503 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3504 case JVMTI_ERROR_NOT_AVAILABLE :
3505 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3506 case JVMTI_ERROR_ABSENT_INFORMATION :
3507 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3508 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3509 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3510 case JVMTI_ERROR_NATIVE_METHOD :
3511 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3512 case JVMTI_ERROR_INVALID_THREAD :
3513 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3514 case JVMTI_ERROR_INVALID_FIELDID :
3515 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3516 case JVMTI_ERROR_INVALID_METHODID :
3517 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3518 case JVMTI_ERROR_INVALID_LOCATION :
3519 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3520 case JVMTI_ERROR_INVALID_OBJECT :
3521 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3522 case JVMTI_ERROR_INVALID_CLASS :
3523 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3524 case JVMTI_ERROR_TYPE_MISMATCH :
3525 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3526 case JVMTI_ERROR_INVALID_SLOT :
3527 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3528 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3529 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3530 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3531 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3532 case JVMTI_ERROR_INVALID_MONITOR :
3533 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3534 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3535 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3536 case JVMTI_ERROR_INVALID_TYPESTATE :
3537 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3538 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3539 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3540 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3541 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3542 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3543 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3544 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3545 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3546 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3547 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3548 case JVMTI_ERROR_FAILS_VERIFICATION :
3549 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3550 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3551 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3552 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3553 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3554 case JVMTI_ERROR_NAMES_DONT_MATCH :
3555 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3556 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3557 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3558 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3559 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3561 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3563 return JVMTI_ERROR_NONE;
3566 /* GetJLocationFormat **********************************************************
3568 This function describes the representation of jlocation used in this VM.
3570 *******************************************************************************/
3573 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3575 *format_ptr = JVMTI_JLOCATION_OTHER;
3576 return JVMTI_ERROR_NONE;
3580 /* GetSystemProperties ********************************************************
3582 The list of VM system property keys which may be used with GetSystemProperty
3585 *******************************************************************************/
3588 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3590 jmethodID mid, moremid;
3591 classinfo *sysclass, *propclass, *enumclass;
3592 java_objectheader *sysprop, *keys, *obj;
3597 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3598 CHECK_PHASE(JVMTI_PHASE_LIVE)
3601 if ((count_ptr == NULL) || (property_ptr == NULL))
3602 return JVMTI_ERROR_NULL_POINTER;
3604 sysclass = load_class_from_sysloader(
3605 utf_new_char_classname ("java/lang/System"));
3607 if (!sysclass) throw_main_exception_exit();
3609 mid = (jmethodID)class_resolvemethod(sysclass,
3610 utf_new_char("getProperties"),
3611 utf_new_char("()Ljava/util/Properties;"));
3612 if (!mid) throw_main_exception_exit();
3615 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3616 if (!sysprop) throw_main_exception_exit();
3618 propclass = sysprop->vftbl->class;
3620 mid = (jmethodID)class_resolvemethod(propclass,
3621 utf_new_char("size"),
3622 utf_new_char("()I"));
3623 if (!mid) throw_main_exception_exit();
3626 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3627 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3629 mid = (jmethodID)class_resolvemethod(propclass,
3630 utf_new_char("keys"),
3631 utf_new_char("()Ljava/util/Enumeration;"));
3632 if (!mid) throw_main_exception_exit();
3634 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3635 enumclass = keys->vftbl->class;
3637 moremid = (jmethodID)class_resolvemethod(enumclass,
3638 utf_new_char("hasMoreElements"),
3639 utf_new_char("()Z"));
3640 if (!moremid) throw_main_exception_exit();
3642 mid = (jmethodID)class_resolvemethod(propclass,
3643 utf_new_char("nextElement"),
3644 utf_new_char("()Ljava/lang/Object;"));
3645 if (!mid) throw_main_exception_exit();
3648 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3649 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3650 ch = javastring_tochar(obj);
3651 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3652 memcpy(*property_ptr[i], ch, strlen (ch));
3653 MFREE(ch,char,strlen(ch)+1);
3657 return JVMTI_ERROR_NONE;
3661 /* GetSystemProperty **********************************************************
3663 Return a VM system property value given the property key.
3665 *******************************************************************************/
3668 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3671 classinfo *sysclass, *propclass;
3672 java_objectheader *sysprop, *obj;
3676 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3677 CHECK_PHASE(JVMTI_PHASE_LIVE)
3680 if ((value_ptr == NULL) || (property == NULL))
3681 return JVMTI_ERROR_NULL_POINTER;
3683 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3684 if (!sysclass) throw_main_exception_exit();
3686 mid = (jmethodID)class_resolvemethod(sysclass,
3687 utf_new_char("getProperties"),
3688 utf_new_char("()Ljava/util/Properties;"));
3689 if (!mid) throw_main_exception_exit();
3691 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3693 propclass = sysprop->vftbl->class;
3695 mid = (jmethodID)class_resolvemethod(propclass,
3696 utf_new_char("getProperty"),
3697 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3698 if (!mid) throw_main_exception_exit();
3700 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3701 NULL, sysprop, mid, javastring_new_from_ascii(property));
3702 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3704 ch = javastring_tochar(obj);
3705 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3706 memcpy(*value_ptr, ch, strlen (ch));
3707 MFREE(ch,char,strlen(ch)+1);
3709 return JVMTI_ERROR_NONE;
3713 /* SetSystemProperty **********************************************************
3715 Set a VM system property value.
3717 *******************************************************************************/
3720 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3723 classinfo *sysclass, *propclass;
3724 java_objectheader *sysprop;
3727 CHECK_PHASE(JVMTI_PHASE_START)
3730 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3731 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3733 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3734 if (!sysclass) throw_main_exception_exit();
3736 mid = (jmethodID)class_resolvemethod(sysclass,
3737 utf_new_char("getProperties"),
3738 utf_new_char("()Ljava/util/Properties;"));
3739 if (!mid) throw_main_exception_exit();
3741 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3743 propclass = sysprop->vftbl->class;
3745 mid = (jmethodID)class_resolvemethod(propclass,
3746 utf_new_char("setProperty"),
3747 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3748 if (!mid) throw_main_exception_exit();
3750 _Jv_JNINativeInterface.CallObjectMethod(
3751 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3753 return JVMTI_ERROR_NONE;
3756 /* GetPhase ********************************************************************
3758 Return the current phase of VM execution
3760 *******************************************************************************/
3763 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3765 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3769 return JVMTI_ERROR_NONE;
3772 /* GetCurrentThreadCpuTimerInfo ************************************************
3776 *******************************************************************************/
3779 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3782 CHECK_PHASE(JVMTI_PHASE_START)
3783 CHECK_PHASE(JVMTI_PHASE_LIVE)
3785 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3787 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3789 return JVMTI_ERROR_NONE;
3792 /* GetCurrentThreadCpuTime ****************************************************
3796 *******************************************************************************/
3799 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3802 CHECK_PHASE(JVMTI_PHASE_START)
3803 CHECK_PHASE(JVMTI_PHASE_LIVE)
3805 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3807 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3808 return JVMTI_ERROR_NONE;
3811 /* GetThreadCpuTimerInfo ******************************************************
3815 *******************************************************************************/
3818 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3821 CHECK_PHASE(JVMTI_PHASE_START)
3822 CHECK_PHASE(JVMTI_PHASE_LIVE)
3824 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3826 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3827 return JVMTI_ERROR_NONE;
3830 /* GetThreadCpuTime ***********************************************************
3834 *******************************************************************************/
3837 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3840 CHECK_PHASE(JVMTI_PHASE_LIVE)
3842 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3843 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3844 return JVMTI_ERROR_NONE;
3847 /* GetTimerInfo ***************************************************************
3849 Get information about the GetTime timer.
3851 *******************************************************************************/
3854 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3856 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3858 info_ptr->max_value = !0x0;
3859 info_ptr->may_skip_forward = true;
3860 info_ptr->may_skip_backward = true;
3861 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3863 return JVMTI_ERROR_NONE;
3866 /* GetTime ********************************************************************
3868 Return the current value of the system timer, in nanoseconds
3870 *******************************************************************************/
3873 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3875 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3878 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3880 if (gettimeofday (&tp, NULL) == -1)
3881 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3883 *nanos_ptr = (jlong) tp.tv_sec;
3885 *nanos_ptr += (tp.tv_usec / 1000);
3887 return JVMTI_ERROR_NONE;
3890 /* GetPotentialCapabilities ***************************************************
3892 Returns the JVM TI features that can potentially be possessed by this
3893 environment at this time.
3895 *******************************************************************************/
3898 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3901 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3902 CHECK_PHASE(JVMTI_PHASE_LIVE)
3905 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3907 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3909 return JVMTI_ERROR_NONE;
3913 #define CHECK_ADD_CAPABILITY(env,CAN) \
3914 if (capabilities_ptr->CAN == 1) { \
3915 if (JVMTI_Capabilities.CAN == 0) \
3916 return JVMTI_ERROR_NOT_AVAILABLE; \
3918 env->capabilities.CAN = 1; \
3921 /* AddCapabilities ************************************************************
3923 Set new capabilities by adding the capabilities pointed to by
3924 capabilities_ptr. All previous capabilities are retained.
3926 *******************************************************************************/
3929 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3931 environment* cacao_env;
3934 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3935 CHECK_PHASE(JVMTI_PHASE_LIVE)
3938 if ((env == NULL) || (capabilities_ptr == NULL))
3939 return JVMTI_ERROR_NULL_POINTER;
3941 cacao_env = (environment*)env;
3943 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3944 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3945 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3946 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3947 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3948 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3949 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3950 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3951 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3952 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3953 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3965 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3966 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3967 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3968 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3969 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3970 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3971 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3972 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3973 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3974 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3975 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3978 return JVMTI_ERROR_NONE;
3982 #define CHECK_DEL_CAPABILITY(env,CAN) \
3983 if (capabilities_ptr->CAN == 1) \
3984 env->capabilities.CAN = 0;
3986 /* RelinquishCapabilities *****************************************************
3988 Relinquish the capabilities pointed to by capabilities_ptr.
3990 *******************************************************************************/
3993 RelinquishCapabilities (jvmtiEnv * env,
3994 const jvmtiCapabilities * capabilities_ptr)
3996 environment* cacao_env;
3999 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4000 CHECK_PHASE(JVMTI_PHASE_LIVE)
4003 if ((env == NULL) || (capabilities_ptr == NULL))
4004 return JVMTI_ERROR_NULL_POINTER;
4006 cacao_env = (environment*)env;
4008 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
4009 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4010 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4011 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4012 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4013 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4014 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4015 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4016 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4017 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4018 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4030 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4031 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4032 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4033 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4034 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4035 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4036 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4037 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4038 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4039 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4040 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4042 return JVMTI_ERROR_NONE;
4045 /* GetAvailableProcessors *****************************************************
4047 Get number of processors available to the virtual machine.
4049 *******************************************************************************/
4052 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4055 CHECK_PHASE(JVMTI_PHASE_START)
4056 CHECK_PHASE(JVMTI_PHASE_LIVE)
4059 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4061 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4063 *processor_count_ptr = 1; /* where do I get this ?*/
4065 return JVMTI_ERROR_NONE;
4068 /* GetEnvironmentLocalStorage **************************************************
4070 Called by the agent to get the value of the JVM TI environment-local storage.
4072 *******************************************************************************/
4075 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4077 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4079 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4081 return JVMTI_ERROR_NONE;
4084 /* SetEnvironmentLocalStorage **************************************************
4086 The VM stores a pointer value associated with each environment. Agents can
4087 allocate memory in which they store environment specific information.
4089 *******************************************************************************/
4092 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4094 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4096 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4098 return JVMTI_ERROR_NONE;
4101 /* AddToBootstrapClassLoaderSearch ********************************************
4103 After the bootstrap class loader unsuccessfully searches for a class, the
4104 specified platform-dependent search path segment will be searched as well.
4106 *******************************************************************************/
4109 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4115 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4118 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4120 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4121 tmp_bcp = MNEW(char, ln);
4122 strcat(tmp_bcp, bootclasspath);
4123 strcat(tmp_bcp, ":");
4124 strcat(tmp_bcp, segment);
4125 MFREE(bootclasspath,char,ln);
4126 bootclasspath = tmp_bcp;
4128 return JVMTI_ERROR_NONE;
4131 /* SetVerboseFlag *************************************************************
4133 Control verbose output. This is the output which typically is sent to stderr
4135 *******************************************************************************/
4138 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4141 case JVMTI_VERBOSE_OTHER:
4142 /* where is this defined ?
4146 case JVMTI_VERBOSE_GC:
4147 opt_verbosegc = value;
4149 case JVMTI_VERBOSE_CLASS:
4150 loadverbose = value;
4152 case JVMTI_VERBOSE_JNI:
4155 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4157 return JVMTI_ERROR_NONE;
4160 /* GetObjectSize **************************************************************
4162 For the object object return the size.
4164 *******************************************************************************/
4167 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4170 CHECK_PHASE(JVMTI_PHASE_START)
4171 CHECK_PHASE(JVMTI_PHASE_LIVE)
4174 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4175 if (!builtin_instanceof(object,class_java_lang_Object))
4176 return JVMTI_ERROR_INVALID_OBJECT;
4178 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4180 return JVMTI_ERROR_NONE;
4184 /* *****************************************************************************
4186 Environment variables
4188 *******************************************************************************/
4190 static jvmtiCapabilities JVMTI_Capabilities = {
4191 0, /* can_tag_objects */
4192 0, /* can_generate_field_modification_events */
4193 0, /* can_generate_field_access_events */
4194 1, /* can_get_bytecodes */
4195 0, /* can_get_synthetic_attribute */
4197 #if defined(ENABLE_THREADS)
4198 1, /* can_get_owned_monitor_info */
4199 1, /* can_get_current_contended_monitor */
4201 0, /* can_get_owned_monitor_info */
4202 0, /* can_get_current_contended_monitor */
4205 0, /* can_get_monitor_info */
4206 0, /* can_pop_frame */
4207 0, /* can_redefine_classes */
4208 0, /* can_signal_thread */
4209 1, /* can_get_source_file_name */
4210 1, /* can_get_line_numbers */
4211 0, /* can_get_source_debug_extension */
4212 0, /* can_access_local_variables */
4213 0, /* can_maintain_original_method_order */
4214 0, /* can_generate_single_step_events */
4215 1, /* can_generate_exception_events */
4216 0, /* can_generate_frame_pop_events */
4217 1, /* can_generate_breakpoint_events */
4218 1, /* can_suspend */
4219 0, /* can_redefine_any_class */
4220 0, /* can_get_current_thread_cpu_time */
4221 0, /* can_get_thread_cpu_time */
4222 1, /* can_generate_method_entry_events */
4223 0, /* can_generate_method_exit_events */
4224 0, /* can_generate_all_class_hook_events */
4225 0, /* can_generate_compiled_method_load_events */
4226 1, /* can_generate_monitor_events */
4227 0, /* can_generate_vm_object_alloc_events */
4228 0, /* can_generate_native_method_bind_events */
4229 0, /* can_generate_garbage_collection_events */
4230 0, /* can_generate_object_free_events */
4233 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4235 &SetEventNotificationMode,
4243 &GetOwnedMonitorInfo,
4244 &GetCurrentContendedMonitor,
4246 &GetTopThreadGroups,
4247 &GetThreadGroupInfo,
4248 &GetThreadGroupChildren,
4270 &RawMonitorNotifyAll,
4274 &SetFieldAccessWatch,
4275 &ClearFieldAccessWatch,
4276 &SetFieldModificationWatch,
4277 &ClearFieldModificationWatch,
4287 &GetImplementedInterfaces,
4292 &GetObjectMonitorUsage,
4294 &GetFieldDeclaringClass,
4298 &GetMethodDeclaringClass,
4299 &GetMethodModifiers,
4303 &GetLineNumberTable,
4305 &GetLocalVariableTable,
4312 &GetClassLoaderClasses,
4323 &GetSourceDebugExtension,
4334 &GetThreadListStackTraces,
4335 &GetThreadLocalStorage,
4336 &SetThreadLocalStorage,
4341 &ForceGarbageCollection,
4342 &IterateOverObjectsReachableFromObject,
4343 &IterateOverReachableObjects,
4345 &IterateOverInstancesOfClass,
4347 &GetObjectsWithTags,
4353 &SetJNIFunctionTable,
4354 &GetJNIFunctionTable,
4357 &GetExtensionFunctions,
4358 &GetExtensionEvents,
4359 &SetExtensionEventCallback,
4360 &DisposeEnvironment,
4362 &GetJLocationFormat,
4363 &GetSystemProperties,
4367 &GetCurrentThreadCpuTimerInfo,
4368 &GetCurrentThreadCpuTime,
4369 &GetThreadCpuTimerInfo,
4373 &GetPotentialCapabilities,
4376 &RelinquishCapabilities,
4377 &GetAvailableProcessors,
4380 &GetEnvironmentLocalStorage,
4381 &SetEnvironmentLocalStorage,
4382 &AddToBootstrapClassLoaderSearch,
4390 /* jvmti_set_phase ************************************************************
4392 sets a new jvmti phase a fires an apropriate event.
4394 *******************************************************************************/
4396 void jvmti_set_phase(jvmtiPhase p) {
4399 fprintf (stderr,"set JVMTI phase %d\n",p);
4403 case JVMTI_PHASE_ONLOAD:
4406 case JVMTI_PHASE_PRIMORDIAL:
4409 case JVMTI_PHASE_START:
4411 d.ev = JVMTI_EVENT_VM_START;
4413 case JVMTI_PHASE_LIVE:
4415 d.ev = JVMTI_EVENT_VM_INIT;
4416 jvmti_fireEvent(&d);
4417 /* thread start event for main thread */
4418 d.ev = JVMTI_EVENT_THREAD_START;
4420 case JVMTI_PHASE_DEAD:
4422 d.ev = JVMTI_EVENT_VM_DEATH;
4425 log_text("wrong jvmti phase to be set");
4429 jvmti_fireEvent(&d);
4433 /* jvmti_new_environment ******************************************************
4435 creates a new JVMTI environment
4437 *******************************************************************************/
4439 jvmtiEnv* jvmti_new_environment() {
4443 envs = heap_allocate(sizeof(environment),true,NULL);
4447 while (env->next != NULL) env = env->next;
4448 env->next = heap_allocate(sizeof(environment),true,NULL);
4452 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4453 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4454 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4455 sizeof(jvmtiEventModeLL));
4456 /* To possess a capability, the agent must add the capability.*/
4457 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4458 RelinquishCapabilities(&(env->env),&(env->capabilities));
4459 env->EnvironmentLocalStorage = NULL;
4462 /* initialize cacao debugging facilities */
4463 jvmti_cacao_debug_init();
4465 return (jvmtiEnv*)env;
4468 /* jvmti_agentload ************************************************************
4470 loads the indicated shared library containing the jvmti agent and calls the
4471 Agent_OnLoad function.
4473 *******************************************************************************/
4475 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4481 len = strlen(opt_arg);
4483 /* separate arguments */
4485 while ((opt_arg[i] != '=') && (i < len))
4491 arg = &opt_arg[i + 1];
4498 *libname = GCMNEW(char, i);
4500 strcpy(*libname, opt_arg);
4505 len = strlen("lib") + i + strlen(".so") + strlen("0");
4507 *libname = GCMNEW(char, len);
4509 strcpy(*libname, "lib");
4510 strcat(*libname, opt_arg);
4511 strcat(*libname, ".so");
4514 /* try to open the library */
4516 if (!(*handle = lt_dlopen(*libname))) {
4517 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4521 /* resolve Agent_OnLoad function */
4522 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4523 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4527 /* resolve Agent_UnLoad function */
4528 unload = lt_dlsym(*handle, "Agent_Unload");
4531 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4532 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4534 if (retval != 0) exit (retval);
4537 /* jvmti_agentunload **********************************************************
4539 calls the Agent_UnLoad function in the jvmti agent if present.
4541 *******************************************************************************/
4543 void jvmti_agentunload() {
4544 if (unload != NULL) {
4545 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4546 ((JavaVM*) &_Jv_JNIInvokeInterface);
4552 * These are local overrides for various environment variables in Emacs.
4553 * Please do not remove this and leave it at the end of the file, where
4554 * Emacs will automagically detect them.
4555 * ---------------------------------------------------------------------
4558 * indent-tabs-mode: t
4562 * vim:noexpandtab:sw=4:ts=4: