1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
5 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
6 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
7 J. Wenninger, Institut f. Computersprachen - TU Wien
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 Contact: cacao@cacaojvm.org
28 Author: Martin Platter
30 Changes: Edwin Steiner
34 $Id: jvmti.c 5900 2006-11-04 17:30:44Z michi $
43 #include <linux/unistd.h>
46 #include <sys/types.h>
51 #include "native/jni.h"
52 #include "native/native.h"
53 #include "native/jvmti/cacaodbg.h"
54 #include "native/jvmti/jvmti.h"
55 #include "vm/jit/stacktrace.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/builtin.h"
59 #include "vm/jit/asmpart.h"
61 #include "vm/classcache.h"
62 #include "mm/gc-common.h"
63 #include "toolbox/logging.h"
64 #include "vm/options.h"
65 #include "vm/stringlocal.h"
66 #include "mm/memory.h"
67 #include "threads/native/threads.h"
68 #include "threads/native/lock.h"
69 #include "vm/exceptions.h"
70 #include "native/include/java_util_Vector.h"
71 #include "native/include/java_io_PrintStream.h"
72 #include "native/include/java_io_InputStream.h"
73 #include "native/include/java_lang_Cloneable.h"
74 #include "native/include/java_lang_ThreadGroup.h"
75 #include "native/include/java_lang_VMObject.h"
76 #include "native/include/java_lang_VMSystem.h"
77 #include "native/include/java_lang_VMClass.h"
79 #include "boehm-gc/include/gc.h"
81 #if defined(ENABLE_THREADS)
82 #include "threads/native/threads.h"
90 typedef struct _environment environment;
91 static environment *envs=NULL;
92 pthread_mutex_t dbgcomlock;
94 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
96 static jvmtiPhase phase;
97 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
98 struct _jvmtiEventModeLL {
100 jthread event_thread;
101 jvmtiEventModeLL *next;
104 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
105 struct _jvmtiThreadLocalStorage{
108 jvmtiThreadLocalStorage *next;
111 struct _environment {
114 jvmtiEventCallbacks callbacks;
115 /* table for enabled/disabled jvmtiEvents - first element contains global
117 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
118 jvmtiCapabilities capabilities;
119 void *EnvironmentLocalStorage;
120 jvmtiThreadLocalStorage *tls;
123 static struct jvmtiEnv_struct JVMTI_EnvTable;
124 static jvmtiCapabilities JVMTI_Capabilities;
125 static lt_ptr unload;
127 #define CHECK_PHASE_START if (!(false
128 #define CHECK_PHASE(chkphase) || (phase == chkphase)
129 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
130 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
131 env)->capabilities.CAP == 0) \
132 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
133 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
134 JVMTI_ERROR_THREAD_NOT_ALIVE) \
135 return JVMTI_ERROR_THREAD_NOT_ALIVE;
140 /* check_thread_is_alive *******************************************************
142 checks if the given thread is alive
144 *******************************************************************************/
145 static jvmtiError check_thread_is_alive(jthread t) {
146 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
147 if(((java_lang_Thread*) t)->vmThread == NULL)
148 return JVMTI_ERROR_THREAD_NOT_ALIVE;
149 return JVMTI_ERROR_NONE;
152 /* execute_callback ************************************************************
154 executes the registerd callbacks for the given jvmti event with parameter
155 in the data structure.
157 *******************************************************************************/
158 static void execute_callback(jvmtiEvent e, functionptr ec,
159 genericEventData* data) {
160 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
162 fprintf(stderr,"execcallback called (event: %d)\n",e);
165 case JVMTI_EVENT_VM_INIT:
166 if (phase != JVMTI_PHASE_LIVE) return;
167 case JVMTI_EVENT_THREAD_START:
168 case JVMTI_EVENT_THREAD_END:
169 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
170 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
173 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
174 if ((phase == JVMTI_PHASE_START) ||
175 (phase == JVMTI_PHASE_LIVE) ||
176 (phase == JVMTI_PHASE_PRIMORDIAL))
177 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
182 data->protection_domain,
185 data->new_class_data_len,
186 data->new_class_data);
188 /* if class data has been modified use it as class data for other agents
189 waiting for the same event */
190 if (data->new_class_data != NULL) {
191 data->jint1 = *(data->new_class_data_len);
192 data->class_data = *(data->new_class_data);
197 case JVMTI_EVENT_CLASS_PREPARE:
198 case JVMTI_EVENT_CLASS_LOAD:
199 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
200 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
201 data->thread, data->klass);
204 case JVMTI_EVENT_VM_DEATH:
205 if (phase != JVMTI_PHASE_LIVE) return;
206 case JVMTI_EVENT_VM_START:
207 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
208 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
211 case JVMTI_EVENT_NATIVE_METHOD_BIND:
212 if ((phase == JVMTI_PHASE_START) ||
213 (phase == JVMTI_PHASE_LIVE) ||
214 (phase == JVMTI_PHASE_PRIMORDIAL))
215 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
219 data->new_address_ptr);
223 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
224 if ((phase == JVMTI_PHASE_START) ||
225 (phase == JVMTI_PHASE_LIVE) ||
226 (phase == JVMTI_PHASE_PRIMORDIAL))
227 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
236 if (phase != JVMTI_PHASE_LIVE) return;
238 case JVMTI_EVENT_EXCEPTION:
239 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
245 data->catch_location);
248 case JVMTI_EVENT_EXCEPTION_CATCH:
249 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
256 case JVMTI_EVENT_BREAKPOINT:
257 case JVMTI_EVENT_SINGLE_STEP:
258 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
264 case JVMTI_EVENT_FRAME_POP:
265 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
272 case JVMTI_EVENT_FIELD_ACCESS:
273 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
282 case JVMTI_EVENT_FIELD_MODIFICATION:
284 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
291 data->signature_type,
295 case JVMTI_EVENT_METHOD_ENTRY:
296 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
301 case JVMTI_EVENT_METHOD_EXIT:
302 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
309 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
310 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
319 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
320 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
325 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
326 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
327 case JVMTI_EVENT_DATA_DUMP_REQUEST:
328 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
331 case JVMTI_EVENT_MONITOR_WAIT:
332 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
338 case JVMTI_EVENT_MONITOR_WAITED:
339 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
346 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
347 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
348 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
353 case JVMTI_EVENT_OBJECT_FREE:
354 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
357 case JVMTI_EVENT_VM_OBJECT_ALLOC:
358 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
365 log_text ("unknown event");
372 /* dofireEvent ******************************************************************
374 sends event if it is enabled either globally or for some threads
376 *******************************************************************************/
377 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
379 jvmtiEventModeLL *evm;
383 while (env != NULL) {
384 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
385 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
386 /* test if the event is enable for some threads */
387 while (evm != NULL) {
388 if (evm->mode == JVMTI_ENABLE) {
390 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
392 data->jvmti_env=&env->env;
393 execute_callback(e, ec, data);
398 } else { /* event enabled globally */
399 data->jvmti_env=&env->env;
400 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
401 if (ec != NULL) execute_callback(e, ec, data);
409 /* fireEvent ******************************************************************
411 fire event callback with data arguments. This function mainly fills the
414 *******************************************************************************/
415 void jvmti_fireEvent(genericEventData* d) {
417 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
419 if (d->ev == JVMTI_EVENT_VM_START)
422 thread = jvmti_get_current_thread();
426 dofireEvent(d->ev,d);
430 /* SetEventNotificationMode ****************************************************
432 Control the generation of events
434 *******************************************************************************/
437 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
438 jvmtiEvent event_type, jthread event_thread, ...)
440 environment* cacao_env;
441 jvmtiEventModeLL *ll;
444 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
445 CHECK_PHASE(JVMTI_PHASE_LIVE)
448 if(event_thread != NULL) {
449 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
450 return JVMTI_ERROR_INVALID_THREAD;
451 CHECK_THREAD_IS_ALIVE(event_thread);
454 cacao_env = (environment*) env;
455 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
456 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
458 switch (event_type) { /* check capability and set system breakpoint */
459 case JVMTI_EVENT_EXCEPTION:
460 case JVMTI_EVENT_EXCEPTION_CATCH:
461 CHECK_CAPABILITY(env,can_generate_exception_events)
463 case JVMTI_EVENT_SINGLE_STEP:
464 CHECK_CAPABILITY(env,can_generate_single_step_events)
466 case JVMTI_EVENT_FRAME_POP:
467 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
469 case JVMTI_EVENT_BREAKPOINT:
470 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
472 case JVMTI_EVENT_FIELD_ACCESS:
473 CHECK_CAPABILITY(env,can_generate_field_access_events)
475 case JVMTI_EVENT_FIELD_MODIFICATION:
476 CHECK_CAPABILITY(env,can_generate_field_modification_events)
478 case JVMTI_EVENT_METHOD_ENTRY:
479 CHECK_CAPABILITY(env,can_generate_method_entry_events)
481 case JVMTI_EVENT_METHOD_EXIT:
482 CHECK_CAPABILITY(env, can_generate_method_exit_events)
484 case JVMTI_EVENT_NATIVE_METHOD_BIND:
485 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
487 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
488 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
489 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
491 case JVMTI_EVENT_MONITOR_WAIT:
492 case JVMTI_EVENT_MONITOR_WAITED:
493 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
494 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
495 CHECK_CAPABILITY(env,can_generate_monitor_events)
497 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
498 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
499 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
501 case JVMTI_EVENT_OBJECT_FREE:
502 CHECK_CAPABILITY(env,can_generate_object_free_events)
504 case JVMTI_EVENT_VM_OBJECT_ALLOC:
505 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
508 /* all other events are required */
509 if ((event_type < JVMTI_EVENT_START_ENUM) ||
510 (event_type > JVMTI_EVENT_END_ENUM))
511 return JVMTI_ERROR_INVALID_EVENT_TYPE;
516 if (event_thread != NULL) {
517 /* thread level control */
518 if ((JVMTI_EVENT_VM_INIT == mode) ||
519 (JVMTI_EVENT_VM_DEATH == mode) ||
520 (JVMTI_EVENT_VM_START == mode) ||
521 (JVMTI_EVENT_THREAD_START == mode) ||
522 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
523 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
524 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
525 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
526 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
527 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
528 while (ll->next != NULL) {
530 if (ll->event_thread == event_thread) {
532 return JVMTI_ERROR_NONE;
535 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
539 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
543 return JVMTI_ERROR_NONE;
546 /* GetAllThreads ***************************************************************
550 *******************************************************************************/
553 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
554 jthread ** threads_ptr)
556 threadobject** threads;
561 CHECK_PHASE(JVMTI_PHASE_LIVE)
564 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
565 return JVMTI_ERROR_NULL_POINTER;
567 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
568 if (retval != JVMTI_ERROR_NONE) return retval;
571 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
573 for (i=0; i<*threads_count_ptr; i++)
574 (*threads_ptr)[i] = threads[i]->o.thread;
576 return JVMTI_ERROR_NONE;
580 /* SuspendThread ***************************************************************
582 Suspend specified thread
584 *******************************************************************************/
587 SuspendThread (jvmtiEnv * env, jthread thread)
590 CHECK_PHASE(JVMTI_PHASE_LIVE)
592 CHECK_CAPABILITY(env,can_suspend);
594 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
595 if (!builtin_instanceof(thread,class_java_lang_Thread))
596 return JVMTI_ERROR_INVALID_THREAD;
597 CHECK_THREAD_IS_ALIVE(thread);
599 /* threads_suspend_thread will implement suspend
600 threads_suspend_thread (
601 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
603 return JVMTI_ERROR_NONE;
606 /* ResumeThread ***************************************************************
608 Resume a suspended thread
610 *******************************************************************************/
613 ResumeThread (jvmtiEnv * env, jthread thread)
616 CHECK_PHASE(JVMTI_PHASE_LIVE)
618 CHECK_CAPABILITY(env,can_suspend);
620 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
621 if (!builtin_instanceof(thread,class_java_lang_Thread))
622 return JVMTI_ERROR_INVALID_THREAD;
623 CHECK_THREAD_IS_ALIVE(thread);
625 /* threads_resume_thread will implement resume
626 threads_resume_thread (
627 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
629 return JVMTI_ERROR_NONE;
632 /* StopThread *****************************************************************
634 Send asynchronous exception to the specified thread. Similar to
635 java.lang.Thread.stop(). Used to kill thread.
637 *******************************************************************************/
640 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
643 CHECK_PHASE(JVMTI_PHASE_LIVE)
645 CHECK_CAPABILITY(env,can_signal_thread);
647 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
648 return JVMTI_ERROR_NOT_AVAILABLE;
650 return JVMTI_ERROR_NONE;
653 /* InterruptThread ************************************************************
655 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
657 *******************************************************************************/
660 InterruptThread (jvmtiEnv * env, jthread thread)
663 CHECK_PHASE(JVMTI_PHASE_LIVE)
665 CHECK_CAPABILITY(env,can_signal_thread)
667 #if defined(ENABLE_THREADS)
668 if(!builtin_instanceof(thread,class_java_lang_Thread))
669 return JVMTI_ERROR_INVALID_THREAD;
671 CHECK_THREAD_IS_ALIVE(thread);
673 threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
676 return JVMTI_ERROR_NONE;
678 return JVMTI_ERROR_NOT_AVAILABLE;
682 /* GetThreadInfo ***************************************************************
684 Get thread information. Details of the specified thread are stored in the
685 jvmtiThreadInfo structure.
687 *******************************************************************************/
690 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
693 java_lang_Thread* th = (java_lang_Thread*)t;
697 CHECK_PHASE(JVMTI_PHASE_LIVE)
700 info_ptr->priority=(jint)th->priority;
701 info_ptr->is_daemon=(jboolean)th->daemon;
702 info_ptr->thread_group=(jthreadGroup)th->group;
703 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
705 name = javastring_toutf(th->name,false);
706 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
707 utf_sprint_convert_to_latin1(info_ptr->name, name);
709 return JVMTI_ERROR_NONE;
712 /* GetOwnedMonitorInfo *********************************************************
714 Gets all monitors owned by the specified thread
716 *******************************************************************************/
719 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
720 jint * owned_monitor_count_ptr,
721 jobject ** owned_monitors_ptr)
724 java_objectheader **om;
725 lock_record_pool_t* lrp;
729 CHECK_PHASE(JVMTI_PHASE_LIVE)
731 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
733 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
734 return JVMTI_ERROR_NULL_POINTER;
736 if (thread == NULL) {
737 t = jvmti_get_current_thread();
739 if(!builtin_instanceof(thread,class_java_lang_Thread))
740 return JVMTI_ERROR_INVALID_THREAD;
742 CHECK_THREAD_IS_ALIVE(thread);
743 t = (threadobject*) thread;
746 #if defined(ENABLE_THREADS)
748 om=MNEW(java_objectheader*,size);
750 pthread_mutex_lock(&lock_global_pool_lock);
751 lrp=lock_global_pool;
753 /* iterate over all lock record pools */
754 while (lrp != NULL) {
755 /* iterate over every lock record in a pool */
756 for (j=0; j<lrp->header.size; j++) {
757 /* if the lock record is owned by the given thread add it to
759 if(lrp->lr[j].owner == t) {
761 MREALLOC(om, java_objectheader*, size, size * 2);
764 om[i] = lrp->lr[j].obj;
768 lrp=lrp->header.next;
771 pthread_mutex_unlock(&lock_global_pool_lock);
773 *owned_monitors_ptr =
774 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
775 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
776 MFREE(om, java_objectheader*, size);
778 *owned_monitor_count_ptr = i;
782 return JVMTI_ERROR_NONE;
785 /* GetCurrentContendedMonitor *************************************************
787 Get the object the specified thread waits for.
789 *******************************************************************************/
792 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
793 jobject * monitor_ptr)
796 lock_record_pool_t* lrp;
798 lock_waiter_t* waiter;
801 CHECK_PHASE(JVMTI_PHASE_LIVE)
803 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
805 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
808 if (thread == NULL) {
809 t = jvmti_get_current_thread();
811 if(!builtin_instanceof(thread,class_java_lang_Thread))
812 return JVMTI_ERROR_INVALID_THREAD;
814 CHECK_THREAD_IS_ALIVE(thread);
815 t = (threadobject*) thread;
818 #if defined(ENABLE_THREADS)
820 pthread_mutex_lock(&lock_global_pool_lock);
822 lrp=lock_global_pool;
824 /* iterate over all lock record pools */
825 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
826 /* iterate over every lock record in a pool */
827 for (j=0; j<lrp->header.size; j++) {
828 /* iterate over every thread that is wait on this lock record */
829 waiter = lrp->lr[j].waiters;
830 while (waiter != NULL)
831 /* if the waiting thread equals to the given thread we are
832 done. Stop iterateting. */
833 if(waiter->waiter == t) {
834 *monitor_ptr=lrp->lr[j].obj;
838 lrp=lrp->header.next;
841 pthread_mutex_unlock(&lock_global_pool_lock);
845 return JVMTI_ERROR_NONE;
849 jvmtiStartFunction sf;
855 static void *threadstartup(void *t) {
856 runagentparam *rap = (runagentparam*)t;
857 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
861 /* RunAgentThread *************************************************************
863 Starts the execution of an agent thread of the specified native function
864 within the specified thread
866 *******************************************************************************/
869 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
870 const void *arg, jint priority)
872 pthread_attr_t threadattr;
873 struct sched_param sp;
877 CHECK_PHASE(JVMTI_PHASE_LIVE)
880 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
881 return JVMTI_ERROR_INVALID_THREAD;
882 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
883 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
884 (priority > JVMTI_THREAD_MAX_PRIORITY))
885 return JVMTI_ERROR_INVALID_PRIORITY;
887 /* XXX: Threads started with this function should not be visible to
888 Java programming language queries but are included in JVM TI queries */
891 rap.arg = (void*)arg;
894 #if defined(ENABLE_THREADS)
895 pthread_attr_init(&threadattr);
896 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
897 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
898 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
900 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
901 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
903 pthread_attr_setschedparam(&threadattr,&sp);
904 if (pthread_create(&((threadobject*)
905 thread)->tid, &threadattr, &threadstartup, &rap)) {
906 log_text("pthread_create failed");
911 return JVMTI_ERROR_NONE;
915 /* GetTopThreadGroups *********************************************************
917 Get all top-level thread groups in the VM.
919 *******************************************************************************/
922 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
923 jthreadGroup ** groups_ptr)
925 jint threads_count_ptr;
926 threadobject *threads_ptr;
928 jthreadGroup **tg,*ttgp;
931 CHECK_PHASE(JVMTI_PHASE_LIVE)
934 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
935 return JVMTI_ERROR_NULL_POINTER;
937 #if defined(ENABLE_THREADS)
938 tg = MNEW(jthreadGroup*,size);
940 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
941 return JVMTI_ERROR_INTERNAL;
943 for (i=0;i<threads_count_ptr;i++){
944 if (threads_ptr[i].o.thread->group == NULL) {
945 log_text("threadgroup not set");
946 return JVMTI_ERROR_INTERNAL;
948 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
951 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
956 MREALLOC(tg,jthreadGroup*,size,size*2);
965 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
966 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
967 MFREE(tg,jthreadGroup*,size);
969 *group_count_ptr = x;
972 return JVMTI_ERROR_NOT_AVAILABLE;
974 return JVMTI_ERROR_NONE;
978 /* GetThreadGroupInfo *********************************************************
980 Get information about the specified thread group.
982 *******************************************************************************/
985 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
986 jvmtiThreadGroupInfo * info_ptr)
990 java_lang_ThreadGroup* grp;
993 CHECK_PHASE(JVMTI_PHASE_LIVE)
996 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
997 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
998 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1000 grp = (java_lang_ThreadGroup*)group;
1002 info_ptr->parent = (jthreadGroup)
1003 Java_java_lang_VMObject_clone(NULL,
1004 (jclass)grp->header.vftbl->class,
1005 (java_lang_Cloneable*) &grp->parent);
1007 name = javastring_tochar((java_objectheader*)grp->name);
1008 size = strlen(name);
1009 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
1010 strncpy(info_ptr->name,name,size);
1011 info_ptr->max_priority= (jint)grp->maxpri;
1012 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1014 return JVMTI_ERROR_NONE;
1018 /* GetThreadGroupChildren *****************************************************
1020 Get the live threads and active subgroups in this thread group.
1022 *******************************************************************************/
1025 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1026 jint * thread_count_ptr, jthread ** threads_ptr,
1027 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1029 java_lang_ThreadGroup* tgp;
1032 CHECK_PHASE(JVMTI_PHASE_LIVE)
1035 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1036 (group_count_ptr == NULL) || (groups_ptr == NULL))
1037 return JVMTI_ERROR_NULL_POINTER;
1039 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1040 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1042 tgp = (java_lang_ThreadGroup*)group;
1044 *thread_count_ptr = (jint)tgp->threads->elementCount;
1047 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1049 memcpy(*threads_ptr, &tgp->threads->elementData,
1050 (*thread_count_ptr)*sizeof(java_objectarray*));
1052 *group_count_ptr = (jint) tgp->groups->elementCount;
1055 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1057 memcpy(*groups_ptr, &tgp->threads->elementData,
1058 (*group_count_ptr)*sizeof(jthreadGroup*));
1060 return JVMTI_ERROR_NONE;
1064 /* getcacaostacktrace *********************************************************
1066 Helper function that retrives stack trace for specified thread.
1068 *******************************************************************************/
1070 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1074 if (thread == NULL) {
1075 t = jvmti_get_current_thread();
1076 *trace = stacktrace_create(t);
1078 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1079 /* if (t != jvmti_get_current_thread())
1080 resume = threads_suspend_thread_if_running(thread);
1082 *trace = stacktrace_create(thread );
1085 threads_resume_thread ( thread );*/
1088 return JVMTI_ERROR_NONE;
1092 /* GetFrameCount **************************************************************
1095 Get the number of frames in the specified thread's stack. Calling function
1096 has to take care of suspending/resuming thread.
1098 *******************************************************************************/
1101 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1103 stacktracebuffer* trace;
1107 CHECK_PHASE(JVMTI_PHASE_LIVE)
1110 if (thread != NULL){
1111 if(!builtin_instanceof(thread,class_java_lang_Thread))
1112 return JVMTI_ERROR_INVALID_THREAD;
1114 CHECK_THREAD_IS_ALIVE(thread);
1117 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1119 er = getcacaostacktrace(&trace, thread);
1120 if (er == JVMTI_ERROR_NONE) {
1125 *count_ptr = trace->used;
1128 return JVMTI_ERROR_NONE;
1132 /* GetThreadState **************************************************************
1134 Get the state of a thread.
1136 *******************************************************************************/
1139 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1141 java_lang_Thread* th = (java_lang_Thread*)thread;
1142 threadobject* t = (threadobject*)th->vmThread;
1145 CHECK_PHASE(JVMTI_PHASE_LIVE)
1148 if(!builtin_instanceof(thread,class_java_lang_Thread))
1149 return JVMTI_ERROR_INVALID_THREAD;
1151 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1153 *thread_state_ptr = 0;
1154 #if defined(ENABLE_THREADS)
1155 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1157 if (((threadobject*)th->vmThread)->tid == 0)
1158 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1161 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1162 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1163 /* XXX todo - info not available */
1164 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1165 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1166 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1167 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1168 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1169 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1170 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1171 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1172 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1173 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1176 return JVMTI_ERROR_INTERNAL;
1179 return JVMTI_ERROR_NONE;
1183 /* GetFrameLocation ************************************************************
1185 Get the location of the instruction currently executing
1187 *******************************************************************************/
1190 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1191 jmethodID * method_ptr, jlocation * location_ptr)
1193 stackframeinfo *sfi;
1198 CHECK_PHASE(JVMTI_PHASE_LIVE)
1201 if (thread == NULL) {
1202 th = jvmti_get_current_thread();
1204 if(!builtin_instanceof(thread,class_java_lang_Thread))
1205 return JVMTI_ERROR_INVALID_THREAD;
1207 CHECK_THREAD_IS_ALIVE(thread);
1208 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1211 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1213 if ((method_ptr == NULL)&&(location_ptr == NULL))
1214 return JVMTI_ERROR_NULL_POINTER;
1216 sfi = th->_stackframeinfo;
1219 while ((sfi != NULL) && (i<depth)) {
1224 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1226 *method_ptr=(jmethodID)sfi->method;
1227 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1229 return JVMTI_ERROR_NONE;
1233 /* NotifyFramePop *************************************************************
1237 *******************************************************************************/
1240 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1243 CHECK_PHASE(JVMTI_PHASE_LIVE)
1245 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1247 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1248 return JVMTI_ERROR_NONE;
1251 /* GetLocalObject *************************************************************
1255 *******************************************************************************/
1258 GetLocalObject (jvmtiEnv * env,
1259 jthread thread, jint depth, jint slot, jobject * value_ptr)
1262 CHECK_PHASE(JVMTI_PHASE_LIVE)
1264 CHECK_CAPABILITY(env,can_access_local_variables)
1266 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1267 return JVMTI_ERROR_NONE;
1270 /* GetLocalInt ****************************************************************
1274 *******************************************************************************/
1277 GetLocalInt (jvmtiEnv * env,
1278 jthread thread, jint depth, jint slot, jint * value_ptr)
1281 CHECK_PHASE(JVMTI_PHASE_LIVE)
1283 CHECK_CAPABILITY(env,can_access_local_variables)
1284 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1285 return JVMTI_ERROR_NONE;
1288 /* *****************************************************************************
1292 *******************************************************************************/
1295 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1299 CHECK_PHASE(JVMTI_PHASE_LIVE)
1301 CHECK_CAPABILITY(env,can_access_local_variables)
1303 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1304 return JVMTI_ERROR_NONE;
1308 /* *****************************************************************************
1312 *******************************************************************************/
1315 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1319 CHECK_PHASE(JVMTI_PHASE_LIVE)
1321 CHECK_CAPABILITY(env,can_access_local_variables)
1323 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1324 return JVMTI_ERROR_NONE;
1328 /* *****************************************************************************
1332 *******************************************************************************/
1335 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1336 jdouble * value_ptr)
1339 CHECK_PHASE(JVMTI_PHASE_LIVE)
1341 CHECK_CAPABILITY(env,can_access_local_variables)
1343 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1344 return JVMTI_ERROR_NONE;
1348 /* *****************************************************************************
1352 *******************************************************************************/
1355 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1359 CHECK_PHASE(JVMTI_PHASE_LIVE)
1361 CHECK_CAPABILITY(env,can_access_local_variables)
1363 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1364 return JVMTI_ERROR_NONE;
1368 /* *****************************************************************************
1372 *******************************************************************************/
1375 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1379 CHECK_PHASE(JVMTI_PHASE_LIVE)
1381 CHECK_CAPABILITY(env,can_access_local_variables)
1383 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1384 return JVMTI_ERROR_NONE;
1388 /* *****************************************************************************
1392 *******************************************************************************/
1395 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1399 CHECK_PHASE(JVMTI_PHASE_LIVE)
1401 CHECK_CAPABILITY(env,can_access_local_variables)
1403 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1404 return JVMTI_ERROR_NONE;
1408 /* *****************************************************************************
1412 *******************************************************************************/
1415 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1419 CHECK_PHASE(JVMTI_PHASE_LIVE)
1421 CHECK_CAPABILITY(env,can_access_local_variables)
1423 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1424 return JVMTI_ERROR_NONE;
1428 /* *****************************************************************************
1432 *******************************************************************************/
1435 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1439 CHECK_PHASE(JVMTI_PHASE_LIVE)
1441 CHECK_CAPABILITY(env,can_access_local_variables)
1443 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1444 return JVMTI_ERROR_NONE;
1448 /* CreateRawMonitor ***********************************************************
1450 This function creates a new raw monitor.
1452 *******************************************************************************/
1455 CreateRawMonitor (jvmtiEnv * env, const char *name,
1456 jrawMonitorID * monitor_ptr)
1458 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1461 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1462 CHECK_PHASE(JVMTI_PHASE_LIVE)
1465 if ((name == NULL) || (monitor_ptr == NULL))
1466 return JVMTI_ERROR_NULL_POINTER;
1468 #if defined(ENABLE_THREADS)
1469 monitor->name=javastring_new_from_ascii(name);
1471 log_text ("CreateRawMonitor not supported");
1474 return JVMTI_ERROR_NONE;
1478 /* DestroyRawMonitor **********************************************************
1480 This function destroys a raw monitor.
1482 *******************************************************************************/
1485 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1488 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1489 CHECK_PHASE(JVMTI_PHASE_LIVE)
1492 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1493 return JVMTI_ERROR_INVALID_MONITOR;
1495 #if defined(ENABLE_THREADS)
1496 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1497 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1499 lock_monitor_exit((java_objectheader *) monitor->name);
1503 log_text ("DestroyRawMonitor not supported");
1506 return JVMTI_ERROR_NONE;
1510 /* RawMonitorEnter ************************************************************
1512 Gain exclusive ownership of a raw monitor
1514 *******************************************************************************/
1517 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1519 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1520 return JVMTI_ERROR_INVALID_MONITOR;
1522 #if defined(ENABLE_THREADS)
1523 lock_monitor_enter((java_objectheader *) monitor->name);
1525 log_text ("RawMonitorEnter not supported");
1528 return JVMTI_ERROR_NONE;
1532 /* RawMonitorExit *************************************************************
1536 *******************************************************************************/
1539 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1541 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1542 return JVMTI_ERROR_INVALID_MONITOR;
1544 #if defined(ENABLE_THREADS)
1545 /* assure current thread owns this monitor */
1546 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1547 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1549 lock_monitor_exit((java_objectheader *) monitor->name);
1551 log_text ("RawMonitorExit not supported");
1554 return JVMTI_ERROR_NONE;
1558 /* RawMonitorWait *************************************************************
1560 Wait for notification of the raw monitor.
1562 *******************************************************************************/
1565 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1567 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1568 return JVMTI_ERROR_INVALID_MONITOR;
1570 #if defined(ENABLE_THREADS)
1571 /* assure current thread owns this monitor */
1572 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1573 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1575 lock_wait_for_object(&monitor->name->header, millis,0);
1576 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1577 return JVMTI_ERROR_INTERRUPT;
1580 log_text ("RawMonitorWait not supported");
1583 return JVMTI_ERROR_NONE;
1587 /* RawMonitorNotify ***********************************************************
1589 Notify one thread waiting on the given monitor.
1591 *******************************************************************************/
1594 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1596 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1597 return JVMTI_ERROR_INVALID_MONITOR;
1599 #if defined(ENABLE_THREADS)
1600 /* assure current thread owns this monitor */
1601 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1602 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1604 lock_notify_object((java_objectheader*)&monitor->name);
1606 log_text ("RawMonitorNotify not supported");
1609 return JVMTI_ERROR_NONE;
1613 /* RawMonitorNotifyAll *********************************************************
1615 Notify all threads waiting on the given monitor.
1617 *******************************************************************************/
1620 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1622 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1623 return JVMTI_ERROR_INVALID_MONITOR;
1625 #if defined(ENABLE_THREADS)
1626 /* assure current thread owns this monitor */
1627 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1628 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1630 lock_notify_all_object((java_objectheader*)&monitor->name);
1632 log_text ("RawMonitorNotifyAll not supported");
1635 return JVMTI_ERROR_NONE;
1639 /* SetBreakpoint **************************************************************
1643 *******************************************************************************/
1646 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1649 CHECK_PHASE(JVMTI_PHASE_LIVE)
1651 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1654 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1655 return JVMTI_ERROR_NONE;
1659 /* *****************************************************************************
1663 *******************************************************************************/
1666 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1669 CHECK_PHASE(JVMTI_PHASE_LIVE)
1671 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1673 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1674 return JVMTI_ERROR_NONE;
1678 /* SetFieldAccessWatch ********************************************************
1682 *******************************************************************************/
1685 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1688 CHECK_PHASE(JVMTI_PHASE_LIVE)
1690 CHECK_CAPABILITY(env,can_generate_field_access_events)
1692 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1693 return JVMTI_ERROR_NONE;
1697 /* *****************************************************************************
1701 *******************************************************************************/
1704 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1707 CHECK_PHASE(JVMTI_PHASE_LIVE)
1709 CHECK_CAPABILITY(env,can_generate_field_access_events)
1711 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1712 return JVMTI_ERROR_NONE;
1716 /* *****************************************************************************
1720 *******************************************************************************/
1723 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1726 CHECK_PHASE(JVMTI_PHASE_LIVE)
1728 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1730 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1731 return JVMTI_ERROR_NONE;
1735 /* *****************************************************************************
1739 *******************************************************************************/
1742 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1745 CHECK_PHASE(JVMTI_PHASE_LIVE)
1747 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1749 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1750 return JVMTI_ERROR_NONE;
1754 /* Allocate ********************************************************************
1756 Allocate an area of memory through the JVM TI allocator. The allocated
1757 memory should be freed with Deallocate
1759 *******************************************************************************/
1762 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1765 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1766 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1768 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1769 if (*mem_ptr == NULL)
1770 return JVMTI_ERROR_OUT_OF_MEMORY;
1772 return JVMTI_ERROR_NONE;
1777 /* Deallocate ******************************************************************
1779 Deallocate mem using the JVM TI allocator.
1781 *******************************************************************************/
1784 Deallocate (jvmtiEnv * env, unsigned char *mem)
1786 /* let Boehm GC do the job */
1788 return JVMTI_ERROR_NONE;
1792 /* GetClassSignature ************************************************************
1794 For the class indicated by klass, return the JNI type signature and the
1795 generic signature of the class.
1797 *******************************************************************************/
1800 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1804 CHECK_PHASE(JVMTI_PHASE_START)
1805 CHECK_PHASE(JVMTI_PHASE_LIVE)
1808 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1809 if (!builtin_instanceof(klass,class_java_lang_Class))
1810 return JVMTI_ERROR_INVALID_CLASS;
1812 if (signature_ptr != NULL) {
1813 *signature_ptr = (char*)
1814 heap_allocate(sizeof(char) *
1815 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1817 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1820 if (generic_ptr!= NULL)
1821 *generic_ptr = NULL;
1823 return JVMTI_ERROR_NONE;
1826 /* GetClassStatus *************************************************************
1828 Get status of the class.
1830 *******************************************************************************/
1833 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1837 CHECK_PHASE(JVMTI_PHASE_START)
1838 CHECK_PHASE(JVMTI_PHASE_LIVE)
1841 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1842 return JVMTI_ERROR_INVALID_CLASS;
1844 if (status_ptr == NULL)
1845 return JVMTI_ERROR_NULL_POINTER;
1847 c = (classinfo*)klass;
1850 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1851 if (c->state & CLASS_LINKED)
1852 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1854 if (c->state & CLASS_INITIALIZED)
1855 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1857 if (c->state & CLASS_ERROR)
1858 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1860 if (c->vftbl->arraydesc != NULL)
1861 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1863 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1864 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1866 return JVMTI_ERROR_NONE;
1870 /* GetSourceFileName **********************************************************
1872 For the class indicated by klass, return the source file name.
1874 *******************************************************************************/
1877 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1882 CHECK_PHASE(JVMTI_PHASE_START)
1883 CHECK_PHASE(JVMTI_PHASE_LIVE)
1885 CHECK_CAPABILITY(env,can_get_source_file_name)
1887 if ((klass == NULL)||(source_name_ptr == NULL))
1888 return JVMTI_ERROR_NULL_POINTER;
1890 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1892 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1894 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1895 (*source_name_ptr)[size]='\0';
1897 return JVMTI_ERROR_NONE;
1901 /* GetClassModifiers **********************************************************
1903 For class klass return the access flags
1905 *******************************************************************************/
1908 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1911 CHECK_PHASE(JVMTI_PHASE_START)
1912 CHECK_PHASE(JVMTI_PHASE_LIVE)
1915 if (modifiers_ptr == NULL)
1916 return JVMTI_ERROR_NULL_POINTER;
1918 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1919 return JVMTI_ERROR_INVALID_CLASS;
1921 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1923 return JVMTI_ERROR_NONE;
1927 /* GetClassMethods *************************************************************
1929 For class klass return a count of methods and a list of method IDs
1931 *******************************************************************************/
1934 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1935 jmethodID ** methods_ptr)
1940 CHECK_PHASE(JVMTI_PHASE_START)
1941 CHECK_PHASE(JVMTI_PHASE_LIVE)
1944 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1945 return JVMTI_ERROR_NULL_POINTER;
1947 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1948 return JVMTI_ERROR_INVALID_CLASS;
1950 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1951 *methods_ptr = (jmethodID*)
1952 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1954 for (i=0; i<*method_count_ptr;i++)
1955 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1957 return JVMTI_ERROR_NONE;
1961 /* GetClassFields *************************************************************
1963 For the class indicated by klass, return a count of fields and a list of
1966 *******************************************************************************/
1969 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1970 jfieldID ** fields_ptr)
1973 CHECK_PHASE(JVMTI_PHASE_START)
1974 CHECK_PHASE(JVMTI_PHASE_LIVE)
1977 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1978 return JVMTI_ERROR_NULL_POINTER;
1980 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1981 *fields_ptr = (jfieldID*)
1982 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1984 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1985 sizeof(jfieldID) * (*field_count_ptr));
1987 return JVMTI_ERROR_NONE;
1991 /* GetImplementedInterfaces ***************************************************
1993 Return the direct super-interfaces of this class.
1995 *******************************************************************************/
1998 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1999 jint * interface_count_ptr,
2000 jclass ** interfaces_ptr)
2003 classref_or_classinfo *interfaces;
2007 CHECK_PHASE(JVMTI_PHASE_START)
2008 CHECK_PHASE(JVMTI_PHASE_LIVE)
2011 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
2012 return JVMTI_ERROR_NULL_POINTER;
2014 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2015 return JVMTI_ERROR_INVALID_CLASS;
2018 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2020 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2022 interfaces = ((classinfo*)klass)->interfaces;
2023 for (i=0; i<*interface_count_ptr; i++) {
2024 if (IS_CLASSREF(interfaces[i]))
2025 tmp = load_class_bootstrap(interfaces[i].ref->name);
2027 tmp = interfaces[i].cls;
2029 *interfaces_ptr[i]=tmp;
2032 return JVMTI_ERROR_NONE;
2036 /* IsInterface ****************************************************************
2038 Determines whether a class object reference represents an interface.
2040 *******************************************************************************/
2043 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2046 CHECK_PHASE(JVMTI_PHASE_START)
2047 CHECK_PHASE(JVMTI_PHASE_LIVE)
2050 if ((klass == NULL)||(is_interface_ptr == NULL))
2051 return JVMTI_ERROR_NULL_POINTER;
2053 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2055 return JVMTI_ERROR_NONE;
2058 /* IsArrayClass ***************************************************************
2060 Determines whether a class object reference represents an array.
2062 *******************************************************************************/
2065 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2068 CHECK_PHASE(JVMTI_PHASE_START)
2069 CHECK_PHASE(JVMTI_PHASE_LIVE)
2072 if (is_array_class_ptr == NULL)
2073 return JVMTI_ERROR_NULL_POINTER;
2075 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2077 return JVMTI_ERROR_NONE;
2081 /* GetClassLoader *************************************************************
2083 For the class indicated by klass, return via classloader_ptr a reference to
2084 the class loader for the class.
2086 *******************************************************************************/
2089 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2092 CHECK_PHASE(JVMTI_PHASE_START)
2093 CHECK_PHASE(JVMTI_PHASE_LIVE)
2096 if ((klass == NULL)||(classloader_ptr == NULL))
2097 return JVMTI_ERROR_NULL_POINTER;
2099 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2101 return JVMTI_ERROR_NONE;
2105 /* GetObjectHashCode **********************************************************
2107 Return hash code for object object
2109 *******************************************************************************/
2112 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2115 CHECK_PHASE(JVMTI_PHASE_START)
2116 CHECK_PHASE(JVMTI_PHASE_LIVE)
2119 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2120 if (!builtin_instanceof(object,class_java_lang_Object))
2121 return JVMTI_ERROR_INVALID_OBJECT;
2123 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2125 return JVMTI_ERROR_NONE;
2129 /* *****************************************************************************
2133 *******************************************************************************/
2136 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2137 jvmtiMonitorUsage * info_ptr)
2140 CHECK_PHASE(JVMTI_PHASE_LIVE)
2142 CHECK_CAPABILITY(env,can_get_monitor_info)
2144 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2145 return JVMTI_ERROR_NONE;
2149 /* GetFieldName ***************************************************************
2151 For the field indicated by klass and field, return the field name and
2154 *******************************************************************************/
2157 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2158 char **name_ptr, char **signature_ptr, char **generic_ptr)
2163 CHECK_PHASE(JVMTI_PHASE_START)
2164 CHECK_PHASE(JVMTI_PHASE_LIVE)
2168 return JVMTI_ERROR_INVALID_CLASS;
2170 if (!builtin_instanceof(klass,class_java_lang_Class))
2171 return JVMTI_ERROR_INVALID_CLASS;
2172 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2174 if (name_ptr != NULL) {
2175 size = utf_bytes(((fieldinfo*)field)->name)+1;
2176 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2177 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2180 if (signature_ptr != NULL) {
2181 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2182 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2183 utf_sprint_convert_to_latin1(*signature_ptr,
2184 ((fieldinfo*)field)->descriptor);
2187 if (generic_ptr != NULL)
2188 *generic_ptr = NULL;
2190 return JVMTI_ERROR_NONE;
2194 /* GetFieldDeclaringClass *****************************************************
2196 For the field indicated by klass and field return the class that defined it
2197 The declaring class will either be klass, a superclass, or an implemented
2200 *******************************************************************************/
2203 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2204 jclass * declaring_class_ptr)
2207 CHECK_PHASE(JVMTI_PHASE_START)
2208 CHECK_PHASE(JVMTI_PHASE_LIVE)
2212 return JVMTI_ERROR_INVALID_CLASS;
2214 if (!builtin_instanceof(klass,class_java_lang_Class))
2215 return JVMTI_ERROR_INVALID_CLASS;
2217 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2219 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2221 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2223 return JVMTI_ERROR_NONE;
2227 /* GetFieldModifiers **********************************************************
2229 Return access flags of field field
2231 *******************************************************************************/
2234 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2235 jint * modifiers_ptr)
2238 CHECK_PHASE(JVMTI_PHASE_START)
2239 CHECK_PHASE(JVMTI_PHASE_LIVE)
2243 return JVMTI_ERROR_INVALID_CLASS;
2245 if (!builtin_instanceof(klass,class_java_lang_Class))
2246 return JVMTI_ERROR_INVALID_CLASS;
2248 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2250 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2252 *modifiers_ptr = ((fieldinfo*)field)->flags;
2254 return JVMTI_ERROR_NONE;
2258 /* IsFieldSynthetic ***********************************************************
2262 *******************************************************************************/
2265 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2266 jboolean * is_synthetic_ptr)
2269 CHECK_PHASE(JVMTI_PHASE_START)
2270 CHECK_PHASE(JVMTI_PHASE_LIVE)
2272 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2274 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2275 return JVMTI_ERROR_NONE;
2279 /* GetMethodName ***************************************************************
2281 For the method indicated by method, return the method name via name_ptr and
2282 method signature via signature_ptr.
2284 *******************************************************************************/
2287 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2288 char **signature_ptr, char **generic_ptr)
2290 methodinfo* m = (methodinfo*)method;
2293 CHECK_PHASE(JVMTI_PHASE_START)
2294 CHECK_PHASE(JVMTI_PHASE_LIVE)
2298 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2300 if (name_ptr != NULL) {
2302 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2303 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2306 if (signature_ptr != NULL) {
2307 *signature_ptr = (char*)
2308 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2309 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2312 if (generic_ptr != NULL) {
2313 /* there is no generic signature attribute */
2314 *generic_ptr = NULL;
2317 return JVMTI_ERROR_NONE;
2321 /* GetMethodDeclaringClass *****************************************************
2323 For the method indicated by method, return the class that defined it.
2325 *******************************************************************************/
2328 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2329 jclass * declaring_class_ptr)
2332 CHECK_PHASE(JVMTI_PHASE_START)
2333 CHECK_PHASE(JVMTI_PHASE_LIVE)
2336 if ((method == NULL) || (declaring_class_ptr == NULL))
2337 return JVMTI_ERROR_NULL_POINTER;
2339 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2341 return JVMTI_ERROR_NONE;
2345 /* GetMethodModifiers **********************************************************
2347 For the method indicated by method, return the access flags.
2349 *******************************************************************************/
2352 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2355 CHECK_PHASE(JVMTI_PHASE_START)
2356 CHECK_PHASE(JVMTI_PHASE_LIVE)
2359 if ((method == NULL) || (modifiers_ptr == NULL))
2360 return JVMTI_ERROR_NULL_POINTER;
2362 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2364 return JVMTI_ERROR_NONE;
2368 /* GetMaxLocals ****************************************************************
2370 For the method indicated by method, return the number of local variable slots
2371 used by the method, including the local variables used to pass parameters to
2372 the method on its invocation.
2374 *******************************************************************************/
2377 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2380 CHECK_PHASE(JVMTI_PHASE_START)
2381 CHECK_PHASE(JVMTI_PHASE_LIVE)
2384 if ((method == NULL)||(max_ptr == NULL))
2385 return JVMTI_ERROR_NULL_POINTER;
2387 if (((methodinfo*)method)->flags & ACC_NATIVE)
2388 return JVMTI_ERROR_NATIVE_METHOD;
2390 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2392 return JVMTI_ERROR_NONE;
2397 /* GetArgumentsSize ************************************************************
2399 Return the number of local variable slots used by the method's arguments.
2401 *******************************************************************************/
2404 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2407 CHECK_PHASE(JVMTI_PHASE_START)
2408 CHECK_PHASE(JVMTI_PHASE_LIVE)
2411 if ((method == NULL)||(size_ptr == NULL))
2412 return JVMTI_ERROR_NULL_POINTER;
2414 if (((methodinfo*)method)->flags & ACC_NATIVE)
2415 return JVMTI_ERROR_NATIVE_METHOD;
2417 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2418 return JVMTI_ERROR_NONE;
2423 /* GetLineNumberTable **********************************************************
2425 Return table of source line number entries for a given method
2427 *******************************************************************************/
2430 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2431 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2436 CHECK_PHASE(JVMTI_PHASE_START)
2437 CHECK_PHASE(JVMTI_PHASE_LIVE)
2439 CHECK_CAPABILITY(env,can_get_line_numbers)
2441 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2442 return JVMTI_ERROR_NULL_POINTER;
2444 if (((methodinfo*)method)->flags & ACC_NATIVE)
2445 return JVMTI_ERROR_NATIVE_METHOD;
2447 if (((methodinfo*)method)->linenumbers == NULL)
2448 return JVMTI_ERROR_ABSENT_INFORMATION;
2450 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2451 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2452 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2455 for (i=0; i < *entry_count_ptr; i++) {
2456 (*table_ptr)[i].start_location =
2457 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2458 (*table_ptr)[i].line_number =
2459 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2462 return JVMTI_ERROR_NONE;
2466 /* GetMethodLocation ***********************************************************
2468 For the method indicated by method, return the beginning and ending addresses
2469 through start_location_ptr and end_location_ptr. In cacao this points to
2470 entry point in machine code and length of machine code
2472 *******************************************************************************/
2475 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2476 jlocation * start_location_ptr,
2477 jlocation * end_location_ptr)
2479 methodinfo* m = (methodinfo*)method;
2482 CHECK_PHASE(JVMTI_PHASE_START)
2483 CHECK_PHASE(JVMTI_PHASE_LIVE)
2486 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2488 if (((methodinfo*)method)->flags & ACC_NATIVE)
2489 return JVMTI_ERROR_NATIVE_METHOD;
2491 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2492 return JVMTI_ERROR_NULL_POINTER;
2494 /* XXX we return the location of the most recent code. Don't know
2495 * if there is a way to teach jvmti that a method can have more
2496 * than one location. -Edwin */
2498 /* XXX Don't know if that's the right way to deal with not-yet-
2499 * compiled methods. -Edwin */
2501 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2504 /* -1 states location information is not available */
2505 *start_location_ptr = (jlocation)-1;
2506 *end_location_ptr = (jlocation)-1;
2509 *start_location_ptr = (jlocation)m->code->mcode;
2510 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2511 return JVMTI_ERROR_NONE;
2515 /* GetLocalVariableTable *******************************************************
2517 Return local variable information.
2519 *******************************************************************************/
2522 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2523 jint * entry_count_ptr,
2524 jvmtiLocalVariableEntry ** table_ptr)
2527 CHECK_PHASE(JVMTI_PHASE_LIVE)
2529 CHECK_CAPABILITY(env,can_access_local_variables)
2531 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2533 return JVMTI_ERROR_NONE;
2537 /* GetBytecode *****************************************************************
2539 For the method indicated by method, return the byte codes that implement the
2542 *******************************************************************************/
2545 GetBytecodes (jvmtiEnv * env, jmethodID method,
2546 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2548 methodinfo* m = (methodinfo*)method;;
2551 CHECK_PHASE(JVMTI_PHASE_START)
2552 CHECK_PHASE(JVMTI_PHASE_LIVE)
2554 CHECK_CAPABILITY(env,can_get_bytecodes)
2556 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2557 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2559 *bytecode_count_ptr = m->jcodelength;
2560 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2561 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2563 return JVMTI_ERROR_NONE;
2567 /* IsMethodNative **************************************************************
2569 For the method indicated by method, return a value indicating whether the
2570 method is a native function
2572 *******************************************************************************/
2575 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2578 CHECK_PHASE(JVMTI_PHASE_START)
2579 CHECK_PHASE(JVMTI_PHASE_LIVE)
2582 if ((method == NULL)||(is_native_ptr == NULL))
2583 return JVMTI_ERROR_NULL_POINTER;
2585 if (((methodinfo*)method)->flags & ACC_NATIVE)
2586 *is_native_ptr = JNI_TRUE;
2588 *is_native_ptr = JNI_FALSE;
2590 return JVMTI_ERROR_NONE;
2594 /* IsMethodSynthetic ***********************************************************
2596 return a value indicating whether the method is synthetic. Synthetic methods
2597 are generated by the compiler but not present in the original source code.
2599 *******************************************************************************/
2602 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2603 jboolean * is_synthetic_ptr)
2606 CHECK_PHASE(JVMTI_PHASE_START)
2607 CHECK_PHASE(JVMTI_PHASE_LIVE)
2609 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2611 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2612 return JVMTI_ERROR_NONE;
2616 /* GetLoadedClasses ************************************************************
2618 Return an array of all classes loaded in the virtual machine.
2620 *******************************************************************************/
2623 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2626 CHECK_PHASE(JVMTI_PHASE_LIVE)
2629 if (class_count_ptr == NULL)
2630 return JVMTI_ERROR_NULL_POINTER;
2632 if (classes_ptr == NULL)
2633 return JVMTI_ERROR_NULL_POINTER;
2635 classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
2637 return JVMTI_ERROR_NONE;
2641 /* GetClassLoaderClasses *******************************************************
2643 Returns an array of those classes for which this class loader has been
2644 recorded as an initiating loader.
2646 *******************************************************************************/
2649 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2650 jint * class_count_ptr, jclass ** classes_ptr)
2652 log_text("GetClassLoaderClasses called");
2655 CHECK_PHASE(JVMTI_PHASE_LIVE)
2658 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2659 return JVMTI_ERROR_NULL_POINTER;
2661 /* behave like jdk 1.1 and make no distinction between initiating and
2662 defining class loaders */
2664 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2668 /* PopFrame *******************************************************************
2672 *******************************************************************************/
2675 PopFrame (jvmtiEnv * env, jthread thread)
2678 CHECK_PHASE(JVMTI_PHASE_LIVE)
2680 CHECK_CAPABILITY(env,can_pop_frame)
2682 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2683 return JVMTI_ERROR_NONE;
2687 /* RedefineClasses ************************************************************
2691 *******************************************************************************/
2694 RedefineClasses (jvmtiEnv * env, jint class_count,
2695 const jvmtiClassDefinition * class_definitions)
2698 CHECK_PHASE(JVMTI_PHASE_START)
2699 CHECK_PHASE(JVMTI_PHASE_LIVE)
2701 CHECK_CAPABILITY(env,can_redefine_classes)
2702 CHECK_CAPABILITY(env,can_redefine_any_class)
2704 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2705 return JVMTI_ERROR_NONE;
2709 /* GetVersionNumber ***********************************************************
2711 Return the JVM TI version identifier.
2713 *******************************************************************************/
2716 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2718 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2720 *version_ptr = JVMTI_VERSION;
2722 return JVMTI_ERROR_NONE;
2726 /* GetCapabilities ************************************************************
2728 Returns the optional JVM TI features which this environment currently
2731 *******************************************************************************/
2734 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2736 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2738 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2740 return JVMTI_ERROR_NONE;
2744 /* *****************************************************************************
2748 *******************************************************************************/
2751 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2752 char **source_debug_extension_ptr)
2755 CHECK_PHASE(JVMTI_PHASE_START)
2756 CHECK_PHASE(JVMTI_PHASE_LIVE)
2758 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2760 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2761 return JVMTI_ERROR_NONE;
2765 /* IsMethodObsolete ************************************************************
2767 Determine if a method ID refers to an obsolete method version.
2769 *******************************************************************************/
2772 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2773 jboolean * is_obsolete_ptr)
2776 CHECK_PHASE(JVMTI_PHASE_START)
2777 CHECK_PHASE(JVMTI_PHASE_LIVE)
2779 CHECK_CAPABILITY(env,can_redefine_classes)
2781 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2782 return JVMTI_ERROR_NONE;
2786 /* SuspendThreadList **********************************************************
2788 Suspend all threads in the request list.
2790 *******************************************************************************/
2793 SuspendThreadList (jvmtiEnv * env, jint request_count,
2794 const jthread * request_list, jvmtiError * results)
2801 CHECK_PHASE(JVMTI_PHASE_START)
2802 CHECK_PHASE(JVMTI_PHASE_LIVE)
2804 CHECK_CAPABILITY(env,can_suspend);
2806 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2807 if ((request_list == NULL) || (results == NULL))
2808 return JVMTI_ERROR_NULL_POINTER;
2810 me = jvmti_get_current_thread();
2812 for (i=0;i<request_count;i++) {
2813 if (request_list[i] == me)
2816 results[i]=SuspendThread(env, request_list[i]);
2819 if (suspendme != -1)
2820 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2822 return JVMTI_ERROR_NONE;
2826 /* ResumeThreadList ***********************************************************
2828 Resumes all threads in the request list.
2830 *******************************************************************************/
2833 ResumeThreadList (jvmtiEnv * env, jint request_count,
2834 const jthread * request_list, jvmtiError * results)
2839 CHECK_PHASE(JVMTI_PHASE_LIVE)
2841 CHECK_CAPABILITY(env,can_suspend);
2843 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2844 if ((request_list == NULL) || (results == NULL))
2845 return JVMTI_ERROR_NULL_POINTER;
2847 for (i=0;i<request_count;i++)
2848 results[i]=ResumeThread(env, request_list[i]);
2850 return JVMTI_ERROR_NONE;
2854 /* GetStackTrace **************************************************************
2856 Get information about the stack of a thread
2858 *******************************************************************************/
2861 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2862 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2865 stacktracebuffer* trace;
2870 CHECK_PHASE(JVMTI_PHASE_LIVE)
2873 if (thread != NULL){
2874 if(!builtin_instanceof(thread,class_java_lang_Thread))
2875 return JVMTI_ERROR_INVALID_THREAD;
2877 CHECK_THREAD_IS_ALIVE(thread);
2880 if((count_ptr == NULL)||(frame_buffer == NULL))
2881 return JVMTI_ERROR_NULL_POINTER;
2883 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2885 er = getcacaostacktrace(&trace, thread);
2886 if (er == JVMTI_ERROR_NONE) {
2891 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2892 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2894 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2895 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2896 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2897 frame_buffer[j].location = 0;
2902 return JVMTI_ERROR_NONE;
2906 /* GetThreadListStackTraces ***************************************************
2908 Get information about the stacks of the supplied threads.
2910 *******************************************************************************/
2913 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2914 const jthread * thread_list,
2915 jint max_frame_count,
2916 jvmtiStackInfo ** stack_info_ptr)
2922 CHECK_PHASE(JVMTI_PHASE_LIVE)
2925 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2926 return JVMTI_ERROR_NULL_POINTER;
2928 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2930 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2932 *stack_info_ptr = (jvmtiStackInfo*)
2933 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2935 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2936 (*stack_info_ptr)[i].thread=thread_list[i];
2937 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2938 (*stack_info_ptr)[i].frame_buffer =
2939 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2940 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2941 (*stack_info_ptr)[i].frame_buffer,
2942 &((*stack_info_ptr)[i].frame_count));
2944 if (er != JVMTI_ERROR_NONE) return er;
2947 return JVMTI_ERROR_NONE;
2951 /* GetAllStackTraces **********************************************************
2953 Get stack traces of all live threads
2955 *******************************************************************************/
2958 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2959 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2961 jthread *threads_ptr;
2965 CHECK_PHASE(JVMTI_PHASE_LIVE)
2968 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2970 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2971 return JVMTI_ERROR_INTERNAL;
2973 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2974 max_frame_count, stack_info_ptr);
2976 if (er != JVMTI_ERROR_NONE) return er;
2978 return JVMTI_ERROR_NONE;
2982 /* GetThreadLocalStorage ******************************************************
2984 Get the value of the JVM TI thread-local storage.
2986 *******************************************************************************/
2989 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2991 jvmtiThreadLocalStorage *tls;
2994 CHECK_PHASE(JVMTI_PHASE_START)
2995 CHECK_PHASE(JVMTI_PHASE_LIVE)
2999 thread = (jthread) THREADOBJECT;
3001 if (!builtin_instanceof(thread,class_java_lang_Thread))
3002 return JVMTI_ERROR_INVALID_THREAD;
3003 CHECK_THREAD_IS_ALIVE(thread);
3006 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3008 tls = ((environment*)env)->tls;
3009 while ((tls->thread != thread) && (tls != NULL)) {
3013 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3015 *data_ptr = tls->data;
3017 return JVMTI_ERROR_NONE;
3021 /* SetThreadLocalStorage *******************************************************
3023 Stores a pointer value associated with each environment-thread pair. The
3024 value is NULL unless set with this function. Agents can allocate memory in
3025 which they store thread specific information
3027 *******************************************************************************/
3030 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3032 jvmtiThreadLocalStorage *tls, *pre;
3033 environment* env = (environment*)jenv;
3036 CHECK_PHASE(JVMTI_PHASE_START)
3037 CHECK_PHASE(JVMTI_PHASE_LIVE)
3041 thread = (jthread) THREADOBJECT;
3043 if (!builtin_instanceof(thread,class_java_lang_Thread))
3044 return JVMTI_ERROR_INVALID_THREAD;
3045 CHECK_THREAD_IS_ALIVE(thread);
3048 if (env->tls == NULL) {
3049 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3052 while ((tls->thread != thread) && (tls->next != NULL)) {
3055 if (tls->thread != thread) {
3056 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3062 tls->data = (void*)data;
3064 /* remove current tls */
3066 while (pre->next == tls) pre = pre->next;
3067 pre->next = tls->next;
3069 return JVMTI_ERROR_NONE;
3073 /* *****************************************************************************
3077 *******************************************************************************/
3080 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3083 CHECK_PHASE(JVMTI_PHASE_START)
3084 CHECK_PHASE(JVMTI_PHASE_LIVE)
3086 CHECK_CAPABILITY(env,can_tag_objects)
3088 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3089 return JVMTI_ERROR_NONE;
3092 /* *****************************************************************************
3096 *******************************************************************************/
3099 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3102 CHECK_PHASE(JVMTI_PHASE_START)
3103 CHECK_PHASE(JVMTI_PHASE_LIVE)
3105 CHECK_CAPABILITY(env,can_tag_objects)
3107 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3108 return JVMTI_ERROR_NONE;
3112 /* ForceGarbageCollection *****************************************************
3114 Force boehm-gc to perform a garbage collection
3116 *******************************************************************************/
3119 ForceGarbageCollection (jvmtiEnv * env)
3122 CHECK_PHASE(JVMTI_PHASE_LIVE)
3127 return JVMTI_ERROR_NONE;
3131 /* IterateOverObjectsReachableFromObject **************************************
3135 *******************************************************************************/
3138 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3139 jvmtiObjectReferenceCallback
3140 object_reference_callback,
3144 CHECK_PHASE(JVMTI_PHASE_LIVE)
3146 CHECK_CAPABILITY(env,can_tag_objects)
3148 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3149 return JVMTI_ERROR_NONE;
3153 /* IterateOverReachableObjects ************************************************
3157 *******************************************************************************/
3160 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3162 jvmtiStackReferenceCallback
3164 jvmtiObjectReferenceCallback
3165 object_ref_callback, void *user_data)
3168 CHECK_PHASE(JVMTI_PHASE_LIVE)
3170 CHECK_CAPABILITY(env,can_tag_objects)
3172 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3173 return JVMTI_ERROR_NONE;
3177 /* IterateOverHeap ************************************************************
3181 *******************************************************************************/
3184 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3185 jvmtiHeapObjectCallback heap_object_callback,
3189 CHECK_PHASE(JVMTI_PHASE_LIVE)
3191 CHECK_CAPABILITY(env,can_tag_objects)
3193 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3194 return JVMTI_ERROR_NONE;
3198 /* IterateOverInstancesOfClass ************************************************
3202 *******************************************************************************/
3205 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3206 jvmtiHeapObjectFilter object_filter,
3207 jvmtiHeapObjectCallback
3208 heap_object_callback, void *user_data)
3211 CHECK_PHASE(JVMTI_PHASE_LIVE)
3213 CHECK_CAPABILITY(env,can_tag_objects)
3215 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3216 return JVMTI_ERROR_NONE;
3220 /* *****************************************************************************
3224 *******************************************************************************/
3227 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3228 jint * count_ptr, jobject ** object_result_ptr,
3229 jlong ** tag_result_ptr)
3232 CHECK_PHASE(JVMTI_PHASE_LIVE)
3234 CHECK_CAPABILITY(env,can_tag_objects)
3236 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3237 return JVMTI_ERROR_NONE;
3241 /* SetJNIFunctionTable **********************************************************
3243 Set the JNI function table in all current and future JNI environments
3245 *******************************************************************************/
3248 SetJNIFunctionTable (jvmtiEnv * env,
3249 const jniNativeInterface * function_table)
3252 CHECK_PHASE(JVMTI_PHASE_START)
3253 CHECK_PHASE(JVMTI_PHASE_LIVE)
3256 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3257 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3258 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3259 return JVMTI_ERROR_NONE;
3263 /* GetJNIFunctionTable *********************************************************
3265 Get the JNI function table. The JNI function table is copied into allocated
3268 *******************************************************************************/
3271 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3274 CHECK_PHASE(JVMTI_PHASE_START)
3275 CHECK_PHASE(JVMTI_PHASE_LIVE)
3278 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3279 *function_table = (jniNativeInterface*)
3280 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3281 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3282 return JVMTI_ERROR_NONE;
3286 /* SetEventCallbacks **********************************************************
3288 Set the functions to be called for each event. The callbacks are specified
3289 by supplying a replacement function table.
3291 *******************************************************************************/
3294 SetEventCallbacks (jvmtiEnv * env,
3295 const jvmtiEventCallbacks * callbacks,
3296 jint size_of_callbacks)
3299 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3300 CHECK_PHASE(JVMTI_PHASE_LIVE)
3303 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3306 if (callbacks == NULL) { /* remove the existing callbacks */
3307 memset(&(((environment* )env)->callbacks), 0,
3308 sizeof(jvmtiEventCallbacks));
3311 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3313 return JVMTI_ERROR_NONE;
3317 /* GenerateEvents *************************************************************
3319 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3320 the current state of the VM.
3322 *******************************************************************************/
3325 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3328 CHECK_PHASE(JVMTI_PHASE_LIVE)
3330 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3332 return JVMTI_ERROR_NONE;
3336 /* GetExtensionFunctions ******************************************************
3338 Returns the set of extension functions.
3340 *******************************************************************************/
3343 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3344 jvmtiExtensionFunctionInfo ** extensions)
3347 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3348 CHECK_PHASE(JVMTI_PHASE_LIVE)
3351 if ((extension_count_ptr == NULL)||(extensions == NULL))
3352 return JVMTI_ERROR_NULL_POINTER;
3354 /* cacao has no extended functions yet */
3355 *extension_count_ptr = 0;
3357 return JVMTI_ERROR_NONE;
3361 /* GetExtensionEvents *********************************************************
3363 Returns the set of extension events.
3365 *******************************************************************************/
3368 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3369 jvmtiExtensionEventInfo ** extensions)
3372 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3373 CHECK_PHASE(JVMTI_PHASE_LIVE)
3376 if ((extension_count_ptr == NULL)||(extensions == NULL))
3377 return JVMTI_ERROR_NULL_POINTER;
3379 /* cacao has no extended events yet */
3380 *extension_count_ptr = 0;
3382 return JVMTI_ERROR_NONE;
3386 /* SetExtensionEventCallback **************************************************
3388 Sets the callback function for an extension event and enables the event.
3390 *******************************************************************************/
3393 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3394 jvmtiExtensionEvent callback)
3397 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3398 CHECK_PHASE(JVMTI_PHASE_LIVE)
3401 /* cacao has no extended events yet */
3402 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3406 /* DisposeEnvironment **********************************************************
3408 Shutdown a JVM TI connection created with JNI GetEnv.
3410 *******************************************************************************/
3413 DisposeEnvironment (jvmtiEnv * env)
3415 environment* cacao_env = (environment*)env;
3416 environment* tenvs = envs;
3417 jvmtiThreadLocalStorage *jtls, *tjtls;
3419 if (tenvs != cacao_env) {
3420 while (tenvs->next != cacao_env) {
3421 tenvs = tenvs->next;
3423 tenvs->next = cacao_env->next;
3427 cacao_env->env=NULL;
3428 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3429 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3430 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3431 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3432 cacao_env->EnvironmentLocalStorage = NULL;
3434 jtls = cacao_env->tls;
3435 while (jtls != NULL) {
3440 cacao_env->tls = NULL;
3443 jvmti_cacaodbgserver_quit();
3445 /* let the GC do the rest */
3446 return JVMTI_ERROR_NONE;
3450 /* GetErrorName ***************************************************************
3452 Return the symbolic name for an error code.
3454 *******************************************************************************/
3456 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3457 memcpy(*name_ptr, &str, sizeof(str)); \
3461 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3463 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3466 case JVMTI_ERROR_NONE :
3467 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3468 case JVMTI_ERROR_NULL_POINTER :
3469 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3470 case JVMTI_ERROR_OUT_OF_MEMORY :
3471 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3472 case JVMTI_ERROR_ACCESS_DENIED :
3473 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3474 case JVMTI_ERROR_UNATTACHED_THREAD :
3475 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3476 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3477 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3478 case JVMTI_ERROR_WRONG_PHASE :
3479 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3480 case JVMTI_ERROR_INTERNAL :
3481 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3482 case JVMTI_ERROR_INVALID_PRIORITY :
3483 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3484 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3485 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3486 case JVMTI_ERROR_THREAD_SUSPENDED :
3487 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3488 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3489 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3490 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3491 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3492 case JVMTI_ERROR_NO_MORE_FRAMES :
3493 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3494 case JVMTI_ERROR_OPAQUE_FRAME :
3495 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3496 case JVMTI_ERROR_DUPLICATE :
3497 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3498 case JVMTI_ERROR_NOT_FOUND :
3499 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3500 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3501 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3502 case JVMTI_ERROR_INTERRUPT :
3503 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3504 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3505 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3506 case JVMTI_ERROR_NOT_AVAILABLE :
3507 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3508 case JVMTI_ERROR_ABSENT_INFORMATION :
3509 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3510 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3511 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3512 case JVMTI_ERROR_NATIVE_METHOD :
3513 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3514 case JVMTI_ERROR_INVALID_THREAD :
3515 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3516 case JVMTI_ERROR_INVALID_FIELDID :
3517 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3518 case JVMTI_ERROR_INVALID_METHODID :
3519 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3520 case JVMTI_ERROR_INVALID_LOCATION :
3521 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3522 case JVMTI_ERROR_INVALID_OBJECT :
3523 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3524 case JVMTI_ERROR_INVALID_CLASS :
3525 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3526 case JVMTI_ERROR_TYPE_MISMATCH :
3527 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3528 case JVMTI_ERROR_INVALID_SLOT :
3529 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3530 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3531 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3532 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3533 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3534 case JVMTI_ERROR_INVALID_MONITOR :
3535 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3536 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3537 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3538 case JVMTI_ERROR_INVALID_TYPESTATE :
3539 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3540 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3541 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3542 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3543 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3544 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3545 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3546 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3547 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3548 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3549 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3550 case JVMTI_ERROR_FAILS_VERIFICATION :
3551 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3552 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3553 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3554 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3555 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3556 case JVMTI_ERROR_NAMES_DONT_MATCH :
3557 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3558 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3559 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3560 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3561 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3563 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3565 return JVMTI_ERROR_NONE;
3568 /* GetJLocationFormat **********************************************************
3570 This function describes the representation of jlocation used in this VM.
3572 *******************************************************************************/
3575 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3577 *format_ptr = JVMTI_JLOCATION_OTHER;
3578 return JVMTI_ERROR_NONE;
3582 /* GetSystemProperties ********************************************************
3584 The list of VM system property keys which may be used with GetSystemProperty
3587 *******************************************************************************/
3590 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3592 jmethodID mid, moremid;
3593 classinfo *sysclass, *propclass, *enumclass;
3594 java_objectheader *sysprop, *keys, *obj;
3599 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3600 CHECK_PHASE(JVMTI_PHASE_LIVE)
3603 if ((count_ptr == NULL) || (property_ptr == NULL))
3604 return JVMTI_ERROR_NULL_POINTER;
3606 sysclass = load_class_from_sysloader(
3607 utf_new_char_classname ("java/lang/System"));
3609 if (!sysclass) throw_main_exception_exit();
3611 mid = (jmethodID)class_resolvemethod(sysclass,
3612 utf_new_char("getProperties"),
3613 utf_new_char("()Ljava/util/Properties;"));
3614 if (!mid) throw_main_exception_exit();
3617 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3618 if (!sysprop) throw_main_exception_exit();
3620 propclass = sysprop->vftbl->class;
3622 mid = (jmethodID)class_resolvemethod(propclass,
3623 utf_new_char("size"),
3624 utf_new_char("()I"));
3625 if (!mid) throw_main_exception_exit();
3628 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3629 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3631 mid = (jmethodID)class_resolvemethod(propclass,
3632 utf_new_char("keys"),
3633 utf_new_char("()Ljava/util/Enumeration;"));
3634 if (!mid) throw_main_exception_exit();
3636 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3637 enumclass = keys->vftbl->class;
3639 moremid = (jmethodID)class_resolvemethod(enumclass,
3640 utf_new_char("hasMoreElements"),
3641 utf_new_char("()Z"));
3642 if (!moremid) throw_main_exception_exit();
3644 mid = (jmethodID)class_resolvemethod(propclass,
3645 utf_new_char("nextElement"),
3646 utf_new_char("()Ljava/lang/Object;"));
3647 if (!mid) throw_main_exception_exit();
3650 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3651 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3652 ch = javastring_tochar(obj);
3653 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3654 memcpy(*property_ptr[i], ch, strlen (ch));
3655 MFREE(ch,char,strlen(ch)+1);
3659 return JVMTI_ERROR_NONE;
3663 /* GetSystemProperty **********************************************************
3665 Return a VM system property value given the property key.
3667 *******************************************************************************/
3670 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3673 classinfo *sysclass, *propclass;
3674 java_objectheader *sysprop, *obj;
3678 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3679 CHECK_PHASE(JVMTI_PHASE_LIVE)
3682 if ((value_ptr == NULL) || (property == NULL))
3683 return JVMTI_ERROR_NULL_POINTER;
3685 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3686 if (!sysclass) throw_main_exception_exit();
3688 mid = (jmethodID)class_resolvemethod(sysclass,
3689 utf_new_char("getProperties"),
3690 utf_new_char("()Ljava/util/Properties;"));
3691 if (!mid) throw_main_exception_exit();
3693 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3695 propclass = sysprop->vftbl->class;
3697 mid = (jmethodID)class_resolvemethod(propclass,
3698 utf_new_char("getProperty"),
3699 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3700 if (!mid) throw_main_exception_exit();
3702 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3703 NULL, sysprop, mid, javastring_new_from_ascii(property));
3704 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3706 ch = javastring_tochar(obj);
3707 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3708 memcpy(*value_ptr, ch, strlen (ch));
3709 MFREE(ch,char,strlen(ch)+1);
3711 return JVMTI_ERROR_NONE;
3715 /* SetSystemProperty **********************************************************
3717 Set a VM system property value.
3719 *******************************************************************************/
3722 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3725 classinfo *sysclass, *propclass;
3726 java_objectheader *sysprop;
3729 CHECK_PHASE(JVMTI_PHASE_START)
3732 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3733 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3735 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3736 if (!sysclass) throw_main_exception_exit();
3738 mid = (jmethodID)class_resolvemethod(sysclass,
3739 utf_new_char("getProperties"),
3740 utf_new_char("()Ljava/util/Properties;"));
3741 if (!mid) throw_main_exception_exit();
3743 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3745 propclass = sysprop->vftbl->class;
3747 mid = (jmethodID)class_resolvemethod(propclass,
3748 utf_new_char("setProperty"),
3749 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3750 if (!mid) throw_main_exception_exit();
3752 _Jv_JNINativeInterface.CallObjectMethod(
3753 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3755 return JVMTI_ERROR_NONE;
3758 /* GetPhase ********************************************************************
3760 Return the current phase of VM execution
3762 *******************************************************************************/
3765 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3767 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3771 return JVMTI_ERROR_NONE;
3774 /* GetCurrentThreadCpuTimerInfo ************************************************
3778 *******************************************************************************/
3781 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3784 CHECK_PHASE(JVMTI_PHASE_START)
3785 CHECK_PHASE(JVMTI_PHASE_LIVE)
3787 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3789 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3791 return JVMTI_ERROR_NONE;
3794 /* GetCurrentThreadCpuTime ****************************************************
3798 *******************************************************************************/
3801 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3804 CHECK_PHASE(JVMTI_PHASE_START)
3805 CHECK_PHASE(JVMTI_PHASE_LIVE)
3807 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3809 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3810 return JVMTI_ERROR_NONE;
3813 /* GetThreadCpuTimerInfo ******************************************************
3817 *******************************************************************************/
3820 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3823 CHECK_PHASE(JVMTI_PHASE_START)
3824 CHECK_PHASE(JVMTI_PHASE_LIVE)
3826 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3828 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3829 return JVMTI_ERROR_NONE;
3832 /* GetThreadCpuTime ***********************************************************
3836 *******************************************************************************/
3839 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3842 CHECK_PHASE(JVMTI_PHASE_LIVE)
3844 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3845 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3846 return JVMTI_ERROR_NONE;
3849 /* GetTimerInfo ***************************************************************
3851 Get information about the GetTime timer.
3853 *******************************************************************************/
3856 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3858 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3860 info_ptr->max_value = !0x0;
3861 info_ptr->may_skip_forward = true;
3862 info_ptr->may_skip_backward = true;
3863 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3865 return JVMTI_ERROR_NONE;
3868 /* GetTime ********************************************************************
3870 Return the current value of the system timer, in nanoseconds
3872 *******************************************************************************/
3875 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3877 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3880 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3882 if (gettimeofday (&tp, NULL) == -1)
3883 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3885 *nanos_ptr = (jlong) tp.tv_sec;
3887 *nanos_ptr += (tp.tv_usec / 1000);
3889 return JVMTI_ERROR_NONE;
3892 /* GetPotentialCapabilities ***************************************************
3894 Returns the JVM TI features that can potentially be possessed by this
3895 environment at this time.
3897 *******************************************************************************/
3900 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3903 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3904 CHECK_PHASE(JVMTI_PHASE_LIVE)
3907 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3909 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3911 return JVMTI_ERROR_NONE;
3915 #define CHECK_ADD_CAPABILITY(env,CAN) \
3916 if (capabilities_ptr->CAN == 1) { \
3917 if (JVMTI_Capabilities.CAN == 0) \
3918 return JVMTI_ERROR_NOT_AVAILABLE; \
3920 env->capabilities.CAN = 1; \
3923 /* AddCapabilities ************************************************************
3925 Set new capabilities by adding the capabilities pointed to by
3926 capabilities_ptr. All previous capabilities are retained.
3928 *******************************************************************************/
3931 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3933 environment* cacao_env;
3936 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3937 CHECK_PHASE(JVMTI_PHASE_LIVE)
3940 if ((env == NULL) || (capabilities_ptr == NULL))
3941 return JVMTI_ERROR_NULL_POINTER;
3943 cacao_env = (environment*)env;
3945 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3946 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3947 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3948 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3949 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3950 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3951 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3952 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3953 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3965 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3966 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3967 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3968 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3969 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3970 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3971 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3972 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3973 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3974 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3975 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3976 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3977 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3980 return JVMTI_ERROR_NONE;
3984 #define CHECK_DEL_CAPABILITY(env,CAN) \
3985 if (capabilities_ptr->CAN == 1) \
3986 env->capabilities.CAN = 0;
3988 /* RelinquishCapabilities *****************************************************
3990 Relinquish the capabilities pointed to by capabilities_ptr.
3992 *******************************************************************************/
3995 RelinquishCapabilities (jvmtiEnv * env,
3996 const jvmtiCapabilities * capabilities_ptr)
3998 environment* cacao_env;
4001 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4002 CHECK_PHASE(JVMTI_PHASE_LIVE)
4005 if ((env == NULL) || (capabilities_ptr == NULL))
4006 return JVMTI_ERROR_NULL_POINTER;
4008 cacao_env = (environment*)env;
4010 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
4011 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4012 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4013 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4014 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4015 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4016 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4017 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4018 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4030 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4031 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4032 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4033 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4034 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4035 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4036 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4037 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4038 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4039 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4040 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4041 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4042 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4044 return JVMTI_ERROR_NONE;
4047 /* GetAvailableProcessors *****************************************************
4049 Get number of processors available to the virtual machine.
4051 *******************************************************************************/
4054 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4057 CHECK_PHASE(JVMTI_PHASE_START)
4058 CHECK_PHASE(JVMTI_PHASE_LIVE)
4061 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4063 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4065 *processor_count_ptr = 1; /* where do I get this ?*/
4067 return JVMTI_ERROR_NONE;
4070 /* GetEnvironmentLocalStorage **************************************************
4072 Called by the agent to get the value of the JVM TI environment-local storage.
4074 *******************************************************************************/
4077 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4079 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4081 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4083 return JVMTI_ERROR_NONE;
4086 /* SetEnvironmentLocalStorage **************************************************
4088 The VM stores a pointer value associated with each environment. Agents can
4089 allocate memory in which they store environment specific information.
4091 *******************************************************************************/
4094 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4096 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4098 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4100 return JVMTI_ERROR_NONE;
4103 /* AddToBootstrapClassLoaderSearch ********************************************
4105 After the bootstrap class loader unsuccessfully searches for a class, the
4106 specified platform-dependent search path segment will be searched as well.
4108 *******************************************************************************/
4111 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4117 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4120 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4122 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4123 tmp_bcp = MNEW(char, ln);
4124 strcat(tmp_bcp, bootclasspath);
4125 strcat(tmp_bcp, ":");
4126 strcat(tmp_bcp, segment);
4127 MFREE(bootclasspath,char,ln);
4128 bootclasspath = tmp_bcp;
4130 return JVMTI_ERROR_NONE;
4133 /* SetVerboseFlag *************************************************************
4135 Control verbose output. This is the output which typically is sent to stderr
4137 *******************************************************************************/
4140 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4143 case JVMTI_VERBOSE_OTHER:
4144 /* where is this defined ?
4148 case JVMTI_VERBOSE_GC:
4149 opt_verbosegc = value;
4151 case JVMTI_VERBOSE_CLASS:
4152 loadverbose = value;
4154 case JVMTI_VERBOSE_JNI:
4157 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4159 return JVMTI_ERROR_NONE;
4162 /* GetObjectSize **************************************************************
4164 For the object object return the size.
4166 *******************************************************************************/
4169 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4172 CHECK_PHASE(JVMTI_PHASE_START)
4173 CHECK_PHASE(JVMTI_PHASE_LIVE)
4176 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4177 if (!builtin_instanceof(object,class_java_lang_Object))
4178 return JVMTI_ERROR_INVALID_OBJECT;
4180 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4182 return JVMTI_ERROR_NONE;
4186 /* *****************************************************************************
4188 Environment variables
4190 *******************************************************************************/
4192 static jvmtiCapabilities JVMTI_Capabilities = {
4193 0, /* can_tag_objects */
4194 0, /* can_generate_field_modification_events */
4195 0, /* can_generate_field_access_events */
4196 1, /* can_get_bytecodes */
4197 0, /* can_get_synthetic_attribute */
4199 #if defined(ENABLE_THREADS)
4200 1, /* can_get_owned_monitor_info */
4201 1, /* can_get_current_contended_monitor */
4203 0, /* can_get_owned_monitor_info */
4204 0, /* can_get_current_contended_monitor */
4207 0, /* can_get_monitor_info */
4208 0, /* can_pop_frame */
4209 0, /* can_redefine_classes */
4210 0, /* can_signal_thread */
4211 1, /* can_get_source_file_name */
4212 1, /* can_get_line_numbers */
4213 0, /* can_get_source_debug_extension */
4214 0, /* can_access_local_variables */
4215 0, /* can_maintain_original_method_order */
4216 0, /* can_generate_single_step_events */
4217 1, /* can_generate_exception_events */
4218 0, /* can_generate_frame_pop_events */
4219 1, /* can_generate_breakpoint_events */
4220 1, /* can_suspend */
4221 0, /* can_redefine_any_class */
4222 0, /* can_get_current_thread_cpu_time */
4223 0, /* can_get_thread_cpu_time */
4224 1, /* can_generate_method_entry_events */
4225 0, /* can_generate_method_exit_events */
4226 0, /* can_generate_all_class_hook_events */
4227 0, /* can_generate_compiled_method_load_events */
4228 1, /* can_generate_monitor_events */
4229 0, /* can_generate_vm_object_alloc_events */
4230 0, /* can_generate_native_method_bind_events */
4231 0, /* can_generate_garbage_collection_events */
4232 0, /* can_generate_object_free_events */
4235 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4237 &SetEventNotificationMode,
4245 &GetOwnedMonitorInfo,
4246 &GetCurrentContendedMonitor,
4248 &GetTopThreadGroups,
4249 &GetThreadGroupInfo,
4250 &GetThreadGroupChildren,
4272 &RawMonitorNotifyAll,
4276 &SetFieldAccessWatch,
4277 &ClearFieldAccessWatch,
4278 &SetFieldModificationWatch,
4279 &ClearFieldModificationWatch,
4289 &GetImplementedInterfaces,
4294 &GetObjectMonitorUsage,
4296 &GetFieldDeclaringClass,
4300 &GetMethodDeclaringClass,
4301 &GetMethodModifiers,
4305 &GetLineNumberTable,
4307 &GetLocalVariableTable,
4314 &GetClassLoaderClasses,
4325 &GetSourceDebugExtension,
4336 &GetThreadListStackTraces,
4337 &GetThreadLocalStorage,
4338 &SetThreadLocalStorage,
4343 &ForceGarbageCollection,
4344 &IterateOverObjectsReachableFromObject,
4345 &IterateOverReachableObjects,
4347 &IterateOverInstancesOfClass,
4349 &GetObjectsWithTags,
4355 &SetJNIFunctionTable,
4356 &GetJNIFunctionTable,
4359 &GetExtensionFunctions,
4360 &GetExtensionEvents,
4361 &SetExtensionEventCallback,
4362 &DisposeEnvironment,
4364 &GetJLocationFormat,
4365 &GetSystemProperties,
4369 &GetCurrentThreadCpuTimerInfo,
4370 &GetCurrentThreadCpuTime,
4371 &GetThreadCpuTimerInfo,
4375 &GetPotentialCapabilities,
4378 &RelinquishCapabilities,
4379 &GetAvailableProcessors,
4382 &GetEnvironmentLocalStorage,
4383 &SetEnvironmentLocalStorage,
4384 &AddToBootstrapClassLoaderSearch,
4392 /* jvmti_set_phase ************************************************************
4394 sets a new jvmti phase a fires an apropriate event.
4396 *******************************************************************************/
4398 void jvmti_set_phase(jvmtiPhase p) {
4401 fprintf (stderr,"set JVMTI phase %d\n",p);
4405 case JVMTI_PHASE_ONLOAD:
4408 case JVMTI_PHASE_PRIMORDIAL:
4411 case JVMTI_PHASE_START:
4413 d.ev = JVMTI_EVENT_VM_START;
4415 case JVMTI_PHASE_LIVE:
4417 d.ev = JVMTI_EVENT_VM_INIT;
4418 jvmti_fireEvent(&d);
4419 /* thread start event for main thread */
4420 d.ev = JVMTI_EVENT_THREAD_START;
4422 case JVMTI_PHASE_DEAD:
4424 d.ev = JVMTI_EVENT_VM_DEATH;
4427 log_text("wrong jvmti phase to be set");
4431 jvmti_fireEvent(&d);
4435 /* jvmti_new_environment ******************************************************
4437 creates a new JVMTI environment
4439 *******************************************************************************/
4441 jvmtiEnv* jvmti_new_environment() {
4445 envs = heap_allocate(sizeof(environment),true,NULL);
4449 while (env->next != NULL) env = env->next;
4450 env->next = heap_allocate(sizeof(environment),true,NULL);
4454 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4455 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4456 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4457 sizeof(jvmtiEventModeLL));
4458 /* To possess a capability, the agent must add the capability.*/
4459 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4460 RelinquishCapabilities(&(env->env),&(env->capabilities));
4461 env->EnvironmentLocalStorage = NULL;
4464 /* initialize cacao debugging facilities */
4465 jvmti_cacao_debug_init();
4467 return (jvmtiEnv*)env;
4470 /* jvmti_agentload ************************************************************
4472 loads the indicated shared library containing the jvmti agent and calls the
4473 Agent_OnLoad function.
4475 *******************************************************************************/
4477 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4483 len = strlen(opt_arg);
4485 /* separate arguments */
4487 while ((opt_arg[i] != '=') && (i < len))
4493 arg = &opt_arg[i + 1];
4500 *libname = GCMNEW(char, i);
4502 strcpy(*libname, opt_arg);
4507 len = strlen("lib") + i + strlen(".so") + strlen("0");
4509 *libname = GCMNEW(char, len);
4511 strcpy(*libname, "lib");
4512 strcat(*libname, opt_arg);
4513 strcat(*libname, ".so");
4516 /* try to open the library */
4518 if (!(*handle = lt_dlopen(*libname))) {
4519 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4523 /* resolve Agent_OnLoad function */
4524 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4525 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4529 /* resolve Agent_UnLoad function */
4530 unload = lt_dlsym(*handle, "Agent_Unload");
4533 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4534 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4536 if (retval != 0) exit (retval);
4539 /* jvmti_agentunload **********************************************************
4541 calls the Agent_UnLoad function in the jvmti agent if present.
4543 *******************************************************************************/
4545 void jvmti_agentunload() {
4546 if (unload != NULL) {
4547 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4548 ((JavaVM*) &_Jv_JNIInvokeInterface);
4554 * These are local overrides for various environment variables in Emacs.
4555 * Please do not remove this and leave it at the end of the file, where
4556 * Emacs will automagically detect them.
4557 * ---------------------------------------------------------------------
4560 * indent-tabs-mode: t
4564 * vim:noexpandtab:sw=4:ts=4: