1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006, 2007, 2008
5 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 #include <linux/unistd.h>
34 #include <sys/types.h>
39 #include "native/jni.hpp"
40 #include "native/native.hpp"
41 #include "native/jvmti/cacaodbg.h"
42 #include "native/jvmti/jvmti.h"
43 #include "vm/jit/stacktrace.hpp"
44 #include "vm/global.h"
45 #include "vm/loader.hpp"
46 #include "vm/jit/builtin.hpp"
47 #include "vm/jit/asmpart.h"
48 #include "vm/class.hpp"
49 #include "vm/classcache.hpp"
51 #include "toolbox/logging.h"
52 #include "vm/options.h"
53 #include "vm/string.hpp"
54 #include "mm/memory.h"
55 #include "threads/mutex.h"
56 #include "threads/thread.hpp"
57 #include "threads/lock.hpp"
58 #include "vm/exceptions.hpp"
59 #include "native/include/java_io_PrintStream.h"
60 #include "native/include/java_io_InputStream.h"
61 #include "native/include/java_lang_Cloneable.h"
62 #include "native/include/java_lang_ThreadGroup.h"
63 #include "native/include/java_lang_VMObject.h"
64 #include "native/include/java_lang_VMSystem.h"
65 #include "native/include/java_lang_VMClass.h"
66 #include "vm/suck.hpp"
67 #include "boehm-gc/include/gc.h"
69 #if defined(ENABLE_THREADS)
77 typedef struct _environment environment;
78 static environment *envs=NULL;
81 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
83 static jvmtiPhase phase;
84 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
85 struct _jvmtiEventModeLL {
88 jvmtiEventModeLL *next;
91 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
92 struct _jvmtiThreadLocalStorage{
95 jvmtiThreadLocalStorage *next;
101 jvmtiEventCallbacks callbacks;
102 /* table for enabled/disabled jvmtiEvents - first element contains global
104 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
105 jvmtiCapabilities capabilities;
106 void *EnvironmentLocalStorage;
107 jvmtiThreadLocalStorage *tls;
110 static struct jvmtiEnv_struct JVMTI_EnvTable;
111 static jvmtiCapabilities JVMTI_Capabilities;
112 static lt_ptr unload;
114 #define CHECK_PHASE_START if (!(false
115 #define CHECK_PHASE(chkphase) || (phase == chkphase)
116 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
117 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
118 env)->capabilities.CAP == 0) \
119 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
120 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
121 JVMTI_ERROR_THREAD_NOT_ALIVE) \
122 return JVMTI_ERROR_THREAD_NOT_ALIVE;
127 /* check_thread_is_alive *******************************************************
129 checks if the given thread is alive
131 *******************************************************************************/
132 static jvmtiError check_thread_is_alive(jthread t) {
133 if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
134 if(((java_lang_Thread*) t)->vmThread == NULL)
135 return JVMTI_ERROR_THREAD_NOT_ALIVE;
136 return JVMTI_ERROR_NONE;
139 /* execute_callback ************************************************************
141 executes the registerd callbacks for the given jvmti event with parameter
142 in the data structure.
144 *******************************************************************************/
145 static void execute_callback(jvmtiEvent e, functionptr ec,
146 genericEventData* data) {
147 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
149 fprintf(stderr,"execcallback called (event: %d)\n",e);
152 case JVMTI_EVENT_VM_INIT:
153 if (phase != JVMTI_PHASE_LIVE) return;
154 case JVMTI_EVENT_THREAD_START:
155 case JVMTI_EVENT_THREAD_END:
156 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
157 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
160 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
161 if ((phase == JVMTI_PHASE_START) ||
162 (phase == JVMTI_PHASE_LIVE) ||
163 (phase == JVMTI_PHASE_PRIMORDIAL))
164 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
169 data->protection_domain,
172 data->new_class_data_len,
173 data->new_class_data);
175 /* if class data has been modified use it as class data for other agents
176 waiting for the same event */
177 if (data->new_class_data != NULL) {
178 data->jint1 = *(data->new_class_data_len);
179 data->class_data = *(data->new_class_data);
184 case JVMTI_EVENT_CLASS_PREPARE:
185 case JVMTI_EVENT_CLASS_LOAD:
186 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
187 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
188 data->thread, data->klass);
191 case JVMTI_EVENT_VM_DEATH:
192 if (phase != JVMTI_PHASE_LIVE) return;
193 case JVMTI_EVENT_VM_START:
194 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
195 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
198 case JVMTI_EVENT_NATIVE_METHOD_BIND:
199 if ((phase == JVMTI_PHASE_START) ||
200 (phase == JVMTI_PHASE_LIVE) ||
201 (phase == JVMTI_PHASE_PRIMORDIAL))
202 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
206 data->new_address_ptr);
210 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
211 if ((phase == JVMTI_PHASE_START) ||
212 (phase == JVMTI_PHASE_LIVE) ||
213 (phase == JVMTI_PHASE_PRIMORDIAL))
214 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
223 if (phase != JVMTI_PHASE_LIVE) return;
225 case JVMTI_EVENT_EXCEPTION:
226 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
232 data->catch_location);
235 case JVMTI_EVENT_EXCEPTION_CATCH:
236 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
243 case JVMTI_EVENT_BREAKPOINT:
244 case JVMTI_EVENT_SINGLE_STEP:
245 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
251 case JVMTI_EVENT_FRAME_POP:
252 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
259 case JVMTI_EVENT_FIELD_ACCESS:
260 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
269 case JVMTI_EVENT_FIELD_MODIFICATION:
271 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
278 data->signature_type,
282 case JVMTI_EVENT_METHOD_ENTRY:
283 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
288 case JVMTI_EVENT_METHOD_EXIT:
289 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
296 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
297 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
306 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
307 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
312 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
313 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
314 case JVMTI_EVENT_DATA_DUMP_REQUEST:
315 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
318 case JVMTI_EVENT_MONITOR_WAIT:
319 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
325 case JVMTI_EVENT_MONITOR_WAITED:
326 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
333 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
334 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
335 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
340 case JVMTI_EVENT_OBJECT_FREE:
341 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
344 case JVMTI_EVENT_VM_OBJECT_ALLOC:
345 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
352 log_text ("unknown event");
359 /* dofireEvent ******************************************************************
361 sends event if it is enabled either globally or for some threads
363 *******************************************************************************/
364 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
366 jvmtiEventModeLL *evm;
370 while (env != NULL) {
371 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
372 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
373 /* test if the event is enable for some threads */
374 while (evm != NULL) {
375 if (evm->mode == JVMTI_ENABLE) {
377 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
379 data->jvmti_env=&env->env;
380 execute_callback(e, ec, data);
385 } else { /* event enabled globally */
386 data->jvmti_env=&env->env;
387 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
388 if (ec != NULL) execute_callback(e, ec, data);
396 /* fireEvent ******************************************************************
398 fire event callback with data arguments. This function mainly fills the
401 *******************************************************************************/
402 void jvmti_fireEvent(genericEventData* d) {
404 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
406 if (d->ev == JVMTI_EVENT_VM_START)
409 thread = jvmti_get_current_thread();
413 dofireEvent(d->ev,d);
417 /* SetEventNotificationMode ****************************************************
419 Control the generation of events
421 *******************************************************************************/
424 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
425 jvmtiEvent event_type, jthread event_thread, ...)
427 environment* cacao_env;
428 jvmtiEventModeLL *ll;
431 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
432 CHECK_PHASE(JVMTI_PHASE_LIVE)
435 if(event_thread != NULL) {
436 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
437 return JVMTI_ERROR_INVALID_THREAD;
438 CHECK_THREAD_IS_ALIVE(event_thread);
441 cacao_env = (environment*) env;
442 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
443 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
445 switch (event_type) { /* check capability and set system breakpoint */
446 case JVMTI_EVENT_EXCEPTION:
447 case JVMTI_EVENT_EXCEPTION_CATCH:
448 CHECK_CAPABILITY(env,can_generate_exception_events)
450 case JVMTI_EVENT_SINGLE_STEP:
451 CHECK_CAPABILITY(env,can_generate_single_step_events)
453 case JVMTI_EVENT_FRAME_POP:
454 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
456 case JVMTI_EVENT_BREAKPOINT:
457 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
459 case JVMTI_EVENT_FIELD_ACCESS:
460 CHECK_CAPABILITY(env,can_generate_field_access_events)
462 case JVMTI_EVENT_FIELD_MODIFICATION:
463 CHECK_CAPABILITY(env,can_generate_field_modification_events)
465 case JVMTI_EVENT_METHOD_ENTRY:
466 CHECK_CAPABILITY(env,can_generate_method_entry_events)
468 case JVMTI_EVENT_METHOD_EXIT:
469 CHECK_CAPABILITY(env, can_generate_method_exit_events)
471 case JVMTI_EVENT_NATIVE_METHOD_BIND:
472 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
474 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
475 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
476 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
478 case JVMTI_EVENT_MONITOR_WAIT:
479 case JVMTI_EVENT_MONITOR_WAITED:
480 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
481 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
482 CHECK_CAPABILITY(env,can_generate_monitor_events)
484 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
485 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
486 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
488 case JVMTI_EVENT_OBJECT_FREE:
489 CHECK_CAPABILITY(env,can_generate_object_free_events)
491 case JVMTI_EVENT_VM_OBJECT_ALLOC:
492 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
495 /* all other events are required */
496 if ((event_type < JVMTI_EVENT_START_ENUM) ||
497 (event_type > JVMTI_EVENT_END_ENUM))
498 return JVMTI_ERROR_INVALID_EVENT_TYPE;
503 if (event_thread != NULL) {
504 /* thread level control */
505 if ((JVMTI_EVENT_VM_INIT == mode) ||
506 (JVMTI_EVENT_VM_DEATH == mode) ||
507 (JVMTI_EVENT_VM_START == mode) ||
508 (JVMTI_EVENT_THREAD_START == mode) ||
509 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
510 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
511 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
512 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
513 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
514 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
515 while (ll->next != NULL) {
517 if (ll->event_thread == event_thread) {
519 return JVMTI_ERROR_NONE;
522 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
526 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
530 return JVMTI_ERROR_NONE;
533 /* GetAllThreads ***************************************************************
537 *******************************************************************************/
540 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
541 jthread ** threads_ptr)
543 threadobject** threads;
548 CHECK_PHASE(JVMTI_PHASE_LIVE)
551 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
552 return JVMTI_ERROR_NULL_POINTER;
554 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
555 if (retval != JVMTI_ERROR_NONE) return retval;
558 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
560 for (i=0; i<*threads_count_ptr; i++)
561 (*threads_ptr)[i] = threads[i]->o.thread;
563 return JVMTI_ERROR_NONE;
567 /* SuspendThread ***************************************************************
569 Suspend specified thread
571 *******************************************************************************/
574 SuspendThread (jvmtiEnv * env, jthread thread)
577 CHECK_PHASE(JVMTI_PHASE_LIVE)
579 CHECK_CAPABILITY(env,can_suspend);
581 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
582 if (!builtin_instanceof(thread,class_java_lang_Thread))
583 return JVMTI_ERROR_INVALID_THREAD;
584 CHECK_THREAD_IS_ALIVE(thread);
586 /* threads_suspend_thread will implement suspend
587 threads_suspend_thread (
588 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
590 return JVMTI_ERROR_NONE;
593 /* ResumeThread ***************************************************************
595 Resume a suspended thread
597 *******************************************************************************/
600 ResumeThread (jvmtiEnv * env, jthread thread)
603 CHECK_PHASE(JVMTI_PHASE_LIVE)
605 CHECK_CAPABILITY(env,can_suspend);
607 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
608 if (!builtin_instanceof(thread,class_java_lang_Thread))
609 return JVMTI_ERROR_INVALID_THREAD;
610 CHECK_THREAD_IS_ALIVE(thread);
612 /* threads_resume_thread will implement resume
613 threads_resume_thread (
614 (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
616 return JVMTI_ERROR_NONE;
619 /* StopThread *****************************************************************
621 Send asynchronous exception to the specified thread. Similar to
622 java.lang.Thread.stop(). Used to kill thread.
624 *******************************************************************************/
627 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
630 CHECK_PHASE(JVMTI_PHASE_LIVE)
632 CHECK_CAPABILITY(env,can_signal_thread);
634 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
635 return JVMTI_ERROR_NOT_AVAILABLE;
637 return JVMTI_ERROR_NONE;
640 /* InterruptThread ************************************************************
642 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
644 *******************************************************************************/
647 InterruptThread (jvmtiEnv * env, jthread thread)
650 CHECK_PHASE(JVMTI_PHASE_LIVE)
652 CHECK_CAPABILITY(env,can_signal_thread)
654 #if defined(ENABLE_THREADS)
655 if(!builtin_instanceof(thread,class_java_lang_Thread))
656 return JVMTI_ERROR_INVALID_THREAD;
658 CHECK_THREAD_IS_ALIVE(thread);
660 threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
663 return JVMTI_ERROR_NONE;
665 return JVMTI_ERROR_NOT_AVAILABLE;
669 /* GetThreadInfo ***************************************************************
671 Get thread information. Details of the specified thread are stored in the
672 jvmtiThreadInfo structure.
674 *******************************************************************************/
677 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
680 java_lang_Thread* th = (java_lang_Thread*)t;
684 CHECK_PHASE(JVMTI_PHASE_LIVE)
687 info_ptr->priority=(jint)th->priority;
688 info_ptr->is_daemon=(jboolean)th->daemon;
689 info_ptr->thread_group=(jthreadGroup)th->group;
690 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
692 name = javastring_toutf(th->name,false);
693 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
694 utf_sprint_convert_to_latin1(info_ptr->name, name);
696 return JVMTI_ERROR_NONE;
699 /* GetOwnedMonitorInfo *********************************************************
701 Gets all monitors owned by the specified thread
703 *******************************************************************************/
706 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
707 jint * owned_monitor_count_ptr,
708 jobject ** owned_monitors_ptr)
711 java_objectheader **om;
712 lock_record_pool_t* lrp;
716 CHECK_PHASE(JVMTI_PHASE_LIVE)
718 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
720 if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
721 return JVMTI_ERROR_NULL_POINTER;
723 if (thread == NULL) {
724 t = jvmti_get_current_thread();
726 if(!builtin_instanceof(thread,class_java_lang_Thread))
727 return JVMTI_ERROR_INVALID_THREAD;
729 CHECK_THREAD_IS_ALIVE(thread);
730 t = (threadobject*) thread;
733 #if defined(ENABLE_THREADS)
735 om=MNEW(java_objectheader*,size);
737 mutex_lock(&lock_global_pool_lock);
738 lrp=lock_global_pool;
740 /* iterate over all lock record pools */
741 while (lrp != NULL) {
742 /* iterate over every lock record in a pool */
743 for (j=0; j<lrp->header.size; j++) {
744 /* if the lock record is owned by the given thread add it to
746 if(lrp->lr[j].owner == t) {
748 MREALLOC(om, java_objectheader*, size, size * 2);
751 om[i] = lrp->lr[j].obj;
755 lrp=lrp->header.next;
758 mutex_unlock(&lock_global_pool_lock);
760 *owned_monitors_ptr =
761 heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
762 memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
763 MFREE(om, java_objectheader*, size);
765 *owned_monitor_count_ptr = i;
769 return JVMTI_ERROR_NONE;
772 /* GetCurrentContendedMonitor *************************************************
774 Get the object the specified thread waits for.
776 *******************************************************************************/
779 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
780 jobject * monitor_ptr)
783 lock_record_pool_t* lrp;
785 lock_waiter_t* waiter;
788 CHECK_PHASE(JVMTI_PHASE_LIVE)
790 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
792 if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
795 if (thread == NULL) {
796 t = jvmti_get_current_thread();
798 if(!builtin_instanceof(thread,class_java_lang_Thread))
799 return JVMTI_ERROR_INVALID_THREAD;
801 CHECK_THREAD_IS_ALIVE(thread);
802 t = (threadobject*) thread;
805 #if defined(ENABLE_THREADS)
807 mutex_lock(&lock_global_pool_lock);
809 lrp=lock_global_pool;
811 /* iterate over all lock record pools */
812 while ((lrp != NULL) && (*monitor_ptr == NULL)) {
813 /* iterate over every lock record in a pool */
814 for (j=0; j<lrp->header.size; j++) {
815 /* iterate over every thread that is wait on this lock record */
816 waiter = lrp->lr[j].waiters;
817 while (waiter != NULL)
818 /* if the waiting thread equals to the given thread we are
819 done. Stop iterateting. */
820 if(waiter->waiter == t) {
821 *monitor_ptr=lrp->lr[j].obj;
825 lrp=lrp->header.next;
828 mutex_unlock(&lock_global_pool_lock);
832 return JVMTI_ERROR_NONE;
836 jvmtiStartFunction sf;
842 static void *threadstartup(void *t) {
843 runagentparam *rap = (runagentparam*)t;
844 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
848 /* RunAgentThread *************************************************************
850 Starts the execution of an agent thread of the specified native function
851 within the specified thread
853 *******************************************************************************/
856 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
857 const void *arg, jint priority)
859 pthread_attr_t threadattr;
860 struct sched_param sp;
864 CHECK_PHASE(JVMTI_PHASE_LIVE)
867 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
868 return JVMTI_ERROR_INVALID_THREAD;
869 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
870 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
871 (priority > JVMTI_THREAD_MAX_PRIORITY))
872 return JVMTI_ERROR_INVALID_PRIORITY;
874 /* XXX: Threads started with this function should not be visible to
875 Java programming language queries but are included in JVM TI queries */
878 rap.arg = (void*)arg;
881 #if defined(ENABLE_THREADS)
882 pthread_attr_init(&threadattr);
883 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
884 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
885 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
887 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
888 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
890 pthread_attr_setschedparam(&threadattr,&sp);
891 if (pthread_create(&((threadobject*)
892 thread)->tid, &threadattr, &threadstartup, &rap)) {
893 log_text("pthread_create failed");
898 return JVMTI_ERROR_NONE;
902 /* GetTopThreadGroups *********************************************************
904 Get all top-level thread groups in the VM.
906 *******************************************************************************/
909 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
910 jthreadGroup ** groups_ptr)
912 jint threads_count_ptr;
913 threadobject *threads_ptr;
915 jthreadGroup **tg,*ttgp;
918 CHECK_PHASE(JVMTI_PHASE_LIVE)
921 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
922 return JVMTI_ERROR_NULL_POINTER;
924 #if defined(ENABLE_THREADS)
925 tg = MNEW(jthreadGroup*,size);
927 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
928 return JVMTI_ERROR_INTERNAL;
930 for (i=0;i<threads_count_ptr;i++){
931 if (threads_ptr[i].o.thread->group == NULL) {
932 log_text("threadgroup not set");
933 return JVMTI_ERROR_INTERNAL;
935 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
938 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
943 MREALLOC(tg,jthreadGroup*,size,size*2);
952 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
953 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
954 MFREE(tg,jthreadGroup*,size);
956 *group_count_ptr = x;
959 return JVMTI_ERROR_NOT_AVAILABLE;
961 return JVMTI_ERROR_NONE;
965 /* GetThreadGroupInfo *********************************************************
967 Get information about the specified thread group.
969 *******************************************************************************/
972 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
973 jvmtiThreadGroupInfo * info_ptr)
977 java_lang_ThreadGroup* grp;
980 CHECK_PHASE(JVMTI_PHASE_LIVE)
983 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
984 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
985 return JVMTI_ERROR_INVALID_THREAD_GROUP;
987 grp = (java_lang_ThreadGroup*)group;
989 info_ptr->parent = (jthreadGroup)
990 Java_java_lang_VMObject_clone(NULL,
991 (jclass)grp->header.vftbl->class,
992 (java_lang_Cloneable*) &grp->parent);
994 name = javastring_tochar((java_objectheader*)grp->name);
996 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
997 strncpy(info_ptr->name,name,size);
998 info_ptr->max_priority= (jint)grp->maxpri;
999 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1001 return JVMTI_ERROR_NONE;
1005 /* GetThreadGroupChildren *****************************************************
1007 Get the live threads and active subgroups in this thread group.
1009 *******************************************************************************/
1012 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1013 jint * thread_count_ptr, jthread ** threads_ptr,
1014 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1016 java_lang_ThreadGroup* tgp;
1019 CHECK_PHASE(JVMTI_PHASE_LIVE)
1022 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1023 (group_count_ptr == NULL) || (groups_ptr == NULL))
1024 return JVMTI_ERROR_NULL_POINTER;
1026 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1027 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1029 tgp = (java_lang_ThreadGroup*)group;
1031 *thread_count_ptr = (jint)tgp->threads->elementCount;
1034 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1036 memcpy(*threads_ptr, &tgp->threads->elementData,
1037 (*thread_count_ptr)*sizeof(java_objectarray*));
1039 *group_count_ptr = (jint) tgp->groups->elementCount;
1042 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1044 memcpy(*groups_ptr, &tgp->threads->elementData,
1045 (*group_count_ptr)*sizeof(jthreadGroup*));
1047 return JVMTI_ERROR_NONE;
1051 /* getcacaostacktrace *********************************************************
1053 Helper function that retrives stack trace for specified thread.
1055 *******************************************************************************/
1057 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1061 if (thread == NULL) {
1062 t = jvmti_get_current_thread();
1063 *trace = stacktrace_create(t);
1065 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1066 /* if (t != jvmti_get_current_thread())
1067 resume = threads_suspend_thread_if_running(thread);
1069 *trace = stacktrace_create(thread );
1072 threads_resume_thread ( thread );*/
1075 return JVMTI_ERROR_NONE;
1079 /* GetFrameCount **************************************************************
1082 Get the number of frames in the specified thread's stack. Calling function
1083 has to take care of suspending/resuming thread.
1085 *******************************************************************************/
1088 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1090 stacktracebuffer* trace;
1094 CHECK_PHASE(JVMTI_PHASE_LIVE)
1097 if (thread != NULL){
1098 if(!builtin_instanceof(thread,class_java_lang_Thread))
1099 return JVMTI_ERROR_INVALID_THREAD;
1101 CHECK_THREAD_IS_ALIVE(thread);
1104 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1106 er = getcacaostacktrace(&trace, thread);
1107 if (er == JVMTI_ERROR_NONE) {
1112 *count_ptr = trace->used;
1115 return JVMTI_ERROR_NONE;
1119 /* GetThreadState **************************************************************
1121 Get the state of a thread.
1123 *******************************************************************************/
1126 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1128 java_lang_Thread* th = (java_lang_Thread*)thread;
1129 threadobject* t = (threadobject*)th->vmThread;
1132 CHECK_PHASE(JVMTI_PHASE_LIVE)
1135 if(!builtin_instanceof(thread,class_java_lang_Thread))
1136 return JVMTI_ERROR_INVALID_THREAD;
1138 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1140 *thread_state_ptr = 0;
1141 #if defined(ENABLE_THREADS)
1142 if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
1144 if (((threadobject*)th->vmThread)->tid == 0)
1145 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1148 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1149 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1150 /* XXX todo - info not available */
1151 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1152 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1153 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1154 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1155 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1156 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1157 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1158 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1159 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1160 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1163 return JVMTI_ERROR_INTERNAL;
1166 return JVMTI_ERROR_NONE;
1170 /* GetFrameLocation ************************************************************
1172 Get the location of the instruction currently executing
1174 *******************************************************************************/
1177 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1178 jmethodID * method_ptr, jlocation * location_ptr)
1180 stackframeinfo_t *sfi;
1185 CHECK_PHASE(JVMTI_PHASE_LIVE)
1188 if (thread == NULL) {
1189 th = jvmti_get_current_thread();
1191 if(!builtin_instanceof(thread,class_java_lang_Thread))
1192 return JVMTI_ERROR_INVALID_THREAD;
1194 CHECK_THREAD_IS_ALIVE(thread);
1195 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1198 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1200 if ((method_ptr == NULL)&&(location_ptr == NULL))
1201 return JVMTI_ERROR_NULL_POINTER;
1203 sfi = th->_stackframeinfo;
1206 while ((sfi != NULL) && (i<depth)) {
1211 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1213 *method_ptr=(jmethodID)sfi->code->m;
1214 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1216 return JVMTI_ERROR_NONE;
1220 /* NotifyFramePop *************************************************************
1224 *******************************************************************************/
1227 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1230 CHECK_PHASE(JVMTI_PHASE_LIVE)
1232 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1234 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1235 return JVMTI_ERROR_NONE;
1238 /* GetLocalObject *************************************************************
1242 *******************************************************************************/
1245 GetLocalObject (jvmtiEnv * env,
1246 jthread thread, jint depth, jint slot, jobject * value_ptr)
1249 CHECK_PHASE(JVMTI_PHASE_LIVE)
1251 CHECK_CAPABILITY(env,can_access_local_variables)
1253 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1254 return JVMTI_ERROR_NONE;
1257 /* GetLocalInt ****************************************************************
1261 *******************************************************************************/
1264 GetLocalInt (jvmtiEnv * env,
1265 jthread thread, jint depth, jint slot, jint * value_ptr)
1268 CHECK_PHASE(JVMTI_PHASE_LIVE)
1270 CHECK_CAPABILITY(env,can_access_local_variables)
1271 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1272 return JVMTI_ERROR_NONE;
1275 /* *****************************************************************************
1279 *******************************************************************************/
1282 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1286 CHECK_PHASE(JVMTI_PHASE_LIVE)
1288 CHECK_CAPABILITY(env,can_access_local_variables)
1290 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1291 return JVMTI_ERROR_NONE;
1295 /* *****************************************************************************
1299 *******************************************************************************/
1302 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1306 CHECK_PHASE(JVMTI_PHASE_LIVE)
1308 CHECK_CAPABILITY(env,can_access_local_variables)
1310 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1311 return JVMTI_ERROR_NONE;
1315 /* *****************************************************************************
1319 *******************************************************************************/
1322 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1323 jdouble * value_ptr)
1326 CHECK_PHASE(JVMTI_PHASE_LIVE)
1328 CHECK_CAPABILITY(env,can_access_local_variables)
1330 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1331 return JVMTI_ERROR_NONE;
1335 /* *****************************************************************************
1339 *******************************************************************************/
1342 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1346 CHECK_PHASE(JVMTI_PHASE_LIVE)
1348 CHECK_CAPABILITY(env,can_access_local_variables)
1350 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1351 return JVMTI_ERROR_NONE;
1355 /* *****************************************************************************
1359 *******************************************************************************/
1362 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1366 CHECK_PHASE(JVMTI_PHASE_LIVE)
1368 CHECK_CAPABILITY(env,can_access_local_variables)
1370 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1371 return JVMTI_ERROR_NONE;
1375 /* *****************************************************************************
1379 *******************************************************************************/
1382 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1386 CHECK_PHASE(JVMTI_PHASE_LIVE)
1388 CHECK_CAPABILITY(env,can_access_local_variables)
1390 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1391 return JVMTI_ERROR_NONE;
1395 /* *****************************************************************************
1399 *******************************************************************************/
1402 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1406 CHECK_PHASE(JVMTI_PHASE_LIVE)
1408 CHECK_CAPABILITY(env,can_access_local_variables)
1410 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1411 return JVMTI_ERROR_NONE;
1415 /* *****************************************************************************
1419 *******************************************************************************/
1422 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1426 CHECK_PHASE(JVMTI_PHASE_LIVE)
1428 CHECK_CAPABILITY(env,can_access_local_variables)
1430 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1431 return JVMTI_ERROR_NONE;
1435 /* CreateRawMonitor ***********************************************************
1437 This function creates a new raw monitor.
1439 *******************************************************************************/
1442 CreateRawMonitor (jvmtiEnv * env, const char *name,
1443 jrawMonitorID * monitor_ptr)
1445 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1448 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1449 CHECK_PHASE(JVMTI_PHASE_LIVE)
1452 if ((name == NULL) || (monitor_ptr == NULL))
1453 return JVMTI_ERROR_NULL_POINTER;
1455 #if defined(ENABLE_THREADS)
1456 monitor->name=javastring_new_from_ascii(name);
1458 log_text ("CreateRawMonitor not supported");
1461 return JVMTI_ERROR_NONE;
1465 /* DestroyRawMonitor **********************************************************
1467 This function destroys a raw monitor.
1469 *******************************************************************************/
1472 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1475 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1476 CHECK_PHASE(JVMTI_PHASE_LIVE)
1479 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1480 return JVMTI_ERROR_INVALID_MONITOR;
1482 #if defined(ENABLE_THREADS)
1483 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1484 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1486 lock_monitor_exit((java_objectheader *) monitor->name);
1490 log_text ("DestroyRawMonitor not supported");
1493 return JVMTI_ERROR_NONE;
1497 /* RawMonitorEnter ************************************************************
1499 Gain exclusive ownership of a raw monitor
1501 *******************************************************************************/
1504 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1506 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1507 return JVMTI_ERROR_INVALID_MONITOR;
1509 #if defined(ENABLE_THREADS)
1510 lock_monitor_enter((java_objectheader *) monitor->name);
1512 log_text ("RawMonitorEnter not supported");
1515 return JVMTI_ERROR_NONE;
1519 /* RawMonitorExit *************************************************************
1523 *******************************************************************************/
1526 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1528 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1529 return JVMTI_ERROR_INVALID_MONITOR;
1531 #if defined(ENABLE_THREADS)
1532 /* assure current thread owns this monitor */
1533 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1534 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1536 lock_monitor_exit((java_objectheader *) monitor->name);
1538 log_text ("RawMonitorExit not supported");
1541 return JVMTI_ERROR_NONE;
1545 /* RawMonitorWait *************************************************************
1547 Wait for notification of the raw monitor.
1549 *******************************************************************************/
1552 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1554 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1555 return JVMTI_ERROR_INVALID_MONITOR;
1557 #if defined(ENABLE_THREADS)
1558 /* assure current thread owns this monitor */
1559 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1560 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1562 lock_wait_for_object(&monitor->name->header, millis,0);
1563 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1564 return JVMTI_ERROR_INTERRUPT;
1567 log_text ("RawMonitorWait not supported");
1570 return JVMTI_ERROR_NONE;
1574 /* RawMonitorNotify ***********************************************************
1576 Notify one thread waiting on the given monitor.
1578 *******************************************************************************/
1581 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1583 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1584 return JVMTI_ERROR_INVALID_MONITOR;
1586 #if defined(ENABLE_THREADS)
1587 /* assure current thread owns this monitor */
1588 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1589 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1591 lock_notify_object((java_objectheader*)&monitor->name);
1593 log_text ("RawMonitorNotify not supported");
1596 return JVMTI_ERROR_NONE;
1600 /* RawMonitorNotifyAll *********************************************************
1602 Notify all threads waiting on the given monitor.
1604 *******************************************************************************/
1607 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1609 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1610 return JVMTI_ERROR_INVALID_MONITOR;
1612 #if defined(ENABLE_THREADS)
1613 /* assure current thread owns this monitor */
1614 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1615 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1617 lock_notify_all_object((java_objectheader*)&monitor->name);
1619 log_text ("RawMonitorNotifyAll not supported");
1622 return JVMTI_ERROR_NONE;
1626 /* SetBreakpoint **************************************************************
1630 *******************************************************************************/
1633 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1636 CHECK_PHASE(JVMTI_PHASE_LIVE)
1638 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1641 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1642 return JVMTI_ERROR_NONE;
1646 /* *****************************************************************************
1650 *******************************************************************************/
1653 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1656 CHECK_PHASE(JVMTI_PHASE_LIVE)
1658 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1660 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1661 return JVMTI_ERROR_NONE;
1665 /* SetFieldAccessWatch ********************************************************
1669 *******************************************************************************/
1672 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1675 CHECK_PHASE(JVMTI_PHASE_LIVE)
1677 CHECK_CAPABILITY(env,can_generate_field_access_events)
1679 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1680 return JVMTI_ERROR_NONE;
1684 /* *****************************************************************************
1688 *******************************************************************************/
1691 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1694 CHECK_PHASE(JVMTI_PHASE_LIVE)
1696 CHECK_CAPABILITY(env,can_generate_field_access_events)
1698 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1699 return JVMTI_ERROR_NONE;
1703 /* *****************************************************************************
1707 *******************************************************************************/
1710 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1713 CHECK_PHASE(JVMTI_PHASE_LIVE)
1715 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1717 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1718 return JVMTI_ERROR_NONE;
1722 /* *****************************************************************************
1726 *******************************************************************************/
1729 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1732 CHECK_PHASE(JVMTI_PHASE_LIVE)
1734 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1736 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1737 return JVMTI_ERROR_NONE;
1741 /* Allocate ********************************************************************
1743 Allocate an area of memory through the JVM TI allocator. The allocated
1744 memory should be freed with Deallocate
1746 *******************************************************************************/
1749 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1752 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1753 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1755 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1756 if (*mem_ptr == NULL)
1757 return JVMTI_ERROR_OUT_OF_MEMORY;
1759 return JVMTI_ERROR_NONE;
1764 /* Deallocate ******************************************************************
1766 Deallocate mem using the JVM TI allocator.
1768 *******************************************************************************/
1771 Deallocate (jvmtiEnv * env, unsigned char *mem)
1773 /* let Boehm GC do the job */
1775 return JVMTI_ERROR_NONE;
1779 /* GetClassSignature ************************************************************
1781 For the class indicated by klass, return the JNI type signature and the
1782 generic signature of the class.
1784 *******************************************************************************/
1787 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1791 CHECK_PHASE(JVMTI_PHASE_START)
1792 CHECK_PHASE(JVMTI_PHASE_LIVE)
1795 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1796 if (!builtin_instanceof(klass,class_java_lang_Class))
1797 return JVMTI_ERROR_INVALID_CLASS;
1799 if (signature_ptr != NULL) {
1800 *signature_ptr = (char*)
1801 heap_allocate(sizeof(char) *
1802 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1804 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1807 if (generic_ptr!= NULL)
1808 *generic_ptr = NULL;
1810 return JVMTI_ERROR_NONE;
1813 /* GetClassStatus *************************************************************
1815 Get status of the class.
1817 *******************************************************************************/
1820 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1824 CHECK_PHASE(JVMTI_PHASE_START)
1825 CHECK_PHASE(JVMTI_PHASE_LIVE)
1828 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1829 return JVMTI_ERROR_INVALID_CLASS;
1831 if (status_ptr == NULL)
1832 return JVMTI_ERROR_NULL_POINTER;
1834 c = (classinfo*)klass;
1837 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1838 if (c->state & CLASS_LINKED)
1839 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1841 if (c->state & CLASS_INITIALIZED)
1842 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1844 if (c->state & CLASS_ERROR)
1845 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1847 if (c->vftbl->arraydesc != NULL)
1848 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1850 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1851 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1853 return JVMTI_ERROR_NONE;
1857 /* GetSourceFileName **********************************************************
1859 For the class indicated by klass, return the source file name.
1861 *******************************************************************************/
1864 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1869 CHECK_PHASE(JVMTI_PHASE_START)
1870 CHECK_PHASE(JVMTI_PHASE_LIVE)
1872 CHECK_CAPABILITY(env,can_get_source_file_name)
1874 if ((klass == NULL)||(source_name_ptr == NULL))
1875 return JVMTI_ERROR_NULL_POINTER;
1877 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1879 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1881 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1882 (*source_name_ptr)[size]='\0';
1884 return JVMTI_ERROR_NONE;
1888 /* GetClassModifiers **********************************************************
1890 For class klass return the access flags
1892 *******************************************************************************/
1895 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1898 CHECK_PHASE(JVMTI_PHASE_START)
1899 CHECK_PHASE(JVMTI_PHASE_LIVE)
1902 if (modifiers_ptr == NULL)
1903 return JVMTI_ERROR_NULL_POINTER;
1905 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1906 return JVMTI_ERROR_INVALID_CLASS;
1908 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1910 return JVMTI_ERROR_NONE;
1914 /* GetClassMethods *************************************************************
1916 For class klass return a count of methods and a list of method IDs
1918 *******************************************************************************/
1921 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1922 jmethodID ** methods_ptr)
1927 CHECK_PHASE(JVMTI_PHASE_START)
1928 CHECK_PHASE(JVMTI_PHASE_LIVE)
1931 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1932 return JVMTI_ERROR_NULL_POINTER;
1934 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1935 return JVMTI_ERROR_INVALID_CLASS;
1937 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1938 *methods_ptr = (jmethodID*)
1939 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1941 for (i=0; i<*method_count_ptr;i++)
1942 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1944 return JVMTI_ERROR_NONE;
1948 /* GetClassFields *************************************************************
1950 For the class indicated by klass, return a count of fields and a list of
1953 *******************************************************************************/
1956 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1957 jfieldID ** fields_ptr)
1960 CHECK_PHASE(JVMTI_PHASE_START)
1961 CHECK_PHASE(JVMTI_PHASE_LIVE)
1964 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1965 return JVMTI_ERROR_NULL_POINTER;
1967 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1968 *fields_ptr = (jfieldID*)
1969 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1971 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1972 sizeof(jfieldID) * (*field_count_ptr));
1974 return JVMTI_ERROR_NONE;
1978 /* GetImplementedInterfaces ***************************************************
1980 Return the direct super-interfaces of this class.
1982 *******************************************************************************/
1985 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1986 jint * interface_count_ptr,
1987 jclass ** interfaces_ptr)
1990 classref_or_classinfo *interfaces;
1994 CHECK_PHASE(JVMTI_PHASE_START)
1995 CHECK_PHASE(JVMTI_PHASE_LIVE)
1998 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1999 return JVMTI_ERROR_NULL_POINTER;
2001 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2002 return JVMTI_ERROR_INVALID_CLASS;
2005 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2007 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2009 interfaces = ((classinfo*)klass)->interfaces;
2010 for (i=0; i<*interface_count_ptr; i++) {
2011 if (IS_CLASSREF(interfaces[i]))
2012 tmp = load_class_bootstrap(interfaces[i].ref->name);
2014 tmp = interfaces[i].cls;
2016 *interfaces_ptr[i]=tmp;
2019 return JVMTI_ERROR_NONE;
2023 /* IsInterface ****************************************************************
2025 Determines whether a class object reference represents an interface.
2027 *******************************************************************************/
2030 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2033 CHECK_PHASE(JVMTI_PHASE_START)
2034 CHECK_PHASE(JVMTI_PHASE_LIVE)
2037 if ((klass == NULL)||(is_interface_ptr == NULL))
2038 return JVMTI_ERROR_NULL_POINTER;
2040 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2042 return JVMTI_ERROR_NONE;
2045 /* IsArrayClass ***************************************************************
2047 Determines whether a class object reference represents an array.
2049 *******************************************************************************/
2052 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2055 CHECK_PHASE(JVMTI_PHASE_START)
2056 CHECK_PHASE(JVMTI_PHASE_LIVE)
2059 if (is_array_class_ptr == NULL)
2060 return JVMTI_ERROR_NULL_POINTER;
2062 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2064 return JVMTI_ERROR_NONE;
2068 /* GetClassLoader *************************************************************
2070 For the class indicated by klass, return via classloader_ptr a reference to
2071 the class loader for the class.
2073 *******************************************************************************/
2076 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2079 CHECK_PHASE(JVMTI_PHASE_START)
2080 CHECK_PHASE(JVMTI_PHASE_LIVE)
2083 if ((klass == NULL)||(classloader_ptr == NULL))
2084 return JVMTI_ERROR_NULL_POINTER;
2086 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2088 return JVMTI_ERROR_NONE;
2092 /* GetObjectHashCode **********************************************************
2094 Return hash code for object object
2096 *******************************************************************************/
2099 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2102 CHECK_PHASE(JVMTI_PHASE_START)
2103 CHECK_PHASE(JVMTI_PHASE_LIVE)
2106 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2107 if (!builtin_instanceof(object,class_java_lang_Object))
2108 return JVMTI_ERROR_INVALID_OBJECT;
2110 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2112 return JVMTI_ERROR_NONE;
2116 /* *****************************************************************************
2120 *******************************************************************************/
2123 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2124 jvmtiMonitorUsage * info_ptr)
2127 CHECK_PHASE(JVMTI_PHASE_LIVE)
2129 CHECK_CAPABILITY(env,can_get_monitor_info)
2131 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2132 return JVMTI_ERROR_NONE;
2136 /* GetFieldName ***************************************************************
2138 For the field indicated by klass and field, return the field name and
2141 *******************************************************************************/
2144 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2145 char **name_ptr, char **signature_ptr, char **generic_ptr)
2150 CHECK_PHASE(JVMTI_PHASE_START)
2151 CHECK_PHASE(JVMTI_PHASE_LIVE)
2155 return JVMTI_ERROR_INVALID_CLASS;
2157 if (!builtin_instanceof(klass,class_java_lang_Class))
2158 return JVMTI_ERROR_INVALID_CLASS;
2159 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2161 if (name_ptr != NULL) {
2162 size = utf_bytes(((fieldinfo*)field)->name)+1;
2163 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2164 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2167 if (signature_ptr != NULL) {
2168 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2169 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2170 utf_sprint_convert_to_latin1(*signature_ptr,
2171 ((fieldinfo*)field)->descriptor);
2174 if (generic_ptr != NULL)
2175 *generic_ptr = NULL;
2177 return JVMTI_ERROR_NONE;
2181 /* GetFieldDeclaringClass *****************************************************
2183 For the field indicated by klass and field return the class that defined it
2184 The declaring class will either be klass, a superclass, or an implemented
2187 *******************************************************************************/
2190 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2191 jclass * declaring_class_ptr)
2194 CHECK_PHASE(JVMTI_PHASE_START)
2195 CHECK_PHASE(JVMTI_PHASE_LIVE)
2199 return JVMTI_ERROR_INVALID_CLASS;
2201 if (!builtin_instanceof(klass,class_java_lang_Class))
2202 return JVMTI_ERROR_INVALID_CLASS;
2204 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2206 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2208 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2210 return JVMTI_ERROR_NONE;
2214 /* GetFieldModifiers **********************************************************
2216 Return access flags of field field
2218 *******************************************************************************/
2221 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2222 jint * modifiers_ptr)
2225 CHECK_PHASE(JVMTI_PHASE_START)
2226 CHECK_PHASE(JVMTI_PHASE_LIVE)
2230 return JVMTI_ERROR_INVALID_CLASS;
2232 if (!builtin_instanceof(klass,class_java_lang_Class))
2233 return JVMTI_ERROR_INVALID_CLASS;
2235 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2237 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2239 *modifiers_ptr = ((fieldinfo*)field)->flags;
2241 return JVMTI_ERROR_NONE;
2245 /* IsFieldSynthetic ***********************************************************
2249 *******************************************************************************/
2252 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2253 jboolean * is_synthetic_ptr)
2256 CHECK_PHASE(JVMTI_PHASE_START)
2257 CHECK_PHASE(JVMTI_PHASE_LIVE)
2259 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2261 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2262 return JVMTI_ERROR_NONE;
2266 /* GetMethodName ***************************************************************
2268 For the method indicated by method, return the method name via name_ptr and
2269 method signature via signature_ptr.
2271 *******************************************************************************/
2274 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2275 char **signature_ptr, char **generic_ptr)
2277 methodinfo* m = (methodinfo*)method;
2280 CHECK_PHASE(JVMTI_PHASE_START)
2281 CHECK_PHASE(JVMTI_PHASE_LIVE)
2285 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2287 if (name_ptr != NULL) {
2289 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2290 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2293 if (signature_ptr != NULL) {
2294 *signature_ptr = (char*)
2295 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2296 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2299 if (generic_ptr != NULL) {
2300 /* there is no generic signature attribute */
2301 *generic_ptr = NULL;
2304 return JVMTI_ERROR_NONE;
2308 /* GetMethodDeclaringClass *****************************************************
2310 For the method indicated by method, return the class that defined it.
2312 *******************************************************************************/
2315 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2316 jclass * declaring_class_ptr)
2319 CHECK_PHASE(JVMTI_PHASE_START)
2320 CHECK_PHASE(JVMTI_PHASE_LIVE)
2323 if ((method == NULL) || (declaring_class_ptr == NULL))
2324 return JVMTI_ERROR_NULL_POINTER;
2326 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2328 return JVMTI_ERROR_NONE;
2332 /* GetMethodModifiers **********************************************************
2334 For the method indicated by method, return the access flags.
2336 *******************************************************************************/
2339 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2342 CHECK_PHASE(JVMTI_PHASE_START)
2343 CHECK_PHASE(JVMTI_PHASE_LIVE)
2346 if ((method == NULL) || (modifiers_ptr == NULL))
2347 return JVMTI_ERROR_NULL_POINTER;
2349 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2351 return JVMTI_ERROR_NONE;
2355 /* GetMaxLocals ****************************************************************
2357 For the method indicated by method, return the number of local variable slots
2358 used by the method, including the local variables used to pass parameters to
2359 the method on its invocation.
2361 *******************************************************************************/
2364 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2367 CHECK_PHASE(JVMTI_PHASE_START)
2368 CHECK_PHASE(JVMTI_PHASE_LIVE)
2371 if ((method == NULL)||(max_ptr == NULL))
2372 return JVMTI_ERROR_NULL_POINTER;
2374 if (((methodinfo*)method)->flags & ACC_NATIVE)
2375 return JVMTI_ERROR_NATIVE_METHOD;
2377 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2379 return JVMTI_ERROR_NONE;
2384 /* GetArgumentsSize ************************************************************
2386 Return the number of local variable slots used by the method's arguments.
2388 *******************************************************************************/
2391 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2394 CHECK_PHASE(JVMTI_PHASE_START)
2395 CHECK_PHASE(JVMTI_PHASE_LIVE)
2398 if ((method == NULL)||(size_ptr == NULL))
2399 return JVMTI_ERROR_NULL_POINTER;
2401 if (((methodinfo*)method)->flags & ACC_NATIVE)
2402 return JVMTI_ERROR_NATIVE_METHOD;
2404 *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
2405 return JVMTI_ERROR_NONE;
2410 /* GetLineNumberTable **********************************************************
2412 Return table of source line number entries for a given method
2414 *******************************************************************************/
2417 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2418 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2423 CHECK_PHASE(JVMTI_PHASE_START)
2424 CHECK_PHASE(JVMTI_PHASE_LIVE)
2426 CHECK_CAPABILITY(env,can_get_line_numbers)
2428 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2429 return JVMTI_ERROR_NULL_POINTER;
2431 if (((methodinfo*)method)->flags & ACC_NATIVE)
2432 return JVMTI_ERROR_NATIVE_METHOD;
2434 if (((methodinfo*)method)->linenumbers == NULL)
2435 return JVMTI_ERROR_ABSENT_INFORMATION;
2437 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2438 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2439 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2442 for (i=0; i < *entry_count_ptr; i++) {
2443 (*table_ptr)[i].start_location =
2444 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2445 (*table_ptr)[i].line_number =
2446 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2449 return JVMTI_ERROR_NONE;
2453 /* GetMethodLocation ***********************************************************
2455 For the method indicated by method, return the beginning and ending addresses
2456 through start_location_ptr and end_location_ptr. In cacao this points to
2457 entry point in machine code and length of machine code
2459 *******************************************************************************/
2462 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2463 jlocation * start_location_ptr,
2464 jlocation * end_location_ptr)
2466 methodinfo* m = (methodinfo*)method;
2469 CHECK_PHASE(JVMTI_PHASE_START)
2470 CHECK_PHASE(JVMTI_PHASE_LIVE)
2473 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2475 if (((methodinfo*)method)->flags & ACC_NATIVE)
2476 return JVMTI_ERROR_NATIVE_METHOD;
2478 if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
2479 return JVMTI_ERROR_NULL_POINTER;
2481 /* XXX we return the location of the most recent code. Don't know
2482 * if there is a way to teach jvmti that a method can have more
2483 * than one location. -Edwin */
2485 /* XXX Don't know if that's the right way to deal with not-yet-
2486 * compiled methods. -Edwin */
2488 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2491 /* -1 states location information is not available */
2492 *start_location_ptr = (jlocation)-1;
2493 *end_location_ptr = (jlocation)-1;
2496 *start_location_ptr = (jlocation)m->code->mcode;
2497 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
2498 return JVMTI_ERROR_NONE;
2502 /* GetLocalVariableTable *******************************************************
2504 Return local variable information.
2506 *******************************************************************************/
2509 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2510 jint * entry_count_ptr,
2511 jvmtiLocalVariableEntry ** table_ptr)
2514 CHECK_PHASE(JVMTI_PHASE_LIVE)
2516 CHECK_CAPABILITY(env,can_access_local_variables)
2518 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2520 return JVMTI_ERROR_NONE;
2524 /* GetBytecode *****************************************************************
2526 For the method indicated by method, return the byte codes that implement the
2529 *******************************************************************************/
2532 GetBytecodes (jvmtiEnv * env, jmethodID method,
2533 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2535 methodinfo* m = (methodinfo*)method;;
2538 CHECK_PHASE(JVMTI_PHASE_START)
2539 CHECK_PHASE(JVMTI_PHASE_LIVE)
2541 CHECK_CAPABILITY(env,can_get_bytecodes)
2543 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2544 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2546 *bytecode_count_ptr = m->jcodelength;
2547 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2548 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2550 return JVMTI_ERROR_NONE;
2554 /* IsMethodNative **************************************************************
2556 For the method indicated by method, return a value indicating whether the
2557 method is a native function
2559 *******************************************************************************/
2562 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2565 CHECK_PHASE(JVMTI_PHASE_START)
2566 CHECK_PHASE(JVMTI_PHASE_LIVE)
2569 if ((method == NULL)||(is_native_ptr == NULL))
2570 return JVMTI_ERROR_NULL_POINTER;
2572 if (((methodinfo*)method)->flags & ACC_NATIVE)
2573 *is_native_ptr = JNI_TRUE;
2575 *is_native_ptr = JNI_FALSE;
2577 return JVMTI_ERROR_NONE;
2581 /* IsMethodSynthetic ***********************************************************
2583 return a value indicating whether the method is synthetic. Synthetic methods
2584 are generated by the compiler but not present in the original source code.
2586 *******************************************************************************/
2589 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2590 jboolean * is_synthetic_ptr)
2593 CHECK_PHASE(JVMTI_PHASE_START)
2594 CHECK_PHASE(JVMTI_PHASE_LIVE)
2596 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2598 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2599 return JVMTI_ERROR_NONE;
2603 /* GetLoadedClasses ************************************************************
2605 Return an array of all classes loaded in the virtual machine.
2607 *******************************************************************************/
2610 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2613 CHECK_PHASE(JVMTI_PHASE_LIVE)
2616 if (class_count_ptr == NULL)
2617 return JVMTI_ERROR_NULL_POINTER;
2619 if (classes_ptr == NULL)
2620 return JVMTI_ERROR_NULL_POINTER;
2622 classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
2624 return JVMTI_ERROR_NONE;
2628 /* GetClassLoaderClasses *******************************************************
2630 Returns an array of those classes for which this class loader has been
2631 recorded as an initiating loader.
2633 *******************************************************************************/
2636 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2637 jint * class_count_ptr, jclass ** classes_ptr)
2639 log_text("GetClassLoaderClasses called");
2642 CHECK_PHASE(JVMTI_PHASE_LIVE)
2645 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2646 return JVMTI_ERROR_NULL_POINTER;
2648 /* behave like jdk 1.1 and make no distinction between initiating and
2649 defining class loaders */
2651 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2655 /* PopFrame *******************************************************************
2659 *******************************************************************************/
2662 PopFrame (jvmtiEnv * env, jthread thread)
2665 CHECK_PHASE(JVMTI_PHASE_LIVE)
2667 CHECK_CAPABILITY(env,can_pop_frame)
2669 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2670 return JVMTI_ERROR_NONE;
2674 /* RedefineClasses ************************************************************
2678 *******************************************************************************/
2681 RedefineClasses (jvmtiEnv * env, jint class_count,
2682 const jvmtiClassDefinition * class_definitions)
2685 CHECK_PHASE(JVMTI_PHASE_START)
2686 CHECK_PHASE(JVMTI_PHASE_LIVE)
2688 CHECK_CAPABILITY(env,can_redefine_classes)
2689 CHECK_CAPABILITY(env,can_redefine_any_class)
2691 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2692 return JVMTI_ERROR_NONE;
2696 /* GetVersionNumber ***********************************************************
2698 Return the JVM TI version identifier.
2700 *******************************************************************************/
2703 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2705 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2707 *version_ptr = JVMTI_VERSION;
2709 return JVMTI_ERROR_NONE;
2713 /* GetCapabilities ************************************************************
2715 Returns the optional JVM TI features which this environment currently
2718 *******************************************************************************/
2721 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2723 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2725 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2727 return JVMTI_ERROR_NONE;
2731 /* *****************************************************************************
2735 *******************************************************************************/
2738 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2739 char **source_debug_extension_ptr)
2742 CHECK_PHASE(JVMTI_PHASE_START)
2743 CHECK_PHASE(JVMTI_PHASE_LIVE)
2745 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2747 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2748 return JVMTI_ERROR_NONE;
2752 /* IsMethodObsolete ************************************************************
2754 Determine if a method ID refers to an obsolete method version.
2756 *******************************************************************************/
2759 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2760 jboolean * is_obsolete_ptr)
2763 CHECK_PHASE(JVMTI_PHASE_START)
2764 CHECK_PHASE(JVMTI_PHASE_LIVE)
2766 CHECK_CAPABILITY(env,can_redefine_classes)
2768 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2769 return JVMTI_ERROR_NONE;
2773 /* SuspendThreadList **********************************************************
2775 Suspend all threads in the request list.
2777 *******************************************************************************/
2780 SuspendThreadList (jvmtiEnv * env, jint request_count,
2781 const jthread * request_list, jvmtiError * results)
2788 CHECK_PHASE(JVMTI_PHASE_START)
2789 CHECK_PHASE(JVMTI_PHASE_LIVE)
2791 CHECK_CAPABILITY(env,can_suspend);
2793 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2794 if ((request_list == NULL) || (results == NULL))
2795 return JVMTI_ERROR_NULL_POINTER;
2797 me = jvmti_get_current_thread();
2799 for (i=0;i<request_count;i++) {
2800 if (request_list[i] == me)
2803 results[i]=SuspendThread(env, request_list[i]);
2806 if (suspendme != -1)
2807 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2809 return JVMTI_ERROR_NONE;
2813 /* ResumeThreadList ***********************************************************
2815 Resumes all threads in the request list.
2817 *******************************************************************************/
2820 ResumeThreadList (jvmtiEnv * env, jint request_count,
2821 const jthread * request_list, jvmtiError * results)
2826 CHECK_PHASE(JVMTI_PHASE_LIVE)
2828 CHECK_CAPABILITY(env,can_suspend);
2830 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2831 if ((request_list == NULL) || (results == NULL))
2832 return JVMTI_ERROR_NULL_POINTER;
2834 for (i=0;i<request_count;i++)
2835 results[i]=ResumeThread(env, request_list[i]);
2837 return JVMTI_ERROR_NONE;
2841 /* GetStackTrace **************************************************************
2843 Get information about the stack of a thread
2845 *******************************************************************************/
2848 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2849 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2852 stacktracebuffer* trace;
2857 CHECK_PHASE(JVMTI_PHASE_LIVE)
2860 if (thread != NULL){
2861 if(!builtin_instanceof(thread,class_java_lang_Thread))
2862 return JVMTI_ERROR_INVALID_THREAD;
2864 CHECK_THREAD_IS_ALIVE(thread);
2867 if((count_ptr == NULL)||(frame_buffer == NULL))
2868 return JVMTI_ERROR_NULL_POINTER;
2870 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2872 er = getcacaostacktrace(&trace, thread);
2873 if (er == JVMTI_ERROR_NONE) {
2878 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2879 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2881 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2882 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2883 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2884 frame_buffer[j].location = 0;
2889 return JVMTI_ERROR_NONE;
2893 /* GetThreadListStackTraces ***************************************************
2895 Get information about the stacks of the supplied threads.
2897 *******************************************************************************/
2900 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2901 const jthread * thread_list,
2902 jint max_frame_count,
2903 jvmtiStackInfo ** stack_info_ptr)
2909 CHECK_PHASE(JVMTI_PHASE_LIVE)
2912 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2913 return JVMTI_ERROR_NULL_POINTER;
2915 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2917 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2919 *stack_info_ptr = (jvmtiStackInfo*)
2920 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2922 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2923 (*stack_info_ptr)[i].thread=thread_list[i];
2924 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2925 (*stack_info_ptr)[i].frame_buffer =
2926 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2927 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2928 (*stack_info_ptr)[i].frame_buffer,
2929 &((*stack_info_ptr)[i].frame_count));
2931 if (er != JVMTI_ERROR_NONE) return er;
2934 return JVMTI_ERROR_NONE;
2938 /* GetAllStackTraces **********************************************************
2940 Get stack traces of all live threads
2942 *******************************************************************************/
2945 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2946 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2948 jthread *threads_ptr;
2952 CHECK_PHASE(JVMTI_PHASE_LIVE)
2955 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2957 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2958 return JVMTI_ERROR_INTERNAL;
2960 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2961 max_frame_count, stack_info_ptr);
2963 if (er != JVMTI_ERROR_NONE) return er;
2965 return JVMTI_ERROR_NONE;
2969 /* GetThreadLocalStorage ******************************************************
2971 Get the value of the JVM TI thread-local storage.
2973 *******************************************************************************/
2976 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2978 jvmtiThreadLocalStorage *tls;
2981 CHECK_PHASE(JVMTI_PHASE_START)
2982 CHECK_PHASE(JVMTI_PHASE_LIVE)
2986 thread = (jthread) THREADOBJECT;
2988 if (!builtin_instanceof(thread,class_java_lang_Thread))
2989 return JVMTI_ERROR_INVALID_THREAD;
2990 CHECK_THREAD_IS_ALIVE(thread);
2993 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2995 tls = ((environment*)env)->tls;
2996 while ((tls->thread != thread) && (tls != NULL)) {
3000 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3002 *data_ptr = tls->data;
3004 return JVMTI_ERROR_NONE;
3008 /* SetThreadLocalStorage *******************************************************
3010 Stores a pointer value associated with each environment-thread pair. The
3011 value is NULL unless set with this function. Agents can allocate memory in
3012 which they store thread specific information
3014 *******************************************************************************/
3017 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3019 jvmtiThreadLocalStorage *tls, *pre;
3020 environment* env = (environment*)jenv;
3023 CHECK_PHASE(JVMTI_PHASE_START)
3024 CHECK_PHASE(JVMTI_PHASE_LIVE)
3028 thread = (jthread) THREADOBJECT;
3030 if (!builtin_instanceof(thread,class_java_lang_Thread))
3031 return JVMTI_ERROR_INVALID_THREAD;
3032 CHECK_THREAD_IS_ALIVE(thread);
3035 if (env->tls == NULL) {
3036 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3039 while ((tls->thread != thread) && (tls->next != NULL)) {
3042 if (tls->thread != thread) {
3043 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3049 tls->data = (void*)data;
3051 /* remove current tls */
3053 while (pre->next == tls) pre = pre->next;
3054 pre->next = tls->next;
3056 return JVMTI_ERROR_NONE;
3060 /* *****************************************************************************
3064 *******************************************************************************/
3067 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3070 CHECK_PHASE(JVMTI_PHASE_START)
3071 CHECK_PHASE(JVMTI_PHASE_LIVE)
3073 CHECK_CAPABILITY(env,can_tag_objects)
3075 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3076 return JVMTI_ERROR_NONE;
3079 /* *****************************************************************************
3083 *******************************************************************************/
3086 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3089 CHECK_PHASE(JVMTI_PHASE_START)
3090 CHECK_PHASE(JVMTI_PHASE_LIVE)
3092 CHECK_CAPABILITY(env,can_tag_objects)
3094 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3095 return JVMTI_ERROR_NONE;
3099 /* ForceGarbageCollection *****************************************************
3101 Force boehm-gc to perform a garbage collection
3103 *******************************************************************************/
3106 ForceGarbageCollection (jvmtiEnv * env)
3109 CHECK_PHASE(JVMTI_PHASE_LIVE)
3114 return JVMTI_ERROR_NONE;
3118 /* IterateOverObjectsReachableFromObject **************************************
3122 *******************************************************************************/
3125 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3126 jvmtiObjectReferenceCallback
3127 object_reference_callback,
3131 CHECK_PHASE(JVMTI_PHASE_LIVE)
3133 CHECK_CAPABILITY(env,can_tag_objects)
3135 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3136 return JVMTI_ERROR_NONE;
3140 /* IterateOverReachableObjects ************************************************
3144 *******************************************************************************/
3147 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3149 jvmtiStackReferenceCallback
3151 jvmtiObjectReferenceCallback
3152 object_ref_callback, void *user_data)
3155 CHECK_PHASE(JVMTI_PHASE_LIVE)
3157 CHECK_CAPABILITY(env,can_tag_objects)
3159 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3160 return JVMTI_ERROR_NONE;
3164 /* IterateOverHeap ************************************************************
3168 *******************************************************************************/
3171 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3172 jvmtiHeapObjectCallback heap_object_callback,
3176 CHECK_PHASE(JVMTI_PHASE_LIVE)
3178 CHECK_CAPABILITY(env,can_tag_objects)
3180 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3181 return JVMTI_ERROR_NONE;
3185 /* IterateOverInstancesOfClass ************************************************
3189 *******************************************************************************/
3192 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3193 jvmtiHeapObjectFilter object_filter,
3194 jvmtiHeapObjectCallback
3195 heap_object_callback, void *user_data)
3198 CHECK_PHASE(JVMTI_PHASE_LIVE)
3200 CHECK_CAPABILITY(env,can_tag_objects)
3202 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3203 return JVMTI_ERROR_NONE;
3207 /* *****************************************************************************
3211 *******************************************************************************/
3214 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3215 jint * count_ptr, jobject ** object_result_ptr,
3216 jlong ** tag_result_ptr)
3219 CHECK_PHASE(JVMTI_PHASE_LIVE)
3221 CHECK_CAPABILITY(env,can_tag_objects)
3223 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3224 return JVMTI_ERROR_NONE;
3228 /* SetJNIFunctionTable **********************************************************
3230 Set the JNI function table in all current and future JNI environments
3232 *******************************************************************************/
3235 SetJNIFunctionTable (jvmtiEnv * env,
3236 const jniNativeInterface * function_table)
3239 CHECK_PHASE(JVMTI_PHASE_START)
3240 CHECK_PHASE(JVMTI_PHASE_LIVE)
3243 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3244 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3245 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3246 return JVMTI_ERROR_NONE;
3250 /* GetJNIFunctionTable *********************************************************
3252 Get the JNI function table. The JNI function table is copied into allocated
3255 *******************************************************************************/
3258 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3261 CHECK_PHASE(JVMTI_PHASE_START)
3262 CHECK_PHASE(JVMTI_PHASE_LIVE)
3265 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3266 *function_table = (jniNativeInterface*)
3267 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3268 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3269 return JVMTI_ERROR_NONE;
3273 /* SetEventCallbacks **********************************************************
3275 Set the functions to be called for each event. The callbacks are specified
3276 by supplying a replacement function table.
3278 *******************************************************************************/
3281 SetEventCallbacks (jvmtiEnv * env,
3282 const jvmtiEventCallbacks * callbacks,
3283 jint size_of_callbacks)
3286 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3287 CHECK_PHASE(JVMTI_PHASE_LIVE)
3290 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3293 if (callbacks == NULL) { /* remove the existing callbacks */
3294 memset(&(((environment* )env)->callbacks), 0,
3295 sizeof(jvmtiEventCallbacks));
3298 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3300 return JVMTI_ERROR_NONE;
3304 /* GenerateEvents *************************************************************
3306 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3307 the current state of the VM.
3309 *******************************************************************************/
3312 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3315 CHECK_PHASE(JVMTI_PHASE_LIVE)
3317 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3319 return JVMTI_ERROR_NONE;
3323 /* GetExtensionFunctions ******************************************************
3325 Returns the set of extension functions.
3327 *******************************************************************************/
3330 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3331 jvmtiExtensionFunctionInfo ** extensions)
3334 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3335 CHECK_PHASE(JVMTI_PHASE_LIVE)
3338 if ((extension_count_ptr == NULL)||(extensions == NULL))
3339 return JVMTI_ERROR_NULL_POINTER;
3341 /* cacao has no extended functions yet */
3342 *extension_count_ptr = 0;
3344 return JVMTI_ERROR_NONE;
3348 /* GetExtensionEvents *********************************************************
3350 Returns the set of extension events.
3352 *******************************************************************************/
3355 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3356 jvmtiExtensionEventInfo ** extensions)
3359 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3360 CHECK_PHASE(JVMTI_PHASE_LIVE)
3363 if ((extension_count_ptr == NULL)||(extensions == NULL))
3364 return JVMTI_ERROR_NULL_POINTER;
3366 /* cacao has no extended events yet */
3367 *extension_count_ptr = 0;
3369 return JVMTI_ERROR_NONE;
3373 /* SetExtensionEventCallback **************************************************
3375 Sets the callback function for an extension event and enables the event.
3377 *******************************************************************************/
3380 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3381 jvmtiExtensionEvent callback)
3384 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3385 CHECK_PHASE(JVMTI_PHASE_LIVE)
3388 /* cacao has no extended events yet */
3389 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3393 /* DisposeEnvironment **********************************************************
3395 Shutdown a JVM TI connection created with JNI GetEnv.
3397 *******************************************************************************/
3400 DisposeEnvironment (jvmtiEnv * env)
3402 environment* cacao_env = (environment*)env;
3403 environment* tenvs = envs;
3404 jvmtiThreadLocalStorage *jtls, *tjtls;
3406 if (tenvs != cacao_env) {
3407 while (tenvs->next != cacao_env) {
3408 tenvs = tenvs->next;
3410 tenvs->next = cacao_env->next;
3414 cacao_env->env=NULL;
3415 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3416 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3417 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3418 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3419 cacao_env->EnvironmentLocalStorage = NULL;
3421 jtls = cacao_env->tls;
3422 while (jtls != NULL) {
3427 cacao_env->tls = NULL;
3430 jvmti_cacaodbgserver_quit();
3432 /* let the GC do the rest */
3433 return JVMTI_ERROR_NONE;
3437 /* GetErrorName ***************************************************************
3439 Return the symbolic name for an error code.
3441 *******************************************************************************/
3443 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3444 memcpy(*name_ptr, &str, sizeof(str)); \
3448 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3450 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3453 case JVMTI_ERROR_NONE :
3454 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3455 case JVMTI_ERROR_NULL_POINTER :
3456 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3457 case JVMTI_ERROR_OUT_OF_MEMORY :
3458 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3459 case JVMTI_ERROR_ACCESS_DENIED :
3460 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3461 case JVMTI_ERROR_UNATTACHED_THREAD :
3462 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3463 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3464 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3465 case JVMTI_ERROR_WRONG_PHASE :
3466 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3467 case JVMTI_ERROR_INTERNAL :
3468 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3469 case JVMTI_ERROR_INVALID_PRIORITY :
3470 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3471 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3472 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3473 case JVMTI_ERROR_THREAD_SUSPENDED :
3474 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3475 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3476 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3477 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3478 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3479 case JVMTI_ERROR_NO_MORE_FRAMES :
3480 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3481 case JVMTI_ERROR_OPAQUE_FRAME :
3482 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3483 case JVMTI_ERROR_DUPLICATE :
3484 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3485 case JVMTI_ERROR_NOT_FOUND :
3486 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3487 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3488 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3489 case JVMTI_ERROR_INTERRUPT :
3490 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3491 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3492 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3493 case JVMTI_ERROR_NOT_AVAILABLE :
3494 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3495 case JVMTI_ERROR_ABSENT_INFORMATION :
3496 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3497 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3498 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3499 case JVMTI_ERROR_NATIVE_METHOD :
3500 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3501 case JVMTI_ERROR_INVALID_THREAD :
3502 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3503 case JVMTI_ERROR_INVALID_FIELDID :
3504 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3505 case JVMTI_ERROR_INVALID_METHODID :
3506 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3507 case JVMTI_ERROR_INVALID_LOCATION :
3508 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3509 case JVMTI_ERROR_INVALID_OBJECT :
3510 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3511 case JVMTI_ERROR_INVALID_CLASS :
3512 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3513 case JVMTI_ERROR_TYPE_MISMATCH :
3514 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3515 case JVMTI_ERROR_INVALID_SLOT :
3516 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3517 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3518 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3519 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3520 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3521 case JVMTI_ERROR_INVALID_MONITOR :
3522 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3523 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3524 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3525 case JVMTI_ERROR_INVALID_TYPESTATE :
3526 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3527 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3528 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3529 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3530 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3531 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3532 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3533 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3534 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3535 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3536 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3537 case JVMTI_ERROR_FAILS_VERIFICATION :
3538 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3539 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3540 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3541 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3542 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3543 case JVMTI_ERROR_NAMES_DONT_MATCH :
3544 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3545 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3546 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3547 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3548 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3550 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3552 return JVMTI_ERROR_NONE;
3555 /* GetJLocationFormat **********************************************************
3557 This function describes the representation of jlocation used in this VM.
3559 *******************************************************************************/
3562 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3564 *format_ptr = JVMTI_JLOCATION_OTHER;
3565 return JVMTI_ERROR_NONE;
3569 /* GetSystemProperties ********************************************************
3571 The list of VM system property keys which may be used with GetSystemProperty
3574 *******************************************************************************/
3577 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3579 jmethodID mid, moremid;
3580 classinfo *sysclass, *propclass, *enumclass;
3581 java_objectheader *sysprop, *keys, *obj;
3586 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3587 CHECK_PHASE(JVMTI_PHASE_LIVE)
3590 if ((count_ptr == NULL) || (property_ptr == NULL))
3591 return JVMTI_ERROR_NULL_POINTER;
3593 sysclass = load_class_from_sysloader(
3594 utf_new_char_classname ("java/lang/System"));
3596 if (!sysclass) throw_main_exception_exit();
3598 mid = (jmethodID)class_resolvemethod(sysclass,
3599 utf_new_char("getProperties"),
3600 utf_new_char("()Ljava/util/Properties;"));
3601 if (!mid) throw_main_exception_exit();
3604 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3605 if (!sysprop) throw_main_exception_exit();
3607 propclass = sysprop->vftbl->class;
3609 mid = (jmethodID)class_resolvemethod(propclass,
3610 utf_new_char("size"),
3611 utf_new_char("()I"));
3612 if (!mid) throw_main_exception_exit();
3615 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3616 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3618 mid = (jmethodID)class_resolvemethod(propclass,
3619 utf_new_char("keys"),
3620 utf_new_char("()Ljava/util/Enumeration;"));
3621 if (!mid) throw_main_exception_exit();
3623 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3624 enumclass = keys->vftbl->class;
3626 moremid = (jmethodID)class_resolvemethod(enumclass,
3627 utf_new_char("hasMoreElements"),
3628 utf_new_char("()Z"));
3629 if (!moremid) throw_main_exception_exit();
3631 mid = (jmethodID)class_resolvemethod(propclass,
3632 utf_new_char("nextElement"),
3633 utf_new_char("()Ljava/lang/Object;"));
3634 if (!mid) throw_main_exception_exit();
3637 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3638 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3639 ch = javastring_tochar(obj);
3640 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3641 memcpy(*property_ptr[i], ch, strlen (ch));
3642 MFREE(ch,char,strlen(ch)+1);
3646 return JVMTI_ERROR_NONE;
3650 /* GetSystemProperty **********************************************************
3652 Return a VM system property value given the property key.
3654 *******************************************************************************/
3657 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3660 classinfo *sysclass, *propclass;
3661 java_objectheader *sysprop, *obj;
3665 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3666 CHECK_PHASE(JVMTI_PHASE_LIVE)
3669 if ((value_ptr == NULL) || (property == NULL))
3670 return JVMTI_ERROR_NULL_POINTER;
3672 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3673 if (!sysclass) throw_main_exception_exit();
3675 mid = (jmethodID)class_resolvemethod(sysclass,
3676 utf_new_char("getProperties"),
3677 utf_new_char("()Ljava/util/Properties;"));
3678 if (!mid) throw_main_exception_exit();
3680 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3682 propclass = sysprop->vftbl->class;
3684 mid = (jmethodID)class_resolvemethod(propclass,
3685 utf_new_char("getProperty"),
3686 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3687 if (!mid) throw_main_exception_exit();
3689 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3690 NULL, sysprop, mid, javastring_new_from_ascii(property));
3691 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3693 ch = javastring_tochar(obj);
3694 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3695 memcpy(*value_ptr, ch, strlen (ch));
3696 MFREE(ch,char,strlen(ch)+1);
3698 return JVMTI_ERROR_NONE;
3702 /* SetSystemProperty **********************************************************
3704 Set a VM system property value.
3706 *******************************************************************************/
3709 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3712 classinfo *sysclass, *propclass;
3713 java_objectheader *sysprop;
3716 CHECK_PHASE(JVMTI_PHASE_START)
3719 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3720 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3722 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3723 if (!sysclass) throw_main_exception_exit();
3725 mid = (jmethodID)class_resolvemethod(sysclass,
3726 utf_new_char("getProperties"),
3727 utf_new_char("()Ljava/util/Properties;"));
3728 if (!mid) throw_main_exception_exit();
3730 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3732 propclass = sysprop->vftbl->class;
3734 mid = (jmethodID)class_resolvemethod(propclass,
3735 utf_new_char("setProperty"),
3736 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3737 if (!mid) throw_main_exception_exit();
3739 _Jv_JNINativeInterface.CallObjectMethod(
3740 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3742 return JVMTI_ERROR_NONE;
3745 /* GetPhase ********************************************************************
3747 Return the current phase of VM execution
3749 *******************************************************************************/
3752 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3754 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3758 return JVMTI_ERROR_NONE;
3761 /* GetCurrentThreadCpuTimerInfo ************************************************
3765 *******************************************************************************/
3768 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3771 CHECK_PHASE(JVMTI_PHASE_START)
3772 CHECK_PHASE(JVMTI_PHASE_LIVE)
3774 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3776 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3778 return JVMTI_ERROR_NONE;
3781 /* GetCurrentThreadCpuTime ****************************************************
3785 *******************************************************************************/
3788 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3791 CHECK_PHASE(JVMTI_PHASE_START)
3792 CHECK_PHASE(JVMTI_PHASE_LIVE)
3794 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3796 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3797 return JVMTI_ERROR_NONE;
3800 /* GetThreadCpuTimerInfo ******************************************************
3804 *******************************************************************************/
3807 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3810 CHECK_PHASE(JVMTI_PHASE_START)
3811 CHECK_PHASE(JVMTI_PHASE_LIVE)
3813 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3815 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3816 return JVMTI_ERROR_NONE;
3819 /* GetThreadCpuTime ***********************************************************
3823 *******************************************************************************/
3826 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3829 CHECK_PHASE(JVMTI_PHASE_LIVE)
3831 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3832 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3833 return JVMTI_ERROR_NONE;
3836 /* GetTimerInfo ***************************************************************
3838 Get information about the GetTime timer.
3840 *******************************************************************************/
3843 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3845 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3847 info_ptr->max_value = !0x0;
3848 info_ptr->may_skip_forward = true;
3849 info_ptr->may_skip_backward = true;
3850 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3852 return JVMTI_ERROR_NONE;
3855 /* GetTime ********************************************************************
3857 Return the current value of the system timer, in nanoseconds
3859 *******************************************************************************/
3862 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3864 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3867 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3869 if (gettimeofday (&tp, NULL) == -1)
3870 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3872 *nanos_ptr = (jlong) tp.tv_sec;
3874 *nanos_ptr += (tp.tv_usec / 1000);
3876 return JVMTI_ERROR_NONE;
3879 /* GetPotentialCapabilities ***************************************************
3881 Returns the JVM TI features that can potentially be possessed by this
3882 environment at this time.
3884 *******************************************************************************/
3887 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3890 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3891 CHECK_PHASE(JVMTI_PHASE_LIVE)
3894 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3896 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3898 return JVMTI_ERROR_NONE;
3902 #define CHECK_ADD_CAPABILITY(env,CAN) \
3903 if (capabilities_ptr->CAN == 1) { \
3904 if (JVMTI_Capabilities.CAN == 0) \
3905 return JVMTI_ERROR_NOT_AVAILABLE; \
3907 env->capabilities.CAN = 1; \
3910 /* AddCapabilities ************************************************************
3912 Set new capabilities by adding the capabilities pointed to by
3913 capabilities_ptr. All previous capabilities are retained.
3915 *******************************************************************************/
3918 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3920 environment* cacao_env;
3923 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3924 CHECK_PHASE(JVMTI_PHASE_LIVE)
3927 if ((env == NULL) || (capabilities_ptr == NULL))
3928 return JVMTI_ERROR_NULL_POINTER;
3930 cacao_env = (environment*)env;
3932 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3933 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3934 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3935 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3936 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3937 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3938 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3939 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3940 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3941 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3942 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3943 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3944 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3945 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3946 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3947 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3948 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3949 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3950 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3951 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3952 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3953 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3967 return JVMTI_ERROR_NONE;
3971 #define CHECK_DEL_CAPABILITY(env,CAN) \
3972 if (capabilities_ptr->CAN == 1) \
3973 env->capabilities.CAN = 0;
3975 /* RelinquishCapabilities *****************************************************
3977 Relinquish the capabilities pointed to by capabilities_ptr.
3979 *******************************************************************************/
3982 RelinquishCapabilities (jvmtiEnv * env,
3983 const jvmtiCapabilities * capabilities_ptr)
3985 environment* cacao_env;
3988 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3989 CHECK_PHASE(JVMTI_PHASE_LIVE)
3992 if ((env == NULL) || (capabilities_ptr == NULL))
3993 return JVMTI_ERROR_NULL_POINTER;
3995 cacao_env = (environment*)env;
3997 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3998 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3999 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4000 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4001 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4002 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4003 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4004 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4005 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4006 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4007 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4008 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4009 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4010 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4011 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4012 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4013 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4014 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4015 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4016 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4017 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4018 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4031 return JVMTI_ERROR_NONE;
4034 /* GetAvailableProcessors *****************************************************
4036 Get number of processors available to the virtual machine.
4038 *******************************************************************************/
4041 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4044 CHECK_PHASE(JVMTI_PHASE_START)
4045 CHECK_PHASE(JVMTI_PHASE_LIVE)
4048 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4050 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4052 *processor_count_ptr = 1; /* where do I get this ?*/
4054 return JVMTI_ERROR_NONE;
4057 /* GetEnvironmentLocalStorage **************************************************
4059 Called by the agent to get the value of the JVM TI environment-local storage.
4061 *******************************************************************************/
4064 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4066 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4068 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4070 return JVMTI_ERROR_NONE;
4073 /* SetEnvironmentLocalStorage **************************************************
4075 The VM stores a pointer value associated with each environment. Agents can
4076 allocate memory in which they store environment specific information.
4078 *******************************************************************************/
4081 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4083 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4085 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4087 return JVMTI_ERROR_NONE;
4090 /* AddToBootstrapClassLoaderSearch ********************************************
4092 After the bootstrap class loader unsuccessfully searches for a class, the
4093 specified platform-dependent search path segment will be searched as well.
4095 *******************************************************************************/
4098 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4104 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4107 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4109 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4110 tmp_bcp = MNEW(char, ln);
4111 strcat(tmp_bcp, bootclasspath);
4112 strcat(tmp_bcp, ":");
4113 strcat(tmp_bcp, segment);
4114 MFREE(bootclasspath,char,ln);
4115 bootclasspath = tmp_bcp;
4117 return JVMTI_ERROR_NONE;
4120 /* SetVerboseFlag *************************************************************
4122 Control verbose output. This is the output which typically is sent to stderr
4124 *******************************************************************************/
4127 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4130 case JVMTI_VERBOSE_OTHER:
4131 /* where is this defined ?
4135 case JVMTI_VERBOSE_GC:
4136 opt_verbosegc = value;
4138 case JVMTI_VERBOSE_CLASS:
4139 loadverbose = value;
4141 case JVMTI_VERBOSE_JNI:
4144 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4146 return JVMTI_ERROR_NONE;
4149 /* GetObjectSize **************************************************************
4151 For the object object return the size.
4153 *******************************************************************************/
4156 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4159 CHECK_PHASE(JVMTI_PHASE_START)
4160 CHECK_PHASE(JVMTI_PHASE_LIVE)
4163 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4164 if (!builtin_instanceof(object,class_java_lang_Object))
4165 return JVMTI_ERROR_INVALID_OBJECT;
4167 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4169 return JVMTI_ERROR_NONE;
4173 /* *****************************************************************************
4175 Environment variables
4177 *******************************************************************************/
4179 static jvmtiCapabilities JVMTI_Capabilities = {
4180 0, /* can_tag_objects */
4181 0, /* can_generate_field_modification_events */
4182 0, /* can_generate_field_access_events */
4183 1, /* can_get_bytecodes */
4184 0, /* can_get_synthetic_attribute */
4186 #if defined(ENABLE_THREADS)
4187 1, /* can_get_owned_monitor_info */
4188 1, /* can_get_current_contended_monitor */
4190 0, /* can_get_owned_monitor_info */
4191 0, /* can_get_current_contended_monitor */
4194 0, /* can_get_monitor_info */
4195 0, /* can_pop_frame */
4196 0, /* can_redefine_classes */
4197 0, /* can_signal_thread */
4198 1, /* can_get_source_file_name */
4199 1, /* can_get_line_numbers */
4200 0, /* can_get_source_debug_extension */
4201 0, /* can_access_local_variables */
4202 0, /* can_maintain_original_method_order */
4203 0, /* can_generate_single_step_events */
4204 1, /* can_generate_exception_events */
4205 0, /* can_generate_frame_pop_events */
4206 1, /* can_generate_breakpoint_events */
4207 1, /* can_suspend */
4208 0, /* can_redefine_any_class */
4209 0, /* can_get_current_thread_cpu_time */
4210 0, /* can_get_thread_cpu_time */
4211 1, /* can_generate_method_entry_events */
4212 0, /* can_generate_method_exit_events */
4213 0, /* can_generate_all_class_hook_events */
4214 0, /* can_generate_compiled_method_load_events */
4215 1, /* can_generate_monitor_events */
4216 0, /* can_generate_vm_object_alloc_events */
4217 0, /* can_generate_native_method_bind_events */
4218 0, /* can_generate_garbage_collection_events */
4219 0, /* can_generate_object_free_events */
4222 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4224 &SetEventNotificationMode,
4232 &GetOwnedMonitorInfo,
4233 &GetCurrentContendedMonitor,
4235 &GetTopThreadGroups,
4236 &GetThreadGroupInfo,
4237 &GetThreadGroupChildren,
4259 &RawMonitorNotifyAll,
4263 &SetFieldAccessWatch,
4264 &ClearFieldAccessWatch,
4265 &SetFieldModificationWatch,
4266 &ClearFieldModificationWatch,
4276 &GetImplementedInterfaces,
4281 &GetObjectMonitorUsage,
4283 &GetFieldDeclaringClass,
4287 &GetMethodDeclaringClass,
4288 &GetMethodModifiers,
4292 &GetLineNumberTable,
4294 &GetLocalVariableTable,
4301 &GetClassLoaderClasses,
4312 &GetSourceDebugExtension,
4323 &GetThreadListStackTraces,
4324 &GetThreadLocalStorage,
4325 &SetThreadLocalStorage,
4330 &ForceGarbageCollection,
4331 &IterateOverObjectsReachableFromObject,
4332 &IterateOverReachableObjects,
4334 &IterateOverInstancesOfClass,
4336 &GetObjectsWithTags,
4342 &SetJNIFunctionTable,
4343 &GetJNIFunctionTable,
4346 &GetExtensionFunctions,
4347 &GetExtensionEvents,
4348 &SetExtensionEventCallback,
4349 &DisposeEnvironment,
4351 &GetJLocationFormat,
4352 &GetSystemProperties,
4356 &GetCurrentThreadCpuTimerInfo,
4357 &GetCurrentThreadCpuTime,
4358 &GetThreadCpuTimerInfo,
4362 &GetPotentialCapabilities,
4365 &RelinquishCapabilities,
4366 &GetAvailableProcessors,
4369 &GetEnvironmentLocalStorage,
4370 &SetEnvironmentLocalStorage,
4371 &AddToBootstrapClassLoaderSearch,
4379 /* jvmti_set_phase ************************************************************
4381 sets a new jvmti phase a fires an apropriate event.
4383 *******************************************************************************/
4385 void jvmti_set_phase(jvmtiPhase p) {
4388 fprintf (stderr,"set JVMTI phase %d\n",p);
4392 case JVMTI_PHASE_ONLOAD:
4395 case JVMTI_PHASE_PRIMORDIAL:
4398 case JVMTI_PHASE_START:
4400 d.ev = JVMTI_EVENT_VM_START;
4402 case JVMTI_PHASE_LIVE:
4404 d.ev = JVMTI_EVENT_VM_INIT;
4405 jvmti_fireEvent(&d);
4406 /* thread start event for main thread */
4407 d.ev = JVMTI_EVENT_THREAD_START;
4409 case JVMTI_PHASE_DEAD:
4411 d.ev = JVMTI_EVENT_VM_DEATH;
4414 log_text("wrong jvmti phase to be set");
4418 jvmti_fireEvent(&d);
4422 /* jvmti_new_environment ******************************************************
4424 creates a new JVMTI environment
4426 *******************************************************************************/
4428 jvmtiEnv* jvmti_new_environment() {
4432 envs = heap_allocate(sizeof(environment),true,NULL);
4436 while (env->next != NULL) env = env->next;
4437 env->next = heap_allocate(sizeof(environment),true,NULL);
4441 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4442 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4443 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4444 sizeof(jvmtiEventModeLL));
4445 /* To possess a capability, the agent must add the capability.*/
4446 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4447 RelinquishCapabilities(&(env->env),&(env->capabilities));
4448 env->EnvironmentLocalStorage = NULL;
4451 /* initialize cacao debugging facilities */
4452 jvmti_cacao_debug_init();
4454 return (jvmtiEnv*)env;
4457 /* jvmti_agentload ************************************************************
4459 loads the indicated shared library containing the jvmti agent and calls the
4460 Agent_OnLoad function.
4462 *******************************************************************************/
4464 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4470 len = strlen(opt_arg);
4472 /* separate arguments */
4474 while ((opt_arg[i] != '=') && (i < len))
4480 arg = &opt_arg[i + 1];
4487 *libname = GCMNEW(char, i);
4489 strcpy(*libname, opt_arg);
4494 len = strlen("lib") + i + strlen(".so") + strlen("0");
4496 *libname = GCMNEW(char, len);
4498 strcpy(*libname, "lib");
4499 strcat(*libname, opt_arg);
4500 strcat(*libname, ".so");
4503 /* try to open the library */
4505 if (!(*handle = lt_dlopen(*libname))) {
4506 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4510 /* resolve Agent_OnLoad function */
4511 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4512 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4516 /* resolve Agent_UnLoad function */
4517 unload = lt_dlsym(*handle, "Agent_Unload");
4520 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4521 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4523 if (retval != 0) exit (retval);
4526 /* jvmti_agentunload **********************************************************
4528 calls the Agent_UnLoad function in the jvmti agent if present.
4530 *******************************************************************************/
4532 void jvmti_agentunload() {
4533 if (unload != NULL) {
4534 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4535 ((JavaVM*) &_Jv_JNIInvokeInterface);
4541 * These are local overrides for various environment variables in Emacs.
4542 * Please do not remove this and leave it at the end of the file, where
4543 * Emacs will automagically detect them.
4544 * ---------------------------------------------------------------------
4547 * indent-tabs-mode: t
4551 * vim:noexpandtab:sw=4:ts=4: