1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006, 2007 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
33 #include <linux/unistd.h>
36 #include <sys/types.h>
41 #include "native/jni.h"
42 #include "native/native.h"
43 #include "native/jvmti/cacaodbg.h"
44 #include "native/jvmti/jvmti.h"
45 #include "vm/jit/stacktrace.h"
46 #include "vm/global.h"
47 #include "vm/loader.h"
48 #include "vm/builtin.h"
49 #include "vm/jit/asmpart.h"
51 #include "vm/classcache.h"
52 #include "mm/gc-common.h"
53 #include "toolbox/logging.h"
54 #include "vm/options.h"
55 #include "vm/stringlocal.h"
56 #include "mm/memory.h"
57 #include "threads/native/threads.h"
58 #include "threads/native/lock.h"
59 #include "vm/exceptions.h"
60 #include "native/include/java_util_Vector.h"
61 #include "native/include/java_io_PrintStream.h"
62 #include "native/include/java_io_InputStream.h"
63 #include "native/include/java_lang_Cloneable.h"
64 #include "native/include/java_lang_ThreadGroup.h"
65 #include "native/include/java_lang_VMObject.h"
66 #include "native/include/java_lang_VMSystem.h"
67 #include "native/include/java_lang_VMClass.h"
69 #include "boehm-gc/include/gc.h"
71 #if defined(ENABLE_THREADS)
72 #include "threads/native/threads.h"
80 typedef struct _environment environment;
81 static environment *envs=NULL;
82 pthread_mutex_t dbgcomlock;
84 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
86 static jvmtiPhase phase;
87 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
88 struct _jvmtiEventModeLL {
91 jvmtiEventModeLL *next;
94 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
95 struct _jvmtiThreadLocalStorage{
98 jvmtiThreadLocalStorage *next;
101 struct _environment {
104 jvmtiEventCallbacks callbacks;
105 /* table for enabled/disabled jvmtiEvents - first element contains global
107 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
108 jvmtiCapabilities capabilities;
109 void *EnvironmentLocalStorage;
110 jvmtiThreadLocalStorage *tls;
113 static struct jvmtiEnv_struct JVMTI_EnvTable;
114 static jvmtiCapabilities JVMTI_Capabilities;
115 static lt_ptr unload;
117 #define CHECK_PHASE_START if (!(false
118 #define CHECK_PHASE(chkphase) || (phase == chkphase)
119 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
120 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
121 env)->capabilities.CAP == 0) \
122 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
123 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
124 JVMTI_ERROR_THREAD_NOT_ALIVE) \
125 return JVMTI_ERROR_THREAD_NOT_ALIVE;
130 /* check_thread_is_alive *******************************************************
132 checks if the given thread is alive
134 *******************************************************************************/
135 static jvmtiError check_thread_is_alive(jthread t) {
136 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
137 if(((java_lang_Thread*) t)->vmThread == NULL)
138 return JVMTI_ERROR_THREAD_NOT_ALIVE;
139 return JVMTI_ERROR_NONE;
142 /* execute_callback ************************************************************
144 executes the registerd callbacks for the given jvmti event with parameter
145 in the data structure.
147 *******************************************************************************/
148 static void execute_callback(jvmtiEvent e, functionptr ec,
149 genericEventData* data) {
150 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
152 fprintf(stderr,"execcallback called (event: %d)\n",e);
155 case JVMTI_EVENT_VM_INIT:
156 if (phase != JVMTI_PHASE_LIVE) return;
157 case JVMTI_EVENT_THREAD_START:
158 case JVMTI_EVENT_THREAD_END:
159 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
160 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
163 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
164 if ((phase == JVMTI_PHASE_START) ||
165 (phase == JVMTI_PHASE_LIVE) ||
166 (phase == JVMTI_PHASE_PRIMORDIAL))
167 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
172 data->protection_domain,
175 data->new_class_data_len,
176 data->new_class_data);
178 /* if class data has been modified use it as class data for other agents
179 waiting for the same event */
180 if (data->new_class_data != NULL) {
181 data->jint1 = *(data->new_class_data_len);
182 data->class_data = *(data->new_class_data);
187 case JVMTI_EVENT_CLASS_PREPARE:
188 case JVMTI_EVENT_CLASS_LOAD:
189 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
190 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
191 data->thread, data->klass);
194 case JVMTI_EVENT_VM_DEATH:
195 if (phase != JVMTI_PHASE_LIVE) return;
196 case JVMTI_EVENT_VM_START:
197 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
198 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
201 case JVMTI_EVENT_NATIVE_METHOD_BIND:
202 if ((phase == JVMTI_PHASE_START) ||
203 (phase == JVMTI_PHASE_LIVE) ||
204 (phase == JVMTI_PHASE_PRIMORDIAL))
205 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
209 data->new_address_ptr);
213 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
214 if ((phase == JVMTI_PHASE_START) ||
215 (phase == JVMTI_PHASE_LIVE) ||
216 (phase == JVMTI_PHASE_PRIMORDIAL))
217 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
226 if (phase != JVMTI_PHASE_LIVE) return;
228 case JVMTI_EVENT_EXCEPTION:
229 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
235 data->catch_location);
238 case JVMTI_EVENT_EXCEPTION_CATCH:
239 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
246 case JVMTI_EVENT_BREAKPOINT:
247 case JVMTI_EVENT_SINGLE_STEP:
248 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
254 case JVMTI_EVENT_FRAME_POP:
255 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
262 case JVMTI_EVENT_FIELD_ACCESS:
263 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
272 case JVMTI_EVENT_FIELD_MODIFICATION:
274 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
281 data->signature_type,
285 case JVMTI_EVENT_METHOD_ENTRY:
286 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
291 case JVMTI_EVENT_METHOD_EXIT:
292 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
299 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
300 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
309 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
310 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
315 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
316 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
317 case JVMTI_EVENT_DATA_DUMP_REQUEST:
318 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
321 case JVMTI_EVENT_MONITOR_WAIT:
322 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
328 case JVMTI_EVENT_MONITOR_WAITED:
329 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
336 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
337 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
338 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
343 case JVMTI_EVENT_OBJECT_FREE:
344 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
347 case JVMTI_EVENT_VM_OBJECT_ALLOC:
348 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
355 log_text ("unknown event");
362 /* dofireEvent ******************************************************************
364 sends event if it is enabled either globally or for some threads
366 *******************************************************************************/
367 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
369 jvmtiEventModeLL *evm;
373 while (env != NULL) {
374 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
375 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
376 /* test if the event is enable for some threads */
377 while (evm != NULL) {
378 if (evm->mode == JVMTI_ENABLE) {
380 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
382 data->jvmti_env=&env->env;
383 execute_callback(e, ec, data);
388 } else { /* event enabled globally */
389 data->jvmti_env=&env->env;
390 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
391 if (ec != NULL) execute_callback(e, ec, data);
399 /* fireEvent ******************************************************************
401 fire event callback with data arguments. This function mainly fills the
404 *******************************************************************************/
405 void jvmti_fireEvent(genericEventData* d) {
407 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
409 if (d->ev == JVMTI_EVENT_VM_START)
412 thread = jvmti_get_current_thread();
416 dofireEvent(d->ev,d);
420 /* SetEventNotificationMode ****************************************************
422 Control the generation of events
424 *******************************************************************************/
427 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
428 jvmtiEvent event_type, jthread event_thread, ...)
430 environment* cacao_env;
431 jvmtiEventModeLL *ll;
434 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
435 CHECK_PHASE(JVMTI_PHASE_LIVE)
438 if(event_thread != NULL) {
439 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
440 return JVMTI_ERROR_INVALID_THREAD;
441 CHECK_THREAD_IS_ALIVE(event_thread);
444 cacao_env = (environment*) env;
445 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
446 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
448 switch (event_type) { /* check capability and set system breakpoint */
449 case JVMTI_EVENT_EXCEPTION:
450 case JVMTI_EVENT_EXCEPTION_CATCH:
451 CHECK_CAPABILITY(env,can_generate_exception_events)
453 case JVMTI_EVENT_SINGLE_STEP:
454 CHECK_CAPABILITY(env,can_generate_single_step_events)
456 case JVMTI_EVENT_FRAME_POP:
457 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
459 case JVMTI_EVENT_BREAKPOINT:
460 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
462 case JVMTI_EVENT_FIELD_ACCESS:
463 CHECK_CAPABILITY(env,can_generate_field_access_events)
465 case JVMTI_EVENT_FIELD_MODIFICATION:
466 CHECK_CAPABILITY(env,can_generate_field_modification_events)
468 case JVMTI_EVENT_METHOD_ENTRY:
469 CHECK_CAPABILITY(env,can_generate_method_entry_events)
471 case JVMTI_EVENT_METHOD_EXIT:
472 CHECK_CAPABILITY(env, can_generate_method_exit_events)
474 case JVMTI_EVENT_NATIVE_METHOD_BIND:
475 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
477 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
478 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
479 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
481 case JVMTI_EVENT_MONITOR_WAIT:
482 case JVMTI_EVENT_MONITOR_WAITED:
483 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
484 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
485 CHECK_CAPABILITY(env,can_generate_monitor_events)
487 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
488 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
489 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
491 case JVMTI_EVENT_OBJECT_FREE:
492 CHECK_CAPABILITY(env,can_generate_object_free_events)
494 case JVMTI_EVENT_VM_OBJECT_ALLOC:
495 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
498 /* all other events are required */
499 if ((event_type < JVMTI_EVENT_START_ENUM) ||
500 (event_type > JVMTI_EVENT_END_ENUM))
501 return JVMTI_ERROR_INVALID_EVENT_TYPE;
506 if (event_thread != NULL) {
507 /* thread level control */
508 if ((JVMTI_EVENT_VM_INIT == mode) ||
509 (JVMTI_EVENT_VM_DEATH == mode) ||
510 (JVMTI_EVENT_VM_START == mode) ||
511 (JVMTI_EVENT_THREAD_START == mode) ||
512 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
513 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
514 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
515 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
516 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
517 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
518 while (ll->next != NULL) {
520 if (ll->event_thread == event_thread) {
522 return JVMTI_ERROR_NONE;
525 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
529 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
533 return JVMTI_ERROR_NONE;
536 /* GetAllThreads ***************************************************************
540 *******************************************************************************/
543 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
544 jthread ** threads_ptr)
546 threadobject** threads;
551 CHECK_PHASE(JVMTI_PHASE_LIVE)
554 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
555 return JVMTI_ERROR_NULL_POINTER;
557 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
558 if (retval != JVMTI_ERROR_NONE) return retval;
561 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
563 for (i=0; i<*threads_count_ptr; i++)
564 (*threads_ptr)[i] = threads[i]->o.thread;
566 return JVMTI_ERROR_NONE;
570 /* SuspendThread ***************************************************************
572 Suspend specified thread
574 *******************************************************************************/
577 SuspendThread (jvmtiEnv * env, jthread thread)
580 CHECK_PHASE(JVMTI_PHASE_LIVE)
582 CHECK_CAPABILITY(env,can_suspend);
584 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
585 if (!builtin_instanceof(thread,class_java_lang_Thread))
586 return JVMTI_ERROR_INVALID_THREAD;
587 CHECK_THREAD_IS_ALIVE(thread);
589 /* threads_suspend_thread will implement suspend
590 threads_suspend_thread (
591 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
593 return JVMTI_ERROR_NONE;
596 /* ResumeThread ***************************************************************
598 Resume a suspended thread
600 *******************************************************************************/
603 ResumeThread (jvmtiEnv * env, jthread thread)
606 CHECK_PHASE(JVMTI_PHASE_LIVE)
608 CHECK_CAPABILITY(env,can_suspend);
610 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
611 if (!builtin_instanceof(thread,class_java_lang_Thread))
612 return JVMTI_ERROR_INVALID_THREAD;
613 CHECK_THREAD_IS_ALIVE(thread);
615 /* threads_resume_thread will implement resume
616 threads_resume_thread (
617 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
619 return JVMTI_ERROR_NONE;
622 /* StopThread *****************************************************************
624 Send asynchronous exception to the specified thread. Similar to
625 java.lang.Thread.stop(). Used to kill thread.
627 *******************************************************************************/
630 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
633 CHECK_PHASE(JVMTI_PHASE_LIVE)
635 CHECK_CAPABILITY(env,can_signal_thread);
637 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
638 return JVMTI_ERROR_NOT_AVAILABLE;
640 return JVMTI_ERROR_NONE;
643 /* InterruptThread ************************************************************
645 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
647 *******************************************************************************/
650 InterruptThread (jvmtiEnv * env, jthread thread)
653 CHECK_PHASE(JVMTI_PHASE_LIVE)
655 CHECK_CAPABILITY(env,can_signal_thread)
657 #if defined(ENABLE_THREADS)
658 if(!builtin_instanceof(thread,class_java_lang_Thread))
659 return JVMTI_ERROR_INVALID_THREAD;
661 CHECK_THREAD_IS_ALIVE(thread);
663 threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
666 return JVMTI_ERROR_NONE;
668 return JVMTI_ERROR_NOT_AVAILABLE;
672 /* GetThreadInfo ***************************************************************
674 Get thread information. Details of the specified thread are stored in the
675 jvmtiThreadInfo structure.
677 *******************************************************************************/
680 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
683 java_lang_Thread* th = (java_lang_Thread*)t;
687 CHECK_PHASE(JVMTI_PHASE_LIVE)
690 info_ptr->priority=(jint)th->priority;
691 info_ptr->is_daemon=(jboolean)th->daemon;
692 info_ptr->thread_group=(jthreadGroup)th->group;
693 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
695 name = javastring_toutf(th->name,false);
696 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
697 utf_sprint_convert_to_latin1(info_ptr->name, name);
699 return JVMTI_ERROR_NONE;
702 /* GetOwnedMonitorInfo *********************************************************
704 Gets all monitors owned by the specified thread
706 *******************************************************************************/
709 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
710 jint * owned_monitor_count_ptr,
711 jobject ** owned_monitors_ptr)
714 java_objectheader **om;
715 lock_record_pool_t* lrp;
719 CHECK_PHASE(JVMTI_PHASE_LIVE)
721 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
723 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
724 return JVMTI_ERROR_NULL_POINTER;
726 if (thread == NULL) {
727 t = jvmti_get_current_thread();
729 if(!builtin_instanceof(thread,class_java_lang_Thread))
730 return JVMTI_ERROR_INVALID_THREAD;
732 CHECK_THREAD_IS_ALIVE(thread);
733 t = (threadobject*) thread;
736 #if defined(ENABLE_THREADS)
738 om=MNEW(java_objectheader*,size);
740 pthread_mutex_lock(&lock_global_pool_lock);
741 lrp=lock_global_pool;
743 /* iterate over all lock record pools */
744 while (lrp != NULL) {
745 /* iterate over every lock record in a pool */
746 for (j=0; j<lrp->header.size; j++) {
747 /* if the lock record is owned by the given thread add it to
749 if(lrp->lr[j].owner == t) {
751 MREALLOC(om, java_objectheader*, size, size * 2);
754 om[i] = lrp->lr[j].obj;
758 lrp=lrp->header.next;
761 pthread_mutex_unlock(&lock_global_pool_lock);
763 *owned_monitors_ptr =
764 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
765 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
766 MFREE(om, java_objectheader*, size);
768 *owned_monitor_count_ptr = i;
772 return JVMTI_ERROR_NONE;
775 /* GetCurrentContendedMonitor *************************************************
777 Get the object the specified thread waits for.
779 *******************************************************************************/
782 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
783 jobject * monitor_ptr)
786 lock_record_pool_t* lrp;
788 lock_waiter_t* waiter;
791 CHECK_PHASE(JVMTI_PHASE_LIVE)
793 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
795 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
798 if (thread == NULL) {
799 t = jvmti_get_current_thread();
801 if(!builtin_instanceof(thread,class_java_lang_Thread))
802 return JVMTI_ERROR_INVALID_THREAD;
804 CHECK_THREAD_IS_ALIVE(thread);
805 t = (threadobject*) thread;
808 #if defined(ENABLE_THREADS)
810 pthread_mutex_lock(&lock_global_pool_lock);
812 lrp=lock_global_pool;
814 /* iterate over all lock record pools */
815 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
816 /* iterate over every lock record in a pool */
817 for (j=0; j<lrp->header.size; j++) {
818 /* iterate over every thread that is wait on this lock record */
819 waiter = lrp->lr[j].waiters;
820 while (waiter != NULL)
821 /* if the waiting thread equals to the given thread we are
822 done. Stop iterateting. */
823 if(waiter->waiter == t) {
824 *monitor_ptr=lrp->lr[j].obj;
828 lrp=lrp->header.next;
831 pthread_mutex_unlock(&lock_global_pool_lock);
835 return JVMTI_ERROR_NONE;
839 jvmtiStartFunction sf;
845 static void *threadstartup(void *t) {
846 runagentparam *rap = (runagentparam*)t;
847 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
851 /* RunAgentThread *************************************************************
853 Starts the execution of an agent thread of the specified native function
854 within the specified thread
856 *******************************************************************************/
859 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
860 const void *arg, jint priority)
862 pthread_attr_t threadattr;
863 struct sched_param sp;
867 CHECK_PHASE(JVMTI_PHASE_LIVE)
870 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
871 return JVMTI_ERROR_INVALID_THREAD;
872 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
873 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
874 (priority > JVMTI_THREAD_MAX_PRIORITY))
875 return JVMTI_ERROR_INVALID_PRIORITY;
877 /* XXX: Threads started with this function should not be visible to
878 Java programming language queries but are included in JVM TI queries */
881 rap.arg = (void*)arg;
884 #if defined(ENABLE_THREADS)
885 pthread_attr_init(&threadattr);
886 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
887 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
888 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
890 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
891 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
893 pthread_attr_setschedparam(&threadattr,&sp);
894 if (pthread_create(&((threadobject*)
895 thread)->tid, &threadattr, &threadstartup, &rap)) {
896 log_text("pthread_create failed");
901 return JVMTI_ERROR_NONE;
905 /* GetTopThreadGroups *********************************************************
907 Get all top-level thread groups in the VM.
909 *******************************************************************************/
912 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
913 jthreadGroup ** groups_ptr)
915 jint threads_count_ptr;
916 threadobject *threads_ptr;
918 jthreadGroup **tg,*ttgp;
921 CHECK_PHASE(JVMTI_PHASE_LIVE)
924 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
925 return JVMTI_ERROR_NULL_POINTER;
927 #if defined(ENABLE_THREADS)
928 tg = MNEW(jthreadGroup*,size);
930 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
931 return JVMTI_ERROR_INTERNAL;
933 for (i=0;i<threads_count_ptr;i++){
934 if (threads_ptr[i].o.thread->group == NULL) {
935 log_text("threadgroup not set");
936 return JVMTI_ERROR_INTERNAL;
938 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
941 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
946 MREALLOC(tg,jthreadGroup*,size,size*2);
955 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
956 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
957 MFREE(tg,jthreadGroup*,size);
959 *group_count_ptr = x;
962 return JVMTI_ERROR_NOT_AVAILABLE;
964 return JVMTI_ERROR_NONE;
968 /* GetThreadGroupInfo *********************************************************
970 Get information about the specified thread group.
972 *******************************************************************************/
975 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
976 jvmtiThreadGroupInfo * info_ptr)
980 java_lang_ThreadGroup* grp;
983 CHECK_PHASE(JVMTI_PHASE_LIVE)
986 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
987 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
988 return JVMTI_ERROR_INVALID_THREAD_GROUP;
990 grp = (java_lang_ThreadGroup*)group;
992 info_ptr->parent = (jthreadGroup)
993 Java_java_lang_VMObject_clone(NULL,
994 (jclass)grp->header.vftbl->class,
995 (java_lang_Cloneable*) &grp->parent);
997 name = javastring_tochar((java_objectheader*)grp->name);
999 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
1000 strncpy(info_ptr->name,name,size);
1001 info_ptr->max_priority= (jint)grp->maxpri;
1002 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1004 return JVMTI_ERROR_NONE;
1008 /* GetThreadGroupChildren *****************************************************
1010 Get the live threads and active subgroups in this thread group.
1012 *******************************************************************************/
1015 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1016 jint * thread_count_ptr, jthread ** threads_ptr,
1017 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1019 java_lang_ThreadGroup* tgp;
1022 CHECK_PHASE(JVMTI_PHASE_LIVE)
1025 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1026 (group_count_ptr == NULL) || (groups_ptr == NULL))
1027 return JVMTI_ERROR_NULL_POINTER;
1029 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1030 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1032 tgp = (java_lang_ThreadGroup*)group;
1034 *thread_count_ptr = (jint)tgp->threads->elementCount;
1037 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1039 memcpy(*threads_ptr, &tgp->threads->elementData,
1040 (*thread_count_ptr)*sizeof(java_objectarray*));
1042 *group_count_ptr = (jint) tgp->groups->elementCount;
1045 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1047 memcpy(*groups_ptr, &tgp->threads->elementData,
1048 (*group_count_ptr)*sizeof(jthreadGroup*));
1050 return JVMTI_ERROR_NONE;
1054 /* getcacaostacktrace *********************************************************
1056 Helper function that retrives stack trace for specified thread.
1058 *******************************************************************************/
1060 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1064 if (thread == NULL) {
1065 t = jvmti_get_current_thread();
1066 *trace = stacktrace_create(t);
1068 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1069 /* if (t != jvmti_get_current_thread())
1070 resume = threads_suspend_thread_if_running(thread);
1072 *trace = stacktrace_create(thread );
1075 threads_resume_thread ( thread );*/
1078 return JVMTI_ERROR_NONE;
1082 /* GetFrameCount **************************************************************
1085 Get the number of frames in the specified thread's stack. Calling function
1086 has to take care of suspending/resuming thread.
1088 *******************************************************************************/
1091 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1093 stacktracebuffer* trace;
1097 CHECK_PHASE(JVMTI_PHASE_LIVE)
1100 if (thread != NULL){
1101 if(!builtin_instanceof(thread,class_java_lang_Thread))
1102 return JVMTI_ERROR_INVALID_THREAD;
1104 CHECK_THREAD_IS_ALIVE(thread);
1107 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1109 er = getcacaostacktrace(&trace, thread);
1110 if (er == JVMTI_ERROR_NONE) {
1115 *count_ptr = trace->used;
1118 return JVMTI_ERROR_NONE;
1122 /* GetThreadState **************************************************************
1124 Get the state of a thread.
1126 *******************************************************************************/
1129 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1131 java_lang_Thread* th = (java_lang_Thread*)thread;
1132 threadobject* t = (threadobject*)th->vmThread;
1135 CHECK_PHASE(JVMTI_PHASE_LIVE)
1138 if(!builtin_instanceof(thread,class_java_lang_Thread))
1139 return JVMTI_ERROR_INVALID_THREAD;
1141 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1143 *thread_state_ptr = 0;
1144 #if defined(ENABLE_THREADS)
1145 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1147 if (((threadobject*)th->vmThread)->tid == 0)
1148 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1151 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1152 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1153 /* XXX todo - info not available */
1154 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1155 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1156 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1157 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1158 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1159 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1160 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1161 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1162 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1163 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1166 return JVMTI_ERROR_INTERNAL;
1169 return JVMTI_ERROR_NONE;
1173 /* GetFrameLocation ************************************************************
1175 Get the location of the instruction currently executing
1177 *******************************************************************************/
1180 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1181 jmethodID * method_ptr, jlocation * location_ptr)
1183 stackframeinfo_t *sfi;
1188 CHECK_PHASE(JVMTI_PHASE_LIVE)
1191 if (thread == NULL) {
1192 th = jvmti_get_current_thread();
1194 if(!builtin_instanceof(thread,class_java_lang_Thread))
1195 return JVMTI_ERROR_INVALID_THREAD;
1197 CHECK_THREAD_IS_ALIVE(thread);
1198 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1201 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1203 if ((method_ptr == NULL)&&(location_ptr == NULL))
1204 return JVMTI_ERROR_NULL_POINTER;
1206 sfi = th->_stackframeinfo;
1209 while ((sfi != NULL) && (i<depth)) {
1214 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1216 *method_ptr=(jmethodID)sfi->code->m;
1217 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1219 return JVMTI_ERROR_NONE;
1223 /* NotifyFramePop *************************************************************
1227 *******************************************************************************/
1230 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1233 CHECK_PHASE(JVMTI_PHASE_LIVE)
1235 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1237 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1238 return JVMTI_ERROR_NONE;
1241 /* GetLocalObject *************************************************************
1245 *******************************************************************************/
1248 GetLocalObject (jvmtiEnv * env,
1249 jthread thread, jint depth, jint slot, jobject * value_ptr)
1252 CHECK_PHASE(JVMTI_PHASE_LIVE)
1254 CHECK_CAPABILITY(env,can_access_local_variables)
1256 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1257 return JVMTI_ERROR_NONE;
1260 /* GetLocalInt ****************************************************************
1264 *******************************************************************************/
1267 GetLocalInt (jvmtiEnv * env,
1268 jthread thread, jint depth, jint slot, jint * value_ptr)
1271 CHECK_PHASE(JVMTI_PHASE_LIVE)
1273 CHECK_CAPABILITY(env,can_access_local_variables)
1274 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1275 return JVMTI_ERROR_NONE;
1278 /* *****************************************************************************
1282 *******************************************************************************/
1285 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1289 CHECK_PHASE(JVMTI_PHASE_LIVE)
1291 CHECK_CAPABILITY(env,can_access_local_variables)
1293 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1294 return JVMTI_ERROR_NONE;
1298 /* *****************************************************************************
1302 *******************************************************************************/
1305 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1309 CHECK_PHASE(JVMTI_PHASE_LIVE)
1311 CHECK_CAPABILITY(env,can_access_local_variables)
1313 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1314 return JVMTI_ERROR_NONE;
1318 /* *****************************************************************************
1322 *******************************************************************************/
1325 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1326 jdouble * value_ptr)
1329 CHECK_PHASE(JVMTI_PHASE_LIVE)
1331 CHECK_CAPABILITY(env,can_access_local_variables)
1333 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1334 return JVMTI_ERROR_NONE;
1338 /* *****************************************************************************
1342 *******************************************************************************/
1345 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1349 CHECK_PHASE(JVMTI_PHASE_LIVE)
1351 CHECK_CAPABILITY(env,can_access_local_variables)
1353 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1354 return JVMTI_ERROR_NONE;
1358 /* *****************************************************************************
1362 *******************************************************************************/
1365 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1369 CHECK_PHASE(JVMTI_PHASE_LIVE)
1371 CHECK_CAPABILITY(env,can_access_local_variables)
1373 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1374 return JVMTI_ERROR_NONE;
1378 /* *****************************************************************************
1382 *******************************************************************************/
1385 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1389 CHECK_PHASE(JVMTI_PHASE_LIVE)
1391 CHECK_CAPABILITY(env,can_access_local_variables)
1393 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1394 return JVMTI_ERROR_NONE;
1398 /* *****************************************************************************
1402 *******************************************************************************/
1405 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1409 CHECK_PHASE(JVMTI_PHASE_LIVE)
1411 CHECK_CAPABILITY(env,can_access_local_variables)
1413 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1414 return JVMTI_ERROR_NONE;
1418 /* *****************************************************************************
1422 *******************************************************************************/
1425 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1429 CHECK_PHASE(JVMTI_PHASE_LIVE)
1431 CHECK_CAPABILITY(env,can_access_local_variables)
1433 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1434 return JVMTI_ERROR_NONE;
1438 /* CreateRawMonitor ***********************************************************
1440 This function creates a new raw monitor.
1442 *******************************************************************************/
1445 CreateRawMonitor (jvmtiEnv * env, const char *name,
1446 jrawMonitorID * monitor_ptr)
1448 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1451 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1452 CHECK_PHASE(JVMTI_PHASE_LIVE)
1455 if ((name == NULL) || (monitor_ptr == NULL))
1456 return JVMTI_ERROR_NULL_POINTER;
1458 #if defined(ENABLE_THREADS)
1459 monitor->name=javastring_new_from_ascii(name);
1461 log_text ("CreateRawMonitor not supported");
1464 return JVMTI_ERROR_NONE;
1468 /* DestroyRawMonitor **********************************************************
1470 This function destroys a raw monitor.
1472 *******************************************************************************/
1475 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1478 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1479 CHECK_PHASE(JVMTI_PHASE_LIVE)
1482 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1483 return JVMTI_ERROR_INVALID_MONITOR;
1485 #if defined(ENABLE_THREADS)
1486 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1487 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1489 lock_monitor_exit((java_objectheader *) monitor->name);
1493 log_text ("DestroyRawMonitor not supported");
1496 return JVMTI_ERROR_NONE;
1500 /* RawMonitorEnter ************************************************************
1502 Gain exclusive ownership of a raw monitor
1504 *******************************************************************************/
1507 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1509 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1510 return JVMTI_ERROR_INVALID_MONITOR;
1512 #if defined(ENABLE_THREADS)
1513 lock_monitor_enter((java_objectheader *) monitor->name);
1515 log_text ("RawMonitorEnter not supported");
1518 return JVMTI_ERROR_NONE;
1522 /* RawMonitorExit *************************************************************
1526 *******************************************************************************/
1529 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1531 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1532 return JVMTI_ERROR_INVALID_MONITOR;
1534 #if defined(ENABLE_THREADS)
1535 /* assure current thread owns this monitor */
1536 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1537 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1539 lock_monitor_exit((java_objectheader *) monitor->name);
1541 log_text ("RawMonitorExit not supported");
1544 return JVMTI_ERROR_NONE;
1548 /* RawMonitorWait *************************************************************
1550 Wait for notification of the raw monitor.
1552 *******************************************************************************/
1555 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1557 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1558 return JVMTI_ERROR_INVALID_MONITOR;
1560 #if defined(ENABLE_THREADS)
1561 /* assure current thread owns this monitor */
1562 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1563 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1565 lock_wait_for_object(&monitor->name->header, millis,0);
1566 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1567 return JVMTI_ERROR_INTERRUPT;
1570 log_text ("RawMonitorWait not supported");
1573 return JVMTI_ERROR_NONE;
1577 /* RawMonitorNotify ***********************************************************
1579 Notify one thread waiting on the given monitor.
1581 *******************************************************************************/
1584 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1586 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1587 return JVMTI_ERROR_INVALID_MONITOR;
1589 #if defined(ENABLE_THREADS)
1590 /* assure current thread owns this monitor */
1591 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1592 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1594 lock_notify_object((java_objectheader*)&monitor->name);
1596 log_text ("RawMonitorNotify not supported");
1599 return JVMTI_ERROR_NONE;
1603 /* RawMonitorNotifyAll *********************************************************
1605 Notify all threads waiting on the given monitor.
1607 *******************************************************************************/
1610 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1612 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1613 return JVMTI_ERROR_INVALID_MONITOR;
1615 #if defined(ENABLE_THREADS)
1616 /* assure current thread owns this monitor */
1617 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1618 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1620 lock_notify_all_object((java_objectheader*)&monitor->name);
1622 log_text ("RawMonitorNotifyAll not supported");
1625 return JVMTI_ERROR_NONE;
1629 /* SetBreakpoint **************************************************************
1633 *******************************************************************************/
1636 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1639 CHECK_PHASE(JVMTI_PHASE_LIVE)
1641 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1644 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1645 return JVMTI_ERROR_NONE;
1649 /* *****************************************************************************
1653 *******************************************************************************/
1656 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1659 CHECK_PHASE(JVMTI_PHASE_LIVE)
1661 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1663 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1664 return JVMTI_ERROR_NONE;
1668 /* SetFieldAccessWatch ********************************************************
1672 *******************************************************************************/
1675 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1678 CHECK_PHASE(JVMTI_PHASE_LIVE)
1680 CHECK_CAPABILITY(env,can_generate_field_access_events)
1682 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1683 return JVMTI_ERROR_NONE;
1687 /* *****************************************************************************
1691 *******************************************************************************/
1694 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1697 CHECK_PHASE(JVMTI_PHASE_LIVE)
1699 CHECK_CAPABILITY(env,can_generate_field_access_events)
1701 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1702 return JVMTI_ERROR_NONE;
1706 /* *****************************************************************************
1710 *******************************************************************************/
1713 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1716 CHECK_PHASE(JVMTI_PHASE_LIVE)
1718 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1720 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1721 return JVMTI_ERROR_NONE;
1725 /* *****************************************************************************
1729 *******************************************************************************/
1732 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1735 CHECK_PHASE(JVMTI_PHASE_LIVE)
1737 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1739 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1740 return JVMTI_ERROR_NONE;
1744 /* Allocate ********************************************************************
1746 Allocate an area of memory through the JVM TI allocator. The allocated
1747 memory should be freed with Deallocate
1749 *******************************************************************************/
1752 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1755 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1756 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1758 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1759 if (*mem_ptr == NULL)
1760 return JVMTI_ERROR_OUT_OF_MEMORY;
1762 return JVMTI_ERROR_NONE;
1767 /* Deallocate ******************************************************************
1769 Deallocate mem using the JVM TI allocator.
1771 *******************************************************************************/
1774 Deallocate (jvmtiEnv * env, unsigned char *mem)
1776 /* let Boehm GC do the job */
1778 return JVMTI_ERROR_NONE;
1782 /* GetClassSignature ************************************************************
1784 For the class indicated by klass, return the JNI type signature and the
1785 generic signature of the class.
1787 *******************************************************************************/
1790 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1794 CHECK_PHASE(JVMTI_PHASE_START)
1795 CHECK_PHASE(JVMTI_PHASE_LIVE)
1798 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1799 if (!builtin_instanceof(klass,class_java_lang_Class))
1800 return JVMTI_ERROR_INVALID_CLASS;
1802 if (signature_ptr != NULL) {
1803 *signature_ptr = (char*)
1804 heap_allocate(sizeof(char) *
1805 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1807 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1810 if (generic_ptr!= NULL)
1811 *generic_ptr = NULL;
1813 return JVMTI_ERROR_NONE;
1816 /* GetClassStatus *************************************************************
1818 Get status of the class.
1820 *******************************************************************************/
1823 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1827 CHECK_PHASE(JVMTI_PHASE_START)
1828 CHECK_PHASE(JVMTI_PHASE_LIVE)
1831 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1832 return JVMTI_ERROR_INVALID_CLASS;
1834 if (status_ptr == NULL)
1835 return JVMTI_ERROR_NULL_POINTER;
1837 c = (classinfo*)klass;
1840 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1841 if (c->state & CLASS_LINKED)
1842 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1844 if (c->state & CLASS_INITIALIZED)
1845 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1847 if (c->state & CLASS_ERROR)
1848 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1850 if (c->vftbl->arraydesc != NULL)
1851 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1853 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1854 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1856 return JVMTI_ERROR_NONE;
1860 /* GetSourceFileName **********************************************************
1862 For the class indicated by klass, return the source file name.
1864 *******************************************************************************/
1867 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1872 CHECK_PHASE(JVMTI_PHASE_START)
1873 CHECK_PHASE(JVMTI_PHASE_LIVE)
1875 CHECK_CAPABILITY(env,can_get_source_file_name)
1877 if ((klass == NULL)||(source_name_ptr == NULL))
1878 return JVMTI_ERROR_NULL_POINTER;
1880 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1882 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1884 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1885 (*source_name_ptr)[size]='\0';
1887 return JVMTI_ERROR_NONE;
1891 /* GetClassModifiers **********************************************************
1893 For class klass return the access flags
1895 *******************************************************************************/
1898 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1901 CHECK_PHASE(JVMTI_PHASE_START)
1902 CHECK_PHASE(JVMTI_PHASE_LIVE)
1905 if (modifiers_ptr == NULL)
1906 return JVMTI_ERROR_NULL_POINTER;
1908 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1909 return JVMTI_ERROR_INVALID_CLASS;
1911 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1913 return JVMTI_ERROR_NONE;
1917 /* GetClassMethods *************************************************************
1919 For class klass return a count of methods and a list of method IDs
1921 *******************************************************************************/
1924 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1925 jmethodID ** methods_ptr)
1930 CHECK_PHASE(JVMTI_PHASE_START)
1931 CHECK_PHASE(JVMTI_PHASE_LIVE)
1934 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1935 return JVMTI_ERROR_NULL_POINTER;
1937 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1938 return JVMTI_ERROR_INVALID_CLASS;
1940 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1941 *methods_ptr = (jmethodID*)
1942 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1944 for (i=0; i<*method_count_ptr;i++)
1945 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1947 return JVMTI_ERROR_NONE;
1951 /* GetClassFields *************************************************************
1953 For the class indicated by klass, return a count of fields and a list of
1956 *******************************************************************************/
1959 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1960 jfieldID ** fields_ptr)
1963 CHECK_PHASE(JVMTI_PHASE_START)
1964 CHECK_PHASE(JVMTI_PHASE_LIVE)
1967 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1968 return JVMTI_ERROR_NULL_POINTER;
1970 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1971 *fields_ptr = (jfieldID*)
1972 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1974 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1975 sizeof(jfieldID) * (*field_count_ptr));
1977 return JVMTI_ERROR_NONE;
1981 /* GetImplementedInterfaces ***************************************************
1983 Return the direct super-interfaces of this class.
1985 *******************************************************************************/
1988 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1989 jint * interface_count_ptr,
1990 jclass ** interfaces_ptr)
1993 classref_or_classinfo *interfaces;
1997 CHECK_PHASE(JVMTI_PHASE_START)
1998 CHECK_PHASE(JVMTI_PHASE_LIVE)
2001 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
2002 return JVMTI_ERROR_NULL_POINTER;
2004 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2005 return JVMTI_ERROR_INVALID_CLASS;
2008 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2010 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2012 interfaces = ((classinfo*)klass)->interfaces;
2013 for (i=0; i<*interface_count_ptr; i++) {
2014 if (IS_CLASSREF(interfaces[i]))
2015 tmp = load_class_bootstrap(interfaces[i].ref->name);
2017 tmp = interfaces[i].cls;
2019 *interfaces_ptr[i]=tmp;
2022 return JVMTI_ERROR_NONE;
2026 /* IsInterface ****************************************************************
2028 Determines whether a class object reference represents an interface.
2030 *******************************************************************************/
2033 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2036 CHECK_PHASE(JVMTI_PHASE_START)
2037 CHECK_PHASE(JVMTI_PHASE_LIVE)
2040 if ((klass == NULL)||(is_interface_ptr == NULL))
2041 return JVMTI_ERROR_NULL_POINTER;
2043 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2045 return JVMTI_ERROR_NONE;
2048 /* IsArrayClass ***************************************************************
2050 Determines whether a class object reference represents an array.
2052 *******************************************************************************/
2055 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2058 CHECK_PHASE(JVMTI_PHASE_START)
2059 CHECK_PHASE(JVMTI_PHASE_LIVE)
2062 if (is_array_class_ptr == NULL)
2063 return JVMTI_ERROR_NULL_POINTER;
2065 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2067 return JVMTI_ERROR_NONE;
2071 /* GetClassLoader *************************************************************
2073 For the class indicated by klass, return via classloader_ptr a reference to
2074 the class loader for the class.
2076 *******************************************************************************/
2079 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2082 CHECK_PHASE(JVMTI_PHASE_START)
2083 CHECK_PHASE(JVMTI_PHASE_LIVE)
2086 if ((klass == NULL)||(classloader_ptr == NULL))
2087 return JVMTI_ERROR_NULL_POINTER;
2089 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2091 return JVMTI_ERROR_NONE;
2095 /* GetObjectHashCode **********************************************************
2097 Return hash code for object object
2099 *******************************************************************************/
2102 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2105 CHECK_PHASE(JVMTI_PHASE_START)
2106 CHECK_PHASE(JVMTI_PHASE_LIVE)
2109 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2110 if (!builtin_instanceof(object,class_java_lang_Object))
2111 return JVMTI_ERROR_INVALID_OBJECT;
2113 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2115 return JVMTI_ERROR_NONE;
2119 /* *****************************************************************************
2123 *******************************************************************************/
2126 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2127 jvmtiMonitorUsage * info_ptr)
2130 CHECK_PHASE(JVMTI_PHASE_LIVE)
2132 CHECK_CAPABILITY(env,can_get_monitor_info)
2134 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2135 return JVMTI_ERROR_NONE;
2139 /* GetFieldName ***************************************************************
2141 For the field indicated by klass and field, return the field name and
2144 *******************************************************************************/
2147 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2148 char **name_ptr, char **signature_ptr, char **generic_ptr)
2153 CHECK_PHASE(JVMTI_PHASE_START)
2154 CHECK_PHASE(JVMTI_PHASE_LIVE)
2158 return JVMTI_ERROR_INVALID_CLASS;
2160 if (!builtin_instanceof(klass,class_java_lang_Class))
2161 return JVMTI_ERROR_INVALID_CLASS;
2162 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2164 if (name_ptr != NULL) {
2165 size = utf_bytes(((fieldinfo*)field)->name)+1;
2166 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2167 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2170 if (signature_ptr != NULL) {
2171 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2172 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2173 utf_sprint_convert_to_latin1(*signature_ptr,
2174 ((fieldinfo*)field)->descriptor);
2177 if (generic_ptr != NULL)
2178 *generic_ptr = NULL;
2180 return JVMTI_ERROR_NONE;
2184 /* GetFieldDeclaringClass *****************************************************
2186 For the field indicated by klass and field return the class that defined it
2187 The declaring class will either be klass, a superclass, or an implemented
2190 *******************************************************************************/
2193 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2194 jclass * declaring_class_ptr)
2197 CHECK_PHASE(JVMTI_PHASE_START)
2198 CHECK_PHASE(JVMTI_PHASE_LIVE)
2202 return JVMTI_ERROR_INVALID_CLASS;
2204 if (!builtin_instanceof(klass,class_java_lang_Class))
2205 return JVMTI_ERROR_INVALID_CLASS;
2207 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2209 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2211 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2213 return JVMTI_ERROR_NONE;
2217 /* GetFieldModifiers **********************************************************
2219 Return access flags of field field
2221 *******************************************************************************/
2224 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2225 jint * modifiers_ptr)
2228 CHECK_PHASE(JVMTI_PHASE_START)
2229 CHECK_PHASE(JVMTI_PHASE_LIVE)
2233 return JVMTI_ERROR_INVALID_CLASS;
2235 if (!builtin_instanceof(klass,class_java_lang_Class))
2236 return JVMTI_ERROR_INVALID_CLASS;
2238 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2240 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2242 *modifiers_ptr = ((fieldinfo*)field)->flags;
2244 return JVMTI_ERROR_NONE;
2248 /* IsFieldSynthetic ***********************************************************
2252 *******************************************************************************/
2255 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2256 jboolean * is_synthetic_ptr)
2259 CHECK_PHASE(JVMTI_PHASE_START)
2260 CHECK_PHASE(JVMTI_PHASE_LIVE)
2262 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2264 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2265 return JVMTI_ERROR_NONE;
2269 /* GetMethodName ***************************************************************
2271 For the method indicated by method, return the method name via name_ptr and
2272 method signature via signature_ptr.
2274 *******************************************************************************/
2277 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2278 char **signature_ptr, char **generic_ptr)
2280 methodinfo* m = (methodinfo*)method;
2283 CHECK_PHASE(JVMTI_PHASE_START)
2284 CHECK_PHASE(JVMTI_PHASE_LIVE)
2288 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2290 if (name_ptr != NULL) {
2292 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2293 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2296 if (signature_ptr != NULL) {
2297 *signature_ptr = (char*)
2298 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2299 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2302 if (generic_ptr != NULL) {
2303 /* there is no generic signature attribute */
2304 *generic_ptr = NULL;
2307 return JVMTI_ERROR_NONE;
2311 /* GetMethodDeclaringClass *****************************************************
2313 For the method indicated by method, return the class that defined it.
2315 *******************************************************************************/
2318 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2319 jclass * declaring_class_ptr)
2322 CHECK_PHASE(JVMTI_PHASE_START)
2323 CHECK_PHASE(JVMTI_PHASE_LIVE)
2326 if ((method == NULL) || (declaring_class_ptr == NULL))
2327 return JVMTI_ERROR_NULL_POINTER;
2329 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2331 return JVMTI_ERROR_NONE;
2335 /* GetMethodModifiers **********************************************************
2337 For the method indicated by method, return the access flags.
2339 *******************************************************************************/
2342 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2345 CHECK_PHASE(JVMTI_PHASE_START)
2346 CHECK_PHASE(JVMTI_PHASE_LIVE)
2349 if ((method == NULL) || (modifiers_ptr == NULL))
2350 return JVMTI_ERROR_NULL_POINTER;
2352 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2354 return JVMTI_ERROR_NONE;
2358 /* GetMaxLocals ****************************************************************
2360 For the method indicated by method, return the number of local variable slots
2361 used by the method, including the local variables used to pass parameters to
2362 the method on its invocation.
2364 *******************************************************************************/
2367 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2370 CHECK_PHASE(JVMTI_PHASE_START)
2371 CHECK_PHASE(JVMTI_PHASE_LIVE)
2374 if ((method == NULL)||(max_ptr == NULL))
2375 return JVMTI_ERROR_NULL_POINTER;
2377 if (((methodinfo*)method)->flags & ACC_NATIVE)
2378 return JVMTI_ERROR_NATIVE_METHOD;
2380 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2382 return JVMTI_ERROR_NONE;
2387 /* GetArgumentsSize ************************************************************
2389 Return the number of local variable slots used by the method's arguments.
2391 *******************************************************************************/
2394 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2397 CHECK_PHASE(JVMTI_PHASE_START)
2398 CHECK_PHASE(JVMTI_PHASE_LIVE)
2401 if ((method == NULL)||(size_ptr == NULL))
2402 return JVMTI_ERROR_NULL_POINTER;
2404 if (((methodinfo*)method)->flags & ACC_NATIVE)
2405 return JVMTI_ERROR_NATIVE_METHOD;
2407 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2408 return JVMTI_ERROR_NONE;
2413 /* GetLineNumberTable **********************************************************
2415 Return table of source line number entries for a given method
2417 *******************************************************************************/
2420 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2421 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2426 CHECK_PHASE(JVMTI_PHASE_START)
2427 CHECK_PHASE(JVMTI_PHASE_LIVE)
2429 CHECK_CAPABILITY(env,can_get_line_numbers)
2431 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2432 return JVMTI_ERROR_NULL_POINTER;
2434 if (((methodinfo*)method)->flags & ACC_NATIVE)
2435 return JVMTI_ERROR_NATIVE_METHOD;
2437 if (((methodinfo*)method)->linenumbers == NULL)
2438 return JVMTI_ERROR_ABSENT_INFORMATION;
2440 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2441 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2442 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2445 for (i=0; i < *entry_count_ptr; i++) {
2446 (*table_ptr)[i].start_location =
2447 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2448 (*table_ptr)[i].line_number =
2449 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2452 return JVMTI_ERROR_NONE;
2456 /* GetMethodLocation ***********************************************************
2458 For the method indicated by method, return the beginning and ending addresses
2459 through start_location_ptr and end_location_ptr. In cacao this points to
2460 entry point in machine code and length of machine code
2462 *******************************************************************************/
2465 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2466 jlocation * start_location_ptr,
2467 jlocation * end_location_ptr)
2469 methodinfo* m = (methodinfo*)method;
2472 CHECK_PHASE(JVMTI_PHASE_START)
2473 CHECK_PHASE(JVMTI_PHASE_LIVE)
2476 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2478 if (((methodinfo*)method)->flags & ACC_NATIVE)
2479 return JVMTI_ERROR_NATIVE_METHOD;
2481 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2482 return JVMTI_ERROR_NULL_POINTER;
2484 /* XXX we return the location of the most recent code. Don't know
2485 * if there is a way to teach jvmti that a method can have more
2486 * than one location. -Edwin */
2488 /* XXX Don't know if that's the right way to deal with not-yet-
2489 * compiled methods. -Edwin */
2491 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2494 /* -1 states location information is not available */
2495 *start_location_ptr = (jlocation)-1;
2496 *end_location_ptr = (jlocation)-1;
2499 *start_location_ptr = (jlocation)m->code->mcode;
2500 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2501 return JVMTI_ERROR_NONE;
2505 /* GetLocalVariableTable *******************************************************
2507 Return local variable information.
2509 *******************************************************************************/
2512 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2513 jint * entry_count_ptr,
2514 jvmtiLocalVariableEntry ** table_ptr)
2517 CHECK_PHASE(JVMTI_PHASE_LIVE)
2519 CHECK_CAPABILITY(env,can_access_local_variables)
2521 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2523 return JVMTI_ERROR_NONE;
2527 /* GetBytecode *****************************************************************
2529 For the method indicated by method, return the byte codes that implement the
2532 *******************************************************************************/
2535 GetBytecodes (jvmtiEnv * env, jmethodID method,
2536 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2538 methodinfo* m = (methodinfo*)method;;
2541 CHECK_PHASE(JVMTI_PHASE_START)
2542 CHECK_PHASE(JVMTI_PHASE_LIVE)
2544 CHECK_CAPABILITY(env,can_get_bytecodes)
2546 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2547 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2549 *bytecode_count_ptr = m->jcodelength;
2550 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2551 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2553 return JVMTI_ERROR_NONE;
2557 /* IsMethodNative **************************************************************
2559 For the method indicated by method, return a value indicating whether the
2560 method is a native function
2562 *******************************************************************************/
2565 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2568 CHECK_PHASE(JVMTI_PHASE_START)
2569 CHECK_PHASE(JVMTI_PHASE_LIVE)
2572 if ((method == NULL)||(is_native_ptr == NULL))
2573 return JVMTI_ERROR_NULL_POINTER;
2575 if (((methodinfo*)method)->flags & ACC_NATIVE)
2576 *is_native_ptr = JNI_TRUE;
2578 *is_native_ptr = JNI_FALSE;
2580 return JVMTI_ERROR_NONE;
2584 /* IsMethodSynthetic ***********************************************************
2586 return a value indicating whether the method is synthetic. Synthetic methods
2587 are generated by the compiler but not present in the original source code.
2589 *******************************************************************************/
2592 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2593 jboolean * is_synthetic_ptr)
2596 CHECK_PHASE(JVMTI_PHASE_START)
2597 CHECK_PHASE(JVMTI_PHASE_LIVE)
2599 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2601 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2602 return JVMTI_ERROR_NONE;
2606 /* GetLoadedClasses ************************************************************
2608 Return an array of all classes loaded in the virtual machine.
2610 *******************************************************************************/
2613 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2616 CHECK_PHASE(JVMTI_PHASE_LIVE)
2619 if (class_count_ptr == NULL)
2620 return JVMTI_ERROR_NULL_POINTER;
2622 if (classes_ptr == NULL)
2623 return JVMTI_ERROR_NULL_POINTER;
2625 classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
2627 return JVMTI_ERROR_NONE;
2631 /* GetClassLoaderClasses *******************************************************
2633 Returns an array of those classes for which this class loader has been
2634 recorded as an initiating loader.
2636 *******************************************************************************/
2639 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2640 jint * class_count_ptr, jclass ** classes_ptr)
2642 log_text("GetClassLoaderClasses called");
2645 CHECK_PHASE(JVMTI_PHASE_LIVE)
2648 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2649 return JVMTI_ERROR_NULL_POINTER;
2651 /* behave like jdk 1.1 and make no distinction between initiating and
2652 defining class loaders */
2654 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2658 /* PopFrame *******************************************************************
2662 *******************************************************************************/
2665 PopFrame (jvmtiEnv * env, jthread thread)
2668 CHECK_PHASE(JVMTI_PHASE_LIVE)
2670 CHECK_CAPABILITY(env,can_pop_frame)
2672 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2673 return JVMTI_ERROR_NONE;
2677 /* RedefineClasses ************************************************************
2681 *******************************************************************************/
2684 RedefineClasses (jvmtiEnv * env, jint class_count,
2685 const jvmtiClassDefinition * class_definitions)
2688 CHECK_PHASE(JVMTI_PHASE_START)
2689 CHECK_PHASE(JVMTI_PHASE_LIVE)
2691 CHECK_CAPABILITY(env,can_redefine_classes)
2692 CHECK_CAPABILITY(env,can_redefine_any_class)
2694 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2695 return JVMTI_ERROR_NONE;
2699 /* GetVersionNumber ***********************************************************
2701 Return the JVM TI version identifier.
2703 *******************************************************************************/
2706 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2708 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2710 *version_ptr = JVMTI_VERSION;
2712 return JVMTI_ERROR_NONE;
2716 /* GetCapabilities ************************************************************
2718 Returns the optional JVM TI features which this environment currently
2721 *******************************************************************************/
2724 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2726 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2728 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2730 return JVMTI_ERROR_NONE;
2734 /* *****************************************************************************
2738 *******************************************************************************/
2741 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2742 char **source_debug_extension_ptr)
2745 CHECK_PHASE(JVMTI_PHASE_START)
2746 CHECK_PHASE(JVMTI_PHASE_LIVE)
2748 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2750 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2751 return JVMTI_ERROR_NONE;
2755 /* IsMethodObsolete ************************************************************
2757 Determine if a method ID refers to an obsolete method version.
2759 *******************************************************************************/
2762 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2763 jboolean * is_obsolete_ptr)
2766 CHECK_PHASE(JVMTI_PHASE_START)
2767 CHECK_PHASE(JVMTI_PHASE_LIVE)
2769 CHECK_CAPABILITY(env,can_redefine_classes)
2771 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2772 return JVMTI_ERROR_NONE;
2776 /* SuspendThreadList **********************************************************
2778 Suspend all threads in the request list.
2780 *******************************************************************************/
2783 SuspendThreadList (jvmtiEnv * env, jint request_count,
2784 const jthread * request_list, jvmtiError * results)
2791 CHECK_PHASE(JVMTI_PHASE_START)
2792 CHECK_PHASE(JVMTI_PHASE_LIVE)
2794 CHECK_CAPABILITY(env,can_suspend);
2796 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2797 if ((request_list == NULL) || (results == NULL))
2798 return JVMTI_ERROR_NULL_POINTER;
2800 me = jvmti_get_current_thread();
2802 for (i=0;i<request_count;i++) {
2803 if (request_list[i] == me)
2806 results[i]=SuspendThread(env, request_list[i]);
2809 if (suspendme != -1)
2810 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2812 return JVMTI_ERROR_NONE;
2816 /* ResumeThreadList ***********************************************************
2818 Resumes all threads in the request list.
2820 *******************************************************************************/
2823 ResumeThreadList (jvmtiEnv * env, jint request_count,
2824 const jthread * request_list, jvmtiError * results)
2829 CHECK_PHASE(JVMTI_PHASE_LIVE)
2831 CHECK_CAPABILITY(env,can_suspend);
2833 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2834 if ((request_list == NULL) || (results == NULL))
2835 return JVMTI_ERROR_NULL_POINTER;
2837 for (i=0;i<request_count;i++)
2838 results[i]=ResumeThread(env, request_list[i]);
2840 return JVMTI_ERROR_NONE;
2844 /* GetStackTrace **************************************************************
2846 Get information about the stack of a thread
2848 *******************************************************************************/
2851 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2852 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2855 stacktracebuffer* trace;
2860 CHECK_PHASE(JVMTI_PHASE_LIVE)
2863 if (thread != NULL){
2864 if(!builtin_instanceof(thread,class_java_lang_Thread))
2865 return JVMTI_ERROR_INVALID_THREAD;
2867 CHECK_THREAD_IS_ALIVE(thread);
2870 if((count_ptr == NULL)||(frame_buffer == NULL))
2871 return JVMTI_ERROR_NULL_POINTER;
2873 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2875 er = getcacaostacktrace(&trace, thread);
2876 if (er == JVMTI_ERROR_NONE) {
2881 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2882 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2884 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2885 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2886 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2887 frame_buffer[j].location = 0;
2892 return JVMTI_ERROR_NONE;
2896 /* GetThreadListStackTraces ***************************************************
2898 Get information about the stacks of the supplied threads.
2900 *******************************************************************************/
2903 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2904 const jthread * thread_list,
2905 jint max_frame_count,
2906 jvmtiStackInfo ** stack_info_ptr)
2912 CHECK_PHASE(JVMTI_PHASE_LIVE)
2915 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2916 return JVMTI_ERROR_NULL_POINTER;
2918 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2920 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2922 *stack_info_ptr = (jvmtiStackInfo*)
2923 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2925 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2926 (*stack_info_ptr)[i].thread=thread_list[i];
2927 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2928 (*stack_info_ptr)[i].frame_buffer =
2929 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2930 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2931 (*stack_info_ptr)[i].frame_buffer,
2932 &((*stack_info_ptr)[i].frame_count));
2934 if (er != JVMTI_ERROR_NONE) return er;
2937 return JVMTI_ERROR_NONE;
2941 /* GetAllStackTraces **********************************************************
2943 Get stack traces of all live threads
2945 *******************************************************************************/
2948 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2949 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2951 jthread *threads_ptr;
2955 CHECK_PHASE(JVMTI_PHASE_LIVE)
2958 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2960 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2961 return JVMTI_ERROR_INTERNAL;
2963 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2964 max_frame_count, stack_info_ptr);
2966 if (er != JVMTI_ERROR_NONE) return er;
2968 return JVMTI_ERROR_NONE;
2972 /* GetThreadLocalStorage ******************************************************
2974 Get the value of the JVM TI thread-local storage.
2976 *******************************************************************************/
2979 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2981 jvmtiThreadLocalStorage *tls;
2984 CHECK_PHASE(JVMTI_PHASE_START)
2985 CHECK_PHASE(JVMTI_PHASE_LIVE)
2989 thread = (jthread) THREADOBJECT;
2991 if (!builtin_instanceof(thread,class_java_lang_Thread))
2992 return JVMTI_ERROR_INVALID_THREAD;
2993 CHECK_THREAD_IS_ALIVE(thread);
2996 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2998 tls = ((environment*)env)->tls;
2999 while ((tls->thread != thread) && (tls != NULL)) {
3003 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3005 *data_ptr = tls->data;
3007 return JVMTI_ERROR_NONE;
3011 /* SetThreadLocalStorage *******************************************************
3013 Stores a pointer value associated with each environment-thread pair. The
3014 value is NULL unless set with this function. Agents can allocate memory in
3015 which they store thread specific information
3017 *******************************************************************************/
3020 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3022 jvmtiThreadLocalStorage *tls, *pre;
3023 environment* env = (environment*)jenv;
3026 CHECK_PHASE(JVMTI_PHASE_START)
3027 CHECK_PHASE(JVMTI_PHASE_LIVE)
3031 thread = (jthread) THREADOBJECT;
3033 if (!builtin_instanceof(thread,class_java_lang_Thread))
3034 return JVMTI_ERROR_INVALID_THREAD;
3035 CHECK_THREAD_IS_ALIVE(thread);
3038 if (env->tls == NULL) {
3039 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3042 while ((tls->thread != thread) && (tls->next != NULL)) {
3045 if (tls->thread != thread) {
3046 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3052 tls->data = (void*)data;
3054 /* remove current tls */
3056 while (pre->next == tls) pre = pre->next;
3057 pre->next = tls->next;
3059 return JVMTI_ERROR_NONE;
3063 /* *****************************************************************************
3067 *******************************************************************************/
3070 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3073 CHECK_PHASE(JVMTI_PHASE_START)
3074 CHECK_PHASE(JVMTI_PHASE_LIVE)
3076 CHECK_CAPABILITY(env,can_tag_objects)
3078 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3079 return JVMTI_ERROR_NONE;
3082 /* *****************************************************************************
3086 *******************************************************************************/
3089 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3092 CHECK_PHASE(JVMTI_PHASE_START)
3093 CHECK_PHASE(JVMTI_PHASE_LIVE)
3095 CHECK_CAPABILITY(env,can_tag_objects)
3097 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3098 return JVMTI_ERROR_NONE;
3102 /* ForceGarbageCollection *****************************************************
3104 Force boehm-gc to perform a garbage collection
3106 *******************************************************************************/
3109 ForceGarbageCollection (jvmtiEnv * env)
3112 CHECK_PHASE(JVMTI_PHASE_LIVE)
3117 return JVMTI_ERROR_NONE;
3121 /* IterateOverObjectsReachableFromObject **************************************
3125 *******************************************************************************/
3128 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3129 jvmtiObjectReferenceCallback
3130 object_reference_callback,
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 /* IterateOverReachableObjects ************************************************
3147 *******************************************************************************/
3150 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3152 jvmtiStackReferenceCallback
3154 jvmtiObjectReferenceCallback
3155 object_ref_callback, void *user_data)
3158 CHECK_PHASE(JVMTI_PHASE_LIVE)
3160 CHECK_CAPABILITY(env,can_tag_objects)
3162 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3163 return JVMTI_ERROR_NONE;
3167 /* IterateOverHeap ************************************************************
3171 *******************************************************************************/
3174 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3175 jvmtiHeapObjectCallback heap_object_callback,
3179 CHECK_PHASE(JVMTI_PHASE_LIVE)
3181 CHECK_CAPABILITY(env,can_tag_objects)
3183 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3184 return JVMTI_ERROR_NONE;
3188 /* IterateOverInstancesOfClass ************************************************
3192 *******************************************************************************/
3195 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3196 jvmtiHeapObjectFilter object_filter,
3197 jvmtiHeapObjectCallback
3198 heap_object_callback, void *user_data)
3201 CHECK_PHASE(JVMTI_PHASE_LIVE)
3203 CHECK_CAPABILITY(env,can_tag_objects)
3205 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3206 return JVMTI_ERROR_NONE;
3210 /* *****************************************************************************
3214 *******************************************************************************/
3217 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3218 jint * count_ptr, jobject ** object_result_ptr,
3219 jlong ** tag_result_ptr)
3222 CHECK_PHASE(JVMTI_PHASE_LIVE)
3224 CHECK_CAPABILITY(env,can_tag_objects)
3226 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3227 return JVMTI_ERROR_NONE;
3231 /* SetJNIFunctionTable **********************************************************
3233 Set the JNI function table in all current and future JNI environments
3235 *******************************************************************************/
3238 SetJNIFunctionTable (jvmtiEnv * env,
3239 const jniNativeInterface * function_table)
3242 CHECK_PHASE(JVMTI_PHASE_START)
3243 CHECK_PHASE(JVMTI_PHASE_LIVE)
3246 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3247 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3248 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3249 return JVMTI_ERROR_NONE;
3253 /* GetJNIFunctionTable *********************************************************
3255 Get the JNI function table. The JNI function table is copied into allocated
3258 *******************************************************************************/
3261 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3264 CHECK_PHASE(JVMTI_PHASE_START)
3265 CHECK_PHASE(JVMTI_PHASE_LIVE)
3268 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3269 *function_table = (jniNativeInterface*)
3270 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3271 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3272 return JVMTI_ERROR_NONE;
3276 /* SetEventCallbacks **********************************************************
3278 Set the functions to be called for each event. The callbacks are specified
3279 by supplying a replacement function table.
3281 *******************************************************************************/
3284 SetEventCallbacks (jvmtiEnv * env,
3285 const jvmtiEventCallbacks * callbacks,
3286 jint size_of_callbacks)
3289 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3290 CHECK_PHASE(JVMTI_PHASE_LIVE)
3293 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3296 if (callbacks == NULL) { /* remove the existing callbacks */
3297 memset(&(((environment* )env)->callbacks), 0,
3298 sizeof(jvmtiEventCallbacks));
3301 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3303 return JVMTI_ERROR_NONE;
3307 /* GenerateEvents *************************************************************
3309 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3310 the current state of the VM.
3312 *******************************************************************************/
3315 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3318 CHECK_PHASE(JVMTI_PHASE_LIVE)
3320 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3322 return JVMTI_ERROR_NONE;
3326 /* GetExtensionFunctions ******************************************************
3328 Returns the set of extension functions.
3330 *******************************************************************************/
3333 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3334 jvmtiExtensionFunctionInfo ** extensions)
3337 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3338 CHECK_PHASE(JVMTI_PHASE_LIVE)
3341 if ((extension_count_ptr == NULL)||(extensions == NULL))
3342 return JVMTI_ERROR_NULL_POINTER;
3344 /* cacao has no extended functions yet */
3345 *extension_count_ptr = 0;
3347 return JVMTI_ERROR_NONE;
3351 /* GetExtensionEvents *********************************************************
3353 Returns the set of extension events.
3355 *******************************************************************************/
3358 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3359 jvmtiExtensionEventInfo ** extensions)
3362 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3363 CHECK_PHASE(JVMTI_PHASE_LIVE)
3366 if ((extension_count_ptr == NULL)||(extensions == NULL))
3367 return JVMTI_ERROR_NULL_POINTER;
3369 /* cacao has no extended events yet */
3370 *extension_count_ptr = 0;
3372 return JVMTI_ERROR_NONE;
3376 /* SetExtensionEventCallback **************************************************
3378 Sets the callback function for an extension event and enables the event.
3380 *******************************************************************************/
3383 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3384 jvmtiExtensionEvent callback)
3387 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3388 CHECK_PHASE(JVMTI_PHASE_LIVE)
3391 /* cacao has no extended events yet */
3392 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3396 /* DisposeEnvironment **********************************************************
3398 Shutdown a JVM TI connection created with JNI GetEnv.
3400 *******************************************************************************/
3403 DisposeEnvironment (jvmtiEnv * env)
3405 environment* cacao_env = (environment*)env;
3406 environment* tenvs = envs;
3407 jvmtiThreadLocalStorage *jtls, *tjtls;
3409 if (tenvs != cacao_env) {
3410 while (tenvs->next != cacao_env) {
3411 tenvs = tenvs->next;
3413 tenvs->next = cacao_env->next;
3417 cacao_env->env=NULL;
3418 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3419 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3420 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3421 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3422 cacao_env->EnvironmentLocalStorage = NULL;
3424 jtls = cacao_env->tls;
3425 while (jtls != NULL) {
3430 cacao_env->tls = NULL;
3433 jvmti_cacaodbgserver_quit();
3435 /* let the GC do the rest */
3436 return JVMTI_ERROR_NONE;
3440 /* GetErrorName ***************************************************************
3442 Return the symbolic name for an error code.
3444 *******************************************************************************/
3446 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3447 memcpy(*name_ptr, &str, sizeof(str)); \
3451 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3453 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3456 case JVMTI_ERROR_NONE :
3457 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3458 case JVMTI_ERROR_NULL_POINTER :
3459 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3460 case JVMTI_ERROR_OUT_OF_MEMORY :
3461 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3462 case JVMTI_ERROR_ACCESS_DENIED :
3463 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3464 case JVMTI_ERROR_UNATTACHED_THREAD :
3465 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3466 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3467 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3468 case JVMTI_ERROR_WRONG_PHASE :
3469 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3470 case JVMTI_ERROR_INTERNAL :
3471 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3472 case JVMTI_ERROR_INVALID_PRIORITY :
3473 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3474 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3475 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3476 case JVMTI_ERROR_THREAD_SUSPENDED :
3477 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3478 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3479 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3480 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3481 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3482 case JVMTI_ERROR_NO_MORE_FRAMES :
3483 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3484 case JVMTI_ERROR_OPAQUE_FRAME :
3485 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3486 case JVMTI_ERROR_DUPLICATE :
3487 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3488 case JVMTI_ERROR_NOT_FOUND :
3489 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3490 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3491 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3492 case JVMTI_ERROR_INTERRUPT :
3493 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3494 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3495 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3496 case JVMTI_ERROR_NOT_AVAILABLE :
3497 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3498 case JVMTI_ERROR_ABSENT_INFORMATION :
3499 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3500 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3501 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3502 case JVMTI_ERROR_NATIVE_METHOD :
3503 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3504 case JVMTI_ERROR_INVALID_THREAD :
3505 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3506 case JVMTI_ERROR_INVALID_FIELDID :
3507 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3508 case JVMTI_ERROR_INVALID_METHODID :
3509 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3510 case JVMTI_ERROR_INVALID_LOCATION :
3511 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3512 case JVMTI_ERROR_INVALID_OBJECT :
3513 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3514 case JVMTI_ERROR_INVALID_CLASS :
3515 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3516 case JVMTI_ERROR_TYPE_MISMATCH :
3517 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3518 case JVMTI_ERROR_INVALID_SLOT :
3519 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3520 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3521 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3522 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3523 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3524 case JVMTI_ERROR_INVALID_MONITOR :
3525 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3526 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3527 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3528 case JVMTI_ERROR_INVALID_TYPESTATE :
3529 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3530 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3531 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3532 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3533 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3534 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3535 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3536 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3537 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3538 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3539 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3540 case JVMTI_ERROR_FAILS_VERIFICATION :
3541 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3542 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3543 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3544 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3545 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3546 case JVMTI_ERROR_NAMES_DONT_MATCH :
3547 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3548 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3549 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3550 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3551 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3553 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3555 return JVMTI_ERROR_NONE;
3558 /* GetJLocationFormat **********************************************************
3560 This function describes the representation of jlocation used in this VM.
3562 *******************************************************************************/
3565 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3567 *format_ptr = JVMTI_JLOCATION_OTHER;
3568 return JVMTI_ERROR_NONE;
3572 /* GetSystemProperties ********************************************************
3574 The list of VM system property keys which may be used with GetSystemProperty
3577 *******************************************************************************/
3580 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3582 jmethodID mid, moremid;
3583 classinfo *sysclass, *propclass, *enumclass;
3584 java_objectheader *sysprop, *keys, *obj;
3589 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3590 CHECK_PHASE(JVMTI_PHASE_LIVE)
3593 if ((count_ptr == NULL) || (property_ptr == NULL))
3594 return JVMTI_ERROR_NULL_POINTER;
3596 sysclass = load_class_from_sysloader(
3597 utf_new_char_classname ("java/lang/System"));
3599 if (!sysclass) throw_main_exception_exit();
3601 mid = (jmethodID)class_resolvemethod(sysclass,
3602 utf_new_char("getProperties"),
3603 utf_new_char("()Ljava/util/Properties;"));
3604 if (!mid) throw_main_exception_exit();
3607 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3608 if (!sysprop) throw_main_exception_exit();
3610 propclass = sysprop->vftbl->class;
3612 mid = (jmethodID)class_resolvemethod(propclass,
3613 utf_new_char("size"),
3614 utf_new_char("()I"));
3615 if (!mid) throw_main_exception_exit();
3618 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3619 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3621 mid = (jmethodID)class_resolvemethod(propclass,
3622 utf_new_char("keys"),
3623 utf_new_char("()Ljava/util/Enumeration;"));
3624 if (!mid) throw_main_exception_exit();
3626 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3627 enumclass = keys->vftbl->class;
3629 moremid = (jmethodID)class_resolvemethod(enumclass,
3630 utf_new_char("hasMoreElements"),
3631 utf_new_char("()Z"));
3632 if (!moremid) throw_main_exception_exit();
3634 mid = (jmethodID)class_resolvemethod(propclass,
3635 utf_new_char("nextElement"),
3636 utf_new_char("()Ljava/lang/Object;"));
3637 if (!mid) throw_main_exception_exit();
3640 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3641 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3642 ch = javastring_tochar(obj);
3643 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3644 memcpy(*property_ptr[i], ch, strlen (ch));
3645 MFREE(ch,char,strlen(ch)+1);
3649 return JVMTI_ERROR_NONE;
3653 /* GetSystemProperty **********************************************************
3655 Return a VM system property value given the property key.
3657 *******************************************************************************/
3660 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3663 classinfo *sysclass, *propclass;
3664 java_objectheader *sysprop, *obj;
3668 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3669 CHECK_PHASE(JVMTI_PHASE_LIVE)
3672 if ((value_ptr == NULL) || (property == NULL))
3673 return JVMTI_ERROR_NULL_POINTER;
3675 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3676 if (!sysclass) throw_main_exception_exit();
3678 mid = (jmethodID)class_resolvemethod(sysclass,
3679 utf_new_char("getProperties"),
3680 utf_new_char("()Ljava/util/Properties;"));
3681 if (!mid) throw_main_exception_exit();
3683 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3685 propclass = sysprop->vftbl->class;
3687 mid = (jmethodID)class_resolvemethod(propclass,
3688 utf_new_char("getProperty"),
3689 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3690 if (!mid) throw_main_exception_exit();
3692 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3693 NULL, sysprop, mid, javastring_new_from_ascii(property));
3694 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3696 ch = javastring_tochar(obj);
3697 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3698 memcpy(*value_ptr, ch, strlen (ch));
3699 MFREE(ch,char,strlen(ch)+1);
3701 return JVMTI_ERROR_NONE;
3705 /* SetSystemProperty **********************************************************
3707 Set a VM system property value.
3709 *******************************************************************************/
3712 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3715 classinfo *sysclass, *propclass;
3716 java_objectheader *sysprop;
3719 CHECK_PHASE(JVMTI_PHASE_START)
3722 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3723 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3725 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3726 if (!sysclass) throw_main_exception_exit();
3728 mid = (jmethodID)class_resolvemethod(sysclass,
3729 utf_new_char("getProperties"),
3730 utf_new_char("()Ljava/util/Properties;"));
3731 if (!mid) throw_main_exception_exit();
3733 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3735 propclass = sysprop->vftbl->class;
3737 mid = (jmethodID)class_resolvemethod(propclass,
3738 utf_new_char("setProperty"),
3739 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3740 if (!mid) throw_main_exception_exit();
3742 _Jv_JNINativeInterface.CallObjectMethod(
3743 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3745 return JVMTI_ERROR_NONE;
3748 /* GetPhase ********************************************************************
3750 Return the current phase of VM execution
3752 *******************************************************************************/
3755 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3757 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3761 return JVMTI_ERROR_NONE;
3764 /* GetCurrentThreadCpuTimerInfo ************************************************
3768 *******************************************************************************/
3771 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3774 CHECK_PHASE(JVMTI_PHASE_START)
3775 CHECK_PHASE(JVMTI_PHASE_LIVE)
3777 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3779 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3781 return JVMTI_ERROR_NONE;
3784 /* GetCurrentThreadCpuTime ****************************************************
3788 *******************************************************************************/
3791 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3794 CHECK_PHASE(JVMTI_PHASE_START)
3795 CHECK_PHASE(JVMTI_PHASE_LIVE)
3797 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3799 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3800 return JVMTI_ERROR_NONE;
3803 /* GetThreadCpuTimerInfo ******************************************************
3807 *******************************************************************************/
3810 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3813 CHECK_PHASE(JVMTI_PHASE_START)
3814 CHECK_PHASE(JVMTI_PHASE_LIVE)
3816 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3818 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3819 return JVMTI_ERROR_NONE;
3822 /* GetThreadCpuTime ***********************************************************
3826 *******************************************************************************/
3829 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3832 CHECK_PHASE(JVMTI_PHASE_LIVE)
3834 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3835 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3836 return JVMTI_ERROR_NONE;
3839 /* GetTimerInfo ***************************************************************
3841 Get information about the GetTime timer.
3843 *******************************************************************************/
3846 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3848 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3850 info_ptr->max_value = !0x0;
3851 info_ptr->may_skip_forward = true;
3852 info_ptr->may_skip_backward = true;
3853 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3855 return JVMTI_ERROR_NONE;
3858 /* GetTime ********************************************************************
3860 Return the current value of the system timer, in nanoseconds
3862 *******************************************************************************/
3865 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3867 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3870 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3872 if (gettimeofday (&tp, NULL) == -1)
3873 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3875 *nanos_ptr = (jlong) tp.tv_sec;
3877 *nanos_ptr += (tp.tv_usec / 1000);
3879 return JVMTI_ERROR_NONE;
3882 /* GetPotentialCapabilities ***************************************************
3884 Returns the JVM TI features that can potentially be possessed by this
3885 environment at this time.
3887 *******************************************************************************/
3890 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3893 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3894 CHECK_PHASE(JVMTI_PHASE_LIVE)
3897 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3899 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3901 return JVMTI_ERROR_NONE;
3905 #define CHECK_ADD_CAPABILITY(env,CAN) \
3906 if (capabilities_ptr->CAN == 1) { \
3907 if (JVMTI_Capabilities.CAN == 0) \
3908 return JVMTI_ERROR_NOT_AVAILABLE; \
3910 env->capabilities.CAN = 1; \
3913 /* AddCapabilities ************************************************************
3915 Set new capabilities by adding the capabilities pointed to by
3916 capabilities_ptr. All previous capabilities are retained.
3918 *******************************************************************************/
3921 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3923 environment* cacao_env;
3926 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3927 CHECK_PHASE(JVMTI_PHASE_LIVE)
3930 if ((env == NULL) || (capabilities_ptr == NULL))
3931 return JVMTI_ERROR_NULL_POINTER;
3933 cacao_env = (environment*)env;
3935 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3936 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3937 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3938 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3939 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3940 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3941 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3942 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3943 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3944 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3945 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3946 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3947 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3948 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3949 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3950 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3951 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3952 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3953 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3965 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3966 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3967 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3970 return JVMTI_ERROR_NONE;
3974 #define CHECK_DEL_CAPABILITY(env,CAN) \
3975 if (capabilities_ptr->CAN == 1) \
3976 env->capabilities.CAN = 0;
3978 /* RelinquishCapabilities *****************************************************
3980 Relinquish the capabilities pointed to by capabilities_ptr.
3982 *******************************************************************************/
3985 RelinquishCapabilities (jvmtiEnv * env,
3986 const jvmtiCapabilities * capabilities_ptr)
3988 environment* cacao_env;
3991 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3992 CHECK_PHASE(JVMTI_PHASE_LIVE)
3995 if ((env == NULL) || (capabilities_ptr == NULL))
3996 return JVMTI_ERROR_NULL_POINTER;
3998 cacao_env = (environment*)env;
4000 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
4001 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4002 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4003 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4004 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4005 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4006 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4007 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4008 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4009 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4010 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4011 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4012 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4013 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4014 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4015 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4016 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4017 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4018 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4030 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4031 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4032 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4034 return JVMTI_ERROR_NONE;
4037 /* GetAvailableProcessors *****************************************************
4039 Get number of processors available to the virtual machine.
4041 *******************************************************************************/
4044 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4047 CHECK_PHASE(JVMTI_PHASE_START)
4048 CHECK_PHASE(JVMTI_PHASE_LIVE)
4051 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4053 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4055 *processor_count_ptr = 1; /* where do I get this ?*/
4057 return JVMTI_ERROR_NONE;
4060 /* GetEnvironmentLocalStorage **************************************************
4062 Called by the agent to get the value of the JVM TI environment-local storage.
4064 *******************************************************************************/
4067 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4069 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4071 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4073 return JVMTI_ERROR_NONE;
4076 /* SetEnvironmentLocalStorage **************************************************
4078 The VM stores a pointer value associated with each environment. Agents can
4079 allocate memory in which they store environment specific information.
4081 *******************************************************************************/
4084 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4086 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4088 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4090 return JVMTI_ERROR_NONE;
4093 /* AddToBootstrapClassLoaderSearch ********************************************
4095 After the bootstrap class loader unsuccessfully searches for a class, the
4096 specified platform-dependent search path segment will be searched as well.
4098 *******************************************************************************/
4101 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4107 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4110 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4112 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4113 tmp_bcp = MNEW(char, ln);
4114 strcat(tmp_bcp, bootclasspath);
4115 strcat(tmp_bcp, ":");
4116 strcat(tmp_bcp, segment);
4117 MFREE(bootclasspath,char,ln);
4118 bootclasspath = tmp_bcp;
4120 return JVMTI_ERROR_NONE;
4123 /* SetVerboseFlag *************************************************************
4125 Control verbose output. This is the output which typically is sent to stderr
4127 *******************************************************************************/
4130 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4133 case JVMTI_VERBOSE_OTHER:
4134 /* where is this defined ?
4138 case JVMTI_VERBOSE_GC:
4139 opt_verbosegc = value;
4141 case JVMTI_VERBOSE_CLASS:
4142 loadverbose = value;
4144 case JVMTI_VERBOSE_JNI:
4147 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4149 return JVMTI_ERROR_NONE;
4152 /* GetObjectSize **************************************************************
4154 For the object object return the size.
4156 *******************************************************************************/
4159 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4162 CHECK_PHASE(JVMTI_PHASE_START)
4163 CHECK_PHASE(JVMTI_PHASE_LIVE)
4166 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4167 if (!builtin_instanceof(object,class_java_lang_Object))
4168 return JVMTI_ERROR_INVALID_OBJECT;
4170 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4172 return JVMTI_ERROR_NONE;
4176 /* *****************************************************************************
4178 Environment variables
4180 *******************************************************************************/
4182 static jvmtiCapabilities JVMTI_Capabilities = {
4183 0, /* can_tag_objects */
4184 0, /* can_generate_field_modification_events */
4185 0, /* can_generate_field_access_events */
4186 1, /* can_get_bytecodes */
4187 0, /* can_get_synthetic_attribute */
4189 #if defined(ENABLE_THREADS)
4190 1, /* can_get_owned_monitor_info */
4191 1, /* can_get_current_contended_monitor */
4193 0, /* can_get_owned_monitor_info */
4194 0, /* can_get_current_contended_monitor */
4197 0, /* can_get_monitor_info */
4198 0, /* can_pop_frame */
4199 0, /* can_redefine_classes */
4200 0, /* can_signal_thread */
4201 1, /* can_get_source_file_name */
4202 1, /* can_get_line_numbers */
4203 0, /* can_get_source_debug_extension */
4204 0, /* can_access_local_variables */
4205 0, /* can_maintain_original_method_order */
4206 0, /* can_generate_single_step_events */
4207 1, /* can_generate_exception_events */
4208 0, /* can_generate_frame_pop_events */
4209 1, /* can_generate_breakpoint_events */
4210 1, /* can_suspend */
4211 0, /* can_redefine_any_class */
4212 0, /* can_get_current_thread_cpu_time */
4213 0, /* can_get_thread_cpu_time */
4214 1, /* can_generate_method_entry_events */
4215 0, /* can_generate_method_exit_events */
4216 0, /* can_generate_all_class_hook_events */
4217 0, /* can_generate_compiled_method_load_events */
4218 1, /* can_generate_monitor_events */
4219 0, /* can_generate_vm_object_alloc_events */
4220 0, /* can_generate_native_method_bind_events */
4221 0, /* can_generate_garbage_collection_events */
4222 0, /* can_generate_object_free_events */
4225 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4227 &SetEventNotificationMode,
4235 &GetOwnedMonitorInfo,
4236 &GetCurrentContendedMonitor,
4238 &GetTopThreadGroups,
4239 &GetThreadGroupInfo,
4240 &GetThreadGroupChildren,
4262 &RawMonitorNotifyAll,
4266 &SetFieldAccessWatch,
4267 &ClearFieldAccessWatch,
4268 &SetFieldModificationWatch,
4269 &ClearFieldModificationWatch,
4279 &GetImplementedInterfaces,
4284 &GetObjectMonitorUsage,
4286 &GetFieldDeclaringClass,
4290 &GetMethodDeclaringClass,
4291 &GetMethodModifiers,
4295 &GetLineNumberTable,
4297 &GetLocalVariableTable,
4304 &GetClassLoaderClasses,
4315 &GetSourceDebugExtension,
4326 &GetThreadListStackTraces,
4327 &GetThreadLocalStorage,
4328 &SetThreadLocalStorage,
4333 &ForceGarbageCollection,
4334 &IterateOverObjectsReachableFromObject,
4335 &IterateOverReachableObjects,
4337 &IterateOverInstancesOfClass,
4339 &GetObjectsWithTags,
4345 &SetJNIFunctionTable,
4346 &GetJNIFunctionTable,
4349 &GetExtensionFunctions,
4350 &GetExtensionEvents,
4351 &SetExtensionEventCallback,
4352 &DisposeEnvironment,
4354 &GetJLocationFormat,
4355 &GetSystemProperties,
4359 &GetCurrentThreadCpuTimerInfo,
4360 &GetCurrentThreadCpuTime,
4361 &GetThreadCpuTimerInfo,
4365 &GetPotentialCapabilities,
4368 &RelinquishCapabilities,
4369 &GetAvailableProcessors,
4372 &GetEnvironmentLocalStorage,
4373 &SetEnvironmentLocalStorage,
4374 &AddToBootstrapClassLoaderSearch,
4382 /* jvmti_set_phase ************************************************************
4384 sets a new jvmti phase a fires an apropriate event.
4386 *******************************************************************************/
4388 void jvmti_set_phase(jvmtiPhase p) {
4391 fprintf (stderr,"set JVMTI phase %d\n",p);
4395 case JVMTI_PHASE_ONLOAD:
4398 case JVMTI_PHASE_PRIMORDIAL:
4401 case JVMTI_PHASE_START:
4403 d.ev = JVMTI_EVENT_VM_START;
4405 case JVMTI_PHASE_LIVE:
4407 d.ev = JVMTI_EVENT_VM_INIT;
4408 jvmti_fireEvent(&d);
4409 /* thread start event for main thread */
4410 d.ev = JVMTI_EVENT_THREAD_START;
4412 case JVMTI_PHASE_DEAD:
4414 d.ev = JVMTI_EVENT_VM_DEATH;
4417 log_text("wrong jvmti phase to be set");
4421 jvmti_fireEvent(&d);
4425 /* jvmti_new_environment ******************************************************
4427 creates a new JVMTI environment
4429 *******************************************************************************/
4431 jvmtiEnv* jvmti_new_environment() {
4435 envs = heap_allocate(sizeof(environment),true,NULL);
4439 while (env->next != NULL) env = env->next;
4440 env->next = heap_allocate(sizeof(environment),true,NULL);
4444 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4445 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4446 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4447 sizeof(jvmtiEventModeLL));
4448 /* To possess a capability, the agent must add the capability.*/
4449 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4450 RelinquishCapabilities(&(env->env),&(env->capabilities));
4451 env->EnvironmentLocalStorage = NULL;
4454 /* initialize cacao debugging facilities */
4455 jvmti_cacao_debug_init();
4457 return (jvmtiEnv*)env;
4460 /* jvmti_agentload ************************************************************
4462 loads the indicated shared library containing the jvmti agent and calls the
4463 Agent_OnLoad function.
4465 *******************************************************************************/
4467 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4473 len = strlen(opt_arg);
4475 /* separate arguments */
4477 while ((opt_arg[i] != '=') && (i < len))
4483 arg = &opt_arg[i + 1];
4490 *libname = GCMNEW(char, i);
4492 strcpy(*libname, opt_arg);
4497 len = strlen("lib") + i + strlen(".so") + strlen("0");
4499 *libname = GCMNEW(char, len);
4501 strcpy(*libname, "lib");
4502 strcat(*libname, opt_arg);
4503 strcat(*libname, ".so");
4506 /* try to open the library */
4508 if (!(*handle = lt_dlopen(*libname))) {
4509 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4513 /* resolve Agent_OnLoad function */
4514 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4515 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4519 /* resolve Agent_UnLoad function */
4520 unload = lt_dlsym(*handle, "Agent_Unload");
4523 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4524 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4526 if (retval != 0) exit (retval);
4529 /* jvmti_agentunload **********************************************************
4531 calls the Agent_UnLoad function in the jvmti agent if present.
4533 *******************************************************************************/
4535 void jvmti_agentunload() {
4536 if (unload != NULL) {
4537 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4538 ((JavaVM*) &_Jv_JNIInvokeInterface);
4544 * These are local overrides for various environment variables in Emacs.
4545 * Please do not remove this and leave it at the end of the file, where
4546 * Emacs will automagically detect them.
4547 * ---------------------------------------------------------------------
4550 * indent-tabs-mode: t
4554 * vim:noexpandtab:sw=4:ts=4: