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
34 $Id: jvmti.c 5031 2006-06-14 18:36:22Z motse $
40 #include "native/jni.h"
41 #include "native/native.h"
42 #include "native/jvmti/cacaodbg.h"
43 #include "native/jvmti/jvmti.h"
44 #include "vm/jit/stacktrace.h"
45 #include "vm/global.h"
46 #include "vm/loader.h"
47 #include "vm/builtin.h"
48 #include "vm/jit/asmpart.h"
50 #include "vm/classcache.h"
52 #include "toolbox/logging.h"
53 #include "vm/options.h"
54 #include "vm/stringlocal.h"
55 #include "mm/memory.h"
56 #include "threads/native/threads.h"
57 #include "threads/native/lock.h"
58 #include "vm/exceptions.h"
59 #include "native/include/java_util_Vector.h"
60 #include "native/include/java_io_PrintStream.h"
61 #include "native/include/java_io_InputStream.h"
62 #include "native/include/java_lang_Cloneable.h"
63 #include "native/include/java_lang_ThreadGroup.h"
64 #include "native/include/java_lang_VMObject.h"
65 #include "native/include/java_lang_VMSystem.h"
66 #include "native/include/java_lang_VMClass.h"
68 #include "boehm-gc/include/gc.h"
71 #include <linux/unistd.h>
73 #include "toolbox/logging.h"
75 #include <sys/types.h>
80 #if defined(ENABLE_THREADS)
81 #include "threads/native/threads.h"
89 typedef struct _environment environment;
90 static environment *envs=NULL;
91 pthread_mutex_t dbgcomlock;
93 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
95 static jvmtiPhase phase;
96 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
97 struct _jvmtiEventModeLL {
100 jvmtiEventModeLL *next;
103 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
104 struct _jvmtiThreadLocalStorage{
107 jvmtiThreadLocalStorage *next;
110 struct _environment {
113 jvmtiEventCallbacks callbacks;
114 /* table for enabled/disabled jvmtiEvents - first element contains global
116 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
117 jvmtiCapabilities capabilities;
118 void *EnvironmentLocalStorage;
119 jvmtiThreadLocalStorage *tls;
122 static struct jvmtiEnv_struct JVMTI_EnvTable;
123 static jvmtiCapabilities JVMTI_Capabilities;
124 static lt_ptr unload;
126 #define CHECK_PHASE_START if (!(false
127 #define CHECK_PHASE(chkphase) || (phase == chkphase)
128 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
129 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
130 env)->capabilities.CAP == 0) \
131 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
132 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
133 JVMTI_ERROR_THREAD_NOT_ALIVE) \
134 return JVMTI_ERROR_THREAD_NOT_ALIVE;
139 /* check_thread_is_alive *******************************************************
141 checks if the given thread is alive
143 *******************************************************************************/
144 static jvmtiError check_thread_is_alive(jthread t) {
145 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
146 if(((java_lang_Thread*) t)->vmThread == NULL)
147 return JVMTI_ERROR_THREAD_NOT_ALIVE;
148 return JVMTI_ERROR_NONE;
151 /* execute_callback ************************************************************
153 executes the registerd callbacks for the given jvmti event with parameter
154 in the data structure.
156 *******************************************************************************/
157 static void execute_callback(jvmtiEvent e, functionptr ec,
158 genericEventData* data) {
159 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
161 fprintf(stderr,"execcallback called (event: %d)\n",e);
164 case JVMTI_EVENT_VM_INIT:
165 if (phase != JVMTI_PHASE_LIVE) return;
166 case JVMTI_EVENT_THREAD_START:
167 case JVMTI_EVENT_THREAD_END:
168 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
169 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
172 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
173 if ((phase == JVMTI_PHASE_START) ||
174 (phase == JVMTI_PHASE_LIVE) ||
175 (phase == JVMTI_PHASE_PRIMORDIAL))
176 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
181 data->protection_domain,
184 data->new_class_data_len,
185 data->new_class_data);
187 /* if class data has been modified use it as class data for other agents
188 waiting for the same event */
189 if (data->new_class_data != NULL) {
190 data->jint1 = *(data->new_class_data_len);
191 data->class_data = *(data->new_class_data);
196 case JVMTI_EVENT_CLASS_PREPARE:
197 case JVMTI_EVENT_CLASS_LOAD:
198 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
199 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
200 data->thread, data->klass);
203 case JVMTI_EVENT_VM_DEATH:
204 if (phase != JVMTI_PHASE_LIVE) return;
205 case JVMTI_EVENT_VM_START:
206 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
207 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
210 case JVMTI_EVENT_NATIVE_METHOD_BIND:
211 if ((phase == JVMTI_PHASE_START) ||
212 (phase == JVMTI_PHASE_LIVE) ||
213 (phase == JVMTI_PHASE_PRIMORDIAL))
214 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
218 data->new_address_ptr);
222 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
223 if ((phase == JVMTI_PHASE_START) ||
224 (phase == JVMTI_PHASE_LIVE) ||
225 (phase == JVMTI_PHASE_PRIMORDIAL))
226 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
235 if (phase != JVMTI_PHASE_LIVE) return;
237 case JVMTI_EVENT_EXCEPTION:
238 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
244 data->catch_location);
247 case JVMTI_EVENT_EXCEPTION_CATCH:
248 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
255 case JVMTI_EVENT_BREAKPOINT:
256 case JVMTI_EVENT_SINGLE_STEP:
257 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
263 case JVMTI_EVENT_FRAME_POP:
264 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
271 case JVMTI_EVENT_FIELD_ACCESS:
272 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
281 case JVMTI_EVENT_FIELD_MODIFICATION:
283 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
290 data->signature_type,
294 case JVMTI_EVENT_METHOD_ENTRY:
295 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
300 case JVMTI_EVENT_METHOD_EXIT:
301 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
308 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
309 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
318 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
319 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
324 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
325 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
326 case JVMTI_EVENT_DATA_DUMP_REQUEST:
327 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
330 case JVMTI_EVENT_MONITOR_WAIT:
331 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
337 case JVMTI_EVENT_MONITOR_WAITED:
338 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
345 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
346 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
347 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
352 case JVMTI_EVENT_OBJECT_FREE:
353 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
356 case JVMTI_EVENT_VM_OBJECT_ALLOC:
357 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
364 log_text ("unknown event");
371 /* dofireEvent ******************************************************************
373 sends event if it is enabled either globally or for some threads
375 *******************************************************************************/
376 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
378 jvmtiEventModeLL *evm;
382 while (env != NULL) {
383 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
384 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
385 /* test if the event is enable for some threads */
386 while (evm != NULL) {
387 if (evm->mode == JVMTI_ENABLE) {
389 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
391 data->jvmti_env=&env->env;
392 execute_callback(e, ec, data);
397 } else { /* event enabled globally */
398 data->jvmti_env=&env->env;
399 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
400 if (ec != NULL) execute_callback(e, ec, data);
408 /* fireEvent ******************************************************************
410 fire event callback with data arguments. This function mainly fills the
413 *******************************************************************************/
414 void jvmti_fireEvent(genericEventData* d) {
416 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
418 if (d->ev == JVMTI_EVENT_VM_START)
421 thread = jvmti_get_current_thread();
425 dofireEvent(d->ev,d);
429 /* SetEventNotificationMode ****************************************************
431 Control the generation of events
433 *******************************************************************************/
436 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
437 jvmtiEvent event_type, jthread event_thread, ...)
439 environment* cacao_env;
440 jvmtiEventModeLL *ll;
443 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
444 CHECK_PHASE(JVMTI_PHASE_LIVE)
447 if(event_thread != NULL) {
448 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
449 return JVMTI_ERROR_INVALID_THREAD;
450 CHECK_THREAD_IS_ALIVE(event_thread);
453 cacao_env = (environment*) env;
454 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
455 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
457 switch (event_type) { /* check capability and set system breakpoint */
458 case JVMTI_EVENT_EXCEPTION:
459 case JVMTI_EVENT_EXCEPTION_CATCH:
460 CHECK_CAPABILITY(env,can_generate_exception_events)
462 case JVMTI_EVENT_SINGLE_STEP:
463 CHECK_CAPABILITY(env,can_generate_single_step_events)
465 case JVMTI_EVENT_FRAME_POP:
466 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
468 case JVMTI_EVENT_BREAKPOINT:
469 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
471 case JVMTI_EVENT_FIELD_ACCESS:
472 CHECK_CAPABILITY(env,can_generate_field_access_events)
474 case JVMTI_EVENT_FIELD_MODIFICATION:
475 CHECK_CAPABILITY(env,can_generate_field_modification_events)
477 case JVMTI_EVENT_METHOD_ENTRY:
478 CHECK_CAPABILITY(env,can_generate_method_entry_events)
480 case JVMTI_EVENT_METHOD_EXIT:
481 CHECK_CAPABILITY(env, can_generate_method_exit_events)
483 case JVMTI_EVENT_NATIVE_METHOD_BIND:
484 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
486 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
487 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
488 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
490 case JVMTI_EVENT_MONITOR_WAIT:
491 case JVMTI_EVENT_MONITOR_WAITED:
492 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
493 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
494 CHECK_CAPABILITY(env,can_generate_monitor_events)
496 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
497 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
498 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
500 case JVMTI_EVENT_OBJECT_FREE:
501 CHECK_CAPABILITY(env,can_generate_object_free_events)
503 case JVMTI_EVENT_VM_OBJECT_ALLOC:
504 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
507 /* all other events are required */
508 if ((event_type < JVMTI_EVENT_START_ENUM) ||
509 (event_type > JVMTI_EVENT_END_ENUM))
510 return JVMTI_ERROR_INVALID_EVENT_TYPE;
515 if (event_thread != NULL) {
516 /* thread level control */
517 if ((JVMTI_EVENT_VM_INIT == mode) ||
518 (JVMTI_EVENT_VM_DEATH == mode) ||
519 (JVMTI_EVENT_VM_START == mode) ||
520 (JVMTI_EVENT_THREAD_START == mode) ||
521 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
522 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
523 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
524 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
525 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
526 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
527 while (ll->next != NULL) {
529 if (ll->event_thread == event_thread) {
531 return JVMTI_ERROR_NONE;
534 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
538 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
542 return JVMTI_ERROR_NONE;
545 /* GetAllThreads ***************************************************************
549 *******************************************************************************/
552 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
553 jthread ** threads_ptr)
555 threadobject** threads;
560 CHECK_PHASE(JVMTI_PHASE_LIVE)
563 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
564 return JVMTI_ERROR_NULL_POINTER;
566 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
567 if (retval != JVMTI_ERROR_NONE) return retval;
570 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
572 for (i=0; i<*threads_count_ptr; i++)
573 (*threads_ptr)[i] = threads[i]->o.thread;
575 return JVMTI_ERROR_NONE;
579 /* SuspendThread ***************************************************************
581 Suspend specified thread
583 *******************************************************************************/
586 SuspendThread (jvmtiEnv * env, jthread thread)
589 CHECK_PHASE(JVMTI_PHASE_LIVE)
591 CHECK_CAPABILITY(env,can_suspend);
593 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
594 if (!builtin_instanceof(thread,class_java_lang_Thread))
595 return JVMTI_ERROR_INVALID_THREAD;
596 CHECK_THREAD_IS_ALIVE(thread);
598 /* threads_suspend_thread will implement suspend
599 threads_suspend_thread (
600 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
602 return JVMTI_ERROR_NONE;
605 /* ResumeThread ***************************************************************
607 Resume a suspended thread
609 *******************************************************************************/
612 ResumeThread (jvmtiEnv * env, jthread thread)
615 CHECK_PHASE(JVMTI_PHASE_LIVE)
617 CHECK_CAPABILITY(env,can_suspend);
619 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
620 if (!builtin_instanceof(thread,class_java_lang_Thread))
621 return JVMTI_ERROR_INVALID_THREAD;
622 CHECK_THREAD_IS_ALIVE(thread);
624 /* threads_resume_thread will implement resume
625 threads_resume_thread (
626 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
628 return JVMTI_ERROR_NONE;
631 /* StopThread *****************************************************************
633 Send asynchronous exception to the specified thread. Similar to
634 java.lang.Thread.stop(). Used to kill thread.
636 *******************************************************************************/
639 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
642 CHECK_PHASE(JVMTI_PHASE_LIVE)
644 CHECK_CAPABILITY(env,can_signal_thread);
646 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
647 return JVMTI_ERROR_NOT_AVAILABLE;
649 return JVMTI_ERROR_NONE;
652 /* InterruptThread ************************************************************
654 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
656 *******************************************************************************/
659 InterruptThread (jvmtiEnv * env, jthread thread)
662 CHECK_PHASE(JVMTI_PHASE_LIVE)
664 CHECK_CAPABILITY(env,can_signal_thread)
666 #if defined(ENABLE_THREADS)
667 if(!builtin_instanceof(thread,class_java_lang_Thread))
668 return JVMTI_ERROR_INVALID_THREAD;
670 CHECK_THREAD_IS_ALIVE(thread);
672 threads_interrupt_thread(((java_lang_Thread*)thread)->vmThread);
675 return JVMTI_ERROR_NONE;
677 return JVMTI_ERROR_NOT_AVAILABLE;
681 /* GetThreadInfo ***************************************************************
683 Get thread information. Details of the specified thread are stored in the
684 jvmtiThreadInfo structure.
686 *******************************************************************************/
689 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
692 java_lang_Thread* th = (java_lang_Thread*)t;
696 CHECK_PHASE(JVMTI_PHASE_LIVE)
699 info_ptr->priority=(jint)th->priority;
700 info_ptr->is_daemon=(jboolean)th->daemon;
701 info_ptr->thread_group=(jthreadGroup)th->group;
702 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
704 name = javastring_toutf(th->name,false);
705 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
706 utf_sprint_convert_to_latin1(info_ptr->name, name);
708 return JVMTI_ERROR_NONE;
711 /* GetOwnedMonitorInfo *********************************************************
713 Gets all monitors owned by the specified thread
715 *******************************************************************************/
718 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
719 jint * owned_monitor_count_ptr,
720 jobject ** owned_monitors_ptr)
723 java_objectheader **om;
724 lock_record_pool_t* lrp;
728 CHECK_PHASE(JVMTI_PHASE_LIVE)
730 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
732 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
733 return JVMTI_ERROR_NULL_POINTER;
735 if (thread == NULL) {
736 t = jvmti_get_current_thread();
738 if(!builtin_instanceof(thread,class_java_lang_Thread))
739 return JVMTI_ERROR_INVALID_THREAD;
741 CHECK_THREAD_IS_ALIVE(thread);
742 t = (threadobject*) thread;
745 #if defined(ENABLE_THREADS)
747 om=MNEW(java_objectheader*,size);
749 pthread_mutex_lock(&lock_global_pool_lock);
750 lrp=lock_global_pool;
752 /* iterate over all lock record pools */
753 while (lrp != NULL) {
754 /* iterate over every lock record in a pool */
755 for (j=0; j<lrp->header.size; j++) {
756 /* if the lock record is owned by the given thread add it to
758 if(lrp->lr[j].owner == t) {
760 MREALLOC(om, java_objectheader*, size, size * 2);
763 om[i] = lrp->lr[j].obj;
767 lrp=lrp->header.next;
770 pthread_mutex_unlock(&lock_global_pool_lock);
772 *owned_monitors_ptr =
773 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
774 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
775 MFREE(om, java_objectheader*, size);
777 *owned_monitor_count_ptr = i;
781 return JVMTI_ERROR_NONE;
784 /* GetCurrentContendedMonitor *************************************************
786 Get the object the specified thread waits for.
788 *******************************************************************************/
791 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
792 jobject * monitor_ptr)
795 lock_record_pool_t* lrp;
797 lock_waiter_t* waiter;
800 CHECK_PHASE(JVMTI_PHASE_LIVE)
802 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
804 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
807 if (thread == NULL) {
808 t = jvmti_get_current_thread();
810 if(!builtin_instanceof(thread,class_java_lang_Thread))
811 return JVMTI_ERROR_INVALID_THREAD;
813 CHECK_THREAD_IS_ALIVE(thread);
814 t = (threadobject*) thread;
817 #if defined(ENABLE_THREADS)
819 pthread_mutex_lock(&lock_global_pool_lock);
821 lrp=lock_global_pool;
823 /* iterate over all lock record pools */
824 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
825 /* iterate over every lock record in a pool */
826 for (j=0; j<lrp->header.size; j++) {
827 /* iterate over every thread that is wait on this lock record */
828 waiter = lrp->lr[j].waiters;
829 while (waiter != NULL)
830 /* if the waiting thread equals to the given thread we are
831 done. Stop iterateting. */
832 if(waiter->waiter == t) {
833 *monitor_ptr=lrp->lr[j].obj;
837 lrp=lrp->header.next;
840 pthread_mutex_unlock(&lock_global_pool_lock);
844 return JVMTI_ERROR_NONE;
848 jvmtiStartFunction sf;
854 static void *threadstartup(void *t) {
855 runagentparam *rap = (runagentparam*)t;
856 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
860 /* RunAgentThread *************************************************************
862 Starts the execution of an agent thread of the specified native function
863 within the specified thread
865 *******************************************************************************/
868 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
869 const void *arg, jint priority)
871 pthread_attr_t threadattr;
872 struct sched_param sp;
876 CHECK_PHASE(JVMTI_PHASE_LIVE)
879 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
880 return JVMTI_ERROR_INVALID_THREAD;
881 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
882 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
883 (priority > JVMTI_THREAD_MAX_PRIORITY))
884 return JVMTI_ERROR_INVALID_PRIORITY;
886 /* XXX: Threads started with this function should not be visible to
887 Java programming language queries but are included in JVM TI queries */
890 rap.arg = (void*)arg;
893 #if defined(ENABLE_THREADS)
894 pthread_attr_init(&threadattr);
895 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
896 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
897 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
899 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
900 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
902 pthread_attr_setschedparam(&threadattr,&sp);
903 if (pthread_create(&((threadobject*)
904 thread)->tid, &threadattr, &threadstartup, &rap)) {
905 log_text("pthread_create failed");
910 return JVMTI_ERROR_NONE;
914 /* GetTopThreadGroups *********************************************************
916 Get all top-level thread groups in the VM.
918 *******************************************************************************/
921 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
922 jthreadGroup ** groups_ptr)
924 jint threads_count_ptr;
925 threadobject *threads_ptr;
927 jthreadGroup **tg,*ttgp;
930 CHECK_PHASE(JVMTI_PHASE_LIVE)
933 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
934 return JVMTI_ERROR_NULL_POINTER;
936 #if defined(ENABLE_THREADS)
937 tg = MNEW(jthreadGroup*,size);
939 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
940 return JVMTI_ERROR_INTERNAL;
942 for (i=0;i<threads_count_ptr;i++){
943 if (threads_ptr[i].o.thread->group == NULL) {
944 log_text("threadgroup not set");
945 return JVMTI_ERROR_INTERNAL;
947 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
950 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
955 MREALLOC(tg,jthreadGroup*,size,size*2);
964 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
965 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
966 MFREE(tg,jthreadGroup*,size);
968 *group_count_ptr = x;
971 return JVMTI_ERROR_NOT_AVAILABLE;
973 return JVMTI_ERROR_NONE;
977 /* GetThreadGroupInfo *********************************************************
979 Get information about the specified thread group.
981 *******************************************************************************/
984 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
985 jvmtiThreadGroupInfo * info_ptr)
989 java_lang_ThreadGroup* grp;
992 CHECK_PHASE(JVMTI_PHASE_LIVE)
995 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
996 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
997 return JVMTI_ERROR_INVALID_THREAD_GROUP;
999 grp = (java_lang_ThreadGroup*)group;
1001 info_ptr->parent = (jthreadGroup)
1002 Java_java_lang_VMObject_clone(NULL,
1003 (jclass)grp->header.vftbl->class,
1004 (java_lang_Cloneable*) &grp->parent);
1006 name = javastring_tochar((java_objectheader*)grp->name);
1007 size = strlen(name);
1008 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
1009 strncpy(info_ptr->name,name,size);
1010 info_ptr->max_priority= (jint)grp->maxpri;
1011 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1013 return JVMTI_ERROR_NONE;
1017 /* GetThreadGroupChildren *****************************************************
1019 Get the live threads and active subgroups in this thread group.
1021 *******************************************************************************/
1024 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1025 jint * thread_count_ptr, jthread ** threads_ptr,
1026 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1028 java_lang_ThreadGroup* tgp;
1031 CHECK_PHASE(JVMTI_PHASE_LIVE)
1034 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1035 (group_count_ptr == NULL) || (groups_ptr == NULL))
1036 return JVMTI_ERROR_NULL_POINTER;
1038 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1039 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1041 tgp = (java_lang_ThreadGroup*)group;
1043 *thread_count_ptr = (jint)tgp->threads->elementCount;
1046 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1048 memcpy(*threads_ptr, &tgp->threads->elementData,
1049 (*thread_count_ptr)*sizeof(java_objectarray*));
1051 *group_count_ptr = (jint) tgp->groups->elementCount;
1054 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1056 memcpy(*groups_ptr, &tgp->threads->elementData,
1057 (*group_count_ptr)*sizeof(jthreadGroup*));
1059 return JVMTI_ERROR_NONE;
1063 /* getcacaostacktrace *********************************************************
1065 Helper function that retrives stack trace for specified thread.
1067 *******************************************************************************/
1069 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1073 if (thread == NULL) {
1074 t = jvmti_get_current_thread();
1075 *trace = stacktrace_create(t);
1077 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1078 /* if (t != jvmti_get_current_thread())
1079 resume = threads_suspend_thread_if_running(thread);
1081 *trace = stacktrace_create(thread );
1084 threads_resume_thread ( thread );*/
1087 return JVMTI_ERROR_NONE;
1091 /* GetFrameCount **************************************************************
1094 Get the number of frames in the specified thread's stack. Calling function
1095 has to take care of suspending/resuming thread.
1097 *******************************************************************************/
1100 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1102 stacktracebuffer* trace;
1106 CHECK_PHASE(JVMTI_PHASE_LIVE)
1109 if (thread != NULL){
1110 if(!builtin_instanceof(thread,class_java_lang_Thread))
1111 return JVMTI_ERROR_INVALID_THREAD;
1113 CHECK_THREAD_IS_ALIVE(thread);
1116 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1118 er = getcacaostacktrace(&trace, thread);
1119 if (er == JVMTI_ERROR_NONE) {
1124 *count_ptr = trace->used;
1127 return JVMTI_ERROR_NONE;
1131 /* GetThreadState **************************************************************
1133 Get the state of a thread.
1135 *******************************************************************************/
1138 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1140 java_lang_Thread* th = (java_lang_Thread*)thread;
1141 threadobject* t = (threadobject*)th->vmThread;
1144 CHECK_PHASE(JVMTI_PHASE_LIVE)
1147 if(!builtin_instanceof(thread,class_java_lang_Thread))
1148 return JVMTI_ERROR_INVALID_THREAD;
1150 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1152 *thread_state_ptr = 0;
1153 #if defined(ENABLE_THREADS)
1154 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1156 if (((threadobject*)th->vmThread)->tid == 0)
1157 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1160 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1161 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1162 /* XXX todo - info not available */
1163 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1164 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1165 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1166 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1167 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1168 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1169 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1170 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1171 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1172 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1175 return JVMTI_ERROR_INTERNAL;
1178 return JVMTI_ERROR_NONE;
1182 /* GetFrameLocation ************************************************************
1184 Get the location of the instruction currently executing
1186 *******************************************************************************/
1189 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1190 jmethodID * method_ptr, jlocation * location_ptr)
1192 stackframeinfo *sfi;
1197 CHECK_PHASE(JVMTI_PHASE_LIVE)
1200 if (thread == NULL) {
1201 th = jvmti_get_current_thread();
1203 if(!builtin_instanceof(thread,class_java_lang_Thread))
1204 return JVMTI_ERROR_INVALID_THREAD;
1206 CHECK_THREAD_IS_ALIVE(thread);
1207 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1210 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1212 if ((method_ptr == NULL)&&(location_ptr == NULL))
1213 return JVMTI_ERROR_NULL_POINTER;
1215 sfi = th->_stackframeinfo;
1218 while ((sfi != NULL) && (i<depth)) {
1223 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1225 *method_ptr=(jmethodID)sfi->method;
1226 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1228 return JVMTI_ERROR_NONE;
1232 /* NotifyFramePop *************************************************************
1236 *******************************************************************************/
1239 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1242 CHECK_PHASE(JVMTI_PHASE_LIVE)
1244 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1246 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1247 return JVMTI_ERROR_NONE;
1250 /* GetLocalObject *************************************************************
1254 *******************************************************************************/
1257 GetLocalObject (jvmtiEnv * env,
1258 jthread thread, jint depth, jint slot, jobject * value_ptr)
1261 CHECK_PHASE(JVMTI_PHASE_LIVE)
1263 CHECK_CAPABILITY(env,can_access_local_variables)
1265 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1266 return JVMTI_ERROR_NONE;
1269 /* GetLocalInt ****************************************************************
1273 *******************************************************************************/
1276 GetLocalInt (jvmtiEnv * env,
1277 jthread thread, jint depth, jint slot, jint * value_ptr)
1280 CHECK_PHASE(JVMTI_PHASE_LIVE)
1282 CHECK_CAPABILITY(env,can_access_local_variables)
1283 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1284 return JVMTI_ERROR_NONE;
1287 /* *****************************************************************************
1291 *******************************************************************************/
1294 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1298 CHECK_PHASE(JVMTI_PHASE_LIVE)
1300 CHECK_CAPABILITY(env,can_access_local_variables)
1302 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1303 return JVMTI_ERROR_NONE;
1307 /* *****************************************************************************
1311 *******************************************************************************/
1314 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1318 CHECK_PHASE(JVMTI_PHASE_LIVE)
1320 CHECK_CAPABILITY(env,can_access_local_variables)
1322 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1323 return JVMTI_ERROR_NONE;
1327 /* *****************************************************************************
1331 *******************************************************************************/
1334 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1335 jdouble * value_ptr)
1338 CHECK_PHASE(JVMTI_PHASE_LIVE)
1340 CHECK_CAPABILITY(env,can_access_local_variables)
1342 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1343 return JVMTI_ERROR_NONE;
1347 /* *****************************************************************************
1351 *******************************************************************************/
1354 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1358 CHECK_PHASE(JVMTI_PHASE_LIVE)
1360 CHECK_CAPABILITY(env,can_access_local_variables)
1362 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1363 return JVMTI_ERROR_NONE;
1367 /* *****************************************************************************
1371 *******************************************************************************/
1374 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1378 CHECK_PHASE(JVMTI_PHASE_LIVE)
1380 CHECK_CAPABILITY(env,can_access_local_variables)
1382 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1383 return JVMTI_ERROR_NONE;
1387 /* *****************************************************************************
1391 *******************************************************************************/
1394 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1398 CHECK_PHASE(JVMTI_PHASE_LIVE)
1400 CHECK_CAPABILITY(env,can_access_local_variables)
1402 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1403 return JVMTI_ERROR_NONE;
1407 /* *****************************************************************************
1411 *******************************************************************************/
1414 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1418 CHECK_PHASE(JVMTI_PHASE_LIVE)
1420 CHECK_CAPABILITY(env,can_access_local_variables)
1422 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1423 return JVMTI_ERROR_NONE;
1427 /* *****************************************************************************
1431 *******************************************************************************/
1434 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1438 CHECK_PHASE(JVMTI_PHASE_LIVE)
1440 CHECK_CAPABILITY(env,can_access_local_variables)
1442 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1443 return JVMTI_ERROR_NONE;
1447 /* CreateRawMonitor ***********************************************************
1449 This function creates a new raw monitor.
1451 *******************************************************************************/
1454 CreateRawMonitor (jvmtiEnv * env, const char *name,
1455 jrawMonitorID * monitor_ptr)
1457 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1460 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1461 CHECK_PHASE(JVMTI_PHASE_LIVE)
1464 if ((name == NULL) || (monitor_ptr == NULL))
1465 return JVMTI_ERROR_NULL_POINTER;
1467 #if defined(ENABLE_THREADS)
1468 monitor->name=javastring_new_from_ascii(name);
1470 log_text ("CreateRawMonitor not supported");
1473 return JVMTI_ERROR_NONE;
1477 /* DestroyRawMonitor **********************************************************
1479 This function destroys a raw monitor.
1481 *******************************************************************************/
1484 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1487 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1488 CHECK_PHASE(JVMTI_PHASE_LIVE)
1491 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1492 return JVMTI_ERROR_INVALID_MONITOR;
1494 #if defined(ENABLE_THREADS)
1495 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1496 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1498 lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1502 log_text ("DestroyRawMonitor not supported");
1505 return JVMTI_ERROR_NONE;
1509 /* RawMonitorEnter ************************************************************
1511 Gain exclusive ownership of a raw monitor
1513 *******************************************************************************/
1516 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1518 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1519 return JVMTI_ERROR_INVALID_MONITOR;
1521 #if defined(ENABLE_THREADS)
1522 builtin_monitorenter((java_objectheader*)monitor->name);
1524 log_text ("RawMonitorEnter not supported");
1527 return JVMTI_ERROR_NONE;
1531 /* RawMonitorExit *************************************************************
1535 *******************************************************************************/
1538 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1540 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1541 return JVMTI_ERROR_INVALID_MONITOR;
1543 #if defined(ENABLE_THREADS)
1544 /* assure current thread owns this monitor */
1545 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1546 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1548 builtin_monitorexit((java_objectheader*)monitor->name);
1550 log_text ("RawMonitorExit not supported");
1553 return JVMTI_ERROR_NONE;
1557 /* RawMonitorWait *************************************************************
1559 Wait for notification of the raw monitor.
1561 *******************************************************************************/
1564 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1566 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1567 return JVMTI_ERROR_INVALID_MONITOR;
1569 #if defined(ENABLE_THREADS)
1570 /* assure current thread owns this monitor */
1571 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1572 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1574 lock_wait_for_object(&monitor->name->header, millis,0);
1575 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1576 return JVMTI_ERROR_INTERRUPT;
1579 log_text ("RawMonitorWait not supported");
1582 return JVMTI_ERROR_NONE;
1586 /* RawMonitorNotify ***********************************************************
1588 Notify one thread waiting on the given monitor.
1590 *******************************************************************************/
1593 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1595 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1596 return JVMTI_ERROR_INVALID_MONITOR;
1598 #if defined(ENABLE_THREADS)
1599 /* assure current thread owns this monitor */
1600 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1601 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1603 lock_notify_object((java_objectheader*)&monitor->name);
1605 log_text ("RawMonitorNotify not supported");
1608 return JVMTI_ERROR_NONE;
1612 /* RawMonitorNotifyAll *********************************************************
1614 Notify all threads waiting on the given monitor.
1616 *******************************************************************************/
1619 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1621 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1622 return JVMTI_ERROR_INVALID_MONITOR;
1624 #if defined(ENABLE_THREADS)
1625 /* assure current thread owns this monitor */
1626 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1627 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1629 lock_notify_all_object((java_objectheader*)&monitor->name);
1631 log_text ("RawMonitorNotifyAll not supported");
1634 return JVMTI_ERROR_NONE;
1638 /* SetBreakpoint **************************************************************
1642 *******************************************************************************/
1645 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1648 CHECK_PHASE(JVMTI_PHASE_LIVE)
1650 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1653 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1654 return JVMTI_ERROR_NONE;
1658 /* *****************************************************************************
1662 *******************************************************************************/
1665 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1668 CHECK_PHASE(JVMTI_PHASE_LIVE)
1670 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1672 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1673 return JVMTI_ERROR_NONE;
1677 /* SetFieldAccessWatch ********************************************************
1681 *******************************************************************************/
1684 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1687 CHECK_PHASE(JVMTI_PHASE_LIVE)
1689 CHECK_CAPABILITY(env,can_generate_field_access_events)
1691 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1692 return JVMTI_ERROR_NONE;
1696 /* *****************************************************************************
1700 *******************************************************************************/
1703 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1706 CHECK_PHASE(JVMTI_PHASE_LIVE)
1708 CHECK_CAPABILITY(env,can_generate_field_access_events)
1710 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1711 return JVMTI_ERROR_NONE;
1715 /* *****************************************************************************
1719 *******************************************************************************/
1722 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1725 CHECK_PHASE(JVMTI_PHASE_LIVE)
1727 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1729 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1730 return JVMTI_ERROR_NONE;
1734 /* *****************************************************************************
1738 *******************************************************************************/
1741 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1744 CHECK_PHASE(JVMTI_PHASE_LIVE)
1746 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1748 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1749 return JVMTI_ERROR_NONE;
1753 /* Allocate ********************************************************************
1755 Allocate an area of memory through the JVM TI allocator. The allocated
1756 memory should be freed with Deallocate
1758 *******************************************************************************/
1761 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1764 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1765 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1767 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1768 if (*mem_ptr == NULL)
1769 return JVMTI_ERROR_OUT_OF_MEMORY;
1771 return JVMTI_ERROR_NONE;
1776 /* Deallocate ******************************************************************
1778 Deallocate mem using the JVM TI allocator.
1780 *******************************************************************************/
1783 Deallocate (jvmtiEnv * env, unsigned char *mem)
1785 /* let Boehm GC do the job */
1787 return JVMTI_ERROR_NONE;
1791 /* GetClassSignature ************************************************************
1793 For the class indicated by klass, return the JNI type signature and the
1794 generic signature of the class.
1796 *******************************************************************************/
1799 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1803 CHECK_PHASE(JVMTI_PHASE_START)
1804 CHECK_PHASE(JVMTI_PHASE_LIVE)
1807 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1808 if (!builtin_instanceof(klass,class_java_lang_Class))
1809 return JVMTI_ERROR_INVALID_CLASS;
1811 if (signature_ptr != NULL) {
1812 *signature_ptr = (char*)
1813 heap_allocate(sizeof(char) *
1814 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1816 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1819 if (generic_ptr!= NULL)
1820 *generic_ptr = NULL;
1822 return JVMTI_ERROR_NONE;
1825 /* GetClassStatus *************************************************************
1827 Get status of the class.
1829 *******************************************************************************/
1832 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1836 CHECK_PHASE(JVMTI_PHASE_START)
1837 CHECK_PHASE(JVMTI_PHASE_LIVE)
1840 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1841 return JVMTI_ERROR_INVALID_CLASS;
1843 if (status_ptr == NULL)
1844 return JVMTI_ERROR_NULL_POINTER;
1846 c = (classinfo*)klass;
1849 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1850 if (c->state & CLASS_LINKED)
1851 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1853 if (c->state & CLASS_INITIALIZED)
1854 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1856 if (c->state & CLASS_ERROR)
1857 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1859 if (c->vftbl->arraydesc != NULL)
1860 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1862 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1863 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1865 return JVMTI_ERROR_NONE;
1869 /* GetSourceFileName **********************************************************
1871 For the class indicated by klass, return the source file name.
1873 *******************************************************************************/
1876 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1881 CHECK_PHASE(JVMTI_PHASE_START)
1882 CHECK_PHASE(JVMTI_PHASE_LIVE)
1884 CHECK_CAPABILITY(env,can_get_source_file_name)
1886 if ((klass == NULL)||(source_name_ptr == NULL))
1887 return JVMTI_ERROR_NULL_POINTER;
1889 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1891 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1893 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1894 (*source_name_ptr)[size]='\0';
1896 return JVMTI_ERROR_NONE;
1900 /* GetClassModifiers **********************************************************
1902 For class klass return the access flags
1904 *******************************************************************************/
1907 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1910 CHECK_PHASE(JVMTI_PHASE_START)
1911 CHECK_PHASE(JVMTI_PHASE_LIVE)
1914 if (modifiers_ptr == NULL)
1915 return JVMTI_ERROR_NULL_POINTER;
1917 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1918 return JVMTI_ERROR_INVALID_CLASS;
1920 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1922 return JVMTI_ERROR_NONE;
1926 /* GetClassMethods *************************************************************
1928 For class klass return a count of methods and a list of method IDs
1930 *******************************************************************************/
1933 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1934 jmethodID ** methods_ptr)
1939 CHECK_PHASE(JVMTI_PHASE_START)
1940 CHECK_PHASE(JVMTI_PHASE_LIVE)
1943 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1944 return JVMTI_ERROR_NULL_POINTER;
1946 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1947 return JVMTI_ERROR_INVALID_CLASS;
1949 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1950 *methods_ptr = (jmethodID*)
1951 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1953 for (i=0; i<*method_count_ptr;i++)
1954 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1956 return JVMTI_ERROR_NONE;
1960 /* GetClassFields *************************************************************
1962 For the class indicated by klass, return a count of fields and a list of
1965 *******************************************************************************/
1968 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1969 jfieldID ** fields_ptr)
1972 CHECK_PHASE(JVMTI_PHASE_START)
1973 CHECK_PHASE(JVMTI_PHASE_LIVE)
1976 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1977 return JVMTI_ERROR_NULL_POINTER;
1979 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1980 *fields_ptr = (jfieldID*)
1981 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1983 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1984 sizeof(jfieldID) * (*field_count_ptr));
1986 return JVMTI_ERROR_NONE;
1990 /* GetImplementedInterfaces ***************************************************
1992 Return the direct super-interfaces of this class.
1994 *******************************************************************************/
1997 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1998 jint * interface_count_ptr,
1999 jclass ** interfaces_ptr)
2002 classref_or_classinfo *interfaces;
2006 CHECK_PHASE(JVMTI_PHASE_START)
2007 CHECK_PHASE(JVMTI_PHASE_LIVE)
2010 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
2011 return JVMTI_ERROR_NULL_POINTER;
2013 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2014 return JVMTI_ERROR_INVALID_CLASS;
2017 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2019 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2021 interfaces = ((classinfo*)klass)->interfaces;
2022 for (i=0; i<*interface_count_ptr; i++) {
2023 if (IS_CLASSREF(interfaces[i]))
2024 tmp = load_class_bootstrap(interfaces[i].ref->name);
2026 tmp = interfaces[i].cls;
2028 *interfaces_ptr[i]=tmp;
2031 return JVMTI_ERROR_NONE;
2035 /* IsInterface ****************************************************************
2037 Determines whether a class object reference represents an interface.
2039 *******************************************************************************/
2042 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2045 CHECK_PHASE(JVMTI_PHASE_START)
2046 CHECK_PHASE(JVMTI_PHASE_LIVE)
2049 if ((klass == NULL)||(is_interface_ptr == NULL))
2050 return JVMTI_ERROR_NULL_POINTER;
2052 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2054 return JVMTI_ERROR_NONE;
2057 /* IsArrayClass ***************************************************************
2059 Determines whether a class object reference represents an array.
2061 *******************************************************************************/
2064 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2067 CHECK_PHASE(JVMTI_PHASE_START)
2068 CHECK_PHASE(JVMTI_PHASE_LIVE)
2071 if (is_array_class_ptr == NULL)
2072 return JVMTI_ERROR_NULL_POINTER;
2074 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2076 return JVMTI_ERROR_NONE;
2080 /* GetClassLoader *************************************************************
2082 For the class indicated by klass, return via classloader_ptr a reference to
2083 the class loader for the class.
2085 *******************************************************************************/
2088 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2091 CHECK_PHASE(JVMTI_PHASE_START)
2092 CHECK_PHASE(JVMTI_PHASE_LIVE)
2095 if ((klass == NULL)||(classloader_ptr == NULL))
2096 return JVMTI_ERROR_NULL_POINTER;
2098 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2100 return JVMTI_ERROR_NONE;
2104 /* GetObjectHashCode **********************************************************
2106 Return hash code for object object
2108 *******************************************************************************/
2111 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2114 CHECK_PHASE(JVMTI_PHASE_START)
2115 CHECK_PHASE(JVMTI_PHASE_LIVE)
2118 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2119 if (!builtin_instanceof(object,class_java_lang_Object))
2120 return JVMTI_ERROR_INVALID_OBJECT;
2122 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2124 return JVMTI_ERROR_NONE;
2128 /* *****************************************************************************
2132 *******************************************************************************/
2135 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2136 jvmtiMonitorUsage * info_ptr)
2139 CHECK_PHASE(JVMTI_PHASE_LIVE)
2141 CHECK_CAPABILITY(env,can_get_monitor_info)
2143 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2144 return JVMTI_ERROR_NONE;
2148 /* GetFieldName ***************************************************************
2150 For the field indicated by klass and field, return the field name and
2153 *******************************************************************************/
2156 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2157 char **name_ptr, char **signature_ptr, char **generic_ptr)
2162 CHECK_PHASE(JVMTI_PHASE_START)
2163 CHECK_PHASE(JVMTI_PHASE_LIVE)
2167 return JVMTI_ERROR_INVALID_CLASS;
2169 if (!builtin_instanceof(klass,class_java_lang_Class))
2170 return JVMTI_ERROR_INVALID_CLASS;
2171 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2173 if (name_ptr != NULL) {
2174 size = utf_bytes(((fieldinfo*)field)->name)+1;
2175 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2176 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2179 if (signature_ptr != NULL) {
2180 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2181 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2182 utf_sprint_convert_to_latin1(*signature_ptr,
2183 ((fieldinfo*)field)->descriptor);
2186 if (generic_ptr != NULL)
2187 *generic_ptr = NULL;
2189 return JVMTI_ERROR_NONE;
2193 /* GetFieldDeclaringClass *****************************************************
2195 For the field indicated by klass and field return the class that defined it
2196 The declaring class will either be klass, a superclass, or an implemented
2199 *******************************************************************************/
2202 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2203 jclass * declaring_class_ptr)
2206 CHECK_PHASE(JVMTI_PHASE_START)
2207 CHECK_PHASE(JVMTI_PHASE_LIVE)
2211 return JVMTI_ERROR_INVALID_CLASS;
2213 if (!builtin_instanceof(klass,class_java_lang_Class))
2214 return JVMTI_ERROR_INVALID_CLASS;
2216 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2218 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2220 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2222 return JVMTI_ERROR_NONE;
2226 /* GetFieldModifiers **********************************************************
2228 Return access flags of field field
2230 *******************************************************************************/
2233 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2234 jint * modifiers_ptr)
2237 CHECK_PHASE(JVMTI_PHASE_START)
2238 CHECK_PHASE(JVMTI_PHASE_LIVE)
2242 return JVMTI_ERROR_INVALID_CLASS;
2244 if (!builtin_instanceof(klass,class_java_lang_Class))
2245 return JVMTI_ERROR_INVALID_CLASS;
2247 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2249 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2251 *modifiers_ptr = ((fieldinfo*)field)->flags;
2253 return JVMTI_ERROR_NONE;
2257 /* IsFieldSynthetic ***********************************************************
2261 *******************************************************************************/
2264 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2265 jboolean * is_synthetic_ptr)
2268 CHECK_PHASE(JVMTI_PHASE_START)
2269 CHECK_PHASE(JVMTI_PHASE_LIVE)
2271 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2273 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2274 return JVMTI_ERROR_NONE;
2278 /* GetMethodName ***************************************************************
2280 For the method indicated by method, return the method name via name_ptr and
2281 method signature via signature_ptr.
2283 *******************************************************************************/
2286 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2287 char **signature_ptr, char **generic_ptr)
2289 methodinfo* m = (methodinfo*)method;
2292 CHECK_PHASE(JVMTI_PHASE_START)
2293 CHECK_PHASE(JVMTI_PHASE_LIVE)
2297 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2299 if (name_ptr != NULL) {
2301 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2302 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2305 if (signature_ptr != NULL) {
2306 *signature_ptr = (char*)
2307 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2308 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2311 if (generic_ptr != NULL) {
2312 /* there is no generic signature attribute */
2313 *generic_ptr = NULL;
2316 return JVMTI_ERROR_NONE;
2320 /* GetMethodDeclaringClass *****************************************************
2322 For the method indicated by method, return the class that defined it.
2324 *******************************************************************************/
2327 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2328 jclass * declaring_class_ptr)
2331 CHECK_PHASE(JVMTI_PHASE_START)
2332 CHECK_PHASE(JVMTI_PHASE_LIVE)
2335 if ((method == NULL) || (declaring_class_ptr == NULL))
2336 return JVMTI_ERROR_NULL_POINTER;
2338 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2340 return JVMTI_ERROR_NONE;
2344 /* GetMethodModifiers **********************************************************
2346 For the method indicated by method, return the access flags.
2348 *******************************************************************************/
2351 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2354 CHECK_PHASE(JVMTI_PHASE_START)
2355 CHECK_PHASE(JVMTI_PHASE_LIVE)
2358 if ((method == NULL) || (modifiers_ptr == NULL))
2359 return JVMTI_ERROR_NULL_POINTER;
2361 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2363 return JVMTI_ERROR_NONE;
2367 /* GetMaxLocals ****************************************************************
2369 For the method indicated by method, return the number of local variable slots
2370 used by the method, including the local variables used to pass parameters to
2371 the method on its invocation.
2373 *******************************************************************************/
2376 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2379 CHECK_PHASE(JVMTI_PHASE_START)
2380 CHECK_PHASE(JVMTI_PHASE_LIVE)
2383 if ((method == NULL)||(max_ptr == NULL))
2384 return JVMTI_ERROR_NULL_POINTER;
2386 if (((methodinfo*)method)->flags & ACC_NATIVE)
2387 return JVMTI_ERROR_NATIVE_METHOD;
2389 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2391 return JVMTI_ERROR_NONE;
2396 /* GetArgumentsSize ************************************************************
2398 Return the number of local variable slots used by the method's arguments.
2400 *******************************************************************************/
2403 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2406 CHECK_PHASE(JVMTI_PHASE_START)
2407 CHECK_PHASE(JVMTI_PHASE_LIVE)
2410 if ((method == NULL)||(size_ptr == NULL))
2411 return JVMTI_ERROR_NULL_POINTER;
2413 if (((methodinfo*)method)->flags & ACC_NATIVE)
2414 return JVMTI_ERROR_NATIVE_METHOD;
2416 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2417 return JVMTI_ERROR_NONE;
2422 /* GetLineNumberTable **********************************************************
2424 Return table of source line number entries for a given method
2426 *******************************************************************************/
2429 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2430 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2435 CHECK_PHASE(JVMTI_PHASE_START)
2436 CHECK_PHASE(JVMTI_PHASE_LIVE)
2438 CHECK_CAPABILITY(env,can_get_line_numbers)
2440 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2441 return JVMTI_ERROR_NULL_POINTER;
2443 if (((methodinfo*)method)->flags & ACC_NATIVE)
2444 return JVMTI_ERROR_NATIVE_METHOD;
2446 if (((methodinfo*)method)->linenumbers == NULL)
2447 return JVMTI_ERROR_ABSENT_INFORMATION;
2449 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2450 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2451 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2454 for (i=0; i < *entry_count_ptr; i++) {
2455 (*table_ptr)[i].start_location =
2456 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2457 (*table_ptr)[i].line_number =
2458 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2461 return JVMTI_ERROR_NONE;
2465 /* GetMethodLocation ***********************************************************
2467 For the method indicated by method, return the beginning and ending addresses
2468 through start_location_ptr and end_location_ptr. In cacao this points to
2469 entry point in machine code and length of machine code
2471 *******************************************************************************/
2474 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2475 jlocation * start_location_ptr,
2476 jlocation * end_location_ptr)
2478 methodinfo* m = (methodinfo*)method;
2481 CHECK_PHASE(JVMTI_PHASE_START)
2482 CHECK_PHASE(JVMTI_PHASE_LIVE)
2485 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2487 if (((methodinfo*)method)->flags & ACC_NATIVE)
2488 return JVMTI_ERROR_NATIVE_METHOD;
2490 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2491 return JVMTI_ERROR_NULL_POINTER;
2493 /* XXX we return the location of the most recent code. Don't know
2494 * if there is a way to teach jvmti that a method can have more
2495 * than one location. -Edwin */
2497 /* XXX Don't know if that's the right way to deal with not-yet-
2498 * compiled methods. -Edwin */
2500 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2503 /* -1 states location information is not available */
2504 *start_location_ptr = (jlocation)-1;
2505 *end_location_ptr = (jlocation)-1;
2508 *start_location_ptr = (jlocation)m->code->mcode;
2509 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2510 return JVMTI_ERROR_NONE;
2514 /* GetLocalVariableTable *******************************************************
2516 Return local variable information.
2518 *******************************************************************************/
2521 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2522 jint * entry_count_ptr,
2523 jvmtiLocalVariableEntry ** table_ptr)
2526 CHECK_PHASE(JVMTI_PHASE_LIVE)
2528 CHECK_CAPABILITY(env,can_access_local_variables)
2530 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2532 return JVMTI_ERROR_NONE;
2536 /* GetBytecode *****************************************************************
2538 For the method indicated by method, return the byte codes that implement the
2541 *******************************************************************************/
2544 GetBytecodes (jvmtiEnv * env, jmethodID method,
2545 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2547 methodinfo* m = (methodinfo*)method;;
2550 CHECK_PHASE(JVMTI_PHASE_START)
2551 CHECK_PHASE(JVMTI_PHASE_LIVE)
2553 CHECK_CAPABILITY(env,can_get_bytecodes)
2555 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2556 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2558 *bytecode_count_ptr = m->jcodelength;
2559 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2560 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2562 return JVMTI_ERROR_NONE;
2566 /* IsMethodNative **************************************************************
2568 For the method indicated by method, return a value indicating whether the
2569 method is a native function
2571 *******************************************************************************/
2574 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2577 CHECK_PHASE(JVMTI_PHASE_START)
2578 CHECK_PHASE(JVMTI_PHASE_LIVE)
2581 if ((method == NULL)||(is_native_ptr == NULL))
2582 return JVMTI_ERROR_NULL_POINTER;
2584 if (((methodinfo*)method)->flags & ACC_NATIVE)
2585 *is_native_ptr = JNI_TRUE;
2587 *is_native_ptr = JNI_FALSE;
2589 return JVMTI_ERROR_NONE;
2593 /* IsMethodSynthetic ***********************************************************
2595 return a value indicating whether the method is synthetic. Synthetic methods
2596 are generated by the compiler but not present in the original source code.
2598 *******************************************************************************/
2601 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2602 jboolean * is_synthetic_ptr)
2605 CHECK_PHASE(JVMTI_PHASE_START)
2606 CHECK_PHASE(JVMTI_PHASE_LIVE)
2608 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2610 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2611 return JVMTI_ERROR_NONE;
2615 /* GetLoadedClasses ************************************************************
2617 Return an array of all classes loaded in the virtual machine.
2619 *******************************************************************************/
2622 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2625 classcache_name_entry *nameentry;
2626 classcache_class_entry *classentry;
2629 CHECK_PHASE(JVMTI_PHASE_LIVE)
2632 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2633 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2637 heap_allocate(sizeof(jclass)*(hashtable_classcache.entries),true,NULL);
2639 /* look in every slot of the hashtable */
2640 for (i=0; i<hashtable_classcache.size; i++) {
2641 nameentry = hashtable_classcache.ptr[i];
2642 while (nameentry != NULL) { /* iterate over hashlink */
2644 /* filter pseudo classes $NEW$,$NULL$,$ARRAYSTUB$ out */
2645 if (nameentry->name->text[0] == '$')
2647 *class_count_ptr -= 1;
2651 classentry = nameentry->classes;
2652 while (classentry != NULL){ /* iterate over classes with same name */
2653 if (classentry->classobj != NULL) { /*get only loaded classes */
2654 assert(j<hashtable_classcache.entries);
2655 (*classes_ptr)[j]=classentry->classobj;
2658 classentry = classentry->next;
2660 nameentry = nameentry->hashlink;
2664 CLASSCACHE_UNLOCK();
2666 *class_count_ptr = j;
2668 return JVMTI_ERROR_NONE;
2672 /* GetClassLoaderClasses *******************************************************
2674 Returns an array of those classes for which this class loader has been
2675 recorded as an initiating loader.
2677 *******************************************************************************/
2680 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2681 jint * class_count_ptr, jclass ** classes_ptr)
2683 log_text("GetClassLoaderClasses called");
2686 CHECK_PHASE(JVMTI_PHASE_LIVE)
2689 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2690 return JVMTI_ERROR_NULL_POINTER;
2692 /* behave like jdk 1.1 and make no distinction between initiating and
2693 defining class loaders */
2695 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2699 /* PopFrame *******************************************************************
2703 *******************************************************************************/
2706 PopFrame (jvmtiEnv * env, jthread thread)
2709 CHECK_PHASE(JVMTI_PHASE_LIVE)
2711 CHECK_CAPABILITY(env,can_pop_frame)
2713 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2714 return JVMTI_ERROR_NONE;
2718 /* RedefineClasses ************************************************************
2722 *******************************************************************************/
2725 RedefineClasses (jvmtiEnv * env, jint class_count,
2726 const jvmtiClassDefinition * class_definitions)
2729 CHECK_PHASE(JVMTI_PHASE_START)
2730 CHECK_PHASE(JVMTI_PHASE_LIVE)
2732 CHECK_CAPABILITY(env,can_redefine_classes)
2733 CHECK_CAPABILITY(env,can_redefine_any_class)
2735 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2736 return JVMTI_ERROR_NONE;
2740 /* GetVersionNumber ***********************************************************
2742 Return the JVM TI version identifier.
2744 *******************************************************************************/
2747 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2749 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2751 *version_ptr = JVMTI_VERSION;
2753 return JVMTI_ERROR_NONE;
2757 /* GetCapabilities ************************************************************
2759 Returns the optional JVM TI features which this environment currently
2762 *******************************************************************************/
2765 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2767 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2769 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2771 return JVMTI_ERROR_NONE;
2775 /* *****************************************************************************
2779 *******************************************************************************/
2782 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2783 char **source_debug_extension_ptr)
2786 CHECK_PHASE(JVMTI_PHASE_START)
2787 CHECK_PHASE(JVMTI_PHASE_LIVE)
2789 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2791 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2792 return JVMTI_ERROR_NONE;
2796 /* IsMethodObsolete ************************************************************
2798 Determine if a method ID refers to an obsolete method version.
2800 *******************************************************************************/
2803 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2804 jboolean * is_obsolete_ptr)
2807 CHECK_PHASE(JVMTI_PHASE_START)
2808 CHECK_PHASE(JVMTI_PHASE_LIVE)
2810 CHECK_CAPABILITY(env,can_redefine_classes)
2812 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2813 return JVMTI_ERROR_NONE;
2817 /* SuspendThreadList **********************************************************
2819 Suspend all threads in the request list.
2821 *******************************************************************************/
2824 SuspendThreadList (jvmtiEnv * env, jint request_count,
2825 const jthread * request_list, jvmtiError * results)
2832 CHECK_PHASE(JVMTI_PHASE_START)
2833 CHECK_PHASE(JVMTI_PHASE_LIVE)
2835 CHECK_CAPABILITY(env,can_suspend);
2837 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2838 if ((request_list == NULL) || (results == NULL))
2839 return JVMTI_ERROR_NULL_POINTER;
2841 me = jvmti_get_current_thread();
2843 for (i=0;i<request_count;i++) {
2844 if (request_list[i] == me)
2847 results[i]=SuspendThread(env, request_list[i]);
2850 if (suspendme != -1)
2851 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2853 return JVMTI_ERROR_NONE;
2857 /* ResumeThreadList ***********************************************************
2859 Resumes all threads in the request list.
2861 *******************************************************************************/
2864 ResumeThreadList (jvmtiEnv * env, jint request_count,
2865 const jthread * request_list, jvmtiError * results)
2870 CHECK_PHASE(JVMTI_PHASE_LIVE)
2872 CHECK_CAPABILITY(env,can_suspend);
2874 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2875 if ((request_list == NULL) || (results == NULL))
2876 return JVMTI_ERROR_NULL_POINTER;
2878 for (i=0;i<request_count;i++)
2879 results[i]=ResumeThread(env, request_list[i]);
2881 return JVMTI_ERROR_NONE;
2885 /* GetStackTrace **************************************************************
2887 Get information about the stack of a thread
2889 *******************************************************************************/
2892 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2893 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2896 stacktracebuffer* trace;
2901 CHECK_PHASE(JVMTI_PHASE_LIVE)
2904 if (thread != NULL){
2905 if(!builtin_instanceof(thread,class_java_lang_Thread))
2906 return JVMTI_ERROR_INVALID_THREAD;
2908 CHECK_THREAD_IS_ALIVE(thread);
2911 if((count_ptr == NULL)||(frame_buffer == NULL))
2912 return JVMTI_ERROR_NULL_POINTER;
2914 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2916 er = getcacaostacktrace(&trace, thread);
2917 if (er == JVMTI_ERROR_NONE) {
2922 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2923 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2925 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2926 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2927 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2928 frame_buffer[j].location = 0;
2933 return JVMTI_ERROR_NONE;
2937 /* GetThreadListStackTraces ***************************************************
2939 Get information about the stacks of the supplied threads.
2941 *******************************************************************************/
2944 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2945 const jthread * thread_list,
2946 jint max_frame_count,
2947 jvmtiStackInfo ** stack_info_ptr)
2953 CHECK_PHASE(JVMTI_PHASE_LIVE)
2956 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2957 return JVMTI_ERROR_NULL_POINTER;
2959 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2961 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2963 *stack_info_ptr = (jvmtiStackInfo*)
2964 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2966 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2967 (*stack_info_ptr)[i].thread=thread_list[i];
2968 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2969 (*stack_info_ptr)[i].frame_buffer =
2970 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2971 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2972 (*stack_info_ptr)[i].frame_buffer,
2973 &((*stack_info_ptr)[i].frame_count));
2975 if (er != JVMTI_ERROR_NONE) return er;
2978 return JVMTI_ERROR_NONE;
2982 /* GetAllStackTraces **********************************************************
2984 Get stack traces of all live threads
2986 *******************************************************************************/
2989 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2990 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2992 jthread *threads_ptr;
2996 CHECK_PHASE(JVMTI_PHASE_LIVE)
2999 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3001 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
3002 return JVMTI_ERROR_INTERNAL;
3004 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
3005 max_frame_count, stack_info_ptr);
3007 if (er != JVMTI_ERROR_NONE) return er;
3009 return JVMTI_ERROR_NONE;
3013 /* GetThreadLocalStorage ******************************************************
3015 Get the value of the JVM TI thread-local storage.
3017 *******************************************************************************/
3020 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
3022 jvmtiThreadLocalStorage *tls;
3025 CHECK_PHASE(JVMTI_PHASE_START)
3026 CHECK_PHASE(JVMTI_PHASE_LIVE)
3030 thread = (jthread) THREADOBJECT;
3032 if (!builtin_instanceof(thread,class_java_lang_Thread))
3033 return JVMTI_ERROR_INVALID_THREAD;
3034 CHECK_THREAD_IS_ALIVE(thread);
3037 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3039 tls = ((environment*)env)->tls;
3040 while ((tls->thread != thread) && (tls != NULL)) {
3044 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3046 *data_ptr = tls->data;
3048 return JVMTI_ERROR_NONE;
3052 /* SetThreadLocalStorage *******************************************************
3054 Stores a pointer value associated with each environment-thread pair. The
3055 value is NULL unless set with this function. Agents can allocate memory in
3056 which they store thread specific information
3058 *******************************************************************************/
3061 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3063 jvmtiThreadLocalStorage *tls, *pre;
3064 environment* env = (environment*)jenv;
3067 CHECK_PHASE(JVMTI_PHASE_START)
3068 CHECK_PHASE(JVMTI_PHASE_LIVE)
3072 thread = (jthread) THREADOBJECT;
3074 if (!builtin_instanceof(thread,class_java_lang_Thread))
3075 return JVMTI_ERROR_INVALID_THREAD;
3076 CHECK_THREAD_IS_ALIVE(thread);
3079 if (env->tls == NULL) {
3080 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3083 while ((tls->thread != thread) && (tls->next != NULL)) {
3086 if (tls->thread != thread) {
3087 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3093 tls->data = (void*)data;
3095 /* remove current tls */
3097 while (pre->next == tls) pre = pre->next;
3098 pre->next = tls->next;
3100 return JVMTI_ERROR_NONE;
3104 /* *****************************************************************************
3108 *******************************************************************************/
3111 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3114 CHECK_PHASE(JVMTI_PHASE_START)
3115 CHECK_PHASE(JVMTI_PHASE_LIVE)
3117 CHECK_CAPABILITY(env,can_tag_objects)
3119 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3120 return JVMTI_ERROR_NONE;
3123 /* *****************************************************************************
3127 *******************************************************************************/
3130 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3133 CHECK_PHASE(JVMTI_PHASE_START)
3134 CHECK_PHASE(JVMTI_PHASE_LIVE)
3136 CHECK_CAPABILITY(env,can_tag_objects)
3138 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3139 return JVMTI_ERROR_NONE;
3143 /* ForceGarbageCollection *****************************************************
3145 Force boehm-gc to perform a garbage collection
3147 *******************************************************************************/
3150 ForceGarbageCollection (jvmtiEnv * env)
3153 CHECK_PHASE(JVMTI_PHASE_LIVE)
3158 return JVMTI_ERROR_NONE;
3162 /* IterateOverObjectsReachableFromObject **************************************
3166 *******************************************************************************/
3169 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3170 jvmtiObjectReferenceCallback
3171 object_reference_callback,
3175 CHECK_PHASE(JVMTI_PHASE_LIVE)
3177 CHECK_CAPABILITY(env,can_tag_objects)
3179 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3180 return JVMTI_ERROR_NONE;
3184 /* IterateOverReachableObjects ************************************************
3188 *******************************************************************************/
3191 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3193 jvmtiStackReferenceCallback
3195 jvmtiObjectReferenceCallback
3196 object_ref_callback, void *user_data)
3199 CHECK_PHASE(JVMTI_PHASE_LIVE)
3201 CHECK_CAPABILITY(env,can_tag_objects)
3203 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3204 return JVMTI_ERROR_NONE;
3208 /* IterateOverHeap ************************************************************
3212 *******************************************************************************/
3215 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3216 jvmtiHeapObjectCallback heap_object_callback,
3220 CHECK_PHASE(JVMTI_PHASE_LIVE)
3222 CHECK_CAPABILITY(env,can_tag_objects)
3224 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3225 return JVMTI_ERROR_NONE;
3229 /* IterateOverInstancesOfClass ************************************************
3233 *******************************************************************************/
3236 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3237 jvmtiHeapObjectFilter object_filter,
3238 jvmtiHeapObjectCallback
3239 heap_object_callback, void *user_data)
3242 CHECK_PHASE(JVMTI_PHASE_LIVE)
3244 CHECK_CAPABILITY(env,can_tag_objects)
3246 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3247 return JVMTI_ERROR_NONE;
3251 /* *****************************************************************************
3255 *******************************************************************************/
3258 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3259 jint * count_ptr, jobject ** object_result_ptr,
3260 jlong ** tag_result_ptr)
3263 CHECK_PHASE(JVMTI_PHASE_LIVE)
3265 CHECK_CAPABILITY(env,can_tag_objects)
3267 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3268 return JVMTI_ERROR_NONE;
3272 /* SetJNIFunctionTable **********************************************************
3274 Set the JNI function table in all current and future JNI environments
3276 *******************************************************************************/
3279 SetJNIFunctionTable (jvmtiEnv * env,
3280 const jniNativeInterface * function_table)
3283 CHECK_PHASE(JVMTI_PHASE_START)
3284 CHECK_PHASE(JVMTI_PHASE_LIVE)
3287 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3288 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3289 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3290 return JVMTI_ERROR_NONE;
3294 /* GetJNIFunctionTable *********************************************************
3296 Get the JNI function table. The JNI function table is copied into allocated
3299 *******************************************************************************/
3302 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3305 CHECK_PHASE(JVMTI_PHASE_START)
3306 CHECK_PHASE(JVMTI_PHASE_LIVE)
3309 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3310 *function_table = (jniNativeInterface*)
3311 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3312 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3313 return JVMTI_ERROR_NONE;
3317 /* SetEventCallbacks **********************************************************
3319 Set the functions to be called for each event. The callbacks are specified
3320 by supplying a replacement function table.
3322 *******************************************************************************/
3325 SetEventCallbacks (jvmtiEnv * env,
3326 const jvmtiEventCallbacks * callbacks,
3327 jint size_of_callbacks)
3330 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3331 CHECK_PHASE(JVMTI_PHASE_LIVE)
3334 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3337 if (callbacks == NULL) { /* remove the existing callbacks */
3338 memset(&(((environment* )env)->callbacks), 0,
3339 sizeof(jvmtiEventCallbacks));
3342 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3344 return JVMTI_ERROR_NONE;
3348 /* GenerateEvents *************************************************************
3350 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3351 the current state of the VM.
3353 *******************************************************************************/
3356 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3359 CHECK_PHASE(JVMTI_PHASE_LIVE)
3361 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3363 return JVMTI_ERROR_NONE;
3367 /* GetExtensionFunctions ******************************************************
3369 Returns the set of extension functions.
3371 *******************************************************************************/
3374 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3375 jvmtiExtensionFunctionInfo ** extensions)
3378 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3379 CHECK_PHASE(JVMTI_PHASE_LIVE)
3382 if ((extension_count_ptr == NULL)||(extensions == NULL))
3383 return JVMTI_ERROR_NULL_POINTER;
3385 /* cacao has no extended functions yet */
3386 *extension_count_ptr = 0;
3388 return JVMTI_ERROR_NONE;
3392 /* GetExtensionEvents *********************************************************
3394 Returns the set of extension events.
3396 *******************************************************************************/
3399 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3400 jvmtiExtensionEventInfo ** extensions)
3403 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3404 CHECK_PHASE(JVMTI_PHASE_LIVE)
3407 if ((extension_count_ptr == NULL)||(extensions == NULL))
3408 return JVMTI_ERROR_NULL_POINTER;
3410 /* cacao has no extended events yet */
3411 *extension_count_ptr = 0;
3413 return JVMTI_ERROR_NONE;
3417 /* SetExtensionEventCallback **************************************************
3419 Sets the callback function for an extension event and enables the event.
3421 *******************************************************************************/
3424 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3425 jvmtiExtensionEvent callback)
3428 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3429 CHECK_PHASE(JVMTI_PHASE_LIVE)
3432 /* cacao has no extended events yet */
3433 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3437 /* DisposeEnvironment **********************************************************
3439 Shutdown a JVM TI connection created with JNI GetEnv.
3441 *******************************************************************************/
3444 DisposeEnvironment (jvmtiEnv * env)
3446 environment* cacao_env = (environment*)env;
3447 environment* tenvs = envs;
3448 jvmtiThreadLocalStorage *jtls, *tjtls;
3450 if (tenvs != cacao_env) {
3451 while (tenvs->next != cacao_env) {
3452 tenvs = tenvs->next;
3454 tenvs->next = cacao_env->next;
3458 cacao_env->env=NULL;
3459 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3460 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3461 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3462 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3463 cacao_env->EnvironmentLocalStorage = NULL;
3465 jtls = cacao_env->tls;
3466 while (jtls != NULL) {
3471 cacao_env->tls = NULL;
3474 jvmti_cacaodbgserver_quit();
3476 /* let the GC do the rest */
3477 return JVMTI_ERROR_NONE;
3481 /* GetErrorName ***************************************************************
3483 Return the symbolic name for an error code.
3485 *******************************************************************************/
3487 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3488 memcpy(*name_ptr, &str, sizeof(str)); \
3492 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3494 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3497 case JVMTI_ERROR_NONE :
3498 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3499 case JVMTI_ERROR_NULL_POINTER :
3500 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3501 case JVMTI_ERROR_OUT_OF_MEMORY :
3502 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3503 case JVMTI_ERROR_ACCESS_DENIED :
3504 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3505 case JVMTI_ERROR_UNATTACHED_THREAD :
3506 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3507 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3508 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3509 case JVMTI_ERROR_WRONG_PHASE :
3510 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3511 case JVMTI_ERROR_INTERNAL :
3512 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3513 case JVMTI_ERROR_INVALID_PRIORITY :
3514 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3515 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3516 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3517 case JVMTI_ERROR_THREAD_SUSPENDED :
3518 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3519 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3520 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3521 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3522 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3523 case JVMTI_ERROR_NO_MORE_FRAMES :
3524 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3525 case JVMTI_ERROR_OPAQUE_FRAME :
3526 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3527 case JVMTI_ERROR_DUPLICATE :
3528 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3529 case JVMTI_ERROR_NOT_FOUND :
3530 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3531 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3532 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3533 case JVMTI_ERROR_INTERRUPT :
3534 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3535 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3536 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3537 case JVMTI_ERROR_NOT_AVAILABLE :
3538 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3539 case JVMTI_ERROR_ABSENT_INFORMATION :
3540 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3541 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3542 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3543 case JVMTI_ERROR_NATIVE_METHOD :
3544 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3545 case JVMTI_ERROR_INVALID_THREAD :
3546 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3547 case JVMTI_ERROR_INVALID_FIELDID :
3548 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3549 case JVMTI_ERROR_INVALID_METHODID :
3550 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3551 case JVMTI_ERROR_INVALID_LOCATION :
3552 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3553 case JVMTI_ERROR_INVALID_OBJECT :
3554 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3555 case JVMTI_ERROR_INVALID_CLASS :
3556 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3557 case JVMTI_ERROR_TYPE_MISMATCH :
3558 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3559 case JVMTI_ERROR_INVALID_SLOT :
3560 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3561 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3562 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3563 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3564 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3565 case JVMTI_ERROR_INVALID_MONITOR :
3566 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3567 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3568 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3569 case JVMTI_ERROR_INVALID_TYPESTATE :
3570 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3571 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3572 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3573 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3574 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3575 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3576 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3577 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3578 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3579 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3580 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3581 case JVMTI_ERROR_FAILS_VERIFICATION :
3582 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3583 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3584 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3585 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3586 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3587 case JVMTI_ERROR_NAMES_DONT_MATCH :
3588 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3589 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3590 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3591 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3592 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3594 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3596 return JVMTI_ERROR_NONE;
3599 /* GetJLocationFormat **********************************************************
3601 This function describes the representation of jlocation used in this VM.
3603 *******************************************************************************/
3606 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3608 *format_ptr = JVMTI_JLOCATION_OTHER;
3609 return JVMTI_ERROR_NONE;
3613 /* GetSystemProperties ********************************************************
3615 The list of VM system property keys which may be used with GetSystemProperty
3618 *******************************************************************************/
3621 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3623 jmethodID mid, moremid;
3624 classinfo *sysclass, *propclass, *enumclass;
3625 java_objectheader *sysprop, *keys, *obj;
3630 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3631 CHECK_PHASE(JVMTI_PHASE_LIVE)
3634 if ((count_ptr == NULL) || (property_ptr == NULL))
3635 return JVMTI_ERROR_NULL_POINTER;
3637 sysclass = load_class_from_sysloader(
3638 utf_new_char_classname ("java/lang/System"));
3640 if (!sysclass) throw_main_exception_exit();
3642 mid = (jmethodID)class_resolvemethod(sysclass,
3643 utf_new_char("getProperties"),
3644 utf_new_char("()Ljava/util/Properties;"));
3645 if (!mid) throw_main_exception_exit();
3648 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3649 if (!sysprop) throw_main_exception_exit();
3651 propclass = sysprop->vftbl->class;
3653 mid = (jmethodID)class_resolvemethod(propclass,
3654 utf_new_char("size"),
3655 utf_new_char("()I"));
3656 if (!mid) throw_main_exception_exit();
3659 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3660 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3662 mid = (jmethodID)class_resolvemethod(propclass,
3663 utf_new_char("keys"),
3664 utf_new_char("()Ljava/util/Enumeration;"));
3665 if (!mid) throw_main_exception_exit();
3667 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3668 enumclass = keys->vftbl->class;
3670 moremid = (jmethodID)class_resolvemethod(enumclass,
3671 utf_new_char("hasMoreElements"),
3672 utf_new_char("()Z"));
3673 if (!moremid) throw_main_exception_exit();
3675 mid = (jmethodID)class_resolvemethod(propclass,
3676 utf_new_char("nextElement"),
3677 utf_new_char("()Ljava/lang/Object;"));
3678 if (!mid) throw_main_exception_exit();
3681 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3682 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3683 ch = javastring_tochar(obj);
3684 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3685 memcpy(*property_ptr[i], ch, strlen (ch));
3686 MFREE(ch,char,strlen(ch)+1);
3690 return JVMTI_ERROR_NONE;
3694 /* GetSystemProperty **********************************************************
3696 Return a VM system property value given the property key.
3698 *******************************************************************************/
3701 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3704 classinfo *sysclass, *propclass;
3705 java_objectheader *sysprop, *obj;
3709 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3710 CHECK_PHASE(JVMTI_PHASE_LIVE)
3713 if ((value_ptr == NULL) || (property == NULL))
3714 return JVMTI_ERROR_NULL_POINTER;
3716 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3717 if (!sysclass) throw_main_exception_exit();
3719 mid = (jmethodID)class_resolvemethod(sysclass,
3720 utf_new_char("getProperties"),
3721 utf_new_char("()Ljava/util/Properties;"));
3722 if (!mid) throw_main_exception_exit();
3724 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3726 propclass = sysprop->vftbl->class;
3728 mid = (jmethodID)class_resolvemethod(propclass,
3729 utf_new_char("getProperty"),
3730 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3731 if (!mid) throw_main_exception_exit();
3733 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3734 NULL, sysprop, mid, javastring_new_from_ascii(property));
3735 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3737 ch = javastring_tochar(obj);
3738 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3739 memcpy(*value_ptr, ch, strlen (ch));
3740 MFREE(ch,char,strlen(ch)+1);
3742 return JVMTI_ERROR_NONE;
3746 /* SetSystemProperty **********************************************************
3748 Set a VM system property value.
3750 *******************************************************************************/
3753 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3756 classinfo *sysclass, *propclass;
3757 java_objectheader *sysprop;
3760 CHECK_PHASE(JVMTI_PHASE_START)
3763 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3764 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3766 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3767 if (!sysclass) throw_main_exception_exit();
3769 mid = (jmethodID)class_resolvemethod(sysclass,
3770 utf_new_char("getProperties"),
3771 utf_new_char("()Ljava/util/Properties;"));
3772 if (!mid) throw_main_exception_exit();
3774 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3776 propclass = sysprop->vftbl->class;
3778 mid = (jmethodID)class_resolvemethod(propclass,
3779 utf_new_char("setProperty"),
3780 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3781 if (!mid) throw_main_exception_exit();
3783 _Jv_JNINativeInterface.CallObjectMethod(
3784 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3786 return JVMTI_ERROR_NONE;
3789 /* GetPhase ********************************************************************
3791 Return the current phase of VM execution
3793 *******************************************************************************/
3796 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3798 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3802 return JVMTI_ERROR_NONE;
3805 /* GetCurrentThreadCpuTimerInfo ************************************************
3809 *******************************************************************************/
3812 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3815 CHECK_PHASE(JVMTI_PHASE_START)
3816 CHECK_PHASE(JVMTI_PHASE_LIVE)
3818 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3820 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3822 return JVMTI_ERROR_NONE;
3825 /* GetCurrentThreadCpuTime ****************************************************
3829 *******************************************************************************/
3832 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3835 CHECK_PHASE(JVMTI_PHASE_START)
3836 CHECK_PHASE(JVMTI_PHASE_LIVE)
3838 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3840 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3841 return JVMTI_ERROR_NONE;
3844 /* GetThreadCpuTimerInfo ******************************************************
3848 *******************************************************************************/
3851 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3854 CHECK_PHASE(JVMTI_PHASE_START)
3855 CHECK_PHASE(JVMTI_PHASE_LIVE)
3857 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3859 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3860 return JVMTI_ERROR_NONE;
3863 /* GetThreadCpuTime ***********************************************************
3867 *******************************************************************************/
3870 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3873 CHECK_PHASE(JVMTI_PHASE_LIVE)
3875 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3876 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3877 return JVMTI_ERROR_NONE;
3880 /* GetTimerInfo ***************************************************************
3882 Get information about the GetTime timer.
3884 *******************************************************************************/
3887 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3889 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3891 info_ptr->max_value = !0x0;
3892 info_ptr->may_skip_forward = true;
3893 info_ptr->may_skip_backward = true;
3894 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3896 return JVMTI_ERROR_NONE;
3899 /* GetTime ********************************************************************
3901 Return the current value of the system timer, in nanoseconds
3903 *******************************************************************************/
3906 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3908 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3911 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3913 if (gettimeofday (&tp, NULL) == -1)
3914 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3916 *nanos_ptr = (jlong) tp.tv_sec;
3918 *nanos_ptr += (tp.tv_usec / 1000);
3920 return JVMTI_ERROR_NONE;
3923 /* GetPotentialCapabilities ***************************************************
3925 Returns the JVM TI features that can potentially be possessed by this
3926 environment at this time.
3928 *******************************************************************************/
3931 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3934 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3935 CHECK_PHASE(JVMTI_PHASE_LIVE)
3938 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3940 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3942 return JVMTI_ERROR_NONE;
3946 #define CHECK_ADD_CAPABILITY(env,CAN) \
3947 if (capabilities_ptr->CAN == 1) { \
3948 if (JVMTI_Capabilities.CAN == 0) \
3949 return JVMTI_ERROR_NOT_AVAILABLE; \
3951 env->capabilities.CAN = 1; \
3954 /* AddCapabilities ************************************************************
3956 Set new capabilities by adding the capabilities pointed to by
3957 capabilities_ptr. All previous capabilities are retained.
3959 *******************************************************************************/
3962 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3964 environment* cacao_env;
3967 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3968 CHECK_PHASE(JVMTI_PHASE_LIVE)
3971 if ((env == NULL) || (capabilities_ptr == NULL))
3972 return JVMTI_ERROR_NULL_POINTER;
3974 cacao_env = (environment*)env;
3976 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3977 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3978 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3979 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3980 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3981 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3982 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3983 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3984 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3985 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3986 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3987 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3988 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3989 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3990 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3991 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3992 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3993 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3994 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3995 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3996 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3997 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3998 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3999 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4000 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
4001 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
4002 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4003 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4004 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
4005 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4006 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4007 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4008 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
4011 return JVMTI_ERROR_NONE;
4015 #define CHECK_DEL_CAPABILITY(env,CAN) \
4016 if (capabilities_ptr->CAN == 1) \
4017 env->capabilities.CAN = 0;
4019 /* RelinquishCapabilities *****************************************************
4021 Relinquish the capabilities pointed to by capabilities_ptr.
4023 *******************************************************************************/
4026 RelinquishCapabilities (jvmtiEnv * env,
4027 const jvmtiCapabilities * capabilities_ptr)
4029 environment* cacao_env;
4032 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4033 CHECK_PHASE(JVMTI_PHASE_LIVE)
4036 if ((env == NULL) || (capabilities_ptr == NULL))
4037 return JVMTI_ERROR_NULL_POINTER;
4039 cacao_env = (environment*)env;
4041 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
4042 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4043 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4044 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4045 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4046 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4047 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4048 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4049 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4050 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4051 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4052 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4053 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4054 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4055 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4056 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4057 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4058 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4059 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4060 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4061 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4062 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4063 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4064 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4065 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4066 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4067 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4068 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4069 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4070 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4071 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4072 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4073 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4075 return JVMTI_ERROR_NONE;
4078 /* GetAvailableProcessors *****************************************************
4080 Get number of processors available to the virtual machine.
4082 *******************************************************************************/
4085 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4088 CHECK_PHASE(JVMTI_PHASE_START)
4089 CHECK_PHASE(JVMTI_PHASE_LIVE)
4092 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4094 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4096 *processor_count_ptr = 1; /* where do I get this ?*/
4098 return JVMTI_ERROR_NONE;
4101 /* GetEnvironmentLocalStorage **************************************************
4103 Called by the agent to get the value of the JVM TI environment-local storage.
4105 *******************************************************************************/
4108 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4110 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4112 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4114 return JVMTI_ERROR_NONE;
4117 /* SetEnvironmentLocalStorage **************************************************
4119 The VM stores a pointer value associated with each environment. Agents can
4120 allocate memory in which they store environment specific information.
4122 *******************************************************************************/
4125 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4127 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4129 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4131 return JVMTI_ERROR_NONE;
4134 /* AddToBootstrapClassLoaderSearch ********************************************
4136 After the bootstrap class loader unsuccessfully searches for a class, the
4137 specified platform-dependent search path segment will be searched as well.
4139 *******************************************************************************/
4142 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4148 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4151 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4153 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4154 tmp_bcp = MNEW(char, ln);
4155 strcat(tmp_bcp, bootclasspath);
4156 strcat(tmp_bcp, ":");
4157 strcat(tmp_bcp, segment);
4158 MFREE(bootclasspath,char,ln);
4159 bootclasspath = tmp_bcp;
4161 return JVMTI_ERROR_NONE;
4164 /* SetVerboseFlag *************************************************************
4166 Control verbose output. This is the output which typically is sent to stderr
4168 *******************************************************************************/
4171 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4174 case JVMTI_VERBOSE_OTHER:
4175 /* where is this defined ?
4179 case JVMTI_VERBOSE_GC:
4180 opt_verbosegc = value;
4182 case JVMTI_VERBOSE_CLASS:
4183 loadverbose = value;
4185 case JVMTI_VERBOSE_JNI:
4188 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4190 return JVMTI_ERROR_NONE;
4193 /* GetObjectSize **************************************************************
4195 For the object object return the size.
4197 *******************************************************************************/
4200 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4203 CHECK_PHASE(JVMTI_PHASE_START)
4204 CHECK_PHASE(JVMTI_PHASE_LIVE)
4207 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4208 if (!builtin_instanceof(object,class_java_lang_Object))
4209 return JVMTI_ERROR_INVALID_OBJECT;
4211 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4213 return JVMTI_ERROR_NONE;
4217 /* *****************************************************************************
4219 Environment variables
4221 *******************************************************************************/
4223 static jvmtiCapabilities JVMTI_Capabilities = {
4224 0, /* can_tag_objects */
4225 0, /* can_generate_field_modification_events */
4226 0, /* can_generate_field_access_events */
4227 1, /* can_get_bytecodes */
4228 0, /* can_get_synthetic_attribute */
4230 #if defined(ENABLE_THREADS)
4231 1, /* can_get_owned_monitor_info */
4232 1, /* can_get_current_contended_monitor */
4234 0, /* can_get_owned_monitor_info */
4235 0, /* can_get_current_contended_monitor */
4238 0, /* can_get_monitor_info */
4239 0, /* can_pop_frame */
4240 0, /* can_redefine_classes */
4241 0, /* can_signal_thread */
4242 1, /* can_get_source_file_name */
4243 1, /* can_get_line_numbers */
4244 0, /* can_get_source_debug_extension */
4245 0, /* can_access_local_variables */
4246 0, /* can_maintain_original_method_order */
4247 0, /* can_generate_single_step_events */
4248 1, /* can_generate_exception_events */
4249 0, /* can_generate_frame_pop_events */
4250 1, /* can_generate_breakpoint_events */
4251 1, /* can_suspend */
4252 0, /* can_redefine_any_class */
4253 0, /* can_get_current_thread_cpu_time */
4254 0, /* can_get_thread_cpu_time */
4255 1, /* can_generate_method_entry_events */
4256 0, /* can_generate_method_exit_events */
4257 0, /* can_generate_all_class_hook_events */
4258 0, /* can_generate_compiled_method_load_events */
4259 1, /* can_generate_monitor_events */
4260 0, /* can_generate_vm_object_alloc_events */
4261 0, /* can_generate_native_method_bind_events */
4262 0, /* can_generate_garbage_collection_events */
4263 0, /* can_generate_object_free_events */
4266 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4268 &SetEventNotificationMode,
4276 &GetOwnedMonitorInfo,
4277 &GetCurrentContendedMonitor,
4279 &GetTopThreadGroups,
4280 &GetThreadGroupInfo,
4281 &GetThreadGroupChildren,
4303 &RawMonitorNotifyAll,
4307 &SetFieldAccessWatch,
4308 &ClearFieldAccessWatch,
4309 &SetFieldModificationWatch,
4310 &ClearFieldModificationWatch,
4320 &GetImplementedInterfaces,
4325 &GetObjectMonitorUsage,
4327 &GetFieldDeclaringClass,
4331 &GetMethodDeclaringClass,
4332 &GetMethodModifiers,
4336 &GetLineNumberTable,
4338 &GetLocalVariableTable,
4345 &GetClassLoaderClasses,
4356 &GetSourceDebugExtension,
4367 &GetThreadListStackTraces,
4368 &GetThreadLocalStorage,
4369 &SetThreadLocalStorage,
4374 &ForceGarbageCollection,
4375 &IterateOverObjectsReachableFromObject,
4376 &IterateOverReachableObjects,
4378 &IterateOverInstancesOfClass,
4380 &GetObjectsWithTags,
4386 &SetJNIFunctionTable,
4387 &GetJNIFunctionTable,
4390 &GetExtensionFunctions,
4391 &GetExtensionEvents,
4392 &SetExtensionEventCallback,
4393 &DisposeEnvironment,
4395 &GetJLocationFormat,
4396 &GetSystemProperties,
4400 &GetCurrentThreadCpuTimerInfo,
4401 &GetCurrentThreadCpuTime,
4402 &GetThreadCpuTimerInfo,
4406 &GetPotentialCapabilities,
4409 &RelinquishCapabilities,
4410 &GetAvailableProcessors,
4413 &GetEnvironmentLocalStorage,
4414 &SetEnvironmentLocalStorage,
4415 &AddToBootstrapClassLoaderSearch,
4423 /* jvmti_set_phase ************************************************************
4425 sets a new jvmti phase a fires an apropriate event.
4427 *******************************************************************************/
4429 void jvmti_set_phase(jvmtiPhase p) {
4432 fprintf (stderr,"set JVMTI phase %d\n",p);
4436 case JVMTI_PHASE_ONLOAD:
4439 case JVMTI_PHASE_PRIMORDIAL:
4442 case JVMTI_PHASE_START:
4444 d.ev = JVMTI_EVENT_VM_START;
4446 case JVMTI_PHASE_LIVE:
4448 d.ev = JVMTI_EVENT_VM_INIT;
4449 jvmti_fireEvent(&d);
4450 /* thread start event for main thread */
4451 d.ev = JVMTI_EVENT_THREAD_START;
4453 case JVMTI_PHASE_DEAD:
4455 d.ev = JVMTI_EVENT_VM_DEATH;
4458 log_text("wrong jvmti phase to be set");
4462 jvmti_fireEvent(&d);
4466 /* jvmti_new_environment ******************************************************
4468 creates a new JVMTI environment
4470 *******************************************************************************/
4472 jvmtiEnv* jvmti_new_environment() {
4476 envs = heap_allocate(sizeof(environment),true,NULL);
4480 while (env->next != NULL) env = env->next;
4481 env->next = heap_allocate(sizeof(environment),true,NULL);
4485 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4486 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4487 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4488 sizeof(jvmtiEventModeLL));
4489 /* To possess a capability, the agent must add the capability.*/
4490 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4491 RelinquishCapabilities(&(env->env),&(env->capabilities));
4492 env->EnvironmentLocalStorage = NULL;
4495 /* initialize cacao debugging facilities */
4496 jvmti_cacao_debug_init();
4498 return (jvmtiEnv*)env;
4501 /* jvmti_agentload ************************************************************
4503 loads the indicated shared library containing the jvmti agent and calls the
4504 Agent_OnLoad function.
4506 *******************************************************************************/
4508 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4514 len = strlen(opt_arg);
4516 /* separate argumtents */
4517 while ((opt_arg[i] != '=') && (i<len)) i++;
4519 arg = &opt_arg[i+1];
4525 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4526 strncpy(*libname,opt_arg,i);
4530 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4531 strncpy(*libname,"lib",3);
4532 strncpy(&(*libname)[3],opt_arg,i);
4533 strncpy(&(*libname)[i+3],".so",3);
4536 /* try to open the library */
4538 if (!(*handle = lt_dlopen(*libname))) {
4539 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4543 /* resolve Agent_OnLoad function */
4544 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4545 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4549 /* resolve Agent_UnLoad function */
4550 unload = lt_dlsym(*handle, "Agent_Unload");
4553 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4554 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4556 if (retval != 0) exit (retval);
4559 /* jvmti_agentunload **********************************************************
4561 calls the Agent_UnLoad function in the jvmti agent if present.
4563 *******************************************************************************/
4565 void jvmti_agentunload() {
4566 if (unload != NULL) {
4567 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4568 ((JavaVM*) &_Jv_JNIInvokeInterface);
4574 * These are local overrides for various environment variables in Emacs.
4575 * Please do not remove this and leave it at the end of the file, where
4576 * Emacs will automagically detect them.
4577 * ---------------------------------------------------------------------
4580 * indent-tabs-mode: t
4584 * vim:noexpandtab:sw=4:ts=4: