1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006, 2007, 2008
5 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 #include <linux/unistd.h>
34 #include <sys/types.h>
39 #include "native/jni.h"
40 #include "native/native.h"
41 #include "native/jvmti/cacaodbg.h"
42 #include "native/jvmti/jvmti.h"
43 #include "vm/jit/stacktrace.h"
44 #include "vm/global.h"
45 #include "vm/loader.h"
46 #include "vm/builtin.h"
47 #include "vm/jit/asmpart.h"
49 #include "vm/classcache.h"
50 #include "mm/gc-common.h"
51 #include "toolbox/logging.h"
52 #include "vm/options.h"
53 #include "vm/stringlocal.h"
54 #include "mm/memory.h"
55 #include "threads/mutex.h"
56 #include "threads/thread.h"
57 #include "threads/lock-common.h"
58 #include "vm/exceptions.h"
59 #include "native/include/java_util_Vector.h"
60 #include "native/include/java_io_PrintStream.h"
61 #include "native/include/java_io_InputStream.h"
62 #include "native/include/java_lang_Cloneable.h"
63 #include "native/include/java_lang_ThreadGroup.h"
64 #include "native/include/java_lang_VMObject.h"
65 #include "native/include/java_lang_VMSystem.h"
66 #include "native/include/java_lang_VMClass.h"
68 #include "boehm-gc/include/gc.h"
70 #if defined(ENABLE_THREADS)
78 typedef struct _environment environment;
79 static environment *envs=NULL;
82 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
84 static jvmtiPhase phase;
85 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
86 struct _jvmtiEventModeLL {
89 jvmtiEventModeLL *next;
92 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
93 struct _jvmtiThreadLocalStorage{
96 jvmtiThreadLocalStorage *next;
102 jvmtiEventCallbacks callbacks;
103 /* table for enabled/disabled jvmtiEvents - first element contains global
105 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
106 jvmtiCapabilities capabilities;
107 void *EnvironmentLocalStorage;
108 jvmtiThreadLocalStorage *tls;
111 static struct jvmtiEnv_struct JVMTI_EnvTable;
112 static jvmtiCapabilities JVMTI_Capabilities;
113 static lt_ptr unload;
115 #define CHECK_PHASE_START if (!(false
116 #define CHECK_PHASE(chkphase) || (phase == chkphase)
117 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
118 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
119 env)->capabilities.CAP == 0) \
120 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
121 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
122 JVMTI_ERROR_THREAD_NOT_ALIVE) \
123 return JVMTI_ERROR_THREAD_NOT_ALIVE;
128 /* check_thread_is_alive *******************************************************
130 checks if the given thread is alive
132 *******************************************************************************/
133 static jvmtiError check_thread_is_alive(jthread t) {
134 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
135 if(((java_lang_Thread*) t)->vmThread == NULL)
136 return JVMTI_ERROR_THREAD_NOT_ALIVE;
137 return JVMTI_ERROR_NONE;
140 /* execute_callback ************************************************************
142 executes the registerd callbacks for the given jvmti event with parameter
143 in the data structure.
145 *******************************************************************************/
146 static void execute_callback(jvmtiEvent e, functionptr ec,
147 genericEventData* data) {
148 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
150 fprintf(stderr,"execcallback called (event: %d)\n",e);
153 case JVMTI_EVENT_VM_INIT:
154 if (phase != JVMTI_PHASE_LIVE) return;
155 case JVMTI_EVENT_THREAD_START:
156 case JVMTI_EVENT_THREAD_END:
157 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
158 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
161 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
162 if ((phase == JVMTI_PHASE_START) ||
163 (phase == JVMTI_PHASE_LIVE) ||
164 (phase == JVMTI_PHASE_PRIMORDIAL))
165 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
170 data->protection_domain,
173 data->new_class_data_len,
174 data->new_class_data);
176 /* if class data has been modified use it as class data for other agents
177 waiting for the same event */
178 if (data->new_class_data != NULL) {
179 data->jint1 = *(data->new_class_data_len);
180 data->class_data = *(data->new_class_data);
185 case JVMTI_EVENT_CLASS_PREPARE:
186 case JVMTI_EVENT_CLASS_LOAD:
187 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
188 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
189 data->thread, data->klass);
192 case JVMTI_EVENT_VM_DEATH:
193 if (phase != JVMTI_PHASE_LIVE) return;
194 case JVMTI_EVENT_VM_START:
195 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
196 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
199 case JVMTI_EVENT_NATIVE_METHOD_BIND:
200 if ((phase == JVMTI_PHASE_START) ||
201 (phase == JVMTI_PHASE_LIVE) ||
202 (phase == JVMTI_PHASE_PRIMORDIAL))
203 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
207 data->new_address_ptr);
211 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
212 if ((phase == JVMTI_PHASE_START) ||
213 (phase == JVMTI_PHASE_LIVE) ||
214 (phase == JVMTI_PHASE_PRIMORDIAL))
215 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
224 if (phase != JVMTI_PHASE_LIVE) return;
226 case JVMTI_EVENT_EXCEPTION:
227 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
233 data->catch_location);
236 case JVMTI_EVENT_EXCEPTION_CATCH:
237 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
244 case JVMTI_EVENT_BREAKPOINT:
245 case JVMTI_EVENT_SINGLE_STEP:
246 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
252 case JVMTI_EVENT_FRAME_POP:
253 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
260 case JVMTI_EVENT_FIELD_ACCESS:
261 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
270 case JVMTI_EVENT_FIELD_MODIFICATION:
272 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
279 data->signature_type,
283 case JVMTI_EVENT_METHOD_ENTRY:
284 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
289 case JVMTI_EVENT_METHOD_EXIT:
290 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
297 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
298 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
307 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
308 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
313 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
314 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
315 case JVMTI_EVENT_DATA_DUMP_REQUEST:
316 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
319 case JVMTI_EVENT_MONITOR_WAIT:
320 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
326 case JVMTI_EVENT_MONITOR_WAITED:
327 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
334 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
335 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
336 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
341 case JVMTI_EVENT_OBJECT_FREE:
342 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
345 case JVMTI_EVENT_VM_OBJECT_ALLOC:
346 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
353 log_text ("unknown event");
360 /* dofireEvent ******************************************************************
362 sends event if it is enabled either globally or for some threads
364 *******************************************************************************/
365 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
367 jvmtiEventModeLL *evm;
371 while (env != NULL) {
372 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
373 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
374 /* test if the event is enable for some threads */
375 while (evm != NULL) {
376 if (evm->mode == JVMTI_ENABLE) {
378 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
380 data->jvmti_env=&env->env;
381 execute_callback(e, ec, data);
386 } else { /* event enabled globally */
387 data->jvmti_env=&env->env;
388 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
389 if (ec != NULL) execute_callback(e, ec, data);
397 /* fireEvent ******************************************************************
399 fire event callback with data arguments. This function mainly fills the
402 *******************************************************************************/
403 void jvmti_fireEvent(genericEventData* d) {
405 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
407 if (d->ev == JVMTI_EVENT_VM_START)
410 thread = jvmti_get_current_thread();
414 dofireEvent(d->ev,d);
418 /* SetEventNotificationMode ****************************************************
420 Control the generation of events
422 *******************************************************************************/
425 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
426 jvmtiEvent event_type, jthread event_thread, ...)
428 environment* cacao_env;
429 jvmtiEventModeLL *ll;
432 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
433 CHECK_PHASE(JVMTI_PHASE_LIVE)
436 if(event_thread != NULL) {
437 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
438 return JVMTI_ERROR_INVALID_THREAD;
439 CHECK_THREAD_IS_ALIVE(event_thread);
442 cacao_env = (environment*) env;
443 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
444 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
446 switch (event_type) { /* check capability and set system breakpoint */
447 case JVMTI_EVENT_EXCEPTION:
448 case JVMTI_EVENT_EXCEPTION_CATCH:
449 CHECK_CAPABILITY(env,can_generate_exception_events)
451 case JVMTI_EVENT_SINGLE_STEP:
452 CHECK_CAPABILITY(env,can_generate_single_step_events)
454 case JVMTI_EVENT_FRAME_POP:
455 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
457 case JVMTI_EVENT_BREAKPOINT:
458 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
460 case JVMTI_EVENT_FIELD_ACCESS:
461 CHECK_CAPABILITY(env,can_generate_field_access_events)
463 case JVMTI_EVENT_FIELD_MODIFICATION:
464 CHECK_CAPABILITY(env,can_generate_field_modification_events)
466 case JVMTI_EVENT_METHOD_ENTRY:
467 CHECK_CAPABILITY(env,can_generate_method_entry_events)
469 case JVMTI_EVENT_METHOD_EXIT:
470 CHECK_CAPABILITY(env, can_generate_method_exit_events)
472 case JVMTI_EVENT_NATIVE_METHOD_BIND:
473 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
475 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
476 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
477 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
479 case JVMTI_EVENT_MONITOR_WAIT:
480 case JVMTI_EVENT_MONITOR_WAITED:
481 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
482 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
483 CHECK_CAPABILITY(env,can_generate_monitor_events)
485 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
486 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
487 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
489 case JVMTI_EVENT_OBJECT_FREE:
490 CHECK_CAPABILITY(env,can_generate_object_free_events)
492 case JVMTI_EVENT_VM_OBJECT_ALLOC:
493 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
496 /* all other events are required */
497 if ((event_type < JVMTI_EVENT_START_ENUM) ||
498 (event_type > JVMTI_EVENT_END_ENUM))
499 return JVMTI_ERROR_INVALID_EVENT_TYPE;
504 if (event_thread != NULL) {
505 /* thread level control */
506 if ((JVMTI_EVENT_VM_INIT == mode) ||
507 (JVMTI_EVENT_VM_DEATH == mode) ||
508 (JVMTI_EVENT_VM_START == mode) ||
509 (JVMTI_EVENT_THREAD_START == mode) ||
510 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
511 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
512 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
513 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
514 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
515 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
516 while (ll->next != NULL) {
518 if (ll->event_thread == event_thread) {
520 return JVMTI_ERROR_NONE;
523 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
527 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
531 return JVMTI_ERROR_NONE;
534 /* GetAllThreads ***************************************************************
538 *******************************************************************************/
541 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
542 jthread ** threads_ptr)
544 threadobject** threads;
549 CHECK_PHASE(JVMTI_PHASE_LIVE)
552 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
553 return JVMTI_ERROR_NULL_POINTER;
555 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
556 if (retval != JVMTI_ERROR_NONE) return retval;
559 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
561 for (i=0; i<*threads_count_ptr; i++)
562 (*threads_ptr)[i] = threads[i]->o.thread;
564 return JVMTI_ERROR_NONE;
568 /* SuspendThread ***************************************************************
570 Suspend specified thread
572 *******************************************************************************/
575 SuspendThread (jvmtiEnv * env, jthread thread)
578 CHECK_PHASE(JVMTI_PHASE_LIVE)
580 CHECK_CAPABILITY(env,can_suspend);
582 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
583 if (!builtin_instanceof(thread,class_java_lang_Thread))
584 return JVMTI_ERROR_INVALID_THREAD;
585 CHECK_THREAD_IS_ALIVE(thread);
587 /* threads_suspend_thread will implement suspend
588 threads_suspend_thread (
589 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
591 return JVMTI_ERROR_NONE;
594 /* ResumeThread ***************************************************************
596 Resume a suspended thread
598 *******************************************************************************/
601 ResumeThread (jvmtiEnv * env, jthread thread)
604 CHECK_PHASE(JVMTI_PHASE_LIVE)
606 CHECK_CAPABILITY(env,can_suspend);
608 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
609 if (!builtin_instanceof(thread,class_java_lang_Thread))
610 return JVMTI_ERROR_INVALID_THREAD;
611 CHECK_THREAD_IS_ALIVE(thread);
613 /* threads_resume_thread will implement resume
614 threads_resume_thread (
615 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
617 return JVMTI_ERROR_NONE;
620 /* StopThread *****************************************************************
622 Send asynchronous exception to the specified thread. Similar to
623 java.lang.Thread.stop(). Used to kill thread.
625 *******************************************************************************/
628 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
631 CHECK_PHASE(JVMTI_PHASE_LIVE)
633 CHECK_CAPABILITY(env,can_signal_thread);
635 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
636 return JVMTI_ERROR_NOT_AVAILABLE;
638 return JVMTI_ERROR_NONE;
641 /* InterruptThread ************************************************************
643 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
645 *******************************************************************************/
648 InterruptThread (jvmtiEnv * env, jthread thread)
651 CHECK_PHASE(JVMTI_PHASE_LIVE)
653 CHECK_CAPABILITY(env,can_signal_thread)
655 #if defined(ENABLE_THREADS)
656 if(!builtin_instanceof(thread,class_java_lang_Thread))
657 return JVMTI_ERROR_INVALID_THREAD;
659 CHECK_THREAD_IS_ALIVE(thread);
661 threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
664 return JVMTI_ERROR_NONE;
666 return JVMTI_ERROR_NOT_AVAILABLE;
670 /* GetThreadInfo ***************************************************************
672 Get thread information. Details of the specified thread are stored in the
673 jvmtiThreadInfo structure.
675 *******************************************************************************/
678 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
681 java_lang_Thread* th = (java_lang_Thread*)t;
685 CHECK_PHASE(JVMTI_PHASE_LIVE)
688 info_ptr->priority=(jint)th->priority;
689 info_ptr->is_daemon=(jboolean)th->daemon;
690 info_ptr->thread_group=(jthreadGroup)th->group;
691 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
693 name = javastring_toutf(th->name,false);
694 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
695 utf_sprint_convert_to_latin1(info_ptr->name, name);
697 return JVMTI_ERROR_NONE;
700 /* GetOwnedMonitorInfo *********************************************************
702 Gets all monitors owned by the specified thread
704 *******************************************************************************/
707 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
708 jint * owned_monitor_count_ptr,
709 jobject ** owned_monitors_ptr)
712 java_objectheader **om;
713 lock_record_pool_t* lrp;
717 CHECK_PHASE(JVMTI_PHASE_LIVE)
719 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
721 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
722 return JVMTI_ERROR_NULL_POINTER;
724 if (thread == NULL) {
725 t = jvmti_get_current_thread();
727 if(!builtin_instanceof(thread,class_java_lang_Thread))
728 return JVMTI_ERROR_INVALID_THREAD;
730 CHECK_THREAD_IS_ALIVE(thread);
731 t = (threadobject*) thread;
734 #if defined(ENABLE_THREADS)
736 om=MNEW(java_objectheader*,size);
738 mutex_lock(&lock_global_pool_lock);
739 lrp=lock_global_pool;
741 /* iterate over all lock record pools */
742 while (lrp != NULL) {
743 /* iterate over every lock record in a pool */
744 for (j=0; j<lrp->header.size; j++) {
745 /* if the lock record is owned by the given thread add it to
747 if(lrp->lr[j].owner == t) {
749 MREALLOC(om, java_objectheader*, size, size * 2);
752 om[i] = lrp->lr[j].obj;
756 lrp=lrp->header.next;
759 mutex_unlock(&lock_global_pool_lock);
761 *owned_monitors_ptr =
762 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
763 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
764 MFREE(om, java_objectheader*, size);
766 *owned_monitor_count_ptr = i;
770 return JVMTI_ERROR_NONE;
773 /* GetCurrentContendedMonitor *************************************************
775 Get the object the specified thread waits for.
777 *******************************************************************************/
780 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
781 jobject * monitor_ptr)
784 lock_record_pool_t* lrp;
786 lock_waiter_t* waiter;
789 CHECK_PHASE(JVMTI_PHASE_LIVE)
791 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
793 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
796 if (thread == NULL) {
797 t = jvmti_get_current_thread();
799 if(!builtin_instanceof(thread,class_java_lang_Thread))
800 return JVMTI_ERROR_INVALID_THREAD;
802 CHECK_THREAD_IS_ALIVE(thread);
803 t = (threadobject*) thread;
806 #if defined(ENABLE_THREADS)
808 mutex_lock(&lock_global_pool_lock);
810 lrp=lock_global_pool;
812 /* iterate over all lock record pools */
813 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
814 /* iterate over every lock record in a pool */
815 for (j=0; j<lrp->header.size; j++) {
816 /* iterate over every thread that is wait on this lock record */
817 waiter = lrp->lr[j].waiters;
818 while (waiter != NULL)
819 /* if the waiting thread equals to the given thread we are
820 done. Stop iterateting. */
821 if(waiter->waiter == t) {
822 *monitor_ptr=lrp->lr[j].obj;
826 lrp=lrp->header.next;
829 mutex_unlock(&lock_global_pool_lock);
833 return JVMTI_ERROR_NONE;
837 jvmtiStartFunction sf;
843 static void *threadstartup(void *t) {
844 runagentparam *rap = (runagentparam*)t;
845 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
849 /* RunAgentThread *************************************************************
851 Starts the execution of an agent thread of the specified native function
852 within the specified thread
854 *******************************************************************************/
857 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
858 const void *arg, jint priority)
860 pthread_attr_t threadattr;
861 struct sched_param sp;
865 CHECK_PHASE(JVMTI_PHASE_LIVE)
868 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
869 return JVMTI_ERROR_INVALID_THREAD;
870 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
871 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
872 (priority > JVMTI_THREAD_MAX_PRIORITY))
873 return JVMTI_ERROR_INVALID_PRIORITY;
875 /* XXX: Threads started with this function should not be visible to
876 Java programming language queries but are included in JVM TI queries */
879 rap.arg = (void*)arg;
882 #if defined(ENABLE_THREADS)
883 pthread_attr_init(&threadattr);
884 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
885 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
886 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
888 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
889 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
891 pthread_attr_setschedparam(&threadattr,&sp);
892 if (pthread_create(&((threadobject*)
893 thread)->tid, &threadattr, &threadstartup, &rap)) {
894 log_text("pthread_create failed");
899 return JVMTI_ERROR_NONE;
903 /* GetTopThreadGroups *********************************************************
905 Get all top-level thread groups in the VM.
907 *******************************************************************************/
910 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
911 jthreadGroup ** groups_ptr)
913 jint threads_count_ptr;
914 threadobject *threads_ptr;
916 jthreadGroup **tg,*ttgp;
919 CHECK_PHASE(JVMTI_PHASE_LIVE)
922 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
923 return JVMTI_ERROR_NULL_POINTER;
925 #if defined(ENABLE_THREADS)
926 tg = MNEW(jthreadGroup*,size);
928 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
929 return JVMTI_ERROR_INTERNAL;
931 for (i=0;i<threads_count_ptr;i++){
932 if (threads_ptr[i].o.thread->group == NULL) {
933 log_text("threadgroup not set");
934 return JVMTI_ERROR_INTERNAL;
936 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
939 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
944 MREALLOC(tg,jthreadGroup*,size,size*2);
953 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
954 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
955 MFREE(tg,jthreadGroup*,size);
957 *group_count_ptr = x;
960 return JVMTI_ERROR_NOT_AVAILABLE;
962 return JVMTI_ERROR_NONE;
966 /* GetThreadGroupInfo *********************************************************
968 Get information about the specified thread group.
970 *******************************************************************************/
973 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
974 jvmtiThreadGroupInfo * info_ptr)
978 java_lang_ThreadGroup* grp;
981 CHECK_PHASE(JVMTI_PHASE_LIVE)
984 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
985 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
986 return JVMTI_ERROR_INVALID_THREAD_GROUP;
988 grp = (java_lang_ThreadGroup*)group;
990 info_ptr->parent = (jthreadGroup)
991 Java_java_lang_VMObject_clone(NULL,
992 (jclass)grp->header.vftbl->class,
993 (java_lang_Cloneable*) &grp->parent);
995 name = javastring_tochar((java_objectheader*)grp->name);
997 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
998 strncpy(info_ptr->name,name,size);
999 info_ptr->max_priority= (jint)grp->maxpri;
1000 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1002 return JVMTI_ERROR_NONE;
1006 /* GetThreadGroupChildren *****************************************************
1008 Get the live threads and active subgroups in this thread group.
1010 *******************************************************************************/
1013 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1014 jint * thread_count_ptr, jthread ** threads_ptr,
1015 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1017 java_lang_ThreadGroup* tgp;
1020 CHECK_PHASE(JVMTI_PHASE_LIVE)
1023 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1024 (group_count_ptr == NULL) || (groups_ptr == NULL))
1025 return JVMTI_ERROR_NULL_POINTER;
1027 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1028 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1030 tgp = (java_lang_ThreadGroup*)group;
1032 *thread_count_ptr = (jint)tgp->threads->elementCount;
1035 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1037 memcpy(*threads_ptr, &tgp->threads->elementData,
1038 (*thread_count_ptr)*sizeof(java_objectarray*));
1040 *group_count_ptr = (jint) tgp->groups->elementCount;
1043 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1045 memcpy(*groups_ptr, &tgp->threads->elementData,
1046 (*group_count_ptr)*sizeof(jthreadGroup*));
1048 return JVMTI_ERROR_NONE;
1052 /* getcacaostacktrace *********************************************************
1054 Helper function that retrives stack trace for specified thread.
1056 *******************************************************************************/
1058 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1062 if (thread == NULL) {
1063 t = jvmti_get_current_thread();
1064 *trace = stacktrace_create(t);
1066 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1067 /* if (t != jvmti_get_current_thread())
1068 resume = threads_suspend_thread_if_running(thread);
1070 *trace = stacktrace_create(thread );
1073 threads_resume_thread ( thread );*/
1076 return JVMTI_ERROR_NONE;
1080 /* GetFrameCount **************************************************************
1083 Get the number of frames in the specified thread's stack. Calling function
1084 has to take care of suspending/resuming thread.
1086 *******************************************************************************/
1089 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1091 stacktracebuffer* trace;
1095 CHECK_PHASE(JVMTI_PHASE_LIVE)
1098 if (thread != NULL){
1099 if(!builtin_instanceof(thread,class_java_lang_Thread))
1100 return JVMTI_ERROR_INVALID_THREAD;
1102 CHECK_THREAD_IS_ALIVE(thread);
1105 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1107 er = getcacaostacktrace(&trace, thread);
1108 if (er == JVMTI_ERROR_NONE) {
1113 *count_ptr = trace->used;
1116 return JVMTI_ERROR_NONE;
1120 /* GetThreadState **************************************************************
1122 Get the state of a thread.
1124 *******************************************************************************/
1127 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1129 java_lang_Thread* th = (java_lang_Thread*)thread;
1130 threadobject* t = (threadobject*)th->vmThread;
1133 CHECK_PHASE(JVMTI_PHASE_LIVE)
1136 if(!builtin_instanceof(thread,class_java_lang_Thread))
1137 return JVMTI_ERROR_INVALID_THREAD;
1139 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1141 *thread_state_ptr = 0;
1142 #if defined(ENABLE_THREADS)
1143 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1145 if (((threadobject*)th->vmThread)->tid == 0)
1146 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1149 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1150 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1151 /* XXX todo - info not available */
1152 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1153 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1154 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1155 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1156 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1157 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1158 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1159 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1160 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1161 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1164 return JVMTI_ERROR_INTERNAL;
1167 return JVMTI_ERROR_NONE;
1171 /* GetFrameLocation ************************************************************
1173 Get the location of the instruction currently executing
1175 *******************************************************************************/
1178 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1179 jmethodID * method_ptr, jlocation * location_ptr)
1181 stackframeinfo_t *sfi;
1186 CHECK_PHASE(JVMTI_PHASE_LIVE)
1189 if (thread == NULL) {
1190 th = jvmti_get_current_thread();
1192 if(!builtin_instanceof(thread,class_java_lang_Thread))
1193 return JVMTI_ERROR_INVALID_THREAD;
1195 CHECK_THREAD_IS_ALIVE(thread);
1196 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1199 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1201 if ((method_ptr == NULL)&&(location_ptr == NULL))
1202 return JVMTI_ERROR_NULL_POINTER;
1204 sfi = th->_stackframeinfo;
1207 while ((sfi != NULL) && (i<depth)) {
1212 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1214 *method_ptr=(jmethodID)sfi->code->m;
1215 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1217 return JVMTI_ERROR_NONE;
1221 /* NotifyFramePop *************************************************************
1225 *******************************************************************************/
1228 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1231 CHECK_PHASE(JVMTI_PHASE_LIVE)
1233 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1235 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1236 return JVMTI_ERROR_NONE;
1239 /* GetLocalObject *************************************************************
1243 *******************************************************************************/
1246 GetLocalObject (jvmtiEnv * env,
1247 jthread thread, jint depth, jint slot, jobject * value_ptr)
1250 CHECK_PHASE(JVMTI_PHASE_LIVE)
1252 CHECK_CAPABILITY(env,can_access_local_variables)
1254 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1255 return JVMTI_ERROR_NONE;
1258 /* GetLocalInt ****************************************************************
1262 *******************************************************************************/
1265 GetLocalInt (jvmtiEnv * env,
1266 jthread thread, jint depth, jint slot, jint * value_ptr)
1269 CHECK_PHASE(JVMTI_PHASE_LIVE)
1271 CHECK_CAPABILITY(env,can_access_local_variables)
1272 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1273 return JVMTI_ERROR_NONE;
1276 /* *****************************************************************************
1280 *******************************************************************************/
1283 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1287 CHECK_PHASE(JVMTI_PHASE_LIVE)
1289 CHECK_CAPABILITY(env,can_access_local_variables)
1291 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1292 return JVMTI_ERROR_NONE;
1296 /* *****************************************************************************
1300 *******************************************************************************/
1303 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1307 CHECK_PHASE(JVMTI_PHASE_LIVE)
1309 CHECK_CAPABILITY(env,can_access_local_variables)
1311 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1312 return JVMTI_ERROR_NONE;
1316 /* *****************************************************************************
1320 *******************************************************************************/
1323 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1324 jdouble * value_ptr)
1327 CHECK_PHASE(JVMTI_PHASE_LIVE)
1329 CHECK_CAPABILITY(env,can_access_local_variables)
1331 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1332 return JVMTI_ERROR_NONE;
1336 /* *****************************************************************************
1340 *******************************************************************************/
1343 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1347 CHECK_PHASE(JVMTI_PHASE_LIVE)
1349 CHECK_CAPABILITY(env,can_access_local_variables)
1351 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1352 return JVMTI_ERROR_NONE;
1356 /* *****************************************************************************
1360 *******************************************************************************/
1363 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1367 CHECK_PHASE(JVMTI_PHASE_LIVE)
1369 CHECK_CAPABILITY(env,can_access_local_variables)
1371 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1372 return JVMTI_ERROR_NONE;
1376 /* *****************************************************************************
1380 *******************************************************************************/
1383 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1387 CHECK_PHASE(JVMTI_PHASE_LIVE)
1389 CHECK_CAPABILITY(env,can_access_local_variables)
1391 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1392 return JVMTI_ERROR_NONE;
1396 /* *****************************************************************************
1400 *******************************************************************************/
1403 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1407 CHECK_PHASE(JVMTI_PHASE_LIVE)
1409 CHECK_CAPABILITY(env,can_access_local_variables)
1411 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1412 return JVMTI_ERROR_NONE;
1416 /* *****************************************************************************
1420 *******************************************************************************/
1423 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1427 CHECK_PHASE(JVMTI_PHASE_LIVE)
1429 CHECK_CAPABILITY(env,can_access_local_variables)
1431 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1432 return JVMTI_ERROR_NONE;
1436 /* CreateRawMonitor ***********************************************************
1438 This function creates a new raw monitor.
1440 *******************************************************************************/
1443 CreateRawMonitor (jvmtiEnv * env, const char *name,
1444 jrawMonitorID * monitor_ptr)
1446 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1449 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1450 CHECK_PHASE(JVMTI_PHASE_LIVE)
1453 if ((name == NULL) || (monitor_ptr == NULL))
1454 return JVMTI_ERROR_NULL_POINTER;
1456 #if defined(ENABLE_THREADS)
1457 monitor->name=javastring_new_from_ascii(name);
1459 log_text ("CreateRawMonitor not supported");
1462 return JVMTI_ERROR_NONE;
1466 /* DestroyRawMonitor **********************************************************
1468 This function destroys a raw monitor.
1470 *******************************************************************************/
1473 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1476 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1477 CHECK_PHASE(JVMTI_PHASE_LIVE)
1480 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1481 return JVMTI_ERROR_INVALID_MONITOR;
1483 #if defined(ENABLE_THREADS)
1484 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1485 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1487 lock_monitor_exit((java_objectheader *) monitor->name);
1491 log_text ("DestroyRawMonitor not supported");
1494 return JVMTI_ERROR_NONE;
1498 /* RawMonitorEnter ************************************************************
1500 Gain exclusive ownership of a raw monitor
1502 *******************************************************************************/
1505 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1507 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1508 return JVMTI_ERROR_INVALID_MONITOR;
1510 #if defined(ENABLE_THREADS)
1511 lock_monitor_enter((java_objectheader *) monitor->name);
1513 log_text ("RawMonitorEnter not supported");
1516 return JVMTI_ERROR_NONE;
1520 /* RawMonitorExit *************************************************************
1524 *******************************************************************************/
1527 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1529 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1530 return JVMTI_ERROR_INVALID_MONITOR;
1532 #if defined(ENABLE_THREADS)
1533 /* assure current thread owns this monitor */
1534 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1535 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1537 lock_monitor_exit((java_objectheader *) monitor->name);
1539 log_text ("RawMonitorExit not supported");
1542 return JVMTI_ERROR_NONE;
1546 /* RawMonitorWait *************************************************************
1548 Wait for notification of the raw monitor.
1550 *******************************************************************************/
1553 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1555 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1556 return JVMTI_ERROR_INVALID_MONITOR;
1558 #if defined(ENABLE_THREADS)
1559 /* assure current thread owns this monitor */
1560 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1561 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1563 lock_wait_for_object(&monitor->name->header, millis,0);
1564 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1565 return JVMTI_ERROR_INTERRUPT;
1568 log_text ("RawMonitorWait not supported");
1571 return JVMTI_ERROR_NONE;
1575 /* RawMonitorNotify ***********************************************************
1577 Notify one thread waiting on the given monitor.
1579 *******************************************************************************/
1582 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1584 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1585 return JVMTI_ERROR_INVALID_MONITOR;
1587 #if defined(ENABLE_THREADS)
1588 /* assure current thread owns this monitor */
1589 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1590 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1592 lock_notify_object((java_objectheader*)&monitor->name);
1594 log_text ("RawMonitorNotify not supported");
1597 return JVMTI_ERROR_NONE;
1601 /* RawMonitorNotifyAll *********************************************************
1603 Notify all threads waiting on the given monitor.
1605 *******************************************************************************/
1608 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1610 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1611 return JVMTI_ERROR_INVALID_MONITOR;
1613 #if defined(ENABLE_THREADS)
1614 /* assure current thread owns this monitor */
1615 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1616 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1618 lock_notify_all_object((java_objectheader*)&monitor->name);
1620 log_text ("RawMonitorNotifyAll not supported");
1623 return JVMTI_ERROR_NONE;
1627 /* SetBreakpoint **************************************************************
1631 *******************************************************************************/
1634 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1637 CHECK_PHASE(JVMTI_PHASE_LIVE)
1639 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1642 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1643 return JVMTI_ERROR_NONE;
1647 /* *****************************************************************************
1651 *******************************************************************************/
1654 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1657 CHECK_PHASE(JVMTI_PHASE_LIVE)
1659 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1661 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1662 return JVMTI_ERROR_NONE;
1666 /* SetFieldAccessWatch ********************************************************
1670 *******************************************************************************/
1673 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1676 CHECK_PHASE(JVMTI_PHASE_LIVE)
1678 CHECK_CAPABILITY(env,can_generate_field_access_events)
1680 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1681 return JVMTI_ERROR_NONE;
1685 /* *****************************************************************************
1689 *******************************************************************************/
1692 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1695 CHECK_PHASE(JVMTI_PHASE_LIVE)
1697 CHECK_CAPABILITY(env,can_generate_field_access_events)
1699 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1700 return JVMTI_ERROR_NONE;
1704 /* *****************************************************************************
1708 *******************************************************************************/
1711 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1714 CHECK_PHASE(JVMTI_PHASE_LIVE)
1716 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1718 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1719 return JVMTI_ERROR_NONE;
1723 /* *****************************************************************************
1727 *******************************************************************************/
1730 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1733 CHECK_PHASE(JVMTI_PHASE_LIVE)
1735 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1737 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1738 return JVMTI_ERROR_NONE;
1742 /* Allocate ********************************************************************
1744 Allocate an area of memory through the JVM TI allocator. The allocated
1745 memory should be freed with Deallocate
1747 *******************************************************************************/
1750 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1753 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1754 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1756 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1757 if (*mem_ptr == NULL)
1758 return JVMTI_ERROR_OUT_OF_MEMORY;
1760 return JVMTI_ERROR_NONE;
1765 /* Deallocate ******************************************************************
1767 Deallocate mem using the JVM TI allocator.
1769 *******************************************************************************/
1772 Deallocate (jvmtiEnv * env, unsigned char *mem)
1774 /* let Boehm GC do the job */
1776 return JVMTI_ERROR_NONE;
1780 /* GetClassSignature ************************************************************
1782 For the class indicated by klass, return the JNI type signature and the
1783 generic signature of the class.
1785 *******************************************************************************/
1788 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1792 CHECK_PHASE(JVMTI_PHASE_START)
1793 CHECK_PHASE(JVMTI_PHASE_LIVE)
1796 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1797 if (!builtin_instanceof(klass,class_java_lang_Class))
1798 return JVMTI_ERROR_INVALID_CLASS;
1800 if (signature_ptr != NULL) {
1801 *signature_ptr = (char*)
1802 heap_allocate(sizeof(char) *
1803 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1805 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1808 if (generic_ptr!= NULL)
1809 *generic_ptr = NULL;
1811 return JVMTI_ERROR_NONE;
1814 /* GetClassStatus *************************************************************
1816 Get status of the class.
1818 *******************************************************************************/
1821 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1825 CHECK_PHASE(JVMTI_PHASE_START)
1826 CHECK_PHASE(JVMTI_PHASE_LIVE)
1829 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1830 return JVMTI_ERROR_INVALID_CLASS;
1832 if (status_ptr == NULL)
1833 return JVMTI_ERROR_NULL_POINTER;
1835 c = (classinfo*)klass;
1838 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1839 if (c->state & CLASS_LINKED)
1840 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1842 if (c->state & CLASS_INITIALIZED)
1843 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1845 if (c->state & CLASS_ERROR)
1846 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1848 if (c->vftbl->arraydesc != NULL)
1849 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1851 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1852 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1854 return JVMTI_ERROR_NONE;
1858 /* GetSourceFileName **********************************************************
1860 For the class indicated by klass, return the source file name.
1862 *******************************************************************************/
1865 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1870 CHECK_PHASE(JVMTI_PHASE_START)
1871 CHECK_PHASE(JVMTI_PHASE_LIVE)
1873 CHECK_CAPABILITY(env,can_get_source_file_name)
1875 if ((klass == NULL)||(source_name_ptr == NULL))
1876 return JVMTI_ERROR_NULL_POINTER;
1878 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1880 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1882 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1883 (*source_name_ptr)[size]='\0';
1885 return JVMTI_ERROR_NONE;
1889 /* GetClassModifiers **********************************************************
1891 For class klass return the access flags
1893 *******************************************************************************/
1896 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1899 CHECK_PHASE(JVMTI_PHASE_START)
1900 CHECK_PHASE(JVMTI_PHASE_LIVE)
1903 if (modifiers_ptr == NULL)
1904 return JVMTI_ERROR_NULL_POINTER;
1906 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1907 return JVMTI_ERROR_INVALID_CLASS;
1909 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1911 return JVMTI_ERROR_NONE;
1915 /* GetClassMethods *************************************************************
1917 For class klass return a count of methods and a list of method IDs
1919 *******************************************************************************/
1922 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1923 jmethodID ** methods_ptr)
1928 CHECK_PHASE(JVMTI_PHASE_START)
1929 CHECK_PHASE(JVMTI_PHASE_LIVE)
1932 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1933 return JVMTI_ERROR_NULL_POINTER;
1935 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1936 return JVMTI_ERROR_INVALID_CLASS;
1938 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1939 *methods_ptr = (jmethodID*)
1940 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1942 for (i=0; i<*method_count_ptr;i++)
1943 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1945 return JVMTI_ERROR_NONE;
1949 /* GetClassFields *************************************************************
1951 For the class indicated by klass, return a count of fields and a list of
1954 *******************************************************************************/
1957 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1958 jfieldID ** fields_ptr)
1961 CHECK_PHASE(JVMTI_PHASE_START)
1962 CHECK_PHASE(JVMTI_PHASE_LIVE)
1965 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1966 return JVMTI_ERROR_NULL_POINTER;
1968 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1969 *fields_ptr = (jfieldID*)
1970 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1972 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1973 sizeof(jfieldID) * (*field_count_ptr));
1975 return JVMTI_ERROR_NONE;
1979 /* GetImplementedInterfaces ***************************************************
1981 Return the direct super-interfaces of this class.
1983 *******************************************************************************/
1986 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1987 jint * interface_count_ptr,
1988 jclass ** interfaces_ptr)
1991 classref_or_classinfo *interfaces;
1995 CHECK_PHASE(JVMTI_PHASE_START)
1996 CHECK_PHASE(JVMTI_PHASE_LIVE)
1999 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
2000 return JVMTI_ERROR_NULL_POINTER;
2002 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2003 return JVMTI_ERROR_INVALID_CLASS;
2006 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2008 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2010 interfaces = ((classinfo*)klass)->interfaces;
2011 for (i=0; i<*interface_count_ptr; i++) {
2012 if (IS_CLASSREF(interfaces[i]))
2013 tmp = load_class_bootstrap(interfaces[i].ref->name);
2015 tmp = interfaces[i].cls;
2017 *interfaces_ptr[i]=tmp;
2020 return JVMTI_ERROR_NONE;
2024 /* IsInterface ****************************************************************
2026 Determines whether a class object reference represents an interface.
2028 *******************************************************************************/
2031 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2034 CHECK_PHASE(JVMTI_PHASE_START)
2035 CHECK_PHASE(JVMTI_PHASE_LIVE)
2038 if ((klass == NULL)||(is_interface_ptr == NULL))
2039 return JVMTI_ERROR_NULL_POINTER;
2041 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2043 return JVMTI_ERROR_NONE;
2046 /* IsArrayClass ***************************************************************
2048 Determines whether a class object reference represents an array.
2050 *******************************************************************************/
2053 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2056 CHECK_PHASE(JVMTI_PHASE_START)
2057 CHECK_PHASE(JVMTI_PHASE_LIVE)
2060 if (is_array_class_ptr == NULL)
2061 return JVMTI_ERROR_NULL_POINTER;
2063 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2065 return JVMTI_ERROR_NONE;
2069 /* GetClassLoader *************************************************************
2071 For the class indicated by klass, return via classloader_ptr a reference to
2072 the class loader for the class.
2074 *******************************************************************************/
2077 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2080 CHECK_PHASE(JVMTI_PHASE_START)
2081 CHECK_PHASE(JVMTI_PHASE_LIVE)
2084 if ((klass == NULL)||(classloader_ptr == NULL))
2085 return JVMTI_ERROR_NULL_POINTER;
2087 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2089 return JVMTI_ERROR_NONE;
2093 /* GetObjectHashCode **********************************************************
2095 Return hash code for object object
2097 *******************************************************************************/
2100 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2103 CHECK_PHASE(JVMTI_PHASE_START)
2104 CHECK_PHASE(JVMTI_PHASE_LIVE)
2107 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2108 if (!builtin_instanceof(object,class_java_lang_Object))
2109 return JVMTI_ERROR_INVALID_OBJECT;
2111 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2113 return JVMTI_ERROR_NONE;
2117 /* *****************************************************************************
2121 *******************************************************************************/
2124 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2125 jvmtiMonitorUsage * info_ptr)
2128 CHECK_PHASE(JVMTI_PHASE_LIVE)
2130 CHECK_CAPABILITY(env,can_get_monitor_info)
2132 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2133 return JVMTI_ERROR_NONE;
2137 /* GetFieldName ***************************************************************
2139 For the field indicated by klass and field, return the field name and
2142 *******************************************************************************/
2145 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2146 char **name_ptr, char **signature_ptr, char **generic_ptr)
2151 CHECK_PHASE(JVMTI_PHASE_START)
2152 CHECK_PHASE(JVMTI_PHASE_LIVE)
2156 return JVMTI_ERROR_INVALID_CLASS;
2158 if (!builtin_instanceof(klass,class_java_lang_Class))
2159 return JVMTI_ERROR_INVALID_CLASS;
2160 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2162 if (name_ptr != NULL) {
2163 size = utf_bytes(((fieldinfo*)field)->name)+1;
2164 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2165 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2168 if (signature_ptr != NULL) {
2169 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2170 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2171 utf_sprint_convert_to_latin1(*signature_ptr,
2172 ((fieldinfo*)field)->descriptor);
2175 if (generic_ptr != NULL)
2176 *generic_ptr = NULL;
2178 return JVMTI_ERROR_NONE;
2182 /* GetFieldDeclaringClass *****************************************************
2184 For the field indicated by klass and field return the class that defined it
2185 The declaring class will either be klass, a superclass, or an implemented
2188 *******************************************************************************/
2191 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2192 jclass * declaring_class_ptr)
2195 CHECK_PHASE(JVMTI_PHASE_START)
2196 CHECK_PHASE(JVMTI_PHASE_LIVE)
2200 return JVMTI_ERROR_INVALID_CLASS;
2202 if (!builtin_instanceof(klass,class_java_lang_Class))
2203 return JVMTI_ERROR_INVALID_CLASS;
2205 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2207 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2209 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2211 return JVMTI_ERROR_NONE;
2215 /* GetFieldModifiers **********************************************************
2217 Return access flags of field field
2219 *******************************************************************************/
2222 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2223 jint * modifiers_ptr)
2226 CHECK_PHASE(JVMTI_PHASE_START)
2227 CHECK_PHASE(JVMTI_PHASE_LIVE)
2231 return JVMTI_ERROR_INVALID_CLASS;
2233 if (!builtin_instanceof(klass,class_java_lang_Class))
2234 return JVMTI_ERROR_INVALID_CLASS;
2236 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2238 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2240 *modifiers_ptr = ((fieldinfo*)field)->flags;
2242 return JVMTI_ERROR_NONE;
2246 /* IsFieldSynthetic ***********************************************************
2250 *******************************************************************************/
2253 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2254 jboolean * is_synthetic_ptr)
2257 CHECK_PHASE(JVMTI_PHASE_START)
2258 CHECK_PHASE(JVMTI_PHASE_LIVE)
2260 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2262 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2263 return JVMTI_ERROR_NONE;
2267 /* GetMethodName ***************************************************************
2269 For the method indicated by method, return the method name via name_ptr and
2270 method signature via signature_ptr.
2272 *******************************************************************************/
2275 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2276 char **signature_ptr, char **generic_ptr)
2278 methodinfo* m = (methodinfo*)method;
2281 CHECK_PHASE(JVMTI_PHASE_START)
2282 CHECK_PHASE(JVMTI_PHASE_LIVE)
2286 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2288 if (name_ptr != NULL) {
2290 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2291 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2294 if (signature_ptr != NULL) {
2295 *signature_ptr = (char*)
2296 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2297 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2300 if (generic_ptr != NULL) {
2301 /* there is no generic signature attribute */
2302 *generic_ptr = NULL;
2305 return JVMTI_ERROR_NONE;
2309 /* GetMethodDeclaringClass *****************************************************
2311 For the method indicated by method, return the class that defined it.
2313 *******************************************************************************/
2316 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2317 jclass * declaring_class_ptr)
2320 CHECK_PHASE(JVMTI_PHASE_START)
2321 CHECK_PHASE(JVMTI_PHASE_LIVE)
2324 if ((method == NULL) || (declaring_class_ptr == NULL))
2325 return JVMTI_ERROR_NULL_POINTER;
2327 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2329 return JVMTI_ERROR_NONE;
2333 /* GetMethodModifiers **********************************************************
2335 For the method indicated by method, return the access flags.
2337 *******************************************************************************/
2340 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2343 CHECK_PHASE(JVMTI_PHASE_START)
2344 CHECK_PHASE(JVMTI_PHASE_LIVE)
2347 if ((method == NULL) || (modifiers_ptr == NULL))
2348 return JVMTI_ERROR_NULL_POINTER;
2350 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2352 return JVMTI_ERROR_NONE;
2356 /* GetMaxLocals ****************************************************************
2358 For the method indicated by method, return the number of local variable slots
2359 used by the method, including the local variables used to pass parameters to
2360 the method on its invocation.
2362 *******************************************************************************/
2365 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2368 CHECK_PHASE(JVMTI_PHASE_START)
2369 CHECK_PHASE(JVMTI_PHASE_LIVE)
2372 if ((method == NULL)||(max_ptr == NULL))
2373 return JVMTI_ERROR_NULL_POINTER;
2375 if (((methodinfo*)method)->flags & ACC_NATIVE)
2376 return JVMTI_ERROR_NATIVE_METHOD;
2378 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2380 return JVMTI_ERROR_NONE;
2385 /* GetArgumentsSize ************************************************************
2387 Return the number of local variable slots used by the method's arguments.
2389 *******************************************************************************/
2392 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2395 CHECK_PHASE(JVMTI_PHASE_START)
2396 CHECK_PHASE(JVMTI_PHASE_LIVE)
2399 if ((method == NULL)||(size_ptr == NULL))
2400 return JVMTI_ERROR_NULL_POINTER;
2402 if (((methodinfo*)method)->flags & ACC_NATIVE)
2403 return JVMTI_ERROR_NATIVE_METHOD;
2405 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2406 return JVMTI_ERROR_NONE;
2411 /* GetLineNumberTable **********************************************************
2413 Return table of source line number entries for a given method
2415 *******************************************************************************/
2418 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2419 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2424 CHECK_PHASE(JVMTI_PHASE_START)
2425 CHECK_PHASE(JVMTI_PHASE_LIVE)
2427 CHECK_CAPABILITY(env,can_get_line_numbers)
2429 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2430 return JVMTI_ERROR_NULL_POINTER;
2432 if (((methodinfo*)method)->flags & ACC_NATIVE)
2433 return JVMTI_ERROR_NATIVE_METHOD;
2435 if (((methodinfo*)method)->linenumbers == NULL)
2436 return JVMTI_ERROR_ABSENT_INFORMATION;
2438 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2439 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2440 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2443 for (i=0; i < *entry_count_ptr; i++) {
2444 (*table_ptr)[i].start_location =
2445 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2446 (*table_ptr)[i].line_number =
2447 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2450 return JVMTI_ERROR_NONE;
2454 /* GetMethodLocation ***********************************************************
2456 For the method indicated by method, return the beginning and ending addresses
2457 through start_location_ptr and end_location_ptr. In cacao this points to
2458 entry point in machine code and length of machine code
2460 *******************************************************************************/
2463 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2464 jlocation * start_location_ptr,
2465 jlocation * end_location_ptr)
2467 methodinfo* m = (methodinfo*)method;
2470 CHECK_PHASE(JVMTI_PHASE_START)
2471 CHECK_PHASE(JVMTI_PHASE_LIVE)
2474 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2476 if (((methodinfo*)method)->flags & ACC_NATIVE)
2477 return JVMTI_ERROR_NATIVE_METHOD;
2479 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2480 return JVMTI_ERROR_NULL_POINTER;
2482 /* XXX we return the location of the most recent code. Don't know
2483 * if there is a way to teach jvmti that a method can have more
2484 * than one location. -Edwin */
2486 /* XXX Don't know if that's the right way to deal with not-yet-
2487 * compiled methods. -Edwin */
2489 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2492 /* -1 states location information is not available */
2493 *start_location_ptr = (jlocation)-1;
2494 *end_location_ptr = (jlocation)-1;
2497 *start_location_ptr = (jlocation)m->code->mcode;
2498 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2499 return JVMTI_ERROR_NONE;
2503 /* GetLocalVariableTable *******************************************************
2505 Return local variable information.
2507 *******************************************************************************/
2510 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2511 jint * entry_count_ptr,
2512 jvmtiLocalVariableEntry ** table_ptr)
2515 CHECK_PHASE(JVMTI_PHASE_LIVE)
2517 CHECK_CAPABILITY(env,can_access_local_variables)
2519 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2521 return JVMTI_ERROR_NONE;
2525 /* GetBytecode *****************************************************************
2527 For the method indicated by method, return the byte codes that implement the
2530 *******************************************************************************/
2533 GetBytecodes (jvmtiEnv * env, jmethodID method,
2534 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2536 methodinfo* m = (methodinfo*)method;;
2539 CHECK_PHASE(JVMTI_PHASE_START)
2540 CHECK_PHASE(JVMTI_PHASE_LIVE)
2542 CHECK_CAPABILITY(env,can_get_bytecodes)
2544 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2545 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2547 *bytecode_count_ptr = m->jcodelength;
2548 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2549 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2551 return JVMTI_ERROR_NONE;
2555 /* IsMethodNative **************************************************************
2557 For the method indicated by method, return a value indicating whether the
2558 method is a native function
2560 *******************************************************************************/
2563 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2566 CHECK_PHASE(JVMTI_PHASE_START)
2567 CHECK_PHASE(JVMTI_PHASE_LIVE)
2570 if ((method == NULL)||(is_native_ptr == NULL))
2571 return JVMTI_ERROR_NULL_POINTER;
2573 if (((methodinfo*)method)->flags & ACC_NATIVE)
2574 *is_native_ptr = JNI_TRUE;
2576 *is_native_ptr = JNI_FALSE;
2578 return JVMTI_ERROR_NONE;
2582 /* IsMethodSynthetic ***********************************************************
2584 return a value indicating whether the method is synthetic. Synthetic methods
2585 are generated by the compiler but not present in the original source code.
2587 *******************************************************************************/
2590 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2591 jboolean * is_synthetic_ptr)
2594 CHECK_PHASE(JVMTI_PHASE_START)
2595 CHECK_PHASE(JVMTI_PHASE_LIVE)
2597 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2599 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2600 return JVMTI_ERROR_NONE;
2604 /* GetLoadedClasses ************************************************************
2606 Return an array of all classes loaded in the virtual machine.
2608 *******************************************************************************/
2611 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2614 CHECK_PHASE(JVMTI_PHASE_LIVE)
2617 if (class_count_ptr == NULL)
2618 return JVMTI_ERROR_NULL_POINTER;
2620 if (classes_ptr == NULL)
2621 return JVMTI_ERROR_NULL_POINTER;
2623 classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
2625 return JVMTI_ERROR_NONE;
2629 /* GetClassLoaderClasses *******************************************************
2631 Returns an array of those classes for which this class loader has been
2632 recorded as an initiating loader.
2634 *******************************************************************************/
2637 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2638 jint * class_count_ptr, jclass ** classes_ptr)
2640 log_text("GetClassLoaderClasses called");
2643 CHECK_PHASE(JVMTI_PHASE_LIVE)
2646 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2647 return JVMTI_ERROR_NULL_POINTER;
2649 /* behave like jdk 1.1 and make no distinction between initiating and
2650 defining class loaders */
2652 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2656 /* PopFrame *******************************************************************
2660 *******************************************************************************/
2663 PopFrame (jvmtiEnv * env, jthread thread)
2666 CHECK_PHASE(JVMTI_PHASE_LIVE)
2668 CHECK_CAPABILITY(env,can_pop_frame)
2670 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2671 return JVMTI_ERROR_NONE;
2675 /* RedefineClasses ************************************************************
2679 *******************************************************************************/
2682 RedefineClasses (jvmtiEnv * env, jint class_count,
2683 const jvmtiClassDefinition * class_definitions)
2686 CHECK_PHASE(JVMTI_PHASE_START)
2687 CHECK_PHASE(JVMTI_PHASE_LIVE)
2689 CHECK_CAPABILITY(env,can_redefine_classes)
2690 CHECK_CAPABILITY(env,can_redefine_any_class)
2692 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2693 return JVMTI_ERROR_NONE;
2697 /* GetVersionNumber ***********************************************************
2699 Return the JVM TI version identifier.
2701 *******************************************************************************/
2704 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2706 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2708 *version_ptr = JVMTI_VERSION;
2710 return JVMTI_ERROR_NONE;
2714 /* GetCapabilities ************************************************************
2716 Returns the optional JVM TI features which this environment currently
2719 *******************************************************************************/
2722 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2724 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2726 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2728 return JVMTI_ERROR_NONE;
2732 /* *****************************************************************************
2736 *******************************************************************************/
2739 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2740 char **source_debug_extension_ptr)
2743 CHECK_PHASE(JVMTI_PHASE_START)
2744 CHECK_PHASE(JVMTI_PHASE_LIVE)
2746 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2748 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2749 return JVMTI_ERROR_NONE;
2753 /* IsMethodObsolete ************************************************************
2755 Determine if a method ID refers to an obsolete method version.
2757 *******************************************************************************/
2760 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2761 jboolean * is_obsolete_ptr)
2764 CHECK_PHASE(JVMTI_PHASE_START)
2765 CHECK_PHASE(JVMTI_PHASE_LIVE)
2767 CHECK_CAPABILITY(env,can_redefine_classes)
2769 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2770 return JVMTI_ERROR_NONE;
2774 /* SuspendThreadList **********************************************************
2776 Suspend all threads in the request list.
2778 *******************************************************************************/
2781 SuspendThreadList (jvmtiEnv * env, jint request_count,
2782 const jthread * request_list, jvmtiError * results)
2789 CHECK_PHASE(JVMTI_PHASE_START)
2790 CHECK_PHASE(JVMTI_PHASE_LIVE)
2792 CHECK_CAPABILITY(env,can_suspend);
2794 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2795 if ((request_list == NULL) || (results == NULL))
2796 return JVMTI_ERROR_NULL_POINTER;
2798 me = jvmti_get_current_thread();
2800 for (i=0;i<request_count;i++) {
2801 if (request_list[i] == me)
2804 results[i]=SuspendThread(env, request_list[i]);
2807 if (suspendme != -1)
2808 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2810 return JVMTI_ERROR_NONE;
2814 /* ResumeThreadList ***********************************************************
2816 Resumes all threads in the request list.
2818 *******************************************************************************/
2821 ResumeThreadList (jvmtiEnv * env, jint request_count,
2822 const jthread * request_list, jvmtiError * results)
2827 CHECK_PHASE(JVMTI_PHASE_LIVE)
2829 CHECK_CAPABILITY(env,can_suspend);
2831 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2832 if ((request_list == NULL) || (results == NULL))
2833 return JVMTI_ERROR_NULL_POINTER;
2835 for (i=0;i<request_count;i++)
2836 results[i]=ResumeThread(env, request_list[i]);
2838 return JVMTI_ERROR_NONE;
2842 /* GetStackTrace **************************************************************
2844 Get information about the stack of a thread
2846 *******************************************************************************/
2849 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2850 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2853 stacktracebuffer* trace;
2858 CHECK_PHASE(JVMTI_PHASE_LIVE)
2861 if (thread != NULL){
2862 if(!builtin_instanceof(thread,class_java_lang_Thread))
2863 return JVMTI_ERROR_INVALID_THREAD;
2865 CHECK_THREAD_IS_ALIVE(thread);
2868 if((count_ptr == NULL)||(frame_buffer == NULL))
2869 return JVMTI_ERROR_NULL_POINTER;
2871 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2873 er = getcacaostacktrace(&trace, thread);
2874 if (er == JVMTI_ERROR_NONE) {
2879 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2880 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2882 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2883 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2884 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2885 frame_buffer[j].location = 0;
2890 return JVMTI_ERROR_NONE;
2894 /* GetThreadListStackTraces ***************************************************
2896 Get information about the stacks of the supplied threads.
2898 *******************************************************************************/
2901 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2902 const jthread * thread_list,
2903 jint max_frame_count,
2904 jvmtiStackInfo ** stack_info_ptr)
2910 CHECK_PHASE(JVMTI_PHASE_LIVE)
2913 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2914 return JVMTI_ERROR_NULL_POINTER;
2916 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2918 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2920 *stack_info_ptr = (jvmtiStackInfo*)
2921 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2923 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2924 (*stack_info_ptr)[i].thread=thread_list[i];
2925 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2926 (*stack_info_ptr)[i].frame_buffer =
2927 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2928 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2929 (*stack_info_ptr)[i].frame_buffer,
2930 &((*stack_info_ptr)[i].frame_count));
2932 if (er != JVMTI_ERROR_NONE) return er;
2935 return JVMTI_ERROR_NONE;
2939 /* GetAllStackTraces **********************************************************
2941 Get stack traces of all live threads
2943 *******************************************************************************/
2946 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2947 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2949 jthread *threads_ptr;
2953 CHECK_PHASE(JVMTI_PHASE_LIVE)
2956 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2958 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2959 return JVMTI_ERROR_INTERNAL;
2961 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2962 max_frame_count, stack_info_ptr);
2964 if (er != JVMTI_ERROR_NONE) return er;
2966 return JVMTI_ERROR_NONE;
2970 /* GetThreadLocalStorage ******************************************************
2972 Get the value of the JVM TI thread-local storage.
2974 *******************************************************************************/
2977 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2979 jvmtiThreadLocalStorage *tls;
2982 CHECK_PHASE(JVMTI_PHASE_START)
2983 CHECK_PHASE(JVMTI_PHASE_LIVE)
2987 thread = (jthread) THREADOBJECT;
2989 if (!builtin_instanceof(thread,class_java_lang_Thread))
2990 return JVMTI_ERROR_INVALID_THREAD;
2991 CHECK_THREAD_IS_ALIVE(thread);
2994 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2996 tls = ((environment*)env)->tls;
2997 while ((tls->thread != thread) && (tls != NULL)) {
3001 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3003 *data_ptr = tls->data;
3005 return JVMTI_ERROR_NONE;
3009 /* SetThreadLocalStorage *******************************************************
3011 Stores a pointer value associated with each environment-thread pair. The
3012 value is NULL unless set with this function. Agents can allocate memory in
3013 which they store thread specific information
3015 *******************************************************************************/
3018 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3020 jvmtiThreadLocalStorage *tls, *pre;
3021 environment* env = (environment*)jenv;
3024 CHECK_PHASE(JVMTI_PHASE_START)
3025 CHECK_PHASE(JVMTI_PHASE_LIVE)
3029 thread = (jthread) THREADOBJECT;
3031 if (!builtin_instanceof(thread,class_java_lang_Thread))
3032 return JVMTI_ERROR_INVALID_THREAD;
3033 CHECK_THREAD_IS_ALIVE(thread);
3036 if (env->tls == NULL) {
3037 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3040 while ((tls->thread != thread) && (tls->next != NULL)) {
3043 if (tls->thread != thread) {
3044 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3050 tls->data = (void*)data;
3052 /* remove current tls */
3054 while (pre->next == tls) pre = pre->next;
3055 pre->next = tls->next;
3057 return JVMTI_ERROR_NONE;
3061 /* *****************************************************************************
3065 *******************************************************************************/
3068 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3071 CHECK_PHASE(JVMTI_PHASE_START)
3072 CHECK_PHASE(JVMTI_PHASE_LIVE)
3074 CHECK_CAPABILITY(env,can_tag_objects)
3076 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3077 return JVMTI_ERROR_NONE;
3080 /* *****************************************************************************
3084 *******************************************************************************/
3087 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3090 CHECK_PHASE(JVMTI_PHASE_START)
3091 CHECK_PHASE(JVMTI_PHASE_LIVE)
3093 CHECK_CAPABILITY(env,can_tag_objects)
3095 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3096 return JVMTI_ERROR_NONE;
3100 /* ForceGarbageCollection *****************************************************
3102 Force boehm-gc to perform a garbage collection
3104 *******************************************************************************/
3107 ForceGarbageCollection (jvmtiEnv * env)
3110 CHECK_PHASE(JVMTI_PHASE_LIVE)
3115 return JVMTI_ERROR_NONE;
3119 /* IterateOverObjectsReachableFromObject **************************************
3123 *******************************************************************************/
3126 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3127 jvmtiObjectReferenceCallback
3128 object_reference_callback,
3132 CHECK_PHASE(JVMTI_PHASE_LIVE)
3134 CHECK_CAPABILITY(env,can_tag_objects)
3136 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3137 return JVMTI_ERROR_NONE;
3141 /* IterateOverReachableObjects ************************************************
3145 *******************************************************************************/
3148 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3150 jvmtiStackReferenceCallback
3152 jvmtiObjectReferenceCallback
3153 object_ref_callback, void *user_data)
3156 CHECK_PHASE(JVMTI_PHASE_LIVE)
3158 CHECK_CAPABILITY(env,can_tag_objects)
3160 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3161 return JVMTI_ERROR_NONE;
3165 /* IterateOverHeap ************************************************************
3169 *******************************************************************************/
3172 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3173 jvmtiHeapObjectCallback heap_object_callback,
3177 CHECK_PHASE(JVMTI_PHASE_LIVE)
3179 CHECK_CAPABILITY(env,can_tag_objects)
3181 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3182 return JVMTI_ERROR_NONE;
3186 /* IterateOverInstancesOfClass ************************************************
3190 *******************************************************************************/
3193 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3194 jvmtiHeapObjectFilter object_filter,
3195 jvmtiHeapObjectCallback
3196 heap_object_callback, void *user_data)
3199 CHECK_PHASE(JVMTI_PHASE_LIVE)
3201 CHECK_CAPABILITY(env,can_tag_objects)
3203 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3204 return JVMTI_ERROR_NONE;
3208 /* *****************************************************************************
3212 *******************************************************************************/
3215 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3216 jint * count_ptr, jobject ** object_result_ptr,
3217 jlong ** tag_result_ptr)
3220 CHECK_PHASE(JVMTI_PHASE_LIVE)
3222 CHECK_CAPABILITY(env,can_tag_objects)
3224 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3225 return JVMTI_ERROR_NONE;
3229 /* SetJNIFunctionTable **********************************************************
3231 Set the JNI function table in all current and future JNI environments
3233 *******************************************************************************/
3236 SetJNIFunctionTable (jvmtiEnv * env,
3237 const jniNativeInterface * function_table)
3240 CHECK_PHASE(JVMTI_PHASE_START)
3241 CHECK_PHASE(JVMTI_PHASE_LIVE)
3244 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3245 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3246 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3247 return JVMTI_ERROR_NONE;
3251 /* GetJNIFunctionTable *********************************************************
3253 Get the JNI function table. The JNI function table is copied into allocated
3256 *******************************************************************************/
3259 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3262 CHECK_PHASE(JVMTI_PHASE_START)
3263 CHECK_PHASE(JVMTI_PHASE_LIVE)
3266 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3267 *function_table = (jniNativeInterface*)
3268 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3269 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3270 return JVMTI_ERROR_NONE;
3274 /* SetEventCallbacks **********************************************************
3276 Set the functions to be called for each event. The callbacks are specified
3277 by supplying a replacement function table.
3279 *******************************************************************************/
3282 SetEventCallbacks (jvmtiEnv * env,
3283 const jvmtiEventCallbacks * callbacks,
3284 jint size_of_callbacks)
3287 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3288 CHECK_PHASE(JVMTI_PHASE_LIVE)
3291 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3294 if (callbacks == NULL) { /* remove the existing callbacks */
3295 memset(&(((environment* )env)->callbacks), 0,
3296 sizeof(jvmtiEventCallbacks));
3299 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3301 return JVMTI_ERROR_NONE;
3305 /* GenerateEvents *************************************************************
3307 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3308 the current state of the VM.
3310 *******************************************************************************/
3313 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3316 CHECK_PHASE(JVMTI_PHASE_LIVE)
3318 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3320 return JVMTI_ERROR_NONE;
3324 /* GetExtensionFunctions ******************************************************
3326 Returns the set of extension functions.
3328 *******************************************************************************/
3331 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3332 jvmtiExtensionFunctionInfo ** extensions)
3335 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3336 CHECK_PHASE(JVMTI_PHASE_LIVE)
3339 if ((extension_count_ptr == NULL)||(extensions == NULL))
3340 return JVMTI_ERROR_NULL_POINTER;
3342 /* cacao has no extended functions yet */
3343 *extension_count_ptr = 0;
3345 return JVMTI_ERROR_NONE;
3349 /* GetExtensionEvents *********************************************************
3351 Returns the set of extension events.
3353 *******************************************************************************/
3356 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3357 jvmtiExtensionEventInfo ** extensions)
3360 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3361 CHECK_PHASE(JVMTI_PHASE_LIVE)
3364 if ((extension_count_ptr == NULL)||(extensions == NULL))
3365 return JVMTI_ERROR_NULL_POINTER;
3367 /* cacao has no extended events yet */
3368 *extension_count_ptr = 0;
3370 return JVMTI_ERROR_NONE;
3374 /* SetExtensionEventCallback **************************************************
3376 Sets the callback function for an extension event and enables the event.
3378 *******************************************************************************/
3381 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3382 jvmtiExtensionEvent callback)
3385 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3386 CHECK_PHASE(JVMTI_PHASE_LIVE)
3389 /* cacao has no extended events yet */
3390 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3394 /* DisposeEnvironment **********************************************************
3396 Shutdown a JVM TI connection created with JNI GetEnv.
3398 *******************************************************************************/
3401 DisposeEnvironment (jvmtiEnv * env)
3403 environment* cacao_env = (environment*)env;
3404 environment* tenvs = envs;
3405 jvmtiThreadLocalStorage *jtls, *tjtls;
3407 if (tenvs != cacao_env) {
3408 while (tenvs->next != cacao_env) {
3409 tenvs = tenvs->next;
3411 tenvs->next = cacao_env->next;
3415 cacao_env->env=NULL;
3416 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3417 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3418 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3419 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3420 cacao_env->EnvironmentLocalStorage = NULL;
3422 jtls = cacao_env->tls;
3423 while (jtls != NULL) {
3428 cacao_env->tls = NULL;
3431 jvmti_cacaodbgserver_quit();
3433 /* let the GC do the rest */
3434 return JVMTI_ERROR_NONE;
3438 /* GetErrorName ***************************************************************
3440 Return the symbolic name for an error code.
3442 *******************************************************************************/
3444 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3445 memcpy(*name_ptr, &str, sizeof(str)); \
3449 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3451 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3454 case JVMTI_ERROR_NONE :
3455 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3456 case JVMTI_ERROR_NULL_POINTER :
3457 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3458 case JVMTI_ERROR_OUT_OF_MEMORY :
3459 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3460 case JVMTI_ERROR_ACCESS_DENIED :
3461 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3462 case JVMTI_ERROR_UNATTACHED_THREAD :
3463 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3464 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3465 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3466 case JVMTI_ERROR_WRONG_PHASE :
3467 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3468 case JVMTI_ERROR_INTERNAL :
3469 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3470 case JVMTI_ERROR_INVALID_PRIORITY :
3471 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3472 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3473 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3474 case JVMTI_ERROR_THREAD_SUSPENDED :
3475 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3476 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3477 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3478 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3479 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3480 case JVMTI_ERROR_NO_MORE_FRAMES :
3481 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3482 case JVMTI_ERROR_OPAQUE_FRAME :
3483 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3484 case JVMTI_ERROR_DUPLICATE :
3485 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3486 case JVMTI_ERROR_NOT_FOUND :
3487 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3488 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3489 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3490 case JVMTI_ERROR_INTERRUPT :
3491 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3492 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3493 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3494 case JVMTI_ERROR_NOT_AVAILABLE :
3495 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3496 case JVMTI_ERROR_ABSENT_INFORMATION :
3497 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3498 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3499 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3500 case JVMTI_ERROR_NATIVE_METHOD :
3501 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3502 case JVMTI_ERROR_INVALID_THREAD :
3503 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3504 case JVMTI_ERROR_INVALID_FIELDID :
3505 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3506 case JVMTI_ERROR_INVALID_METHODID :
3507 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3508 case JVMTI_ERROR_INVALID_LOCATION :
3509 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3510 case JVMTI_ERROR_INVALID_OBJECT :
3511 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3512 case JVMTI_ERROR_INVALID_CLASS :
3513 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3514 case JVMTI_ERROR_TYPE_MISMATCH :
3515 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3516 case JVMTI_ERROR_INVALID_SLOT :
3517 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3518 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3519 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3520 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3521 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3522 case JVMTI_ERROR_INVALID_MONITOR :
3523 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3524 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3525 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3526 case JVMTI_ERROR_INVALID_TYPESTATE :
3527 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3528 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3529 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3530 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3531 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3532 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3533 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3534 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3535 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3536 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3537 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3538 case JVMTI_ERROR_FAILS_VERIFICATION :
3539 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3540 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3541 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3542 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3543 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3544 case JVMTI_ERROR_NAMES_DONT_MATCH :
3545 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3546 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3547 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3548 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3549 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3551 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3553 return JVMTI_ERROR_NONE;
3556 /* GetJLocationFormat **********************************************************
3558 This function describes the representation of jlocation used in this VM.
3560 *******************************************************************************/
3563 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3565 *format_ptr = JVMTI_JLOCATION_OTHER;
3566 return JVMTI_ERROR_NONE;
3570 /* GetSystemProperties ********************************************************
3572 The list of VM system property keys which may be used with GetSystemProperty
3575 *******************************************************************************/
3578 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3580 jmethodID mid, moremid;
3581 classinfo *sysclass, *propclass, *enumclass;
3582 java_objectheader *sysprop, *keys, *obj;
3587 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3588 CHECK_PHASE(JVMTI_PHASE_LIVE)
3591 if ((count_ptr == NULL) || (property_ptr == NULL))
3592 return JVMTI_ERROR_NULL_POINTER;
3594 sysclass = load_class_from_sysloader(
3595 utf_new_char_classname ("java/lang/System"));
3597 if (!sysclass) throw_main_exception_exit();
3599 mid = (jmethodID)class_resolvemethod(sysclass,
3600 utf_new_char("getProperties"),
3601 utf_new_char("()Ljava/util/Properties;"));
3602 if (!mid) throw_main_exception_exit();
3605 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3606 if (!sysprop) throw_main_exception_exit();
3608 propclass = sysprop->vftbl->class;
3610 mid = (jmethodID)class_resolvemethod(propclass,
3611 utf_new_char("size"),
3612 utf_new_char("()I"));
3613 if (!mid) throw_main_exception_exit();
3616 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3617 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3619 mid = (jmethodID)class_resolvemethod(propclass,
3620 utf_new_char("keys"),
3621 utf_new_char("()Ljava/util/Enumeration;"));
3622 if (!mid) throw_main_exception_exit();
3624 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3625 enumclass = keys->vftbl->class;
3627 moremid = (jmethodID)class_resolvemethod(enumclass,
3628 utf_new_char("hasMoreElements"),
3629 utf_new_char("()Z"));
3630 if (!moremid) throw_main_exception_exit();
3632 mid = (jmethodID)class_resolvemethod(propclass,
3633 utf_new_char("nextElement"),
3634 utf_new_char("()Ljava/lang/Object;"));
3635 if (!mid) throw_main_exception_exit();
3638 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3639 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3640 ch = javastring_tochar(obj);
3641 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3642 memcpy(*property_ptr[i], ch, strlen (ch));
3643 MFREE(ch,char,strlen(ch)+1);
3647 return JVMTI_ERROR_NONE;
3651 /* GetSystemProperty **********************************************************
3653 Return a VM system property value given the property key.
3655 *******************************************************************************/
3658 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3661 classinfo *sysclass, *propclass;
3662 java_objectheader *sysprop, *obj;
3666 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3667 CHECK_PHASE(JVMTI_PHASE_LIVE)
3670 if ((value_ptr == NULL) || (property == NULL))
3671 return JVMTI_ERROR_NULL_POINTER;
3673 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3674 if (!sysclass) throw_main_exception_exit();
3676 mid = (jmethodID)class_resolvemethod(sysclass,
3677 utf_new_char("getProperties"),
3678 utf_new_char("()Ljava/util/Properties;"));
3679 if (!mid) throw_main_exception_exit();
3681 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3683 propclass = sysprop->vftbl->class;
3685 mid = (jmethodID)class_resolvemethod(propclass,
3686 utf_new_char("getProperty"),
3687 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3688 if (!mid) throw_main_exception_exit();
3690 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3691 NULL, sysprop, mid, javastring_new_from_ascii(property));
3692 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3694 ch = javastring_tochar(obj);
3695 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3696 memcpy(*value_ptr, ch, strlen (ch));
3697 MFREE(ch,char,strlen(ch)+1);
3699 return JVMTI_ERROR_NONE;
3703 /* SetSystemProperty **********************************************************
3705 Set a VM system property value.
3707 *******************************************************************************/
3710 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3713 classinfo *sysclass, *propclass;
3714 java_objectheader *sysprop;
3717 CHECK_PHASE(JVMTI_PHASE_START)
3720 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3721 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3723 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3724 if (!sysclass) throw_main_exception_exit();
3726 mid = (jmethodID)class_resolvemethod(sysclass,
3727 utf_new_char("getProperties"),
3728 utf_new_char("()Ljava/util/Properties;"));
3729 if (!mid) throw_main_exception_exit();
3731 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3733 propclass = sysprop->vftbl->class;
3735 mid = (jmethodID)class_resolvemethod(propclass,
3736 utf_new_char("setProperty"),
3737 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3738 if (!mid) throw_main_exception_exit();
3740 _Jv_JNINativeInterface.CallObjectMethod(
3741 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3743 return JVMTI_ERROR_NONE;
3746 /* GetPhase ********************************************************************
3748 Return the current phase of VM execution
3750 *******************************************************************************/
3753 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3755 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3759 return JVMTI_ERROR_NONE;
3762 /* GetCurrentThreadCpuTimerInfo ************************************************
3766 *******************************************************************************/
3769 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3772 CHECK_PHASE(JVMTI_PHASE_START)
3773 CHECK_PHASE(JVMTI_PHASE_LIVE)
3775 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3777 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3779 return JVMTI_ERROR_NONE;
3782 /* GetCurrentThreadCpuTime ****************************************************
3786 *******************************************************************************/
3789 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3792 CHECK_PHASE(JVMTI_PHASE_START)
3793 CHECK_PHASE(JVMTI_PHASE_LIVE)
3795 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3797 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3798 return JVMTI_ERROR_NONE;
3801 /* GetThreadCpuTimerInfo ******************************************************
3805 *******************************************************************************/
3808 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3811 CHECK_PHASE(JVMTI_PHASE_START)
3812 CHECK_PHASE(JVMTI_PHASE_LIVE)
3814 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3816 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3817 return JVMTI_ERROR_NONE;
3820 /* GetThreadCpuTime ***********************************************************
3824 *******************************************************************************/
3827 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3830 CHECK_PHASE(JVMTI_PHASE_LIVE)
3832 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3833 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3834 return JVMTI_ERROR_NONE;
3837 /* GetTimerInfo ***************************************************************
3839 Get information about the GetTime timer.
3841 *******************************************************************************/
3844 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3846 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3848 info_ptr->max_value = !0x0;
3849 info_ptr->may_skip_forward = true;
3850 info_ptr->may_skip_backward = true;
3851 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3853 return JVMTI_ERROR_NONE;
3856 /* GetTime ********************************************************************
3858 Return the current value of the system timer, in nanoseconds
3860 *******************************************************************************/
3863 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3865 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3868 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3870 if (gettimeofday (&tp, NULL) == -1)
3871 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3873 *nanos_ptr = (jlong) tp.tv_sec;
3875 *nanos_ptr += (tp.tv_usec / 1000);
3877 return JVMTI_ERROR_NONE;
3880 /* GetPotentialCapabilities ***************************************************
3882 Returns the JVM TI features that can potentially be possessed by this
3883 environment at this time.
3885 *******************************************************************************/
3888 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3891 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3892 CHECK_PHASE(JVMTI_PHASE_LIVE)
3895 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3897 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3899 return JVMTI_ERROR_NONE;
3903 #define CHECK_ADD_CAPABILITY(env,CAN) \
3904 if (capabilities_ptr->CAN == 1) { \
3905 if (JVMTI_Capabilities.CAN == 0) \
3906 return JVMTI_ERROR_NOT_AVAILABLE; \
3908 env->capabilities.CAN = 1; \
3911 /* AddCapabilities ************************************************************
3913 Set new capabilities by adding the capabilities pointed to by
3914 capabilities_ptr. All previous capabilities are retained.
3916 *******************************************************************************/
3919 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3921 environment* cacao_env;
3924 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3925 CHECK_PHASE(JVMTI_PHASE_LIVE)
3928 if ((env == NULL) || (capabilities_ptr == NULL))
3929 return JVMTI_ERROR_NULL_POINTER;
3931 cacao_env = (environment*)env;
3933 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3934 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3935 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3936 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3937 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3938 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3939 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3940 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3941 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3942 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3943 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3944 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3945 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3946 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3947 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3948 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3949 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3950 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3951 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3952 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3953 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3965 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3968 return JVMTI_ERROR_NONE;
3972 #define CHECK_DEL_CAPABILITY(env,CAN) \
3973 if (capabilities_ptr->CAN == 1) \
3974 env->capabilities.CAN = 0;
3976 /* RelinquishCapabilities *****************************************************
3978 Relinquish the capabilities pointed to by capabilities_ptr.
3980 *******************************************************************************/
3983 RelinquishCapabilities (jvmtiEnv * env,
3984 const jvmtiCapabilities * capabilities_ptr)
3986 environment* cacao_env;
3989 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3990 CHECK_PHASE(JVMTI_PHASE_LIVE)
3993 if ((env == NULL) || (capabilities_ptr == NULL))
3994 return JVMTI_ERROR_NULL_POINTER;
3996 cacao_env = (environment*)env;
3998 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3999 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4000 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4001 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4002 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4003 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4004 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4005 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4006 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4007 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4008 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4009 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4010 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4011 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4012 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4013 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4014 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4015 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4016 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4017 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4018 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4030 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4032 return JVMTI_ERROR_NONE;
4035 /* GetAvailableProcessors *****************************************************
4037 Get number of processors available to the virtual machine.
4039 *******************************************************************************/
4042 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4045 CHECK_PHASE(JVMTI_PHASE_START)
4046 CHECK_PHASE(JVMTI_PHASE_LIVE)
4049 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4051 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4053 *processor_count_ptr = 1; /* where do I get this ?*/
4055 return JVMTI_ERROR_NONE;
4058 /* GetEnvironmentLocalStorage **************************************************
4060 Called by the agent to get the value of the JVM TI environment-local storage.
4062 *******************************************************************************/
4065 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4067 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4069 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4071 return JVMTI_ERROR_NONE;
4074 /* SetEnvironmentLocalStorage **************************************************
4076 The VM stores a pointer value associated with each environment. Agents can
4077 allocate memory in which they store environment specific information.
4079 *******************************************************************************/
4082 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4084 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4086 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4088 return JVMTI_ERROR_NONE;
4091 /* AddToBootstrapClassLoaderSearch ********************************************
4093 After the bootstrap class loader unsuccessfully searches for a class, the
4094 specified platform-dependent search path segment will be searched as well.
4096 *******************************************************************************/
4099 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4105 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4108 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4110 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4111 tmp_bcp = MNEW(char, ln);
4112 strcat(tmp_bcp, bootclasspath);
4113 strcat(tmp_bcp, ":");
4114 strcat(tmp_bcp, segment);
4115 MFREE(bootclasspath,char,ln);
4116 bootclasspath = tmp_bcp;
4118 return JVMTI_ERROR_NONE;
4121 /* SetVerboseFlag *************************************************************
4123 Control verbose output. This is the output which typically is sent to stderr
4125 *******************************************************************************/
4128 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4131 case JVMTI_VERBOSE_OTHER:
4132 /* where is this defined ?
4136 case JVMTI_VERBOSE_GC:
4137 opt_verbosegc = value;
4139 case JVMTI_VERBOSE_CLASS:
4140 loadverbose = value;
4142 case JVMTI_VERBOSE_JNI:
4145 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4147 return JVMTI_ERROR_NONE;
4150 /* GetObjectSize **************************************************************
4152 For the object object return the size.
4154 *******************************************************************************/
4157 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4160 CHECK_PHASE(JVMTI_PHASE_START)
4161 CHECK_PHASE(JVMTI_PHASE_LIVE)
4164 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4165 if (!builtin_instanceof(object,class_java_lang_Object))
4166 return JVMTI_ERROR_INVALID_OBJECT;
4168 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4170 return JVMTI_ERROR_NONE;
4174 /* *****************************************************************************
4176 Environment variables
4178 *******************************************************************************/
4180 static jvmtiCapabilities JVMTI_Capabilities = {
4181 0, /* can_tag_objects */
4182 0, /* can_generate_field_modification_events */
4183 0, /* can_generate_field_access_events */
4184 1, /* can_get_bytecodes */
4185 0, /* can_get_synthetic_attribute */
4187 #if defined(ENABLE_THREADS)
4188 1, /* can_get_owned_monitor_info */
4189 1, /* can_get_current_contended_monitor */
4191 0, /* can_get_owned_monitor_info */
4192 0, /* can_get_current_contended_monitor */
4195 0, /* can_get_monitor_info */
4196 0, /* can_pop_frame */
4197 0, /* can_redefine_classes */
4198 0, /* can_signal_thread */
4199 1, /* can_get_source_file_name */
4200 1, /* can_get_line_numbers */
4201 0, /* can_get_source_debug_extension */
4202 0, /* can_access_local_variables */
4203 0, /* can_maintain_original_method_order */
4204 0, /* can_generate_single_step_events */
4205 1, /* can_generate_exception_events */
4206 0, /* can_generate_frame_pop_events */
4207 1, /* can_generate_breakpoint_events */
4208 1, /* can_suspend */
4209 0, /* can_redefine_any_class */
4210 0, /* can_get_current_thread_cpu_time */
4211 0, /* can_get_thread_cpu_time */
4212 1, /* can_generate_method_entry_events */
4213 0, /* can_generate_method_exit_events */
4214 0, /* can_generate_all_class_hook_events */
4215 0, /* can_generate_compiled_method_load_events */
4216 1, /* can_generate_monitor_events */
4217 0, /* can_generate_vm_object_alloc_events */
4218 0, /* can_generate_native_method_bind_events */
4219 0, /* can_generate_garbage_collection_events */
4220 0, /* can_generate_object_free_events */
4223 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4225 &SetEventNotificationMode,
4233 &GetOwnedMonitorInfo,
4234 &GetCurrentContendedMonitor,
4236 &GetTopThreadGroups,
4237 &GetThreadGroupInfo,
4238 &GetThreadGroupChildren,
4260 &RawMonitorNotifyAll,
4264 &SetFieldAccessWatch,
4265 &ClearFieldAccessWatch,
4266 &SetFieldModificationWatch,
4267 &ClearFieldModificationWatch,
4277 &GetImplementedInterfaces,
4282 &GetObjectMonitorUsage,
4284 &GetFieldDeclaringClass,
4288 &GetMethodDeclaringClass,
4289 &GetMethodModifiers,
4293 &GetLineNumberTable,
4295 &GetLocalVariableTable,
4302 &GetClassLoaderClasses,
4313 &GetSourceDebugExtension,
4324 &GetThreadListStackTraces,
4325 &GetThreadLocalStorage,
4326 &SetThreadLocalStorage,
4331 &ForceGarbageCollection,
4332 &IterateOverObjectsReachableFromObject,
4333 &IterateOverReachableObjects,
4335 &IterateOverInstancesOfClass,
4337 &GetObjectsWithTags,
4343 &SetJNIFunctionTable,
4344 &GetJNIFunctionTable,
4347 &GetExtensionFunctions,
4348 &GetExtensionEvents,
4349 &SetExtensionEventCallback,
4350 &DisposeEnvironment,
4352 &GetJLocationFormat,
4353 &GetSystemProperties,
4357 &GetCurrentThreadCpuTimerInfo,
4358 &GetCurrentThreadCpuTime,
4359 &GetThreadCpuTimerInfo,
4363 &GetPotentialCapabilities,
4366 &RelinquishCapabilities,
4367 &GetAvailableProcessors,
4370 &GetEnvironmentLocalStorage,
4371 &SetEnvironmentLocalStorage,
4372 &AddToBootstrapClassLoaderSearch,
4380 /* jvmti_set_phase ************************************************************
4382 sets a new jvmti phase a fires an apropriate event.
4384 *******************************************************************************/
4386 void jvmti_set_phase(jvmtiPhase p) {
4389 fprintf (stderr,"set JVMTI phase %d\n",p);
4393 case JVMTI_PHASE_ONLOAD:
4396 case JVMTI_PHASE_PRIMORDIAL:
4399 case JVMTI_PHASE_START:
4401 d.ev = JVMTI_EVENT_VM_START;
4403 case JVMTI_PHASE_LIVE:
4405 d.ev = JVMTI_EVENT_VM_INIT;
4406 jvmti_fireEvent(&d);
4407 /* thread start event for main thread */
4408 d.ev = JVMTI_EVENT_THREAD_START;
4410 case JVMTI_PHASE_DEAD:
4412 d.ev = JVMTI_EVENT_VM_DEATH;
4415 log_text("wrong jvmti phase to be set");
4419 jvmti_fireEvent(&d);
4423 /* jvmti_new_environment ******************************************************
4425 creates a new JVMTI environment
4427 *******************************************************************************/
4429 jvmtiEnv* jvmti_new_environment() {
4433 envs = heap_allocate(sizeof(environment),true,NULL);
4437 while (env->next != NULL) env = env->next;
4438 env->next = heap_allocate(sizeof(environment),true,NULL);
4442 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4443 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4444 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4445 sizeof(jvmtiEventModeLL));
4446 /* To possess a capability, the agent must add the capability.*/
4447 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4448 RelinquishCapabilities(&(env->env),&(env->capabilities));
4449 env->EnvironmentLocalStorage = NULL;
4452 /* initialize cacao debugging facilities */
4453 jvmti_cacao_debug_init();
4455 return (jvmtiEnv*)env;
4458 /* jvmti_agentload ************************************************************
4460 loads the indicated shared library containing the jvmti agent and calls the
4461 Agent_OnLoad function.
4463 *******************************************************************************/
4465 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4471 len = strlen(opt_arg);
4473 /* separate arguments */
4475 while ((opt_arg[i] != '=') && (i < len))
4481 arg = &opt_arg[i + 1];
4488 *libname = GCMNEW(char, i);
4490 strcpy(*libname, opt_arg);
4495 len = strlen("lib") + i + strlen(".so") + strlen("0");
4497 *libname = GCMNEW(char, len);
4499 strcpy(*libname, "lib");
4500 strcat(*libname, opt_arg);
4501 strcat(*libname, ".so");
4504 /* try to open the library */
4506 if (!(*handle = lt_dlopen(*libname))) {
4507 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4511 /* resolve Agent_OnLoad function */
4512 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4513 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4517 /* resolve Agent_UnLoad function */
4518 unload = lt_dlsym(*handle, "Agent_Unload");
4521 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4522 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4524 if (retval != 0) exit (retval);
4527 /* jvmti_agentunload **********************************************************
4529 calls the Agent_UnLoad function in the jvmti agent if present.
4531 *******************************************************************************/
4533 void jvmti_agentunload() {
4534 if (unload != NULL) {
4535 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4536 ((JavaVM*) &_Jv_JNIInvokeInterface);
4542 * These are local overrides for various environment variables in Emacs.
4543 * Please do not remove this and leave it at the end of the file, where
4544 * Emacs will automagically detect them.
4545 * ---------------------------------------------------------------------
4548 * indent-tabs-mode: t
4552 * vim:noexpandtab:sw=4:ts=4: