1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
2 Tool Interface functions
4 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
5 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
6 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
7 J. Wenninger, Institut f. Computersprachen - TU Wien
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 Contact: cacao@cacaojvm.org
28 Author: Martin Platter
30 Changes: Edwin Steiner
34 $Id: jvmti.c 4954 2006-05-25 21:59:49Z motse $
40 #include "native/jni.h"
41 #include "native/native.h"
42 #include "native/jvmti/cacaodbg.h"
43 #include "native/jvmti/jvmti.h"
44 #include "vm/global.h"
45 #include "vm/loader.h"
46 #include "vm/builtin.h"
47 #include "vm/jit/asmpart.h"
49 #include "vm/classcache.h"
51 #include "toolbox/logging.h"
52 #include "vm/options.h"
53 #include "vm/stringlocal.h"
54 #include "mm/memory.h"
55 #include "threads/native/threads.h"
56 #include "threads/native/lock.h"
57 #include "vm/exceptions.h"
58 #include "native/include/java_util_Vector.h"
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"
67 #include "boehm-gc/include/gc.h"
70 #include <linux/unistd.h>
72 #include "toolbox/logging.h"
74 #include <sys/types.h>
79 #if defined(ENABLE_THREADS)
80 #include "threads/native/threads.h"
88 typedef struct _environment environment;
89 static environment *envs=NULL;
90 pthread_mutex_t dbgcomlock;
92 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
94 static jvmtiPhase phase;
95 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
96 struct _jvmtiEventModeLL {
99 jvmtiEventModeLL *next;
102 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
103 struct _jvmtiThreadLocalStorage{
106 jvmtiThreadLocalStorage *next;
109 struct _environment {
112 jvmtiEventCallbacks callbacks;
113 /* table for enabled/disabled jvmtiEvents - first element contains global
115 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
116 jvmtiCapabilities capabilities;
117 void *EnvironmentLocalStorage;
118 jvmtiThreadLocalStorage *tls;
121 static struct jvmtiEnv_struct JVMTI_EnvTable;
122 static jvmtiCapabilities JVMTI_Capabilities;
123 static lt_ptr unload;
125 #define CHECK_PHASE_START if (!(false
126 #define CHECK_PHASE(chkphase) || (phase == chkphase)
127 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
128 #define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
129 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
130 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t)== \
131 JVMTI_ERROR_THREAD_NOT_ALIVE) \
132 return JVMTI_ERROR_THREAD_NOT_ALIVE;
137 /* check_thread_is_alive *******************************************************
139 checks if the given thread is alive
141 *******************************************************************************/
142 static jvmtiError check_thread_is_alive(jthread t) {
143 if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
144 if(((java_lang_Thread*) t)->vmThread==NULL)
145 return JVMTI_ERROR_THREAD_NOT_ALIVE;
146 return JVMTI_ERROR_NONE;
149 /* execcallback ***************************************************************
151 executes the registerd callbacks for the given jvmti event with parameter
152 in the data structure.
154 *******************************************************************************/
155 static void execute_callback(jvmtiEvent e, functionptr ec,
156 genericEventData* data) {
157 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
159 fprintf(stderr,"execcallback called (event: %d)\n",e);
162 case JVMTI_EVENT_VM_INIT:
163 if (phase != JVMTI_PHASE_LIVE) return;
164 case JVMTI_EVENT_THREAD_START:
165 case JVMTI_EVENT_THREAD_END:
166 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
167 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
170 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
171 if ((phase == JVMTI_PHASE_START) ||
172 (phase == JVMTI_PHASE_LIVE) ||
173 (phase == JVMTI_PHASE_PRIMORDIAL))
174 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
179 data->protection_domain,
182 data->new_class_data_len,
183 data->new_class_data);
187 case JVMTI_EVENT_CLASS_PREPARE:
188 case JVMTI_EVENT_CLASS_LOAD:
189 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
190 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
191 data->thread, data->klass);
194 case JVMTI_EVENT_VM_DEATH:
195 if (phase != JVMTI_PHASE_LIVE) return;
196 case JVMTI_EVENT_VM_START:
197 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
198 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
201 case JVMTI_EVENT_NATIVE_METHOD_BIND:
202 if ((phase == JVMTI_PHASE_START) ||
203 (phase == JVMTI_PHASE_LIVE) ||
204 (phase == JVMTI_PHASE_PRIMORDIAL))
205 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
209 data->new_address_ptr);
213 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
214 if ((phase == JVMTI_PHASE_START) ||
215 (phase == JVMTI_PHASE_LIVE) ||
216 (phase == JVMTI_PHASE_PRIMORDIAL))
217 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
226 if (phase != JVMTI_PHASE_LIVE) return;
228 case JVMTI_EVENT_EXCEPTION:
229 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
235 data->catch_location);
238 case JVMTI_EVENT_EXCEPTION_CATCH:
239 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
246 case JVMTI_EVENT_BREAKPOINT:
247 case JVMTI_EVENT_SINGLE_STEP:
248 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
254 case JVMTI_EVENT_FRAME_POP:
255 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
262 case JVMTI_EVENT_FIELD_ACCESS:
263 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
272 case JVMTI_EVENT_FIELD_MODIFICATION:
274 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
281 data->signature_type,
285 case JVMTI_EVENT_METHOD_ENTRY:
286 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
291 case JVMTI_EVENT_METHOD_EXIT:
292 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
299 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
300 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
309 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
310 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
315 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
316 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
317 case JVMTI_EVENT_DATA_DUMP_REQUEST:
318 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
321 case JVMTI_EVENT_MONITOR_WAIT:
322 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
328 case JVMTI_EVENT_MONITOR_WAITED:
329 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
336 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
337 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
338 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
343 case JVMTI_EVENT_OBJECT_FREE:
344 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
347 case JVMTI_EVENT_VM_OBJECT_ALLOC:
348 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
355 log_text ("unknown event");
362 /* dofireEvent ******************************************************************
364 sends event if it is enabled either globally or for some threads
366 *******************************************************************************/
367 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
369 jvmtiEventModeLL *evm;
374 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
375 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
376 /* test if the event is enable for some threads */
378 if (evm->mode == JVMTI_ENABLE) {
379 data->jvmti_env=&env->env;
380 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
381 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 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)
407 thread = jvmti_get_current_thread();
412 dofireEvent(d->ev,d);
416 /* SetEventNotificationMode ****************************************************
418 Control the generation of events
420 *******************************************************************************/
423 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
424 jvmtiEvent event_type, jthread event_thread, ...)
426 environment* cacao_env;
427 jvmtiEventModeLL *ll;
430 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
431 CHECK_PHASE(JVMTI_PHASE_LIVE)
434 if(event_thread != NULL) {
435 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
436 return JVMTI_ERROR_INVALID_THREAD;
437 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)
494 case JVMTI_EVENT_THREAD_START:
495 jvmti_set_system_breakpoint(THREADSTARTBRK, mode);
497 case JVMTI_EVENT_THREAD_END:
498 jvmti_set_system_breakpoint(THREADENDBRK, mode);
502 /* all other events are required */
503 if ((event_type < JVMTI_EVENT_START_ENUM) ||
504 (event_type > JVMTI_EVENT_END_ENUM))
505 return JVMTI_ERROR_INVALID_EVENT_TYPE;
509 if (event_thread != NULL) {
510 /* thread level control */
511 if ((JVMTI_EVENT_VM_INIT == mode) ||
512 (JVMTI_EVENT_VM_DEATH == mode) ||
513 (JVMTI_EVENT_VM_START == mode) ||
514 (JVMTI_EVENT_THREAD_START == mode) ||
515 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
516 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
517 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
518 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
519 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
520 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
521 while (ll->next != NULL) {
523 if (ll->event_thread == event_thread) {
525 return JVMTI_ERROR_NONE;
528 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
532 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
536 return JVMTI_ERROR_NONE;
539 /* GetAllThreads ***************************************************************
543 *******************************************************************************/
546 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
547 jthread ** threads_ptr)
549 threadobject** threads;
554 CHECK_PHASE(JVMTI_PHASE_LIVE)
557 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
558 return JVMTI_ERROR_NULL_POINTER;
560 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
561 if (retval != JVMTI_ERROR_NONE) return retval;
564 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
566 for (i=0; i<*threads_count_ptr; i++)
567 (*threads_ptr)[i] = threads[i]->o.thread;
569 return JVMTI_ERROR_NONE;
573 /* SuspendThread ***************************************************************
575 Suspend specified thread
577 *******************************************************************************/
580 SuspendThread (jvmtiEnv * env, jthread thread)
583 CHECK_PHASE(JVMTI_PHASE_LIVE)
585 CHECK_CAPABILITY(env,can_suspend);
587 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
588 if (!builtin_instanceof(thread,class_java_lang_Thread))
589 return JVMTI_ERROR_INVALID_THREAD;
590 CHECK_THREAD_IS_ALIVE(thread);
593 /* quick try - this should be changed in the future */
594 pthread_kill(((threadobject*)((java_lang_Thread*) thread)->vmThread)->tid,
598 return JVMTI_ERROR_NONE;
601 /* ResumeThread ***************************************************************
603 Resume a suspended thread
605 *******************************************************************************/
608 ResumeThread (jvmtiEnv * env, jthread thread)
611 CHECK_PHASE(JVMTI_PHASE_LIVE)
613 CHECK_CAPABILITY(env,can_suspend);
615 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
616 if (!builtin_instanceof(thread,class_java_lang_Thread))
617 return JVMTI_ERROR_INVALID_THREAD;
618 CHECK_THREAD_IS_ALIVE(thread);
621 /* quick try - this should be changed in the future */
622 pthread_kill(((threadobject*)((java_lang_Thread*) thread)->vmThread)->tid,
625 return JVMTI_ERROR_NONE;
628 /* StopThread *****************************************************************
630 Send asynchronous exception to the specified thread. Similar to
631 java.lang.Thread.stop(). Used to kill thread.
633 *******************************************************************************/
636 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
639 CHECK_PHASE(JVMTI_PHASE_LIVE)
641 CHECK_CAPABILITY(env,can_signal_thread);
643 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
644 return JVMTI_ERROR_NOT_AVAILABLE;
646 return JVMTI_ERROR_NONE;
649 /* InterruptThread ************************************************************
651 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
653 *******************************************************************************/
656 InterruptThread (jvmtiEnv * env, jthread thread)
659 CHECK_PHASE(JVMTI_PHASE_LIVE)
661 CHECK_CAPABILITY(env,can_signal_thread)
663 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
665 return JVMTI_ERROR_NOT_AVAILABLE;
667 if(!builtin_instanceof(thread,class_java_lang_Thread))
668 return JVMTI_ERROR_INVALID_THREAD;
670 CHECK_THREAD_IS_ALIVE(thread);
672 return JVMTI_ERROR_NONE;
675 /* GetThreadInfo ***************************************************************
677 Get thread information. Details of the specified thread are stored in the
678 jvmtiThreadInfo structure.
680 *******************************************************************************/
683 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
685 java_lang_Thread* th = (java_lang_Thread*)t;
688 CHECK_PHASE(JVMTI_PHASE_LIVE)
690 info_ptr->priority=(jint)th->priority;
691 info_ptr->is_daemon=(jboolean)th->daemon;
692 info_ptr->thread_group=(jthreadGroup)th->group;
693 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
694 info_ptr->name= javastring_tochar((java_objectheader *)th->name);
696 return JVMTI_ERROR_NONE;
699 /* GetOwnedMonitorInfo *********************************************************
701 Get information about the 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;
714 log_text("GetOwnedMonitorInfo called");
717 CHECK_PHASE(JVMTI_PHASE_LIVE)
719 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
721 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
722 return JVMTI_ERROR_NULL_POINTER;
724 if(!builtin_instanceof(thread,class_java_lang_Thread))
725 return JVMTI_ERROR_INVALID_THREAD;
727 CHECK_THREAD_IS_ALIVE(thread);
729 #if defined(ENABLE_THREADS)
731 om=MNEW(java_objectheader*,size);
733 pthread_mutex_lock(&lock_global_pool_lock);
734 lrp=lock_global_pool;
736 while (lrp != NULL) {
737 for (j=0; j<lrp->header.size; j++) {
738 /* if((lrp->lr[j].owner==(threadobject*)thread)&&
739 (!lrp->lr[j].waiting)) {
741 MREALLOC(om,java_objectheader*,size,size*2);
748 lrp=lrp->header.next;
751 pthread_mutex_unlock(&lock_global_pool_lock);
753 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
754 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
755 MFREE(om,java_objectheader*,size);
757 *owned_monitor_count_ptr = i;
761 return JVMTI_ERROR_NONE;
764 /* GetCurrentContendedMonitor *************************************************
766 Get the object the specified thread waits for.
768 *******************************************************************************/
771 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
772 jobject * monitor_ptr)
775 lock_record_pool_t* lrp;
776 java_objectheader* monitor;
779 CHECK_PHASE(JVMTI_PHASE_LIVE)
781 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
783 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
786 if(!builtin_instanceof(thread,class_java_lang_Thread))
787 return JVMTI_ERROR_INVALID_THREAD;
789 CHECK_THREAD_IS_ALIVE(thread);
792 #if defined(ENABLE_THREADS)
794 pthread_mutex_lock(&lock_global_pool_lock);
796 lrp=lock_global_pool;
798 while ((lrp != NULL)&&(monitor==NULL)) {
799 for (j=0; j<lrp->header.size; j++) {
800 /* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
801 monitor=lrp->lr[j].o;
805 lrp=lrp->header.next;
808 pthread_mutex_unlock(&lock_global_pool_lock);
811 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
812 *monitor_ptr = (jobject)monitor;
816 return JVMTI_ERROR_NONE;
820 jvmtiStartFunction sf;
826 static void *threadstartup(void *t) {
827 runagentparam *rap = (runagentparam*)t;
828 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
832 /* RunAgentThread *************************************************************
834 Starts the execution of an agent thread of the specified native function
835 within the specified thread
837 *******************************************************************************/
840 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
841 const void *arg, jint priority)
843 pthread_attr_t threadattr;
844 struct sched_param sp;
848 CHECK_PHASE(JVMTI_PHASE_LIVE)
851 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
852 return JVMTI_ERROR_INVALID_THREAD;
853 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
854 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
855 (priority > JVMTI_THREAD_MAX_PRIORITY))
856 return JVMTI_ERROR_INVALID_PRIORITY;
858 /* XXX: Threads started with with this function should not be visible to
859 Java programming language queries but are included in JVM TI queries */
862 rap.arg = (void*)arg;
865 #if defined(ENABLE_THREADS)
866 pthread_attr_init(&threadattr);
867 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
868 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
869 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
871 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
872 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
874 pthread_attr_setschedparam(&threadattr,&sp);
875 if (pthread_create(&((threadobject*)
876 thread)->tid, &threadattr, &threadstartup, &rap)) {
877 log_text("pthread_create failed");
882 return JVMTI_ERROR_NONE;
886 /* GetTopThreadGroups *********************************************************
888 Get all top-level thread groups in the VM.
890 *******************************************************************************/
893 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
894 jthreadGroup ** groups_ptr)
896 jint threads_count_ptr;
897 threadobject *threads_ptr;
899 jthreadGroup **tg,*ttgp;
902 CHECK_PHASE(JVMTI_PHASE_LIVE)
905 log_text("GetTopThreadGroups called");
907 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
908 return JVMTI_ERROR_NULL_POINTER;
910 #if defined(ENABLE_THREADS)
911 tg = MNEW(jthreadGroup*,size);
913 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
914 return JVMTI_ERROR_INTERNAL;
916 for (i=0;i<threads_count_ptr;i++){
917 if (threads_ptr[i].o.thread->group == NULL) {
918 log_text("threadgroup not set");
919 return JVMTI_ERROR_INTERNAL;
921 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
924 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
929 MREALLOC(tg,jthreadGroup*,size,size*2);
938 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
939 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
940 MFREE(tg,jthreadGroup*,size);
942 *group_count_ptr = x;
945 return JVMTI_ERROR_NOT_AVAILABLE;
947 return JVMTI_ERROR_NONE;
951 /* GetThreadGroupInfo *********************************************************
953 Get information about the specified thread group.
955 *******************************************************************************/
958 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
959 jvmtiThreadGroupInfo * info_ptr)
963 java_lang_ThreadGroup* grp;
966 CHECK_PHASE(JVMTI_PHASE_LIVE)
969 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
970 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
971 return JVMTI_ERROR_INVALID_THREAD_GROUP;
973 grp = (java_lang_ThreadGroup*)group;
975 info_ptr->parent = (jthreadGroup)
976 Java_java_lang_VMObject_clone(NULL,
977 (jclass)grp->header.vftbl->class,
978 (java_lang_Cloneable*) &grp->parent);
980 name = javastring_tochar((java_objectheader*)grp->name);
982 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
983 strncpy(info_ptr->name,name,size);
984 info_ptr->max_priority= (jint)grp->maxpri;
985 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
987 return JVMTI_ERROR_NONE;
991 /* GetThreadGroupChildren *****************************************************
993 Get the live threads and active subgroups in this thread group.
995 *******************************************************************************/
998 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
999 jint * thread_count_ptr, jthread ** threads_ptr,
1000 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1002 java_lang_ThreadGroup* tgp;
1005 CHECK_PHASE(JVMTI_PHASE_LIVE)
1008 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1009 (group_count_ptr == NULL) || (groups_ptr == NULL))
1010 return JVMTI_ERROR_NULL_POINTER;
1012 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1013 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1015 tgp = (java_lang_ThreadGroup*)group;
1017 *thread_count_ptr = (jint)tgp->threads->elementCount;
1019 *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
1021 memcpy(*threads_ptr, &tgp->threads->elementData,
1022 (*thread_count_ptr)*sizeof(jthread*));
1024 *group_count_ptr = (jint) tgp->groups->elementCount;
1026 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
1028 memcpy(*groups_ptr, &tgp->threads->elementData,
1029 (*group_count_ptr)*sizeof(jthreadGroup*));
1031 return JVMTI_ERROR_NONE;
1035 /* getcacaostacktrace *********************************************************
1037 Helper function that retrives stack trace for specified thread.
1038 Has to take care of suspend/resume issuses
1040 *******************************************************************************/
1041 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1044 log_text("getcacaostacktrace");
1046 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1049 *trace = stacktrace_create(t); */
1051 return JVMTI_ERROR_NONE;
1055 /* GetFrameCount **************************************************************
1058 Get the number of frames in the specified thread's stack.
1060 *******************************************************************************/
1063 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1065 stacktracebuffer* trace;
1069 CHECK_PHASE(JVMTI_PHASE_LIVE)
1072 if(!builtin_instanceof(thread,class_java_lang_Thread))
1073 return JVMTI_ERROR_INVALID_THREAD;
1075 CHECK_THREAD_IS_ALIVE(thread);
1077 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1079 er = getcacaostacktrace(&trace, thread);
1080 if (er==JVMTI_ERROR_NONE) return er;
1082 *count_ptr = trace->used;
1084 return JVMTI_ERROR_NONE;
1088 /* GetThreadState **************************************************************
1090 Get the state of a thread.
1092 *******************************************************************************/
1095 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1097 java_lang_Thread* th = (java_lang_Thread*)thread;
1098 threadobject* t = (threadobject*)th->vmThread;
1101 CHECK_PHASE(JVMTI_PHASE_LIVE)
1104 if(!builtin_instanceof(thread,class_java_lang_Thread))
1105 return JVMTI_ERROR_INVALID_THREAD;
1107 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1109 *thread_state_ptr = 0;
1110 #if defined(ENABLE_THREADS)
1111 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1113 if (((threadobject*)th->vmThread)->tid == 0)
1114 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1117 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1118 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1120 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1121 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1122 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1123 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1124 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1125 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1126 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1127 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1128 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1129 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1132 return JVMTI_ERROR_INTERNAL;
1135 return JVMTI_ERROR_NONE;
1139 /* GetFrameLocation ************************************************************
1141 Get the location of the instruction currently executing
1143 *******************************************************************************/
1146 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1147 jmethodID * method_ptr, jlocation * location_ptr)
1149 stackframeinfo *sfi;
1153 CHECK_PHASE(JVMTI_PHASE_LIVE)
1156 if(!builtin_instanceof(thread,class_java_lang_Thread))
1157 return JVMTI_ERROR_INVALID_THREAD;
1159 CHECK_THREAD_IS_ALIVE(thread);
1161 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1163 if ((method_ptr == NULL)&&(location_ptr == NULL))
1164 return JVMTI_ERROR_NULL_POINTER;
1166 sfi = ((threadobject*)thread)->_stackframeinfo;
1169 while ((sfi != NULL) && (i<depth)) {
1174 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1176 *method_ptr=(jmethodID)sfi->method;
1177 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1179 return JVMTI_ERROR_NONE;
1183 /* NotifyFramePop *************************************************************
1187 *******************************************************************************/
1190 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1193 CHECK_PHASE(JVMTI_PHASE_LIVE)
1195 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1197 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1198 return JVMTI_ERROR_NONE;
1201 /* GetLocalObject *************************************************************
1205 *******************************************************************************/
1208 GetLocalObject (jvmtiEnv * env,
1209 jthread thread, jint depth, jint slot, jobject * value_ptr)
1212 CHECK_PHASE(JVMTI_PHASE_LIVE)
1214 CHECK_CAPABILITY(env,can_access_local_variables)
1216 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1217 return JVMTI_ERROR_NONE;
1220 /* GetLocalInt ****************************************************************
1224 *******************************************************************************/
1227 GetLocalInt (jvmtiEnv * env,
1228 jthread thread, jint depth, jint slot, jint * value_ptr)
1231 CHECK_PHASE(JVMTI_PHASE_LIVE)
1233 CHECK_CAPABILITY(env,can_access_local_variables)
1234 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1235 return JVMTI_ERROR_NONE;
1238 /* *****************************************************************************
1242 *******************************************************************************/
1245 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
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;
1258 /* *****************************************************************************
1262 *******************************************************************************/
1265 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1269 CHECK_PHASE(JVMTI_PHASE_LIVE)
1271 CHECK_CAPABILITY(env,can_access_local_variables)
1273 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1274 return JVMTI_ERROR_NONE;
1278 /* *****************************************************************************
1282 *******************************************************************************/
1285 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1286 jdouble * value_ptr)
1289 CHECK_PHASE(JVMTI_PHASE_LIVE)
1291 CHECK_CAPABILITY(env,can_access_local_variables)
1293 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1294 return JVMTI_ERROR_NONE;
1298 /* *****************************************************************************
1302 *******************************************************************************/
1305 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1309 CHECK_PHASE(JVMTI_PHASE_LIVE)
1311 CHECK_CAPABILITY(env,can_access_local_variables)
1313 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1314 return JVMTI_ERROR_NONE;
1318 /* *****************************************************************************
1322 *******************************************************************************/
1325 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1329 CHECK_PHASE(JVMTI_PHASE_LIVE)
1331 CHECK_CAPABILITY(env,can_access_local_variables)
1333 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1334 return JVMTI_ERROR_NONE;
1338 /* *****************************************************************************
1342 *******************************************************************************/
1345 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1349 CHECK_PHASE(JVMTI_PHASE_LIVE)
1351 CHECK_CAPABILITY(env,can_access_local_variables)
1353 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1354 return JVMTI_ERROR_NONE;
1358 /* *****************************************************************************
1362 *******************************************************************************/
1365 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1369 CHECK_PHASE(JVMTI_PHASE_LIVE)
1371 CHECK_CAPABILITY(env,can_access_local_variables)
1373 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1374 return JVMTI_ERROR_NONE;
1378 /* *****************************************************************************
1382 *******************************************************************************/
1385 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1389 CHECK_PHASE(JVMTI_PHASE_LIVE)
1391 CHECK_CAPABILITY(env,can_access_local_variables)
1393 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1394 return JVMTI_ERROR_NONE;
1398 /* CreateRawMonitor ***********************************************************
1400 This function creates a new raw monitor.
1402 *******************************************************************************/
1405 CreateRawMonitor (jvmtiEnv * env, const char *name,
1406 jrawMonitorID * monitor_ptr)
1408 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1411 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1412 CHECK_PHASE(JVMTI_PHASE_LIVE)
1415 if ((name == NULL) || (monitor_ptr == NULL))
1416 return JVMTI_ERROR_NULL_POINTER;
1418 #if defined(ENABLE_THREADS)
1419 monitor->name=javastring_new_from_ascii(name);
1421 log_text ("CreateRawMonitor not supported");
1424 return JVMTI_ERROR_NONE;
1428 /* DestroyRawMonitor **********************************************************
1430 This function destroys a raw monitor.
1432 *******************************************************************************/
1435 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1438 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1439 CHECK_PHASE(JVMTI_PHASE_LIVE)
1442 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1443 return JVMTI_ERROR_INVALID_MONITOR;
1445 #if defined(ENABLE_THREADS)
1446 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1447 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1449 lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1451 /* GC will clean monitor up */
1453 log_text ("DestroyRawMonitor not supported");
1456 return JVMTI_ERROR_NONE;
1460 /* RawMonitorEnter ************************************************************
1462 Gain exclusive ownership of a raw monitor
1464 *******************************************************************************/
1467 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1469 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1470 return JVMTI_ERROR_INVALID_MONITOR;
1472 #if defined(ENABLE_THREADS)
1473 builtin_monitorenter((java_objectheader*)monitor->name);
1475 log_text ("RawMonitorEnter not supported");
1478 return JVMTI_ERROR_NONE;
1482 /* RawMonitorExit *************************************************************
1486 *******************************************************************************/
1489 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1491 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1492 return JVMTI_ERROR_INVALID_MONITOR;
1494 #if defined(ENABLE_THREADS)
1495 /* assure current thread owns this monitor */
1496 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1497 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1499 builtin_monitorexit((java_objectheader*)monitor->name);
1501 log_text ("RawMonitorExit not supported");
1504 return JVMTI_ERROR_NONE;
1508 /* RawMonitorWait *************************************************************
1510 Wait for notification of the raw monitor.
1512 *******************************************************************************/
1515 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1517 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1518 return JVMTI_ERROR_INVALID_MONITOR;
1520 #if defined(ENABLE_THREADS)
1521 /* assure current thread owns this monitor */
1522 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1523 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1525 lock_wait_for_object(&monitor->name->header, millis,0);
1526 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1527 return JVMTI_ERROR_INTERRUPT;
1530 log_text ("RawMonitorWait not supported");
1533 return JVMTI_ERROR_NONE;
1537 /* RawMonitorNotify ***********************************************************
1539 Notify one thread waiting on the given monitor.
1541 *******************************************************************************/
1544 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1546 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1547 return JVMTI_ERROR_INVALID_MONITOR;
1549 #if defined(ENABLE_THREADS)
1550 /* assure current thread owns this monitor */
1551 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1552 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1554 lock_notify_object((java_objectheader*)&monitor->name);
1556 log_text ("RawMonitorNotify not supported");
1559 return JVMTI_ERROR_NONE;
1563 /* RawMonitorNotifyAll *********************************************************
1565 Notify all threads waiting on the given monitor.
1567 *******************************************************************************/
1570 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1572 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1573 return JVMTI_ERROR_INVALID_MONITOR;
1575 #if defined(ENABLE_THREADS)
1576 /* assure current thread owns this monitor */
1577 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1578 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1580 lock_notify_all_object((java_objectheader*)&monitor->name);
1582 log_text ("RawMonitorNotifyAll not supported");
1585 return JVMTI_ERROR_NONE;
1589 /* SetBreakpoint **************************************************************
1593 *******************************************************************************/
1596 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1599 CHECK_PHASE(JVMTI_PHASE_LIVE)
1601 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1604 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1605 return JVMTI_ERROR_NONE;
1609 /* *****************************************************************************
1613 *******************************************************************************/
1616 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1619 CHECK_PHASE(JVMTI_PHASE_LIVE)
1621 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1623 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1624 return JVMTI_ERROR_NONE;
1628 /* SetFieldAccessWatch ********************************************************
1632 *******************************************************************************/
1635 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1638 CHECK_PHASE(JVMTI_PHASE_LIVE)
1640 CHECK_CAPABILITY(env,can_generate_field_access_events)
1642 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1643 return JVMTI_ERROR_NONE;
1647 /* *****************************************************************************
1651 *******************************************************************************/
1654 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1657 CHECK_PHASE(JVMTI_PHASE_LIVE)
1659 CHECK_CAPABILITY(env,can_generate_field_access_events)
1661 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1662 return JVMTI_ERROR_NONE;
1666 /* *****************************************************************************
1670 *******************************************************************************/
1673 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1676 CHECK_PHASE(JVMTI_PHASE_LIVE)
1678 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1680 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1681 return JVMTI_ERROR_NONE;
1685 /* *****************************************************************************
1689 *******************************************************************************/
1692 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1695 CHECK_PHASE(JVMTI_PHASE_LIVE)
1697 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1699 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1700 return JVMTI_ERROR_NONE;
1704 /* Allocate ********************************************************************
1706 Allocate an area of memory through the JVM TI allocator. The allocated
1707 memory should be freed with Deallocate
1709 *******************************************************************************/
1712 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1715 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1716 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1718 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1719 if (*mem_ptr == NULL)
1720 return JVMTI_ERROR_OUT_OF_MEMORY;
1722 return JVMTI_ERROR_NONE;
1727 /* Deallocate ******************************************************************
1729 Deallocate mem using the JVM TI allocator.
1731 *******************************************************************************/
1734 Deallocate (jvmtiEnv * env, unsigned char *mem)
1736 /* let Boehm GC do the job */
1738 return JVMTI_ERROR_NONE;
1742 /* GetClassSignature ************************************************************
1744 For the class indicated by klass, return the JNI type signature and the
1745 generic signature of the class.
1747 *******************************************************************************/
1750 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1754 CHECK_PHASE(JVMTI_PHASE_START)
1755 CHECK_PHASE(JVMTI_PHASE_LIVE)
1758 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1759 return JVMTI_ERROR_NULL_POINTER;
1761 *signature_ptr = (char*)
1762 heap_allocate(sizeof(char) *
1763 ((classinfo*)klass)->name->blength,true,NULL);
1765 utf_sprint_convert_to_latin1(*signature_ptr, ((classinfo*)klass)->name);
1766 *generic_ptr = NULL;
1768 return JVMTI_ERROR_NONE;
1771 /* GetClassStatus *************************************************************
1773 Get status of the class.
1775 *******************************************************************************/
1778 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1782 CHECK_PHASE(JVMTI_PHASE_START)
1783 CHECK_PHASE(JVMTI_PHASE_LIVE)
1786 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1787 return JVMTI_ERROR_INVALID_CLASS;
1789 if (status_ptr == NULL)
1790 return JVMTI_ERROR_NULL_POINTER;
1792 c = (classinfo*)klass;
1795 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1796 if (c->state&=CLASS_LINKED)
1797 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1799 if (c->state&=CLASS_INITIALIZED)
1800 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1802 if (c->state&=CLASS_ERROR)
1803 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1805 if (c->vftbl->arraydesc != NULL)
1806 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1808 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1809 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1811 return JVMTI_ERROR_NONE;
1815 /* GetSourceFileName **********************************************************
1817 For the class indicated by klass, return the source file name.
1819 *******************************************************************************/
1822 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1827 CHECK_PHASE(JVMTI_PHASE_START)
1828 CHECK_PHASE(JVMTI_PHASE_LIVE)
1830 CHECK_CAPABILITY(env,can_get_source_file_name)
1832 if ((klass == NULL)||(source_name_ptr == NULL))
1833 return JVMTI_ERROR_NULL_POINTER;
1835 size = (((classinfo*)klass)->sourcefile->blength)+1;
1837 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1839 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1840 (*source_name_ptr)[size]='\0';
1842 return JVMTI_ERROR_NONE;
1846 /* GetClassModifiers **********************************************************
1848 For class klass return the access flags
1850 *******************************************************************************/
1853 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1856 CHECK_PHASE(JVMTI_PHASE_START)
1857 CHECK_PHASE(JVMTI_PHASE_LIVE)
1860 if (modifiers_ptr == NULL)
1861 return JVMTI_ERROR_NULL_POINTER;
1863 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1864 return JVMTI_ERROR_INVALID_CLASS;
1866 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1868 return JVMTI_ERROR_NONE;
1872 /* GetClassMethods *************************************************************
1874 For class klass return a count of methods and a list of method IDs
1876 *******************************************************************************/
1879 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1880 jmethodID ** methods_ptr)
1885 CHECK_PHASE(JVMTI_PHASE_START)
1886 CHECK_PHASE(JVMTI_PHASE_LIVE)
1889 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1890 return JVMTI_ERROR_NULL_POINTER;
1892 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1893 return JVMTI_ERROR_INVALID_CLASS;
1895 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1896 *methods_ptr = (jmethodID*)
1897 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1899 for (i=0; i<*method_count_ptr;i++)
1900 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1902 return JVMTI_ERROR_NONE;
1906 /* GetClassFields *************************************************************
1908 For the class indicated by klass, return a count of fields and a list of
1911 *******************************************************************************/
1914 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1915 jfieldID ** fields_ptr)
1918 CHECK_PHASE(JVMTI_PHASE_START)
1919 CHECK_PHASE(JVMTI_PHASE_LIVE)
1922 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1923 return JVMTI_ERROR_NULL_POINTER;
1925 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1926 *fields_ptr = (jfieldID*)
1927 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1929 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1930 sizeof(jfieldID) * (*field_count_ptr));
1932 return JVMTI_ERROR_NONE;
1936 /* GetImplementedInterfaces ***************************************************
1938 Return the direct super-interfaces of this class.
1940 *******************************************************************************/
1943 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1944 jint * interface_count_ptr,
1945 jclass ** interfaces_ptr)
1948 classref_or_classinfo *interfaces;
1952 CHECK_PHASE(JVMTI_PHASE_START)
1953 CHECK_PHASE(JVMTI_PHASE_LIVE)
1956 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1957 return JVMTI_ERROR_NULL_POINTER;
1959 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1960 return JVMTI_ERROR_INVALID_CLASS;
1963 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1965 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1967 interfaces = ((classinfo*)klass)->interfaces;
1968 for (i=0; i<*interface_count_ptr; i++) {
1969 if (IS_CLASSREF(interfaces[i]))
1970 tmp = load_class_bootstrap(interfaces[i].ref->name);
1972 tmp = interfaces[i].cls;
1974 *interfaces_ptr[i]=tmp;
1977 return JVMTI_ERROR_NONE;
1981 /* IsInterface ****************************************************************
1983 Determines whether a class object reference represents an interface.
1985 *******************************************************************************/
1988 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1991 CHECK_PHASE(JVMTI_PHASE_START)
1992 CHECK_PHASE(JVMTI_PHASE_LIVE)
1995 if ((klass == NULL)||(is_interface_ptr == NULL))
1996 return JVMTI_ERROR_NULL_POINTER;
1998 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2000 return JVMTI_ERROR_NONE;
2003 /* IsArrayClass ***************************************************************
2005 Determines whether a class object reference represents an array.
2007 *******************************************************************************/
2010 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2013 CHECK_PHASE(JVMTI_PHASE_START)
2014 CHECK_PHASE(JVMTI_PHASE_LIVE)
2017 if (is_array_class_ptr == NULL)
2018 return JVMTI_ERROR_NULL_POINTER;
2020 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2022 return JVMTI_ERROR_NONE;
2026 /* GetClassLoader *************************************************************
2028 For the class indicated by klass, return via classloader_ptr a reference to
2029 the class loader for the class.
2031 *******************************************************************************/
2034 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2037 CHECK_PHASE(JVMTI_PHASE_START)
2038 CHECK_PHASE(JVMTI_PHASE_LIVE)
2041 if ((klass == NULL)||(classloader_ptr == NULL))
2042 return JVMTI_ERROR_NULL_POINTER;
2044 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2046 return JVMTI_ERROR_NONE;
2050 /* GetObjectHashCode **********************************************************
2052 Return hash code for object object
2054 *******************************************************************************/
2057 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2060 CHECK_PHASE(JVMTI_PHASE_START)
2061 CHECK_PHASE(JVMTI_PHASE_LIVE)
2064 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2065 if (!builtin_instanceof(object,class_java_lang_Object))
2066 return JVMTI_ERROR_INVALID_OBJECT;
2068 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2070 return JVMTI_ERROR_NONE;
2074 /* *****************************************************************************
2078 *******************************************************************************/
2081 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2082 jvmtiMonitorUsage * info_ptr)
2085 CHECK_PHASE(JVMTI_PHASE_LIVE)
2087 CHECK_CAPABILITY(env,can_get_monitor_info)
2089 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2090 return JVMTI_ERROR_NONE;
2094 /* GetFieldName ***************************************************************
2096 For the field indicated by klass and field, return the field name and
2099 *******************************************************************************/
2102 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2103 char **name_ptr, char **signature_ptr, char **generic_ptr)
2108 CHECK_PHASE(JVMTI_PHASE_START)
2109 CHECK_PHASE(JVMTI_PHASE_LIVE)
2112 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2113 return JVMTI_ERROR_NULL_POINTER;
2115 size = (((fieldinfo*)field)->name->blength);
2116 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2117 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2119 size = (((fieldinfo*)field)->descriptor->blength);
2120 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2121 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2123 *generic_ptr = NULL;
2125 return JVMTI_ERROR_NONE;
2129 /* GetFieldDeclaringClass *****************************************************
2131 For the field indicated by klass and field return the class that defined it
2132 The declaring class will either be klass, a superclass, or an implemented
2135 *******************************************************************************/
2138 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2139 jclass * declaring_class_ptr)
2142 CHECK_PHASE(JVMTI_PHASE_START)
2143 CHECK_PHASE(JVMTI_PHASE_LIVE)
2146 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2148 return JVMTI_ERROR_NONE;
2152 /* GetFieldModifiers **********************************************************
2154 Return access flags of field field
2156 *******************************************************************************/
2159 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2160 jint * modifiers_ptr)
2163 CHECK_PHASE(JVMTI_PHASE_START)
2164 CHECK_PHASE(JVMTI_PHASE_LIVE)
2167 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2168 return JVMTI_ERROR_INVALID_OBJECT;
2170 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2172 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2174 *modifiers_ptr = ((fieldinfo*)field)->flags;
2176 return JVMTI_ERROR_NONE;
2180 /* IsFieldSynthetic ***********************************************************
2184 *******************************************************************************/
2187 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2188 jboolean * is_synthetic_ptr)
2191 CHECK_PHASE(JVMTI_PHASE_START)
2192 CHECK_PHASE(JVMTI_PHASE_LIVE)
2194 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2196 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2197 return JVMTI_ERROR_NONE;
2201 /* GetMethodName ***************************************************************
2203 For the method indicated by method, return the method name via name_ptr and
2204 method signature via signature_ptr.
2206 *******************************************************************************/
2209 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2210 char **signature_ptr, char **generic_ptr)
2212 methodinfo* m = (methodinfo*)method;
2215 CHECK_PHASE(JVMTI_PHASE_START)
2216 CHECK_PHASE(JVMTI_PHASE_LIVE)
2219 if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2220 || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2223 heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
2224 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2226 *signature_ptr = (char*)
2227 heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
2228 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2230 /* there is no generic signature attribute */
2231 *generic_ptr = NULL;
2233 return JVMTI_ERROR_NONE;
2237 /* GetMethodDeclaringClass *****************************************************
2239 For the method indicated by method, return the class that defined it.
2241 *******************************************************************************/
2244 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2245 jclass * declaring_class_ptr)
2248 CHECK_PHASE(JVMTI_PHASE_START)
2249 CHECK_PHASE(JVMTI_PHASE_LIVE)
2252 if ((method == NULL) || (declaring_class_ptr == NULL))
2253 return JVMTI_ERROR_NULL_POINTER;
2255 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2257 return JVMTI_ERROR_NONE;
2261 /* GetMethodModifiers **********************************************************
2263 For the method indicated by method, return the access flags.
2265 *******************************************************************************/
2268 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2271 CHECK_PHASE(JVMTI_PHASE_START)
2272 CHECK_PHASE(JVMTI_PHASE_LIVE)
2275 if ((method == NULL) || (modifiers_ptr == NULL))
2276 return JVMTI_ERROR_NULL_POINTER;
2278 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2280 return JVMTI_ERROR_NONE;
2284 /* GetMaxLocals ****************************************************************
2286 For the method indicated by method, return the number of local variable slots
2287 used by the method, including the local variables used to pass parameters to
2288 the method on its invocation.
2290 *******************************************************************************/
2293 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2296 CHECK_PHASE(JVMTI_PHASE_START)
2297 CHECK_PHASE(JVMTI_PHASE_LIVE)
2300 if ((method == NULL)||(max_ptr == NULL))
2301 return JVMTI_ERROR_NULL_POINTER;
2303 if (((methodinfo*)method)->flags & ACC_NATIVE)
2304 return JVMTI_ERROR_NATIVE_METHOD;
2306 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2308 return JVMTI_ERROR_NONE;
2313 /* GetArgumentsSize ************************************************************
2315 Return the number of local variable slots used by the method's arguments.
2317 *******************************************************************************/
2320 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2323 CHECK_PHASE(JVMTI_PHASE_START)
2324 CHECK_PHASE(JVMTI_PHASE_LIVE)
2327 if ((method == NULL)||(size_ptr == NULL))
2328 return JVMTI_ERROR_NULL_POINTER;
2330 if (((methodinfo*)method)->flags & ACC_NATIVE)
2331 return JVMTI_ERROR_NATIVE_METHOD;
2333 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2334 return JVMTI_ERROR_NONE;
2339 /* GetLineNumberTable ***********************************************************
2341 Return table of source line number entries for a given method
2343 *******************************************************************************/
2346 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2347 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2352 CHECK_PHASE(JVMTI_PHASE_START)
2353 CHECK_PHASE(JVMTI_PHASE_LIVE)
2355 CHECK_CAPABILITY(env,can_get_line_numbers)
2357 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2358 return JVMTI_ERROR_NULL_POINTER;
2359 if (((methodinfo*)method)->flags & ACC_NATIVE)
2360 return JVMTI_ERROR_NATIVE_METHOD;
2361 if (((methodinfo*)method)->linenumbers == NULL)
2362 return JVMTI_ERROR_ABSENT_INFORMATION;
2364 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2365 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2366 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2369 for (i=0; i < *entry_count_ptr; i++) {
2370 (*table_ptr[i]).start_location =
2371 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2372 (*table_ptr[i]).line_number =
2373 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2376 return JVMTI_ERROR_NONE;
2380 /* GetMethodLocation ***********************************************************
2382 For the method indicated by method, return the beginning and ending addresses
2383 through start_location_ptr and end_location_ptr. In cacao this points to
2384 entry point in machine code and length of machine code
2386 *******************************************************************************/
2389 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2390 jlocation * start_location_ptr,
2391 jlocation * end_location_ptr)
2393 methodinfo* m = (methodinfo*)method;
2396 CHECK_PHASE(JVMTI_PHASE_START)
2397 CHECK_PHASE(JVMTI_PHASE_LIVE)
2400 if ((method == NULL) || (start_location_ptr == NULL) ||
2401 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2403 /* XXX we return the location of the most recent code. Don't know
2404 * if there is a way to teach jvmti that a method can have more
2405 * than one location. -Edwin */
2407 /* XXX Don't know if that's the right way to deal with not-yet-
2408 * compiled methods. -Edwin */
2411 return JVMTI_ERROR_NULL_POINTER;
2413 *start_location_ptr = (jlocation)m->code->mcode;
2414 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2415 return JVMTI_ERROR_NONE;
2419 /* GetLocalVariableTable *******************************************************
2421 Return local variable information.
2423 *******************************************************************************/
2426 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2427 jint * entry_count_ptr,
2428 jvmtiLocalVariableEntry ** table_ptr)
2431 CHECK_PHASE(JVMTI_PHASE_LIVE)
2433 CHECK_CAPABILITY(env,can_access_local_variables)
2435 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2437 return JVMTI_ERROR_NONE;
2441 /* GetBytecode *****************************************************************
2443 For the method indicated by method, return the byte codes that implement the
2446 *******************************************************************************/
2449 GetBytecodes (jvmtiEnv * env, jmethodID method,
2450 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2452 methodinfo* m = (methodinfo*)method;;
2455 CHECK_PHASE(JVMTI_PHASE_START)
2456 CHECK_PHASE(JVMTI_PHASE_LIVE)
2458 CHECK_CAPABILITY(env,can_get_bytecodes)
2460 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2461 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2463 *bytecode_count_ptr = m->jcodelength;
2464 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2465 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2467 return JVMTI_ERROR_NONE;
2471 /* IsMethodNative **************************************************************
2473 For the method indicated by method, return a value indicating whether the
2474 method is a native function
2476 *******************************************************************************/
2479 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2482 CHECK_PHASE(JVMTI_PHASE_START)
2483 CHECK_PHASE(JVMTI_PHASE_LIVE)
2486 if ((method == NULL)||(is_native_ptr == NULL))
2487 return JVMTI_ERROR_NULL_POINTER;
2489 if (((methodinfo*)method)->flags & ACC_NATIVE)
2490 *is_native_ptr = JNI_TRUE;
2492 *is_native_ptr = JNI_FALSE;
2494 return JVMTI_ERROR_NONE;
2498 /* IsMethodSynthetic ***********************************************************
2500 return a value indicating whether the method is synthetic. Synthetic methods
2501 are generated by the compiler but not present in the original source code.
2503 *******************************************************************************/
2506 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2507 jboolean * is_synthetic_ptr)
2510 CHECK_PHASE(JVMTI_PHASE_START)
2511 CHECK_PHASE(JVMTI_PHASE_LIVE)
2513 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2515 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2516 return JVMTI_ERROR_NONE;
2520 /* GetLoadedClasses ************************************************************
2522 Return an array of all classes loaded in the virtual machine.
2524 *******************************************************************************/
2527 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2530 classcache_name_entry *nameentry;
2531 classcache_class_entry *classentry;
2534 CHECK_PHASE(JVMTI_PHASE_LIVE)
2537 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2538 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2542 heap_allocate(sizeof(jclass)*(hashtable_classcache.entries),true,NULL);
2544 /* look in every slot of the hashtable */
2545 for (i=0; i<hashtable_classcache.size; i++) {
2546 nameentry = hashtable_classcache.ptr[i];
2547 while (nameentry != NULL) { /* iterate over hashlink */
2549 /* filter pseudo classes $NEW$,$NULL$,$ARRAYSTUB$ out */
2550 if (nameentry->name->text[0]=='$')
2552 *class_count_ptr -= 1;
2556 classentry = nameentry->classes;
2557 while (classentry != NULL){ /* iterate over classes with same name */
2558 if (classentry->classobj != NULL) { /*get only loaded classes */
2559 assert(j<hashtable_classcache.entries);
2560 (*classes_ptr)[j]=classentry->classobj;
2563 classentry = classentry->next;
2565 nameentry = nameentry->hashlink;
2569 CLASSCACHE_UNLOCK();
2571 *class_count_ptr = j;
2573 return JVMTI_ERROR_NONE;
2577 /* GetClassLoaderClasses *******************************************************
2579 Returns an array of those classes for which this class loader has been
2580 recorded as an initiating loader.
2582 *******************************************************************************/
2585 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2586 jint * class_count_ptr, jclass ** classes_ptr)
2588 log_text("GetClassLoaderClasses called");
2591 CHECK_PHASE(JVMTI_PHASE_LIVE)
2594 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2595 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2597 /* behave like jdk 1.1 and make no distinction between initiating and
2598 defining class loaders */
2600 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2604 /* PopFrame *******************************************************************
2608 *******************************************************************************/
2611 PopFrame (jvmtiEnv * env, jthread thread)
2614 CHECK_PHASE(JVMTI_PHASE_LIVE)
2616 CHECK_CAPABILITY(env,can_pop_frame)
2618 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2619 return JVMTI_ERROR_NONE;
2623 /* RedefineClasses ************************************************************
2627 *******************************************************************************/
2630 RedefineClasses (jvmtiEnv * env, jint class_count,
2631 const jvmtiClassDefinition * class_definitions)
2634 CHECK_PHASE(JVMTI_PHASE_START)
2635 CHECK_PHASE(JVMTI_PHASE_LIVE)
2637 CHECK_CAPABILITY(env,can_redefine_classes)
2638 CHECK_CAPABILITY(env,can_redefine_any_class)
2639 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2640 return JVMTI_ERROR_NONE;
2644 /* GetVersionNumber ***********************************************************
2646 Return the JVM TI version identifier.
2648 *******************************************************************************/
2651 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2653 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2655 *version_ptr = JVMTI_VERSION;
2657 return JVMTI_ERROR_NONE;
2661 /* GetCapabilities ************************************************************
2663 Returns the optional JVM TI features which this environment currently
2666 *******************************************************************************/
2669 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2671 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2673 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2675 return JVMTI_ERROR_NONE;
2679 /* *****************************************************************************
2683 *******************************************************************************/
2686 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2687 char **source_debug_extension_ptr)
2690 CHECK_PHASE(JVMTI_PHASE_START)
2691 CHECK_PHASE(JVMTI_PHASE_LIVE)
2693 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2695 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2696 return JVMTI_ERROR_NONE;
2700 /* IsMethodObsolete ************************************************************
2702 Determine if a method ID refers to an obsolete method version.
2704 *******************************************************************************/
2707 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2708 jboolean * is_obsolete_ptr)
2711 CHECK_PHASE(JVMTI_PHASE_START)
2712 CHECK_PHASE(JVMTI_PHASE_LIVE)
2714 CHECK_CAPABILITY(env,can_redefine_classes)
2716 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2717 return JVMTI_ERROR_NONE;
2721 /* SuspendThreadList **********************************************************
2723 Suspend all threads in the request list.
2725 *******************************************************************************/
2728 SuspendThreadList (jvmtiEnv * env, jint request_count,
2729 const jthread * request_list, jvmtiError * results)
2736 CHECK_PHASE(JVMTI_PHASE_START)
2737 CHECK_PHASE(JVMTI_PHASE_LIVE)
2739 CHECK_CAPABILITY(env,can_suspend);
2741 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2742 if ((request_list==NULL) || (results == NULL))
2743 return JVMTI_ERROR_NULL_POINTER;
2745 me = jvmti_get_current_thread();
2747 for (i=0;i<request_count;i++) {
2748 if (request_list[i] == me)
2751 results[i]=SuspendThread(env, request_list[i]);
2754 if (suspendme != -1)
2755 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2757 return JVMTI_ERROR_NONE;
2761 /* ResumeThreadList ***********************************************************
2763 Resumes all threads in the request list.
2765 *******************************************************************************/
2768 ResumeThreadList (jvmtiEnv * env, jint request_count,
2769 const jthread * request_list, jvmtiError * results)
2774 CHECK_PHASE(JVMTI_PHASE_LIVE)
2776 CHECK_CAPABILITY(env,can_suspend);
2778 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2779 if ((request_list==NULL) || (results == NULL))
2780 return JVMTI_ERROR_NULL_POINTER;
2782 for (i=0;i<request_count;i++)
2783 results[i]=ResumeThread(env, request_list[i]);
2785 return JVMTI_ERROR_NONE;
2789 /* GetStackTrace **************************************************************
2791 Get information about the stack of a thread
2793 *******************************************************************************/
2796 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2797 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2800 stacktracebuffer* trace;
2805 CHECK_PHASE(JVMTI_PHASE_LIVE)
2808 if(!builtin_instanceof(thread,class_java_lang_Thread))
2809 return JVMTI_ERROR_INVALID_THREAD;
2811 CHECK_THREAD_IS_ALIVE(thread);
2813 if((count_ptr == NULL)||(frame_buffer == NULL))
2814 return JVMTI_ERROR_NULL_POINTER;
2816 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2818 er = getcacaostacktrace(&trace, thread);
2819 if (er==JVMTI_ERROR_NONE) return er;
2821 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2822 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2824 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2825 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2826 /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
2827 frame_buffer[j].location = 0;
2830 return JVMTI_ERROR_NONE;
2834 /* GetThreadListStackTraces ***************************************************
2836 Get information about the stacks of the supplied threads.
2838 *******************************************************************************/
2841 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2842 const jthread * thread_list,
2843 jint max_frame_count,
2844 jvmtiStackInfo ** stack_info_ptr)
2850 CHECK_PHASE(JVMTI_PHASE_LIVE)
2853 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2854 return JVMTI_ERROR_NULL_POINTER;
2856 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2858 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2860 *stack_info_ptr = (jvmtiStackInfo*)
2861 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2863 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2864 (*stack_info_ptr)[i].thread=thread_list[i];
2865 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2866 (*stack_info_ptr)[i].frame_buffer =
2867 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2868 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2869 (*stack_info_ptr)[i].frame_buffer,
2870 &((*stack_info_ptr)[i].frame_count));
2872 if (er != JVMTI_ERROR_NONE) return er;
2875 return JVMTI_ERROR_NONE;
2879 /* GetAllStackTraces **********************************************************
2881 Get stack traces of all live threads
2883 *******************************************************************************/
2886 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2887 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2889 jthread *threads_ptr;
2893 CHECK_PHASE(JVMTI_PHASE_LIVE)
2896 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2898 /* todo: all threads have to be suspended */
2900 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2901 return JVMTI_ERROR_INTERNAL;
2903 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2904 max_frame_count, stack_info_ptr);
2906 /* todo: resume all threads have to be suspended */
2907 if (er != JVMTI_ERROR_NONE) return er;
2909 return JVMTI_ERROR_NONE;
2913 /* GetThreadLocalStorage ******************************************************
2915 Get the value of the JVM TI thread-local storage.
2917 *******************************************************************************/
2920 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2922 jvmtiThreadLocalStorage *tls;
2925 CHECK_PHASE(JVMTI_PHASE_START)
2926 CHECK_PHASE(JVMTI_PHASE_LIVE)
2930 thread = (jthread) THREADOBJECT;
2932 if (!builtin_instanceof(thread,class_java_lang_Thread))
2933 return JVMTI_ERROR_INVALID_THREAD;
2934 CHECK_THREAD_IS_ALIVE(thread);
2937 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2939 tls = ((environment*)env)->tls;
2940 while ((tls->thread != thread) && (tls != NULL)) {
2944 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2946 *data_ptr = tls->data;
2948 return JVMTI_ERROR_NONE;
2952 /* SetThreadLocalStorage *******************************************************
2954 Stores a pointer value associated with each environment-thread pair. The
2955 value is NULL unless set with this function. Agents can allocate memory in
2956 which they store thread specific information
2958 *******************************************************************************/
2961 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2963 jvmtiThreadLocalStorage *tls, *pre;
2964 environment* env = (environment*)jenv;
2967 CHECK_PHASE(JVMTI_PHASE_START)
2968 CHECK_PHASE(JVMTI_PHASE_LIVE)
2972 thread = (jthread) THREADOBJECT;
2974 if (!builtin_instanceof(thread,class_java_lang_Thread))
2975 return JVMTI_ERROR_INVALID_THREAD;
2976 CHECK_THREAD_IS_ALIVE(thread);
2979 if (env->tls == NULL) {
2980 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2983 while ((tls->thread != thread) && (tls->next != NULL)) {
2986 if (tls->thread != thread) {
2987 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2993 tls->data = (void*)data;
2995 /* remove current tls */
2997 while (pre->next == tls) pre = pre->next;
2998 pre->next = tls->next;
3000 return JVMTI_ERROR_NONE;
3004 /* *****************************************************************************
3008 *******************************************************************************/
3011 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3014 CHECK_PHASE(JVMTI_PHASE_START)
3015 CHECK_PHASE(JVMTI_PHASE_LIVE)
3017 CHECK_CAPABILITY(env,can_tag_objects)
3019 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3020 return JVMTI_ERROR_NONE;
3023 /* *****************************************************************************
3027 *******************************************************************************/
3030 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3033 CHECK_PHASE(JVMTI_PHASE_START)
3034 CHECK_PHASE(JVMTI_PHASE_LIVE)
3036 CHECK_CAPABILITY(env,can_tag_objects)
3038 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3039 return JVMTI_ERROR_NONE;
3043 /* ForceGarbageCollection *****************************************************
3045 Force boehm-gc to perform a garbage collection
3047 *******************************************************************************/
3050 ForceGarbageCollection (jvmtiEnv * env)
3053 CHECK_PHASE(JVMTI_PHASE_LIVE)
3058 return JVMTI_ERROR_NONE;
3062 /* IterateOverObjectsReachableFromObject **************************************
3066 *******************************************************************************/
3069 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3070 jvmtiObjectReferenceCallback
3071 object_reference_callback,
3075 CHECK_PHASE(JVMTI_PHASE_LIVE)
3077 CHECK_CAPABILITY(env,can_tag_objects)
3079 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3080 return JVMTI_ERROR_NONE;
3084 /* IterateOverReachableObjects ************************************************
3088 *******************************************************************************/
3091 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3093 jvmtiStackReferenceCallback
3095 jvmtiObjectReferenceCallback
3096 object_ref_callback, void *user_data)
3099 CHECK_PHASE(JVMTI_PHASE_LIVE)
3101 CHECK_CAPABILITY(env,can_tag_objects)
3103 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3104 return JVMTI_ERROR_NONE;
3108 /* IterateOverHeap ************************************************************
3112 *******************************************************************************/
3115 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3116 jvmtiHeapObjectCallback heap_object_callback,
3120 CHECK_PHASE(JVMTI_PHASE_LIVE)
3122 CHECK_CAPABILITY(env,can_tag_objects)
3124 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3125 return JVMTI_ERROR_NONE;
3129 /* IterateOverInstancesOfClass ************************************************
3133 *******************************************************************************/
3136 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3137 jvmtiHeapObjectFilter object_filter,
3138 jvmtiHeapObjectCallback
3139 heap_object_callback, void *user_data)
3142 CHECK_PHASE(JVMTI_PHASE_LIVE)
3144 CHECK_CAPABILITY(env,can_tag_objects)
3146 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3147 return JVMTI_ERROR_NONE;
3151 /* *****************************************************************************
3155 *******************************************************************************/
3158 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3159 jint * count_ptr, jobject ** object_result_ptr,
3160 jlong ** tag_result_ptr)
3163 CHECK_PHASE(JVMTI_PHASE_LIVE)
3165 CHECK_CAPABILITY(env,can_tag_objects)
3167 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3168 return JVMTI_ERROR_NONE;
3172 /* SetJNIFunctionTable **********************************************************
3174 Set the JNI function table in all current and future JNI environments
3176 *******************************************************************************/
3179 SetJNIFunctionTable (jvmtiEnv * env,
3180 const jniNativeInterface * function_table)
3183 CHECK_PHASE(JVMTI_PHASE_START)
3184 CHECK_PHASE(JVMTI_PHASE_LIVE)
3187 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3188 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3189 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3190 return JVMTI_ERROR_NONE;
3194 /* GetJNIFunctionTable *********************************************************
3196 Get the JNI function table. The JNI function table is copied into allocated
3199 *******************************************************************************/
3202 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3205 CHECK_PHASE(JVMTI_PHASE_START)
3206 CHECK_PHASE(JVMTI_PHASE_LIVE)
3209 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3210 *function_table = (jniNativeInterface*)
3211 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3212 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3213 return JVMTI_ERROR_NONE;
3217 /* SetEventCallbacks **********************************************************
3219 Set the functions to be called for each event. The callbacks are specified
3220 by supplying a replacement function table.
3222 *******************************************************************************/
3225 SetEventCallbacks (jvmtiEnv * env,
3226 const jvmtiEventCallbacks * callbacks,
3227 jint size_of_callbacks)
3230 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3231 CHECK_PHASE(JVMTI_PHASE_LIVE)
3234 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3237 if (callbacks == NULL) { /* remove the existing callbacks */
3238 memset(&(((environment* )env)->callbacks), 0,
3239 sizeof(jvmtiEventCallbacks));
3242 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3244 return JVMTI_ERROR_NONE;
3248 /* GenerateEvents *************************************************************
3250 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3251 the current state of the VM.
3253 *******************************************************************************/
3256 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3259 CHECK_PHASE(JVMTI_PHASE_LIVE)
3262 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3263 return JVMTI_ERROR_NONE;
3267 /* GetExtensionFunctions ******************************************************
3269 Returns the set of extension functions.
3271 *******************************************************************************/
3274 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3275 jvmtiExtensionFunctionInfo ** extensions)
3278 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3279 CHECK_PHASE(JVMTI_PHASE_LIVE)
3282 if ((extension_count_ptr== NULL)||(extensions == NULL))
3283 return JVMTI_ERROR_NULL_POINTER;
3285 /* cacao has no extended functions yet */
3286 *extension_count_ptr = 0;
3288 return JVMTI_ERROR_NONE;
3292 /* GetExtensionEvents *********************************************************
3294 Returns the set of extension events.
3296 *******************************************************************************/
3299 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3300 jvmtiExtensionEventInfo ** extensions)
3303 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3304 CHECK_PHASE(JVMTI_PHASE_LIVE)
3307 if ((extension_count_ptr== NULL)||(extensions == NULL))
3308 return JVMTI_ERROR_NULL_POINTER;
3310 /* cacao has no extended events yet */
3311 *extension_count_ptr = 0;
3313 return JVMTI_ERROR_NONE;
3317 /* SetExtensionEventCallback **************************************************
3319 Sets the callback function for an extension event and enables the event.
3321 *******************************************************************************/
3324 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3325 jvmtiExtensionEvent callback)
3328 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3329 CHECK_PHASE(JVMTI_PHASE_LIVE)
3332 /* cacao has no extended events yet */
3333 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3337 /* DisposeEnvironment **********************************************************
3339 Shutdown a JVM TI connection created with JNI GetEnv.
3341 *******************************************************************************/
3344 DisposeEnvironment (jvmtiEnv * env)
3346 environment* cacao_env = (environment*)env;
3347 environment* tenvs = envs;
3348 jvmtiThreadLocalStorage *jtls, *tjtls;
3350 if (tenvs != cacao_env) {
3351 while (tenvs->next != cacao_env) {
3352 tenvs = tenvs->next;
3354 tenvs->next = cacao_env->next;
3358 cacao_env->env=NULL;
3359 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3360 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3361 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3362 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3363 cacao_env->EnvironmentLocalStorage = NULL;
3365 jtls = cacao_env->tls;
3366 while (jtls != NULL) {
3371 cacao_env->tls = NULL;
3374 jvmti_cacaodbgserver_quit();
3376 /* let the GC do the rest */
3377 return JVMTI_ERROR_NONE;
3381 /* GetErrorName ***************************************************************
3383 Return the symbolic name for an error code.
3385 *******************************************************************************/
3387 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3388 memcpy(*name_ptr, &str, sizeof(str)); \
3392 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3394 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3397 case JVMTI_ERROR_NONE :
3398 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3399 case JVMTI_ERROR_NULL_POINTER :
3400 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3401 case JVMTI_ERROR_OUT_OF_MEMORY :
3402 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3403 case JVMTI_ERROR_ACCESS_DENIED :
3404 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3405 case JVMTI_ERROR_UNATTACHED_THREAD :
3406 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3407 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3408 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3409 case JVMTI_ERROR_WRONG_PHASE :
3410 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3411 case JVMTI_ERROR_INTERNAL :
3412 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3413 case JVMTI_ERROR_INVALID_PRIORITY :
3414 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3415 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3416 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3417 case JVMTI_ERROR_THREAD_SUSPENDED :
3418 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3419 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3420 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3421 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3422 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3423 case JVMTI_ERROR_NO_MORE_FRAMES :
3424 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3425 case JVMTI_ERROR_OPAQUE_FRAME :
3426 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3427 case JVMTI_ERROR_DUPLICATE :
3428 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3429 case JVMTI_ERROR_NOT_FOUND :
3430 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3431 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3432 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3433 case JVMTI_ERROR_INTERRUPT :
3434 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3435 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3436 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3437 case JVMTI_ERROR_NOT_AVAILABLE :
3438 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3439 case JVMTI_ERROR_ABSENT_INFORMATION :
3440 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3441 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3442 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3443 case JVMTI_ERROR_NATIVE_METHOD :
3444 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3445 case JVMTI_ERROR_INVALID_THREAD :
3446 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3447 case JVMTI_ERROR_INVALID_FIELDID :
3448 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3449 case JVMTI_ERROR_INVALID_METHODID :
3450 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3451 case JVMTI_ERROR_INVALID_LOCATION :
3452 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3453 case JVMTI_ERROR_INVALID_OBJECT :
3454 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3455 case JVMTI_ERROR_INVALID_CLASS :
3456 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3457 case JVMTI_ERROR_TYPE_MISMATCH :
3458 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3459 case JVMTI_ERROR_INVALID_SLOT :
3460 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3461 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3462 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3463 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3464 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3465 case JVMTI_ERROR_INVALID_MONITOR :
3466 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3467 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3468 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3469 case JVMTI_ERROR_INVALID_TYPESTATE :
3470 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3471 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3472 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3473 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3474 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3475 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3476 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3477 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3478 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3479 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3480 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3481 case JVMTI_ERROR_FAILS_VERIFICATION :
3482 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3483 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3484 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3485 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3486 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3487 case JVMTI_ERROR_NAMES_DONT_MATCH :
3488 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3489 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3490 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3491 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3492 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3494 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3496 return JVMTI_ERROR_NONE;
3499 /* GetJLocationFormat **********************************************************
3501 This function describes the representation of jlocation used in this VM.
3503 *******************************************************************************/
3506 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3508 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3509 return JVMTI_ERROR_NONE;
3513 /* GetSystemProperties ********************************************************
3515 The list of VM system property keys which may be used with GetSystemProperty
3518 *******************************************************************************/
3521 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3523 jmethodID mid, moremid;
3524 classinfo *sysclass, *propclass, *enumclass;
3525 java_objectheader *sysprop, *keys, *obj;
3530 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3531 CHECK_PHASE(JVMTI_PHASE_LIVE)
3534 if ((count_ptr == NULL) || (property_ptr == NULL))
3535 return JVMTI_ERROR_NULL_POINTER;
3537 sysclass = load_class_from_sysloader(
3538 utf_new_char_classname ("java/lang/System"));
3540 if (!sysclass) throw_main_exception_exit();
3542 mid = (jmethodID)class_resolvemethod(sysclass,
3543 utf_new_char("getProperties"),
3544 utf_new_char("()Ljava/util/Properties;"));
3545 if (!mid) throw_main_exception_exit();
3548 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3549 if (!sysprop) throw_main_exception_exit();
3551 propclass = sysprop->vftbl->class;
3553 mid = (jmethodID)class_resolvemethod(propclass,
3554 utf_new_char("size"),
3555 utf_new_char("()I"));
3556 if (!mid) throw_main_exception_exit();
3559 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3560 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3562 mid = (jmethodID)class_resolvemethod(propclass,
3563 utf_new_char("keys"),
3564 utf_new_char("()Ljava/util/Enumeration;"));
3565 if (!mid) throw_main_exception_exit();
3567 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3568 enumclass = keys->vftbl->class;
3570 moremid = (jmethodID)class_resolvemethod(enumclass,
3571 utf_new_char("hasMoreElements"),
3572 utf_new_char("()Z"));
3573 if (!moremid) throw_main_exception_exit();
3575 mid = (jmethodID)class_resolvemethod(propclass,
3576 utf_new_char("nextElement"),
3577 utf_new_char("()Ljava/lang/Object;"));
3578 if (!mid) throw_main_exception_exit();
3581 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3582 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3583 ch = javastring_tochar(obj);
3584 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3585 memcpy(*property_ptr[i], ch, strlen (ch));
3586 MFREE(ch,char,strlen(ch)+1);
3590 return JVMTI_ERROR_NONE;
3594 /* GetSystemProperty **********************************************************
3596 Return a VM system property value given the property key.
3598 *******************************************************************************/
3601 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3604 classinfo *sysclass, *propclass;
3605 java_objectheader *sysprop, *obj;
3609 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3610 CHECK_PHASE(JVMTI_PHASE_LIVE)
3613 if ((value_ptr == NULL) || (property == NULL))
3614 return JVMTI_ERROR_NULL_POINTER;
3616 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3617 if (!sysclass) throw_main_exception_exit();
3619 mid = (jmethodID)class_resolvemethod(sysclass,
3620 utf_new_char("getProperties"),
3621 utf_new_char("()Ljava/util/Properties;"));
3622 if (!mid) throw_main_exception_exit();
3624 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3626 propclass = sysprop->vftbl->class;
3628 mid = (jmethodID)class_resolvemethod(propclass,
3629 utf_new_char("getProperty"),
3630 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3631 if (!mid) throw_main_exception_exit();
3633 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3634 NULL, sysprop, mid, javastring_new_from_ascii(property));
3635 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3637 ch = javastring_tochar(obj);
3638 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3639 memcpy(*value_ptr, ch, strlen (ch));
3640 MFREE(ch,char,strlen(ch)+1);
3642 return JVMTI_ERROR_NONE;
3646 /* SetSystemProperty **********************************************************
3648 Set a VM system property value.
3650 *******************************************************************************/
3653 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3656 classinfo *sysclass, *propclass;
3657 java_objectheader *sysprop;
3660 CHECK_PHASE(JVMTI_PHASE_START)
3663 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3664 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3666 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3667 if (!sysclass) throw_main_exception_exit();
3669 mid = (jmethodID)class_resolvemethod(sysclass,
3670 utf_new_char("getProperties"),
3671 utf_new_char("()Ljava/util/Properties;"));
3672 if (!mid) throw_main_exception_exit();
3674 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3676 propclass = sysprop->vftbl->class;
3678 mid = (jmethodID)class_resolvemethod(propclass,
3679 utf_new_char("setProperty"),
3680 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3681 if (!mid) throw_main_exception_exit();
3683 _Jv_JNINativeInterface.CallObjectMethod(
3684 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3686 return JVMTI_ERROR_NONE;
3689 /* GetPhase ********************************************************************
3691 Return the current phase of VM execution
3693 *******************************************************************************/
3696 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3698 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3702 return JVMTI_ERROR_NONE;
3705 /* GetCurrentThreadCpuTimerInfo ************************************************
3709 *******************************************************************************/
3712 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3715 CHECK_PHASE(JVMTI_PHASE_START)
3716 CHECK_PHASE(JVMTI_PHASE_LIVE)
3718 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3720 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3722 return JVMTI_ERROR_NONE;
3725 /* GetCurrentThreadCpuTime ****************************************************
3729 *******************************************************************************/
3732 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3735 CHECK_PHASE(JVMTI_PHASE_START)
3736 CHECK_PHASE(JVMTI_PHASE_LIVE)
3738 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3740 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3741 return JVMTI_ERROR_NONE;
3744 /* GetThreadCpuTimerInfo ******************************************************
3748 *******************************************************************************/
3751 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3754 CHECK_PHASE(JVMTI_PHASE_START)
3755 CHECK_PHASE(JVMTI_PHASE_LIVE)
3757 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3759 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3760 return JVMTI_ERROR_NONE;
3763 /* GetThreadCpuTime ***********************************************************
3767 *******************************************************************************/
3770 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3773 CHECK_PHASE(JVMTI_PHASE_LIVE)
3775 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3776 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3777 return JVMTI_ERROR_NONE;
3780 /* GetTimerInfo ***************************************************************
3782 Get information about the GetTime timer.
3784 *******************************************************************************/
3787 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3789 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3791 info_ptr->max_value = !0x0;
3792 info_ptr->may_skip_forward = true;
3793 info_ptr->may_skip_backward = true;
3794 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3796 return JVMTI_ERROR_NONE;
3799 /* GetTime ********************************************************************
3801 Return the current value of the system timer, in nanoseconds
3803 *******************************************************************************/
3806 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3808 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3811 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3813 if (gettimeofday (&tp, NULL) == -1)
3814 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3816 *nanos_ptr = (jlong) tp.tv_sec;
3818 *nanos_ptr += (tp.tv_usec / 1000);
3820 return JVMTI_ERROR_NONE;
3823 /* GetPotentialCapabilities ***************************************************
3825 Returns the JVM TI features that can potentially be possessed by this
3826 environment at this time.
3828 *******************************************************************************/
3831 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3834 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3835 CHECK_PHASE(JVMTI_PHASE_LIVE)
3838 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3840 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3842 return JVMTI_ERROR_NONE;
3846 #define CHECK_ADD_CAPABILITY(env,CAN) \
3847 if (capabilities_ptr->CAN == 1) { \
3848 if (JVMTI_Capabilities.CAN == 0) \
3849 return JVMTI_ERROR_NOT_AVAILABLE; \
3851 env->capabilities.CAN = 1; \
3854 /* AddCapabilities ************************************************************
3856 Set new capabilities by adding the capabilities pointed to by
3857 capabilities_ptr. All previous capabilities are retained.
3859 *******************************************************************************/
3862 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3864 environment* cacao_env;
3867 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3868 CHECK_PHASE(JVMTI_PHASE_LIVE)
3871 if ((env == NULL) || (capabilities_ptr == NULL))
3872 return JVMTI_ERROR_NULL_POINTER;
3874 cacao_env = (environment*)env;
3876 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3877 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3878 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3879 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3880 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3881 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3882 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3883 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3884 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3885 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3886 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3887 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3888 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3889 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3890 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3891 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3892 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3893 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3894 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3895 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3896 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3897 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3898 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3899 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3900 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3901 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3902 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3903 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3904 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3905 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3906 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3907 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3908 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3911 return JVMTI_ERROR_NONE;
3915 #define CHECK_DEL_CAPABILITY(env,CAN) \
3916 if (capabilities_ptr->CAN == 1) \
3917 env->capabilities.CAN = 0;
3919 /* RelinquishCapabilities *****************************************************
3921 Relinquish the capabilities pointed to by capabilities_ptr.
3923 *******************************************************************************/
3926 RelinquishCapabilities (jvmtiEnv * env,
3927 const jvmtiCapabilities * capabilities_ptr)
3929 environment* cacao_env;
3932 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3933 CHECK_PHASE(JVMTI_PHASE_LIVE)
3936 if ((env == NULL) || (capabilities_ptr == NULL))
3937 return JVMTI_ERROR_NULL_POINTER;
3939 cacao_env = (environment*)env;
3941 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3942 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3943 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3944 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3945 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3946 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3947 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3948 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3949 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3950 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3951 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3952 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3953 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3954 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3955 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3956 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3957 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3958 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3959 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3960 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3961 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3962 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3963 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3964 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3965 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3966 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3967 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3968 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3969 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3970 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3971 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3972 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3973 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3975 return JVMTI_ERROR_NONE;
3978 /* *****************************************************************************
3982 *******************************************************************************/
3985 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3988 CHECK_PHASE(JVMTI_PHASE_START)
3989 CHECK_PHASE(JVMTI_PHASE_LIVE)
3992 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3994 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3996 *processor_count_ptr = 1; /* where do I get this ?*/
3998 return JVMTI_ERROR_NONE;
4001 /* GetEnvironmentLocalStorage **************************************************
4003 Called by the agent to get the value of the JVM TI environment-local storage.
4005 *******************************************************************************/
4008 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4010 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4012 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4014 return JVMTI_ERROR_NONE;
4017 /* SetEnvironmentLocalStorage **************************************************
4019 The VM stores a pointer value associated with each environment. Agents can
4020 allocate memory in which they store environment specific information.
4022 *******************************************************************************/
4025 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4027 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4029 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4031 return JVMTI_ERROR_NONE;
4034 /* AddToBootstrapClassLoaderSearch ********************************************
4036 After the bootstrap class loader unsuccessfully searches for a class, the
4037 specified platform-dependent search path segment will be searched as well.
4039 *******************************************************************************/
4042 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4048 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4051 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4053 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4054 tmp_bcp = MNEW(char, ln);
4055 strcat(tmp_bcp, bootclasspath);
4056 strcat(tmp_bcp, ":");
4057 strcat(tmp_bcp, segment);
4058 MFREE(bootclasspath,char,ln);
4059 bootclasspath = tmp_bcp;
4061 return JVMTI_ERROR_NONE;
4064 /* SetVerboseFlag *************************************************************
4066 Control verbose output. This is the output which typically is sent to stderr
4068 *******************************************************************************/
4071 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4074 case JVMTI_VERBOSE_OTHER:
4075 /* where is this defined ?
4079 case JVMTI_VERBOSE_GC:
4080 opt_verbosegc = value;
4082 case JVMTI_VERBOSE_CLASS:
4083 loadverbose = value;
4085 case JVMTI_VERBOSE_JNI:
4088 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4090 return JVMTI_ERROR_NONE;
4093 /* GetObjectSize **************************************************************
4095 For the object object return the size.
4097 *******************************************************************************/
4100 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4103 CHECK_PHASE(JVMTI_PHASE_START)
4104 CHECK_PHASE(JVMTI_PHASE_LIVE)
4107 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4108 if (!builtin_instanceof(object,class_java_lang_Object))
4109 return JVMTI_ERROR_INVALID_OBJECT;
4111 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4113 return JVMTI_ERROR_NONE;
4117 /* *****************************************************************************
4119 Environment variables
4121 *******************************************************************************/
4123 static jvmtiCapabilities JVMTI_Capabilities = {
4124 0, /* can_tag_objects */
4125 0, /* can_generate_field_modification_events */
4126 0, /* can_generate_field_access_events */
4127 1, /* can_get_bytecodes */
4128 0, /* can_get_synthetic_attribute */
4130 #if defined(ENABLE_THREADS)
4131 1, /* can_get_owned_monitor_info */
4132 1, /* can_get_current_contended_monitor */
4134 0, /* can_get_owned_monitor_info */
4135 0, /* can_get_current_contended_monitor */
4138 0, /* can_get_monitor_info */
4139 0, /* can_pop_frame */
4140 0, /* can_redefine_classes */
4141 0, /* can_signal_thread */
4142 1, /* can_get_source_file_name */
4143 1, /* can_get_line_numbers */
4144 0, /* can_get_source_debug_extension */
4145 0, /* can_access_local_variables */
4146 0, /* can_maintain_original_method_order */
4147 0, /* can_generate_single_step_events */
4148 0, /* can_generate_exception_events */
4149 0, /* can_generate_frame_pop_events */
4150 0, /* can_generate_breakpoint_events */
4151 1, /* can_suspend */
4152 0, /* can_redefine_any_class */
4153 0, /* can_get_current_thread_cpu_time */
4154 0, /* can_get_thread_cpu_time */
4155 0, /* can_generate_method_entry_events */
4156 0, /* can_generate_method_exit_events */
4157 0, /* can_generate_all_class_hook_events */
4158 0, /* can_generate_compiled_method_load_events */
4159 0, /* can_generate_monitor_events */
4160 0, /* can_generate_vm_object_alloc_events */
4161 0, /* can_generate_native_method_bind_events */
4162 0, /* can_generate_garbage_collection_events */
4163 0, /* can_generate_object_free_events */
4166 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4168 &SetEventNotificationMode,
4176 &GetOwnedMonitorInfo,
4177 &GetCurrentContendedMonitor,
4179 &GetTopThreadGroups,
4180 &GetThreadGroupInfo,
4181 &GetThreadGroupChildren,
4203 &RawMonitorNotifyAll,
4207 &SetFieldAccessWatch,
4208 &ClearFieldAccessWatch,
4209 &SetFieldModificationWatch,
4210 &ClearFieldModificationWatch,
4220 &GetImplementedInterfaces,
4225 &GetObjectMonitorUsage,
4227 &GetFieldDeclaringClass,
4231 &GetMethodDeclaringClass,
4232 &GetMethodModifiers,
4236 &GetLineNumberTable,
4238 &GetLocalVariableTable,
4245 &GetClassLoaderClasses,
4256 &GetSourceDebugExtension,
4267 &GetThreadListStackTraces,
4268 &GetThreadLocalStorage,
4269 &SetThreadLocalStorage,
4274 &ForceGarbageCollection,
4275 &IterateOverObjectsReachableFromObject,
4276 &IterateOverReachableObjects,
4278 &IterateOverInstancesOfClass,
4280 &GetObjectsWithTags,
4286 &SetJNIFunctionTable,
4287 &GetJNIFunctionTable,
4290 &GetExtensionFunctions,
4291 &GetExtensionEvents,
4292 &SetExtensionEventCallback,
4293 &DisposeEnvironment,
4295 &GetJLocationFormat,
4296 &GetSystemProperties,
4300 &GetCurrentThreadCpuTimerInfo,
4301 &GetCurrentThreadCpuTime,
4302 &GetThreadCpuTimerInfo,
4306 &GetPotentialCapabilities,
4309 &RelinquishCapabilities,
4310 &GetAvailableProcessors,
4313 &GetEnvironmentLocalStorage,
4314 &SetEnvironmentLocalStorage,
4315 &AddToBootstrapClassLoaderSearch,
4324 void jvmti_set_phase(jvmtiPhase p) {
4327 fprintf (stderr,"set JVMTI phase %d\n",p);
4331 case JVMTI_PHASE_ONLOAD:
4334 case JVMTI_PHASE_PRIMORDIAL:
4337 case JVMTI_PHASE_START:
4339 d.ev = JVMTI_EVENT_VM_START;
4341 case JVMTI_PHASE_LIVE:
4343 d.ev = JVMTI_EVENT_VM_INIT;
4344 jvmti_fireEvent(&d);
4345 /* thread start event for main thread */
4346 d.ev = JVMTI_EVENT_THREAD_START;
4348 case JVMTI_PHASE_DEAD:
4350 d.ev = JVMTI_EVENT_VM_DEATH;
4353 log_text("wrong jvmti phase to be set");
4357 jvmti_fireEvent(&d);
4360 jvmtiEnv* jvmti_new_environment() {
4364 envs = heap_allocate(sizeof(environment),true,NULL);
4368 while (env->next != NULL) env = env->next;
4369 env->next = heap_allocate(sizeof(environment),true,NULL);
4373 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4374 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4375 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4376 sizeof(jvmtiEventModeLL));
4377 /* To possess a capability, the agent must add the capability.*/
4378 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4379 RelinquishCapabilities(&(env->env),&(env->capabilities));
4380 env->EnvironmentLocalStorage = NULL;
4383 /* initialize cacao debugging facilities */
4384 jvmti_cacao_debug_init();
4386 return (jvmtiEnv*)env;
4389 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4395 len = strlen(opt_arg);
4397 /* separate argumtents */
4398 while ((opt_arg[i]!='=')&&(i<len)) i++;
4400 arg = &opt_arg[i+1];
4406 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4407 strncpy(*libname,opt_arg,i);
4411 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4412 strncpy(*libname,"lib",3);
4413 strncpy(&(*libname)[3],opt_arg,i);
4414 strncpy(&(*libname)[i+3],".so",3);
4417 /* try to open the library */
4419 if (!(*handle = lt_dlopen(*libname))) {
4420 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4424 /* resolve Agent_OnLoad function */
4425 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4426 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4430 /* resolve Agent_UnLoad function */
4431 unload = lt_dlsym(*handle, "Agent_Unload");
4434 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4435 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4437 if (retval != 0) exit (retval);
4440 void jvmti_agentunload() {
4441 if (unload != NULL) {
4442 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4443 ((JavaVM*) &_Jv_JNIInvokeInterface);
4448 * These are local overrides for various environment variables in Emacs.
4449 * Please do not remove this and leave it at the end of the file, where
4450 * Emacs will automagically detect them.
4451 * ---------------------------------------------------------------------
4454 * indent-tabs-mode: t
4458 * vim:noexpandtab:sw=4:ts=4: