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 4996 2006-05-31 13:53:16Z 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/jit/stacktrace.h"
45 #include "vm/global.h"
46 #include "vm/loader.h"
47 #include "vm/builtin.h"
48 #include "vm/jit/asmpart.h"
50 #include "vm/classcache.h"
52 #include "toolbox/logging.h"
53 #include "vm/options.h"
54 #include "vm/stringlocal.h"
55 #include "mm/memory.h"
56 #include "threads/native/threads.h"
57 #include "threads/native/lock.h"
58 #include "vm/exceptions.h"
59 #include "native/include/java_util_Vector.h"
60 #include "native/include/java_io_PrintStream.h"
61 #include "native/include/java_io_InputStream.h"
62 #include "native/include/java_lang_Cloneable.h"
63 #include "native/include/java_lang_ThreadGroup.h"
64 #include "native/include/java_lang_VMObject.h"
65 #include "native/include/java_lang_VMSystem.h"
66 #include "native/include/java_lang_VMClass.h"
68 #include "boehm-gc/include/gc.h"
71 #include <linux/unistd.h>
73 #include "toolbox/logging.h"
75 #include <sys/types.h>
80 #if defined(ENABLE_THREADS)
81 #include "threads/native/threads.h"
89 typedef struct _environment environment;
90 static environment *envs=NULL;
91 pthread_mutex_t dbgcomlock;
93 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
95 static jvmtiPhase phase;
96 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
97 struct _jvmtiEventModeLL {
100 jvmtiEventModeLL *next;
103 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
104 struct _jvmtiThreadLocalStorage{
107 jvmtiThreadLocalStorage *next;
110 struct _environment {
113 jvmtiEventCallbacks callbacks;
114 /* table for enabled/disabled jvmtiEvents - first element contains global
116 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
117 jvmtiCapabilities capabilities;
118 void *EnvironmentLocalStorage;
119 jvmtiThreadLocalStorage *tls;
122 static struct jvmtiEnv_struct JVMTI_EnvTable;
123 static jvmtiCapabilities JVMTI_Capabilities;
124 static lt_ptr unload;
126 #define CHECK_PHASE_START if (!(false
127 #define CHECK_PHASE(chkphase) || (phase == chkphase)
128 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
129 #define CHECK_CAPABILITY(env,CAP) if(((environment*) \
130 env)->capabilities.CAP == 0) \
131 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
132 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t)== \
133 JVMTI_ERROR_THREAD_NOT_ALIVE) \
134 return JVMTI_ERROR_THREAD_NOT_ALIVE;
139 /* check_thread_is_alive *******************************************************
141 checks if the given thread is alive
143 *******************************************************************************/
144 static jvmtiError check_thread_is_alive(jthread t) {
145 if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
146 if(((java_lang_Thread*) t)->vmThread==NULL)
147 return JVMTI_ERROR_THREAD_NOT_ALIVE;
148 return JVMTI_ERROR_NONE;
151 /* execcallback ***************************************************************
153 executes the registerd callbacks for the given jvmti event with parameter
154 in the data structure.
156 *******************************************************************************/
157 static void execute_callback(jvmtiEvent e, functionptr ec,
158 genericEventData* data) {
159 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
161 fprintf(stderr,"execcallback called (event: %d)\n",e);
164 case JVMTI_EVENT_VM_INIT:
165 if (phase != JVMTI_PHASE_LIVE) return;
166 case JVMTI_EVENT_THREAD_START:
167 case JVMTI_EVENT_THREAD_END:
168 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
169 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
172 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
173 if ((phase == JVMTI_PHASE_START) ||
174 (phase == JVMTI_PHASE_LIVE) ||
175 (phase == JVMTI_PHASE_PRIMORDIAL))
176 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
181 data->protection_domain,
184 data->new_class_data_len,
185 data->new_class_data);
189 case JVMTI_EVENT_CLASS_PREPARE:
190 case JVMTI_EVENT_CLASS_LOAD:
191 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
192 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
193 data->thread, data->klass);
196 case JVMTI_EVENT_VM_DEATH:
197 if (phase != JVMTI_PHASE_LIVE) return;
198 case JVMTI_EVENT_VM_START:
199 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
200 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
203 case JVMTI_EVENT_NATIVE_METHOD_BIND:
204 if ((phase == JVMTI_PHASE_START) ||
205 (phase == JVMTI_PHASE_LIVE) ||
206 (phase == JVMTI_PHASE_PRIMORDIAL))
207 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
211 data->new_address_ptr);
215 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
216 if ((phase == JVMTI_PHASE_START) ||
217 (phase == JVMTI_PHASE_LIVE) ||
218 (phase == JVMTI_PHASE_PRIMORDIAL))
219 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
228 if (phase != JVMTI_PHASE_LIVE) return;
230 case JVMTI_EVENT_EXCEPTION:
231 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
237 data->catch_location);
240 case JVMTI_EVENT_EXCEPTION_CATCH:
241 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
248 case JVMTI_EVENT_BREAKPOINT:
249 case JVMTI_EVENT_SINGLE_STEP:
250 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
256 case JVMTI_EVENT_FRAME_POP:
257 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
264 case JVMTI_EVENT_FIELD_ACCESS:
265 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
274 case JVMTI_EVENT_FIELD_MODIFICATION:
276 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
283 data->signature_type,
287 case JVMTI_EVENT_METHOD_ENTRY:
288 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
293 case JVMTI_EVENT_METHOD_EXIT:
294 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
301 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
302 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
311 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
312 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
317 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
318 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
319 case JVMTI_EVENT_DATA_DUMP_REQUEST:
320 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
323 case JVMTI_EVENT_MONITOR_WAIT:
324 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
330 case JVMTI_EVENT_MONITOR_WAITED:
331 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
338 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
339 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
340 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
345 case JVMTI_EVENT_OBJECT_FREE:
346 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
349 case JVMTI_EVENT_VM_OBJECT_ALLOC:
350 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
357 log_text ("unknown event");
364 /* dofireEvent ******************************************************************
366 sends event if it is enabled either globally or for some threads
368 *******************************************************************************/
369 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
371 jvmtiEventModeLL *evm;
376 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
377 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
378 /* test if the event is enable for some threads */
380 if (evm->mode == JVMTI_ENABLE) {
381 data->jvmti_env=&env->env;
382 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
383 execute_callback(e, ec, data);
387 } else { /* event enabled globally */
388 data->jvmti_env=&env->env;
389 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
390 execute_callback(e, ec, data);
398 /* fireEvent ******************************************************************
400 fire event callback with data arguments. This function mainly fills the
403 *******************************************************************************/
404 void jvmti_fireEvent(genericEventData* d) {
406 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
408 if (d->ev != JVMTI_EVENT_VM_START)
409 thread = jvmti_get_current_thread();
414 dofireEvent(d->ev,d);
418 /* SetEventNotificationMode ****************************************************
420 Control the generation of events
422 *******************************************************************************/
425 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
426 jvmtiEvent event_type, jthread event_thread, ...)
428 environment* cacao_env;
429 jvmtiEventModeLL *ll;
432 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
433 CHECK_PHASE(JVMTI_PHASE_LIVE)
436 if(event_thread != NULL) {
437 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
438 return JVMTI_ERROR_INVALID_THREAD;
439 CHECK_THREAD_IS_ALIVE(event_thread);
443 cacao_env = (environment*) env;
444 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
445 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
447 switch (event_type) { /* check capability and set system breakpoint */
448 case JVMTI_EVENT_EXCEPTION:
449 case JVMTI_EVENT_EXCEPTION_CATCH:
450 CHECK_CAPABILITY(env,can_generate_exception_events)
452 case JVMTI_EVENT_SINGLE_STEP:
453 CHECK_CAPABILITY(env,can_generate_single_step_events)
455 case JVMTI_EVENT_FRAME_POP:
456 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
458 case JVMTI_EVENT_BREAKPOINT:
459 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
461 case JVMTI_EVENT_FIELD_ACCESS:
462 CHECK_CAPABILITY(env,can_generate_field_access_events)
464 case JVMTI_EVENT_FIELD_MODIFICATION:
465 CHECK_CAPABILITY(env,can_generate_field_modification_events)
467 case JVMTI_EVENT_METHOD_ENTRY:
468 CHECK_CAPABILITY(env,can_generate_method_entry_events)
470 case JVMTI_EVENT_METHOD_EXIT:
471 CHECK_CAPABILITY(env, can_generate_method_exit_events)
473 case JVMTI_EVENT_NATIVE_METHOD_BIND:
474 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
476 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
477 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
478 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
480 case JVMTI_EVENT_MONITOR_WAIT:
481 case JVMTI_EVENT_MONITOR_WAITED:
482 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
483 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
484 CHECK_CAPABILITY(env,can_generate_monitor_events)
486 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
487 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
488 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
490 case JVMTI_EVENT_OBJECT_FREE:
491 CHECK_CAPABILITY(env,can_generate_object_free_events)
493 case JVMTI_EVENT_VM_OBJECT_ALLOC:
494 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
496 case JVMTI_EVENT_THREAD_START:
497 jvmti_set_system_breakpoint(THREADSTARTBRK, mode);
499 case JVMTI_EVENT_THREAD_END:
500 jvmti_set_system_breakpoint(THREADENDBRK, mode);
504 /* all other events are required */
505 if ((event_type < JVMTI_EVENT_START_ENUM) ||
506 (event_type > JVMTI_EVENT_END_ENUM))
507 return JVMTI_ERROR_INVALID_EVENT_TYPE;
511 if (event_thread != NULL) {
512 /* thread level control */
513 if ((JVMTI_EVENT_VM_INIT == mode) ||
514 (JVMTI_EVENT_VM_DEATH == mode) ||
515 (JVMTI_EVENT_VM_START == mode) ||
516 (JVMTI_EVENT_THREAD_START == mode) ||
517 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
518 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
519 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
520 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
521 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
522 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
523 while (ll->next != NULL) {
525 if (ll->event_thread == event_thread) {
527 return JVMTI_ERROR_NONE;
530 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
534 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
538 return JVMTI_ERROR_NONE;
541 /* GetAllThreads ***************************************************************
545 *******************************************************************************/
548 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
549 jthread ** threads_ptr)
551 threadobject** threads;
556 CHECK_PHASE(JVMTI_PHASE_LIVE)
559 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
560 return JVMTI_ERROR_NULL_POINTER;
562 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
563 if (retval != JVMTI_ERROR_NONE) return retval;
566 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
568 for (i=0; i<*threads_count_ptr; i++)
569 (*threads_ptr)[i] = threads[i]->o.thread;
571 return JVMTI_ERROR_NONE;
575 /* SuspendThread ***************************************************************
577 Suspend specified thread
579 *******************************************************************************/
582 SuspendThread (jvmtiEnv * env, jthread thread)
585 CHECK_PHASE(JVMTI_PHASE_LIVE)
587 CHECK_CAPABILITY(env,can_suspend);
589 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
590 if (!builtin_instanceof(thread,class_java_lang_Thread))
591 return JVMTI_ERROR_INVALID_THREAD;
592 CHECK_THREAD_IS_ALIVE(thread);
595 /* quick try - this should be changed in the future */
596 pthread_kill(((threadobject*)((java_lang_Thread*) thread)->vmThread)->tid,
600 return JVMTI_ERROR_NONE;
603 /* ResumeThread ***************************************************************
605 Resume a suspended thread
607 *******************************************************************************/
610 ResumeThread (jvmtiEnv * env, jthread thread)
613 CHECK_PHASE(JVMTI_PHASE_LIVE)
615 CHECK_CAPABILITY(env,can_suspend);
617 if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
618 if (!builtin_instanceof(thread,class_java_lang_Thread))
619 return JVMTI_ERROR_INVALID_THREAD;
620 CHECK_THREAD_IS_ALIVE(thread);
623 /* quick try - this should be changed in the future */
624 pthread_kill(((threadobject*)((java_lang_Thread*) thread)->vmThread)->tid,
627 return JVMTI_ERROR_NONE;
630 /* StopThread *****************************************************************
632 Send asynchronous exception to the specified thread. Similar to
633 java.lang.Thread.stop(). Used to kill thread.
635 *******************************************************************************/
638 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
641 CHECK_PHASE(JVMTI_PHASE_LIVE)
643 CHECK_CAPABILITY(env,can_signal_thread);
645 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
646 return JVMTI_ERROR_NOT_AVAILABLE;
648 return JVMTI_ERROR_NONE;
651 /* InterruptThread ************************************************************
653 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
655 *******************************************************************************/
658 InterruptThread (jvmtiEnv * env, jthread thread)
661 CHECK_PHASE(JVMTI_PHASE_LIVE)
663 CHECK_CAPABILITY(env,can_signal_thread)
665 #if defined(ENABLE_THREADS)
666 if(!builtin_instanceof(thread,class_java_lang_Thread))
667 return JVMTI_ERROR_INVALID_THREAD;
669 CHECK_THREAD_IS_ALIVE(thread);
671 threads_interrupt_thread(((java_lang_Thread*)thread)->vmThread);
674 return JVMTI_ERROR_NONE;
676 return JVMTI_ERROR_NOT_AVAILABLE;
680 /* GetThreadInfo ***************************************************************
682 Get thread information. Details of the specified thread are stored in the
683 jvmtiThreadInfo structure.
685 *******************************************************************************/
688 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
691 java_lang_Thread* th = (java_lang_Thread*)t;
695 CHECK_PHASE(JVMTI_PHASE_LIVE)
698 info_ptr->priority=(jint)th->priority;
699 info_ptr->is_daemon=(jboolean)th->daemon;
700 info_ptr->thread_group=(jthreadGroup)th->group;
701 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
703 name = javastring_toutf(th->name,false);
704 info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
705 utf_sprint_convert_to_latin1(info_ptr->name, name);
707 return JVMTI_ERROR_NONE;
710 /* GetOwnedMonitorInfo *********************************************************
712 Get information about the monitors owned by the specified thread
714 *******************************************************************************/
717 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
718 jint * owned_monitor_count_ptr,
719 jobject ** owned_monitors_ptr)
722 java_objectheader **om;
723 lock_record_pool_t* lrp;
726 log_text("GetOwnedMonitorInfo called");
729 CHECK_PHASE(JVMTI_PHASE_LIVE)
731 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
733 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
734 return JVMTI_ERROR_NULL_POINTER;
736 if (thread == NULL) {
737 t = jvmti_get_current_thread();
739 if(!builtin_instanceof(thread,class_java_lang_Thread))
740 return JVMTI_ERROR_INVALID_THREAD;
742 CHECK_THREAD_IS_ALIVE(thread);
743 t = (threadobject*) thread;
746 #if defined(ENABLE_THREADS)
748 om=MNEW(java_objectheader*,size);
750 pthread_mutex_lock(&lock_global_pool_lock);
751 lrp=lock_global_pool;
753 while (lrp != NULL) {
754 for (j=0; j<lrp->header.size; j++) {
755 /* if((lrp->lr[j].owner==t)&&
756 (!lrp->lr[j].waiting)) {
758 MREALLOC(om,java_objectheader*,size,size*2);
765 lrp=lrp->header.next;
768 pthread_mutex_unlock(&lock_global_pool_lock);
770 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
771 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
772 MFREE(om,java_objectheader*,size);
774 *owned_monitor_count_ptr = i;
778 return JVMTI_ERROR_NONE;
781 /* GetCurrentContendedMonitor *************************************************
783 Get the object the specified thread waits for.
785 *******************************************************************************/
788 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
789 jobject * monitor_ptr)
792 lock_record_pool_t* lrp;
793 java_objectheader* monitor;
796 CHECK_PHASE(JVMTI_PHASE_LIVE)
798 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
800 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
803 if(!builtin_instanceof(thread,class_java_lang_Thread))
804 return JVMTI_ERROR_INVALID_THREAD;
806 CHECK_THREAD_IS_ALIVE(thread);
809 #if defined(ENABLE_THREADS)
811 pthread_mutex_lock(&lock_global_pool_lock);
813 lrp=lock_global_pool;
815 while ((lrp != NULL)&&(monitor==NULL)) {
816 for (j=0; j<lrp->header.size; j++) {
817 /* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
818 monitor=lrp->lr[j].o;
822 lrp=lrp->header.next;
825 pthread_mutex_unlock(&lock_global_pool_lock);
828 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
829 *monitor_ptr = (jobject)monitor;
833 return JVMTI_ERROR_NONE;
837 jvmtiStartFunction sf;
843 static void *threadstartup(void *t) {
844 runagentparam *rap = (runagentparam*)t;
845 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
849 /* RunAgentThread *************************************************************
851 Starts the execution of an agent thread of the specified native function
852 within the specified thread
854 *******************************************************************************/
857 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
858 const void *arg, jint priority)
860 pthread_attr_t threadattr;
861 struct sched_param sp;
865 CHECK_PHASE(JVMTI_PHASE_LIVE)
868 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
869 return JVMTI_ERROR_INVALID_THREAD;
870 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
871 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
872 (priority > JVMTI_THREAD_MAX_PRIORITY))
873 return JVMTI_ERROR_INVALID_PRIORITY;
875 /* XXX: Threads started with this function should not be visible to
876 Java programming language queries but are included in JVM TI queries */
879 rap.arg = (void*)arg;
882 #if defined(ENABLE_THREADS)
883 pthread_attr_init(&threadattr);
884 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
885 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
886 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
888 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
889 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
891 pthread_attr_setschedparam(&threadattr,&sp);
892 if (pthread_create(&((threadobject*)
893 thread)->tid, &threadattr, &threadstartup, &rap)) {
894 log_text("pthread_create failed");
899 return JVMTI_ERROR_NONE;
903 /* GetTopThreadGroups *********************************************************
905 Get all top-level thread groups in the VM.
907 *******************************************************************************/
910 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
911 jthreadGroup ** groups_ptr)
913 jint threads_count_ptr;
914 threadobject *threads_ptr;
916 jthreadGroup **tg,*ttgp;
919 CHECK_PHASE(JVMTI_PHASE_LIVE)
922 log_text("GetTopThreadGroups called");
924 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
925 return JVMTI_ERROR_NULL_POINTER;
927 #if defined(ENABLE_THREADS)
928 tg = MNEW(jthreadGroup*,size);
930 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
931 return JVMTI_ERROR_INTERNAL;
933 for (i=0;i<threads_count_ptr;i++){
934 if (threads_ptr[i].o.thread->group == NULL) {
935 log_text("threadgroup not set");
936 return JVMTI_ERROR_INTERNAL;
938 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
941 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
946 MREALLOC(tg,jthreadGroup*,size,size*2);
955 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
956 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
957 MFREE(tg,jthreadGroup*,size);
959 *group_count_ptr = x;
962 return JVMTI_ERROR_NOT_AVAILABLE;
964 return JVMTI_ERROR_NONE;
968 /* GetThreadGroupInfo *********************************************************
970 Get information about the specified thread group.
972 *******************************************************************************/
975 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
976 jvmtiThreadGroupInfo * info_ptr)
980 java_lang_ThreadGroup* grp;
983 CHECK_PHASE(JVMTI_PHASE_LIVE)
986 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
987 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
988 return JVMTI_ERROR_INVALID_THREAD_GROUP;
990 grp = (java_lang_ThreadGroup*)group;
992 info_ptr->parent = (jthreadGroup)
993 Java_java_lang_VMObject_clone(NULL,
994 (jclass)grp->header.vftbl->class,
995 (java_lang_Cloneable*) &grp->parent);
997 name = javastring_tochar((java_objectheader*)grp->name);
999 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
1000 strncpy(info_ptr->name,name,size);
1001 info_ptr->max_priority= (jint)grp->maxpri;
1002 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
1004 return JVMTI_ERROR_NONE;
1008 /* GetThreadGroupChildren *****************************************************
1010 Get the live threads and active subgroups in this thread group.
1012 *******************************************************************************/
1015 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1016 jint * thread_count_ptr, jthread ** threads_ptr,
1017 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1019 java_lang_ThreadGroup* tgp;
1022 CHECK_PHASE(JVMTI_PHASE_LIVE)
1025 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1026 (group_count_ptr == NULL) || (groups_ptr == NULL))
1027 return JVMTI_ERROR_NULL_POINTER;
1029 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1030 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1032 tgp = (java_lang_ThreadGroup*)group;
1034 *thread_count_ptr = (jint)tgp->threads->elementCount;
1037 heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
1039 memcpy(*threads_ptr, &tgp->threads->elementData,
1040 (*thread_count_ptr)*sizeof(java_objectarray*));
1042 *group_count_ptr = (jint) tgp->groups->elementCount;
1045 heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
1047 memcpy(*groups_ptr, &tgp->threads->elementData,
1048 (*group_count_ptr)*sizeof(jthreadGroup*));
1050 return JVMTI_ERROR_NONE;
1054 /* getcacaostacktrace *********************************************************
1056 Helper function that retrives stack trace for specified thread.
1057 Has to take care of suspend/resume issuses
1059 *******************************************************************************/
1060 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1064 t = jvmti_get_current_thread();
1066 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1067 if (t != jvmti_get_current_thread())
1068 /* XXX: todo: take care that the requested thread is in a
1069 safe state - this needs a working thread suspend */
1070 return JVMTI_ERROR_INTERNAL;
1073 *trace = stacktrace_create(t);
1075 return JVMTI_ERROR_NONE;
1079 /* GetFrameCount **************************************************************
1082 Get the number of frames in the specified thread's stack.
1084 *******************************************************************************/
1087 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1089 stacktracebuffer* trace;
1093 CHECK_PHASE(JVMTI_PHASE_LIVE)
1096 if (thread != NULL){
1097 if(!builtin_instanceof(thread,class_java_lang_Thread))
1098 return JVMTI_ERROR_INVALID_THREAD;
1100 CHECK_THREAD_IS_ALIVE(thread);
1103 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1105 er = getcacaostacktrace(&trace, thread);
1106 if (er==JVMTI_ERROR_NONE) {
1111 *count_ptr = trace->used;
1114 return JVMTI_ERROR_NONE;
1118 /* GetThreadState **************************************************************
1120 Get the state of a thread.
1122 *******************************************************************************/
1125 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1127 java_lang_Thread* th = (java_lang_Thread*)thread;
1128 threadobject* t = (threadobject*)th->vmThread;
1131 CHECK_PHASE(JVMTI_PHASE_LIVE)
1134 if(!builtin_instanceof(thread,class_java_lang_Thread))
1135 return JVMTI_ERROR_INVALID_THREAD;
1137 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1139 *thread_state_ptr = 0;
1140 #if defined(ENABLE_THREADS)
1141 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1143 if (((threadobject*)th->vmThread)->tid == 0)
1144 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1147 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1148 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1149 /* XXX todo - info not available */
1150 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1151 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1152 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1153 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1154 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1155 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1156 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1157 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1158 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1159 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1162 return JVMTI_ERROR_INTERNAL;
1165 return JVMTI_ERROR_NONE;
1169 /* GetFrameLocation ************************************************************
1171 Get the location of the instruction currently executing
1173 *******************************************************************************/
1176 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1177 jmethodID * method_ptr, jlocation * location_ptr)
1179 stackframeinfo *sfi;
1184 CHECK_PHASE(JVMTI_PHASE_LIVE)
1187 if (thread == NULL) {
1188 th = jvmti_get_current_thread();
1190 if(!builtin_instanceof(thread,class_java_lang_Thread))
1191 return JVMTI_ERROR_INVALID_THREAD;
1193 CHECK_THREAD_IS_ALIVE(thread);
1194 th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
1197 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1199 if ((method_ptr == NULL)&&(location_ptr == NULL))
1200 return JVMTI_ERROR_NULL_POINTER;
1202 sfi = th->_stackframeinfo;
1205 while ((sfi != NULL) && (i<depth)) {
1210 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1212 *method_ptr=(jmethodID)sfi->method;
1213 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1215 return JVMTI_ERROR_NONE;
1219 /* NotifyFramePop *************************************************************
1223 *******************************************************************************/
1226 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1229 CHECK_PHASE(JVMTI_PHASE_LIVE)
1231 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1233 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1234 return JVMTI_ERROR_NONE;
1237 /* GetLocalObject *************************************************************
1241 *******************************************************************************/
1244 GetLocalObject (jvmtiEnv * env,
1245 jthread thread, jint depth, jint slot, jobject * value_ptr)
1248 CHECK_PHASE(JVMTI_PHASE_LIVE)
1250 CHECK_CAPABILITY(env,can_access_local_variables)
1252 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1253 return JVMTI_ERROR_NONE;
1256 /* GetLocalInt ****************************************************************
1260 *******************************************************************************/
1263 GetLocalInt (jvmtiEnv * env,
1264 jthread thread, jint depth, jint slot, jint * value_ptr)
1267 CHECK_PHASE(JVMTI_PHASE_LIVE)
1269 CHECK_CAPABILITY(env,can_access_local_variables)
1270 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1271 return JVMTI_ERROR_NONE;
1274 /* *****************************************************************************
1278 *******************************************************************************/
1281 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1285 CHECK_PHASE(JVMTI_PHASE_LIVE)
1287 CHECK_CAPABILITY(env,can_access_local_variables)
1289 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1290 return JVMTI_ERROR_NONE;
1294 /* *****************************************************************************
1298 *******************************************************************************/
1301 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1305 CHECK_PHASE(JVMTI_PHASE_LIVE)
1307 CHECK_CAPABILITY(env,can_access_local_variables)
1309 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1310 return JVMTI_ERROR_NONE;
1314 /* *****************************************************************************
1318 *******************************************************************************/
1321 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1322 jdouble * value_ptr)
1325 CHECK_PHASE(JVMTI_PHASE_LIVE)
1327 CHECK_CAPABILITY(env,can_access_local_variables)
1329 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1330 return JVMTI_ERROR_NONE;
1334 /* *****************************************************************************
1338 *******************************************************************************/
1341 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1345 CHECK_PHASE(JVMTI_PHASE_LIVE)
1347 CHECK_CAPABILITY(env,can_access_local_variables)
1349 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1350 return JVMTI_ERROR_NONE;
1354 /* *****************************************************************************
1358 *******************************************************************************/
1361 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1365 CHECK_PHASE(JVMTI_PHASE_LIVE)
1367 CHECK_CAPABILITY(env,can_access_local_variables)
1369 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1370 return JVMTI_ERROR_NONE;
1374 /* *****************************************************************************
1378 *******************************************************************************/
1381 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1385 CHECK_PHASE(JVMTI_PHASE_LIVE)
1387 CHECK_CAPABILITY(env,can_access_local_variables)
1389 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1390 return JVMTI_ERROR_NONE;
1394 /* *****************************************************************************
1398 *******************************************************************************/
1401 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1405 CHECK_PHASE(JVMTI_PHASE_LIVE)
1407 CHECK_CAPABILITY(env,can_access_local_variables)
1409 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1410 return JVMTI_ERROR_NONE;
1414 /* *****************************************************************************
1418 *******************************************************************************/
1421 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1425 CHECK_PHASE(JVMTI_PHASE_LIVE)
1427 CHECK_CAPABILITY(env,can_access_local_variables)
1429 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1430 return JVMTI_ERROR_NONE;
1434 /* CreateRawMonitor ***********************************************************
1436 This function creates a new raw monitor.
1438 *******************************************************************************/
1441 CreateRawMonitor (jvmtiEnv * env, const char *name,
1442 jrawMonitorID * monitor_ptr)
1444 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1447 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1448 CHECK_PHASE(JVMTI_PHASE_LIVE)
1451 if ((name == NULL) || (monitor_ptr == NULL))
1452 return JVMTI_ERROR_NULL_POINTER;
1454 #if defined(ENABLE_THREADS)
1455 monitor->name=javastring_new_from_ascii(name);
1457 log_text ("CreateRawMonitor not supported");
1460 return JVMTI_ERROR_NONE;
1464 /* DestroyRawMonitor **********************************************************
1466 This function destroys a raw monitor.
1468 *******************************************************************************/
1471 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1474 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1475 CHECK_PHASE(JVMTI_PHASE_LIVE)
1478 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1479 return JVMTI_ERROR_INVALID_MONITOR;
1481 #if defined(ENABLE_THREADS)
1482 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1483 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1485 lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1489 log_text ("DestroyRawMonitor not supported");
1492 return JVMTI_ERROR_NONE;
1496 /* RawMonitorEnter ************************************************************
1498 Gain exclusive ownership of a raw monitor
1500 *******************************************************************************/
1503 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1505 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1506 return JVMTI_ERROR_INVALID_MONITOR;
1508 #if defined(ENABLE_THREADS)
1509 builtin_monitorenter((java_objectheader*)monitor->name);
1511 log_text ("RawMonitorEnter not supported");
1514 return JVMTI_ERROR_NONE;
1518 /* RawMonitorExit *************************************************************
1522 *******************************************************************************/
1525 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1527 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1528 return JVMTI_ERROR_INVALID_MONITOR;
1530 #if defined(ENABLE_THREADS)
1531 /* assure current thread owns this monitor */
1532 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1533 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1535 builtin_monitorexit((java_objectheader*)monitor->name);
1537 log_text ("RawMonitorExit not supported");
1540 return JVMTI_ERROR_NONE;
1544 /* RawMonitorWait *************************************************************
1546 Wait for notification of the raw monitor.
1548 *******************************************************************************/
1551 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1553 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1554 return JVMTI_ERROR_INVALID_MONITOR;
1556 #if defined(ENABLE_THREADS)
1557 /* assure current thread owns this monitor */
1558 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1559 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1561 lock_wait_for_object(&monitor->name->header, millis,0);
1562 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1563 return JVMTI_ERROR_INTERRUPT;
1566 log_text ("RawMonitorWait not supported");
1569 return JVMTI_ERROR_NONE;
1573 /* RawMonitorNotify ***********************************************************
1575 Notify one thread waiting on the given monitor.
1577 *******************************************************************************/
1580 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1582 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1583 return JVMTI_ERROR_INVALID_MONITOR;
1585 #if defined(ENABLE_THREADS)
1586 /* assure current thread owns this monitor */
1587 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1588 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1590 lock_notify_object((java_objectheader*)&monitor->name);
1592 log_text ("RawMonitorNotify not supported");
1595 return JVMTI_ERROR_NONE;
1599 /* RawMonitorNotifyAll *********************************************************
1601 Notify all threads waiting on the given monitor.
1603 *******************************************************************************/
1606 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1608 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1609 return JVMTI_ERROR_INVALID_MONITOR;
1611 #if defined(ENABLE_THREADS)
1612 /* assure current thread owns this monitor */
1613 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1614 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1616 lock_notify_all_object((java_objectheader*)&monitor->name);
1618 log_text ("RawMonitorNotifyAll not supported");
1621 return JVMTI_ERROR_NONE;
1625 /* SetBreakpoint **************************************************************
1629 *******************************************************************************/
1632 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1635 CHECK_PHASE(JVMTI_PHASE_LIVE)
1637 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1640 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1641 return JVMTI_ERROR_NONE;
1645 /* *****************************************************************************
1649 *******************************************************************************/
1652 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1655 CHECK_PHASE(JVMTI_PHASE_LIVE)
1657 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1659 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1660 return JVMTI_ERROR_NONE;
1664 /* SetFieldAccessWatch ********************************************************
1668 *******************************************************************************/
1671 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1674 CHECK_PHASE(JVMTI_PHASE_LIVE)
1676 CHECK_CAPABILITY(env,can_generate_field_access_events)
1678 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1679 return JVMTI_ERROR_NONE;
1683 /* *****************************************************************************
1687 *******************************************************************************/
1690 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1693 CHECK_PHASE(JVMTI_PHASE_LIVE)
1695 CHECK_CAPABILITY(env,can_generate_field_access_events)
1697 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1698 return JVMTI_ERROR_NONE;
1702 /* *****************************************************************************
1706 *******************************************************************************/
1709 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1712 CHECK_PHASE(JVMTI_PHASE_LIVE)
1714 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1716 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1717 return JVMTI_ERROR_NONE;
1721 /* *****************************************************************************
1725 *******************************************************************************/
1728 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1731 CHECK_PHASE(JVMTI_PHASE_LIVE)
1733 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1735 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1736 return JVMTI_ERROR_NONE;
1740 /* Allocate ********************************************************************
1742 Allocate an area of memory through the JVM TI allocator. The allocated
1743 memory should be freed with Deallocate
1745 *******************************************************************************/
1748 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1751 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1752 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1754 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1755 if (*mem_ptr == NULL)
1756 return JVMTI_ERROR_OUT_OF_MEMORY;
1758 return JVMTI_ERROR_NONE;
1763 /* Deallocate ******************************************************************
1765 Deallocate mem using the JVM TI allocator.
1767 *******************************************************************************/
1770 Deallocate (jvmtiEnv * env, unsigned char *mem)
1772 /* let Boehm GC do the job */
1774 return JVMTI_ERROR_NONE;
1778 /* GetClassSignature ************************************************************
1780 For the class indicated by klass, return the JNI type signature and the
1781 generic signature of the class.
1783 *******************************************************************************/
1786 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1790 CHECK_PHASE(JVMTI_PHASE_START)
1791 CHECK_PHASE(JVMTI_PHASE_LIVE)
1794 if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
1795 if (!builtin_instanceof(klass,class_java_lang_Class))
1796 return JVMTI_ERROR_INVALID_CLASS;
1798 if (signature_ptr != NULL) {
1799 *signature_ptr = (char*)
1800 heap_allocate(sizeof(char) *
1801 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
1803 utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
1806 if (generic_ptr!= NULL)
1807 *generic_ptr = NULL;
1809 return JVMTI_ERROR_NONE;
1812 /* GetClassStatus *************************************************************
1814 Get status of the class.
1816 *******************************************************************************/
1819 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1823 CHECK_PHASE(JVMTI_PHASE_START)
1824 CHECK_PHASE(JVMTI_PHASE_LIVE)
1827 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1828 return JVMTI_ERROR_INVALID_CLASS;
1830 if (status_ptr == NULL)
1831 return JVMTI_ERROR_NULL_POINTER;
1833 c = (classinfo*)klass;
1836 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1837 if (c->state & CLASS_LINKED)
1838 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1840 if (c->state & CLASS_INITIALIZED)
1841 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1843 if (c->state & CLASS_ERROR)
1844 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1846 if (c->vftbl->arraydesc != NULL)
1847 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1849 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1850 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1852 return JVMTI_ERROR_NONE;
1856 /* GetSourceFileName **********************************************************
1858 For the class indicated by klass, return the source file name.
1860 *******************************************************************************/
1863 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1868 CHECK_PHASE(JVMTI_PHASE_START)
1869 CHECK_PHASE(JVMTI_PHASE_LIVE)
1871 CHECK_CAPABILITY(env,can_get_source_file_name)
1873 if ((klass == NULL)||(source_name_ptr == NULL))
1874 return JVMTI_ERROR_NULL_POINTER;
1876 size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
1878 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1880 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1881 (*source_name_ptr)[size]='\0';
1883 return JVMTI_ERROR_NONE;
1887 /* GetClassModifiers **********************************************************
1889 For class klass return the access flags
1891 *******************************************************************************/
1894 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1897 CHECK_PHASE(JVMTI_PHASE_START)
1898 CHECK_PHASE(JVMTI_PHASE_LIVE)
1901 if (modifiers_ptr == NULL)
1902 return JVMTI_ERROR_NULL_POINTER;
1904 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1905 return JVMTI_ERROR_INVALID_CLASS;
1907 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1909 return JVMTI_ERROR_NONE;
1913 /* GetClassMethods *************************************************************
1915 For class klass return a count of methods and a list of method IDs
1917 *******************************************************************************/
1920 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1921 jmethodID ** methods_ptr)
1926 CHECK_PHASE(JVMTI_PHASE_START)
1927 CHECK_PHASE(JVMTI_PHASE_LIVE)
1930 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1931 return JVMTI_ERROR_NULL_POINTER;
1933 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1934 return JVMTI_ERROR_INVALID_CLASS;
1936 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1937 *methods_ptr = (jmethodID*)
1938 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1940 for (i=0; i<*method_count_ptr;i++)
1941 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1943 return JVMTI_ERROR_NONE;
1947 /* GetClassFields *************************************************************
1949 For the class indicated by klass, return a count of fields and a list of
1952 *******************************************************************************/
1955 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1956 jfieldID ** fields_ptr)
1959 CHECK_PHASE(JVMTI_PHASE_START)
1960 CHECK_PHASE(JVMTI_PHASE_LIVE)
1963 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1964 return JVMTI_ERROR_NULL_POINTER;
1966 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1967 *fields_ptr = (jfieldID*)
1968 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1970 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1971 sizeof(jfieldID) * (*field_count_ptr));
1973 return JVMTI_ERROR_NONE;
1977 /* GetImplementedInterfaces ***************************************************
1979 Return the direct super-interfaces of this class.
1981 *******************************************************************************/
1984 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1985 jint * interface_count_ptr,
1986 jclass ** interfaces_ptr)
1989 classref_or_classinfo *interfaces;
1993 CHECK_PHASE(JVMTI_PHASE_START)
1994 CHECK_PHASE(JVMTI_PHASE_LIVE)
1997 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1998 return JVMTI_ERROR_NULL_POINTER;
2000 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
2001 return JVMTI_ERROR_INVALID_CLASS;
2004 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
2006 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
2008 interfaces = ((classinfo*)klass)->interfaces;
2009 for (i=0; i<*interface_count_ptr; i++) {
2010 if (IS_CLASSREF(interfaces[i]))
2011 tmp = load_class_bootstrap(interfaces[i].ref->name);
2013 tmp = interfaces[i].cls;
2015 *interfaces_ptr[i]=tmp;
2018 return JVMTI_ERROR_NONE;
2022 /* IsInterface ****************************************************************
2024 Determines whether a class object reference represents an interface.
2026 *******************************************************************************/
2029 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2032 CHECK_PHASE(JVMTI_PHASE_START)
2033 CHECK_PHASE(JVMTI_PHASE_LIVE)
2036 if ((klass == NULL)||(is_interface_ptr == NULL))
2037 return JVMTI_ERROR_NULL_POINTER;
2039 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2041 return JVMTI_ERROR_NONE;
2044 /* IsArrayClass ***************************************************************
2046 Determines whether a class object reference represents an array.
2048 *******************************************************************************/
2051 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2054 CHECK_PHASE(JVMTI_PHASE_START)
2055 CHECK_PHASE(JVMTI_PHASE_LIVE)
2058 if (is_array_class_ptr == NULL)
2059 return JVMTI_ERROR_NULL_POINTER;
2061 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2063 return JVMTI_ERROR_NONE;
2067 /* GetClassLoader *************************************************************
2069 For the class indicated by klass, return via classloader_ptr a reference to
2070 the class loader for the class.
2072 *******************************************************************************/
2075 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2078 CHECK_PHASE(JVMTI_PHASE_START)
2079 CHECK_PHASE(JVMTI_PHASE_LIVE)
2082 if ((klass == NULL)||(classloader_ptr == NULL))
2083 return JVMTI_ERROR_NULL_POINTER;
2085 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2087 return JVMTI_ERROR_NONE;
2091 /* GetObjectHashCode **********************************************************
2093 Return hash code for object object
2095 *******************************************************************************/
2098 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2101 CHECK_PHASE(JVMTI_PHASE_START)
2102 CHECK_PHASE(JVMTI_PHASE_LIVE)
2105 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2106 if (!builtin_instanceof(object,class_java_lang_Object))
2107 return JVMTI_ERROR_INVALID_OBJECT;
2109 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2111 return JVMTI_ERROR_NONE;
2115 /* *****************************************************************************
2119 *******************************************************************************/
2122 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2123 jvmtiMonitorUsage * info_ptr)
2126 CHECK_PHASE(JVMTI_PHASE_LIVE)
2128 CHECK_CAPABILITY(env,can_get_monitor_info)
2130 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2131 return JVMTI_ERROR_NONE;
2135 /* GetFieldName ***************************************************************
2137 For the field indicated by klass and field, return the field name and
2140 *******************************************************************************/
2143 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2144 char **name_ptr, char **signature_ptr, char **generic_ptr)
2149 CHECK_PHASE(JVMTI_PHASE_START)
2150 CHECK_PHASE(JVMTI_PHASE_LIVE)
2154 return JVMTI_ERROR_INVALID_CLASS;
2156 if (!builtin_instanceof(klass,class_java_lang_Class))
2157 return JVMTI_ERROR_INVALID_CLASS;
2158 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2160 if (name_ptr != NULL) {
2161 size = utf_bytes(((fieldinfo*)field)->name)+1;
2162 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2163 utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
2166 if (signature_ptr != NULL) {
2167 size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
2168 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2169 utf_sprint_convert_to_latin1(*signature_ptr,
2170 ((fieldinfo*)field)->descriptor);
2173 if (generic_ptr != NULL)
2174 *generic_ptr = NULL;
2176 return JVMTI_ERROR_NONE;
2180 /* GetFieldDeclaringClass *****************************************************
2182 For the field indicated by klass and field return the class that defined it
2183 The declaring class will either be klass, a superclass, or an implemented
2186 *******************************************************************************/
2189 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2190 jclass * declaring_class_ptr)
2193 CHECK_PHASE(JVMTI_PHASE_START)
2194 CHECK_PHASE(JVMTI_PHASE_LIVE)
2198 return JVMTI_ERROR_INVALID_CLASS;
2200 if (!builtin_instanceof(klass,class_java_lang_Class))
2201 return JVMTI_ERROR_INVALID_CLASS;
2203 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2205 if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2207 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2209 return JVMTI_ERROR_NONE;
2213 /* GetFieldModifiers **********************************************************
2215 Return access flags of field field
2217 *******************************************************************************/
2220 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2221 jint * modifiers_ptr)
2224 CHECK_PHASE(JVMTI_PHASE_START)
2225 CHECK_PHASE(JVMTI_PHASE_LIVE)
2229 return JVMTI_ERROR_INVALID_CLASS;
2231 if (!builtin_instanceof(klass,class_java_lang_Class))
2232 return JVMTI_ERROR_INVALID_CLASS;
2234 if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
2236 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2238 *modifiers_ptr = ((fieldinfo*)field)->flags;
2240 return JVMTI_ERROR_NONE;
2244 /* IsFieldSynthetic ***********************************************************
2248 *******************************************************************************/
2251 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2252 jboolean * is_synthetic_ptr)
2255 CHECK_PHASE(JVMTI_PHASE_START)
2256 CHECK_PHASE(JVMTI_PHASE_LIVE)
2258 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2260 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2261 return JVMTI_ERROR_NONE;
2265 /* GetMethodName ***************************************************************
2267 For the method indicated by method, return the method name via name_ptr and
2268 method signature via signature_ptr.
2270 *******************************************************************************/
2273 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2274 char **signature_ptr, char **generic_ptr)
2276 methodinfo* m = (methodinfo*)method;
2279 CHECK_PHASE(JVMTI_PHASE_START)
2280 CHECK_PHASE(JVMTI_PHASE_LIVE)
2284 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2286 if (name_ptr != NULL) {
2288 heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
2289 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2292 if (signature_ptr != NULL) {
2293 *signature_ptr = (char*)
2294 heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
2295 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2298 if (generic_ptr != NULL) {
2299 /* there is no generic signature attribute */
2300 *generic_ptr = NULL;
2303 return JVMTI_ERROR_NONE;
2307 /* GetMethodDeclaringClass *****************************************************
2309 For the method indicated by method, return the class that defined it.
2311 *******************************************************************************/
2314 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2315 jclass * declaring_class_ptr)
2318 CHECK_PHASE(JVMTI_PHASE_START)
2319 CHECK_PHASE(JVMTI_PHASE_LIVE)
2322 if ((method == NULL) || (declaring_class_ptr == NULL))
2323 return JVMTI_ERROR_NULL_POINTER;
2325 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2327 return JVMTI_ERROR_NONE;
2331 /* GetMethodModifiers **********************************************************
2333 For the method indicated by method, return the access flags.
2335 *******************************************************************************/
2338 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2341 CHECK_PHASE(JVMTI_PHASE_START)
2342 CHECK_PHASE(JVMTI_PHASE_LIVE)
2345 if ((method == NULL) || (modifiers_ptr == NULL))
2346 return JVMTI_ERROR_NULL_POINTER;
2348 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2350 return JVMTI_ERROR_NONE;
2354 /* GetMaxLocals ****************************************************************
2356 For the method indicated by method, return the number of local variable slots
2357 used by the method, including the local variables used to pass parameters to
2358 the method on its invocation.
2360 *******************************************************************************/
2363 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2366 CHECK_PHASE(JVMTI_PHASE_START)
2367 CHECK_PHASE(JVMTI_PHASE_LIVE)
2370 if ((method == NULL)||(max_ptr == NULL))
2371 return JVMTI_ERROR_NULL_POINTER;
2373 if (((methodinfo*)method)->flags & ACC_NATIVE)
2374 return JVMTI_ERROR_NATIVE_METHOD;
2376 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2378 return JVMTI_ERROR_NONE;
2383 /* GetArgumentsSize ************************************************************
2385 Return the number of local variable slots used by the method's arguments.
2387 *******************************************************************************/
2390 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2393 CHECK_PHASE(JVMTI_PHASE_START)
2394 CHECK_PHASE(JVMTI_PHASE_LIVE)
2397 if ((method == NULL)||(size_ptr == NULL))
2398 return JVMTI_ERROR_NULL_POINTER;
2400 if (((methodinfo*)method)->flags & ACC_NATIVE)
2401 return JVMTI_ERROR_NATIVE_METHOD;
2403 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2404 return JVMTI_ERROR_NONE;
2409 /* GetLineNumberTable ***********************************************************
2411 Return table of source line number entries for a given method
2413 *******************************************************************************/
2416 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2417 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2422 CHECK_PHASE(JVMTI_PHASE_START)
2423 CHECK_PHASE(JVMTI_PHASE_LIVE)
2425 CHECK_CAPABILITY(env,can_get_line_numbers)
2427 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2428 return JVMTI_ERROR_NULL_POINTER;
2429 if (((methodinfo*)method)->flags & ACC_NATIVE)
2430 return JVMTI_ERROR_NATIVE_METHOD;
2431 if (((methodinfo*)method)->linenumbers == NULL)
2432 return JVMTI_ERROR_ABSENT_INFORMATION;
2434 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2435 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2436 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2439 for (i=0; i < *entry_count_ptr; i++) {
2440 (*table_ptr)[i].start_location =
2441 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2442 (*table_ptr)[i].line_number =
2443 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2446 return JVMTI_ERROR_NONE;
2450 /* GetMethodLocation ***********************************************************
2452 For the method indicated by method, return the beginning and ending addresses
2453 through start_location_ptr and end_location_ptr. In cacao this points to
2454 entry point in machine code and length of machine code
2456 *******************************************************************************/
2459 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2460 jlocation * start_location_ptr,
2461 jlocation * end_location_ptr)
2463 methodinfo* m = (methodinfo*)method;
2466 CHECK_PHASE(JVMTI_PHASE_START)
2467 CHECK_PHASE(JVMTI_PHASE_LIVE)
2470 if ((method == NULL) || (start_location_ptr == NULL) ||
2471 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2473 /* XXX we return the location of the most recent code. Don't know
2474 * if there is a way to teach jvmti that a method can have more
2475 * than one location. -Edwin */
2477 /* XXX Don't know if that's the right way to deal with not-yet-
2478 * compiled methods. -Edwin */
2480 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2483 return JVMTI_ERROR_INTERNAL;
2485 *start_location_ptr = (jlocation)m->code->mcode;
2486 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2487 return JVMTI_ERROR_NONE;
2491 /* GetLocalVariableTable *******************************************************
2493 Return local variable information.
2495 *******************************************************************************/
2498 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2499 jint * entry_count_ptr,
2500 jvmtiLocalVariableEntry ** table_ptr)
2503 CHECK_PHASE(JVMTI_PHASE_LIVE)
2505 CHECK_CAPABILITY(env,can_access_local_variables)
2507 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2509 return JVMTI_ERROR_NONE;
2513 /* GetBytecode *****************************************************************
2515 For the method indicated by method, return the byte codes that implement the
2518 *******************************************************************************/
2521 GetBytecodes (jvmtiEnv * env, jmethodID method,
2522 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2524 methodinfo* m = (methodinfo*)method;;
2527 CHECK_PHASE(JVMTI_PHASE_START)
2528 CHECK_PHASE(JVMTI_PHASE_LIVE)
2530 CHECK_CAPABILITY(env,can_get_bytecodes)
2532 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2533 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2535 *bytecode_count_ptr = m->jcodelength;
2536 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2537 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2539 return JVMTI_ERROR_NONE;
2543 /* IsMethodNative **************************************************************
2545 For the method indicated by method, return a value indicating whether the
2546 method is a native function
2548 *******************************************************************************/
2551 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2554 CHECK_PHASE(JVMTI_PHASE_START)
2555 CHECK_PHASE(JVMTI_PHASE_LIVE)
2558 if ((method == NULL)||(is_native_ptr == NULL))
2559 return JVMTI_ERROR_NULL_POINTER;
2561 if (((methodinfo*)method)->flags & ACC_NATIVE)
2562 *is_native_ptr = JNI_TRUE;
2564 *is_native_ptr = JNI_FALSE;
2566 return JVMTI_ERROR_NONE;
2570 /* IsMethodSynthetic ***********************************************************
2572 return a value indicating whether the method is synthetic. Synthetic methods
2573 are generated by the compiler but not present in the original source code.
2575 *******************************************************************************/
2578 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2579 jboolean * is_synthetic_ptr)
2582 CHECK_PHASE(JVMTI_PHASE_START)
2583 CHECK_PHASE(JVMTI_PHASE_LIVE)
2585 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2587 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2588 return JVMTI_ERROR_NONE;
2592 /* GetLoadedClasses ************************************************************
2594 Return an array of all classes loaded in the virtual machine.
2596 *******************************************************************************/
2599 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2602 classcache_name_entry *nameentry;
2603 classcache_class_entry *classentry;
2606 CHECK_PHASE(JVMTI_PHASE_LIVE)
2609 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2610 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2614 heap_allocate(sizeof(jclass)*(hashtable_classcache.entries),true,NULL);
2616 /* look in every slot of the hashtable */
2617 for (i=0; i<hashtable_classcache.size; i++) {
2618 nameentry = hashtable_classcache.ptr[i];
2619 while (nameentry != NULL) { /* iterate over hashlink */
2621 /* filter pseudo classes $NEW$,$NULL$,$ARRAYSTUB$ out */
2622 if (nameentry->name->text[0]=='$')
2624 *class_count_ptr -= 1;
2628 classentry = nameentry->classes;
2629 while (classentry != NULL){ /* iterate over classes with same name */
2630 if (classentry->classobj != NULL) { /*get only loaded classes */
2631 assert(j<hashtable_classcache.entries);
2632 (*classes_ptr)[j]=classentry->classobj;
2635 classentry = classentry->next;
2637 nameentry = nameentry->hashlink;
2641 CLASSCACHE_UNLOCK();
2643 *class_count_ptr = j;
2645 return JVMTI_ERROR_NONE;
2649 /* GetClassLoaderClasses *******************************************************
2651 Returns an array of those classes for which this class loader has been
2652 recorded as an initiating loader.
2654 *******************************************************************************/
2657 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2658 jint * class_count_ptr, jclass ** classes_ptr)
2660 log_text("GetClassLoaderClasses called");
2663 CHECK_PHASE(JVMTI_PHASE_LIVE)
2666 if ((class_count_ptr == NULL) || (classes_ptr == NULL))
2667 return JVMTI_ERROR_NULL_POINTER;
2669 /* behave like jdk 1.1 and make no distinction between initiating and
2670 defining class loaders */
2672 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2676 /* PopFrame *******************************************************************
2680 *******************************************************************************/
2683 PopFrame (jvmtiEnv * env, jthread thread)
2686 CHECK_PHASE(JVMTI_PHASE_LIVE)
2688 CHECK_CAPABILITY(env,can_pop_frame)
2690 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2691 return JVMTI_ERROR_NONE;
2695 /* RedefineClasses ************************************************************
2699 *******************************************************************************/
2702 RedefineClasses (jvmtiEnv * env, jint class_count,
2703 const jvmtiClassDefinition * class_definitions)
2706 CHECK_PHASE(JVMTI_PHASE_START)
2707 CHECK_PHASE(JVMTI_PHASE_LIVE)
2709 CHECK_CAPABILITY(env,can_redefine_classes)
2710 CHECK_CAPABILITY(env,can_redefine_any_class)
2712 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2713 return JVMTI_ERROR_NONE;
2717 /* GetVersionNumber ***********************************************************
2719 Return the JVM TI version identifier.
2721 *******************************************************************************/
2724 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2726 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2728 *version_ptr = JVMTI_VERSION;
2730 return JVMTI_ERROR_NONE;
2734 /* GetCapabilities ************************************************************
2736 Returns the optional JVM TI features which this environment currently
2739 *******************************************************************************/
2742 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2744 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2746 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2748 return JVMTI_ERROR_NONE;
2752 /* *****************************************************************************
2756 *******************************************************************************/
2759 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2760 char **source_debug_extension_ptr)
2763 CHECK_PHASE(JVMTI_PHASE_START)
2764 CHECK_PHASE(JVMTI_PHASE_LIVE)
2766 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2768 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2769 return JVMTI_ERROR_NONE;
2773 /* IsMethodObsolete ************************************************************
2775 Determine if a method ID refers to an obsolete method version.
2777 *******************************************************************************/
2780 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2781 jboolean * is_obsolete_ptr)
2784 CHECK_PHASE(JVMTI_PHASE_START)
2785 CHECK_PHASE(JVMTI_PHASE_LIVE)
2787 CHECK_CAPABILITY(env,can_redefine_classes)
2789 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2790 return JVMTI_ERROR_NONE;
2794 /* SuspendThreadList **********************************************************
2796 Suspend all threads in the request list.
2798 *******************************************************************************/
2801 SuspendThreadList (jvmtiEnv * env, jint request_count,
2802 const jthread * request_list, jvmtiError * results)
2809 CHECK_PHASE(JVMTI_PHASE_START)
2810 CHECK_PHASE(JVMTI_PHASE_LIVE)
2812 CHECK_CAPABILITY(env,can_suspend);
2814 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2815 if ((request_list==NULL) || (results == NULL))
2816 return JVMTI_ERROR_NULL_POINTER;
2818 me = jvmti_get_current_thread();
2820 for (i=0;i<request_count;i++) {
2821 if (request_list[i] == me)
2824 results[i]=SuspendThread(env, request_list[i]);
2827 if (suspendme != -1)
2828 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2830 return JVMTI_ERROR_NONE;
2834 /* ResumeThreadList ***********************************************************
2836 Resumes all threads in the request list.
2838 *******************************************************************************/
2841 ResumeThreadList (jvmtiEnv * env, jint request_count,
2842 const jthread * request_list, jvmtiError * results)
2847 CHECK_PHASE(JVMTI_PHASE_LIVE)
2849 CHECK_CAPABILITY(env,can_suspend);
2851 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2852 if ((request_list==NULL) || (results == NULL))
2853 return JVMTI_ERROR_NULL_POINTER;
2855 for (i=0;i<request_count;i++)
2856 results[i]=ResumeThread(env, request_list[i]);
2858 return JVMTI_ERROR_NONE;
2862 /* GetStackTrace **************************************************************
2864 Get information about the stack of a thread
2866 *******************************************************************************/
2869 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2870 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2873 stacktracebuffer* trace;
2878 CHECK_PHASE(JVMTI_PHASE_LIVE)
2881 if (thread != NULL){
2882 if(!builtin_instanceof(thread,class_java_lang_Thread))
2883 return JVMTI_ERROR_INVALID_THREAD;
2885 CHECK_THREAD_IS_ALIVE(thread);
2888 if((count_ptr == NULL)||(frame_buffer == NULL))
2889 return JVMTI_ERROR_NULL_POINTER;
2891 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2893 er = getcacaostacktrace(&trace, thread);
2894 if (er==JVMTI_ERROR_NONE) {
2899 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2900 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2902 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2903 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2904 /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
2905 frame_buffer[j].location = 0;
2910 return JVMTI_ERROR_NONE;
2914 /* GetThreadListStackTraces ***************************************************
2916 Get information about the stacks of the supplied threads.
2918 *******************************************************************************/
2921 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2922 const jthread * thread_list,
2923 jint max_frame_count,
2924 jvmtiStackInfo ** stack_info_ptr)
2930 CHECK_PHASE(JVMTI_PHASE_LIVE)
2933 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2934 return JVMTI_ERROR_NULL_POINTER;
2936 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2938 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2940 *stack_info_ptr = (jvmtiStackInfo*)
2941 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2943 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2944 (*stack_info_ptr)[i].thread=thread_list[i];
2945 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2946 (*stack_info_ptr)[i].frame_buffer =
2947 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2948 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2949 (*stack_info_ptr)[i].frame_buffer,
2950 &((*stack_info_ptr)[i].frame_count));
2952 if (er != JVMTI_ERROR_NONE) return er;
2955 return JVMTI_ERROR_NONE;
2959 /* GetAllStackTraces **********************************************************
2961 Get stack traces of all live threads
2963 *******************************************************************************/
2966 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2967 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2969 jthread *threads_ptr;
2973 CHECK_PHASE(JVMTI_PHASE_LIVE)
2976 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2978 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2979 return JVMTI_ERROR_INTERNAL;
2981 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2982 max_frame_count, stack_info_ptr);
2984 if (er != JVMTI_ERROR_NONE) return er;
2986 return JVMTI_ERROR_NONE;
2990 /* GetThreadLocalStorage ******************************************************
2992 Get the value of the JVM TI thread-local storage.
2994 *******************************************************************************/
2997 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2999 jvmtiThreadLocalStorage *tls;
3002 CHECK_PHASE(JVMTI_PHASE_START)
3003 CHECK_PHASE(JVMTI_PHASE_LIVE)
3007 thread = (jthread) THREADOBJECT;
3009 if (!builtin_instanceof(thread,class_java_lang_Thread))
3010 return JVMTI_ERROR_INVALID_THREAD;
3011 CHECK_THREAD_IS_ALIVE(thread);
3014 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3016 tls = ((environment*)env)->tls;
3017 while ((tls->thread != thread) && (tls != NULL)) {
3021 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
3023 *data_ptr = tls->data;
3025 return JVMTI_ERROR_NONE;
3029 /* SetThreadLocalStorage *******************************************************
3031 Stores a pointer value associated with each environment-thread pair. The
3032 value is NULL unless set with this function. Agents can allocate memory in
3033 which they store thread specific information
3035 *******************************************************************************/
3038 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
3040 jvmtiThreadLocalStorage *tls, *pre;
3041 environment* env = (environment*)jenv;
3044 CHECK_PHASE(JVMTI_PHASE_START)
3045 CHECK_PHASE(JVMTI_PHASE_LIVE)
3049 thread = (jthread) THREADOBJECT;
3051 if (!builtin_instanceof(thread,class_java_lang_Thread))
3052 return JVMTI_ERROR_INVALID_THREAD;
3053 CHECK_THREAD_IS_ALIVE(thread);
3056 if (env->tls == NULL) {
3057 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3060 while ((tls->thread != thread) && (tls->next != NULL)) {
3063 if (tls->thread != thread) {
3064 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3070 tls->data = (void*)data;
3072 /* remove current tls */
3074 while (pre->next == tls) pre = pre->next;
3075 pre->next = tls->next;
3077 return JVMTI_ERROR_NONE;
3081 /* *****************************************************************************
3085 *******************************************************************************/
3088 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3091 CHECK_PHASE(JVMTI_PHASE_START)
3092 CHECK_PHASE(JVMTI_PHASE_LIVE)
3094 CHECK_CAPABILITY(env,can_tag_objects)
3096 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3097 return JVMTI_ERROR_NONE;
3100 /* *****************************************************************************
3104 *******************************************************************************/
3107 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3110 CHECK_PHASE(JVMTI_PHASE_START)
3111 CHECK_PHASE(JVMTI_PHASE_LIVE)
3113 CHECK_CAPABILITY(env,can_tag_objects)
3115 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3116 return JVMTI_ERROR_NONE;
3120 /* ForceGarbageCollection *****************************************************
3122 Force boehm-gc to perform a garbage collection
3124 *******************************************************************************/
3127 ForceGarbageCollection (jvmtiEnv * env)
3130 CHECK_PHASE(JVMTI_PHASE_LIVE)
3135 return JVMTI_ERROR_NONE;
3139 /* IterateOverObjectsReachableFromObject **************************************
3143 *******************************************************************************/
3146 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3147 jvmtiObjectReferenceCallback
3148 object_reference_callback,
3152 CHECK_PHASE(JVMTI_PHASE_LIVE)
3154 CHECK_CAPABILITY(env,can_tag_objects)
3156 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3157 return JVMTI_ERROR_NONE;
3161 /* IterateOverReachableObjects ************************************************
3165 *******************************************************************************/
3168 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3170 jvmtiStackReferenceCallback
3172 jvmtiObjectReferenceCallback
3173 object_ref_callback, void *user_data)
3176 CHECK_PHASE(JVMTI_PHASE_LIVE)
3178 CHECK_CAPABILITY(env,can_tag_objects)
3180 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3181 return JVMTI_ERROR_NONE;
3185 /* IterateOverHeap ************************************************************
3189 *******************************************************************************/
3192 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3193 jvmtiHeapObjectCallback heap_object_callback,
3197 CHECK_PHASE(JVMTI_PHASE_LIVE)
3199 CHECK_CAPABILITY(env,can_tag_objects)
3201 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3202 return JVMTI_ERROR_NONE;
3206 /* IterateOverInstancesOfClass ************************************************
3210 *******************************************************************************/
3213 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3214 jvmtiHeapObjectFilter object_filter,
3215 jvmtiHeapObjectCallback
3216 heap_object_callback, void *user_data)
3219 CHECK_PHASE(JVMTI_PHASE_LIVE)
3221 CHECK_CAPABILITY(env,can_tag_objects)
3223 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3224 return JVMTI_ERROR_NONE;
3228 /* *****************************************************************************
3232 *******************************************************************************/
3235 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3236 jint * count_ptr, jobject ** object_result_ptr,
3237 jlong ** tag_result_ptr)
3240 CHECK_PHASE(JVMTI_PHASE_LIVE)
3242 CHECK_CAPABILITY(env,can_tag_objects)
3244 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3245 return JVMTI_ERROR_NONE;
3249 /* SetJNIFunctionTable **********************************************************
3251 Set the JNI function table in all current and future JNI environments
3253 *******************************************************************************/
3256 SetJNIFunctionTable (jvmtiEnv * env,
3257 const jniNativeInterface * function_table)
3260 CHECK_PHASE(JVMTI_PHASE_START)
3261 CHECK_PHASE(JVMTI_PHASE_LIVE)
3264 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3265 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3266 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3267 return JVMTI_ERROR_NONE;
3271 /* GetJNIFunctionTable *********************************************************
3273 Get the JNI function table. The JNI function table is copied into allocated
3276 *******************************************************************************/
3279 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3282 CHECK_PHASE(JVMTI_PHASE_START)
3283 CHECK_PHASE(JVMTI_PHASE_LIVE)
3286 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3287 *function_table = (jniNativeInterface*)
3288 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3289 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3290 return JVMTI_ERROR_NONE;
3294 /* SetEventCallbacks **********************************************************
3296 Set the functions to be called for each event. The callbacks are specified
3297 by supplying a replacement function table.
3299 *******************************************************************************/
3302 SetEventCallbacks (jvmtiEnv * env,
3303 const jvmtiEventCallbacks * callbacks,
3304 jint size_of_callbacks)
3307 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3308 CHECK_PHASE(JVMTI_PHASE_LIVE)
3311 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3314 if (callbacks == NULL) { /* remove the existing callbacks */
3315 memset(&(((environment* )env)->callbacks), 0,
3316 sizeof(jvmtiEventCallbacks));
3319 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3321 return JVMTI_ERROR_NONE;
3325 /* GenerateEvents *************************************************************
3327 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3328 the current state of the VM.
3330 *******************************************************************************/
3333 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3336 CHECK_PHASE(JVMTI_PHASE_LIVE)
3338 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
3340 return JVMTI_ERROR_NONE;
3344 /* GetExtensionFunctions ******************************************************
3346 Returns the set of extension functions.
3348 *******************************************************************************/
3351 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3352 jvmtiExtensionFunctionInfo ** extensions)
3355 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3356 CHECK_PHASE(JVMTI_PHASE_LIVE)
3359 if ((extension_count_ptr== NULL)||(extensions == NULL))
3360 return JVMTI_ERROR_NULL_POINTER;
3362 /* cacao has no extended functions yet */
3363 *extension_count_ptr = 0;
3365 return JVMTI_ERROR_NONE;
3369 /* GetExtensionEvents *********************************************************
3371 Returns the set of extension events.
3373 *******************************************************************************/
3376 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3377 jvmtiExtensionEventInfo ** extensions)
3380 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3381 CHECK_PHASE(JVMTI_PHASE_LIVE)
3384 if ((extension_count_ptr== NULL)||(extensions == NULL))
3385 return JVMTI_ERROR_NULL_POINTER;
3387 /* cacao has no extended events yet */
3388 *extension_count_ptr = 0;
3390 return JVMTI_ERROR_NONE;
3394 /* SetExtensionEventCallback **************************************************
3396 Sets the callback function for an extension event and enables the event.
3398 *******************************************************************************/
3401 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3402 jvmtiExtensionEvent callback)
3405 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3406 CHECK_PHASE(JVMTI_PHASE_LIVE)
3409 /* cacao has no extended events yet */
3410 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3414 /* DisposeEnvironment **********************************************************
3416 Shutdown a JVM TI connection created with JNI GetEnv.
3418 *******************************************************************************/
3421 DisposeEnvironment (jvmtiEnv * env)
3423 environment* cacao_env = (environment*)env;
3424 environment* tenvs = envs;
3425 jvmtiThreadLocalStorage *jtls, *tjtls;
3427 if (tenvs != cacao_env) {
3428 while (tenvs->next != cacao_env) {
3429 tenvs = tenvs->next;
3431 tenvs->next = cacao_env->next;
3435 cacao_env->env=NULL;
3436 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3437 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3438 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3439 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3440 cacao_env->EnvironmentLocalStorage = NULL;
3442 jtls = cacao_env->tls;
3443 while (jtls != NULL) {
3448 cacao_env->tls = NULL;
3451 jvmti_cacaodbgserver_quit();
3453 /* let the GC do the rest */
3454 return JVMTI_ERROR_NONE;
3458 /* GetErrorName ***************************************************************
3460 Return the symbolic name for an error code.
3462 *******************************************************************************/
3464 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3465 memcpy(*name_ptr, &str, sizeof(str)); \
3469 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3471 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3474 case JVMTI_ERROR_NONE :
3475 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3476 case JVMTI_ERROR_NULL_POINTER :
3477 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3478 case JVMTI_ERROR_OUT_OF_MEMORY :
3479 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3480 case JVMTI_ERROR_ACCESS_DENIED :
3481 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3482 case JVMTI_ERROR_UNATTACHED_THREAD :
3483 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3484 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3485 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3486 case JVMTI_ERROR_WRONG_PHASE :
3487 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3488 case JVMTI_ERROR_INTERNAL :
3489 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3490 case JVMTI_ERROR_INVALID_PRIORITY :
3491 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3492 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3493 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3494 case JVMTI_ERROR_THREAD_SUSPENDED :
3495 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3496 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3497 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3498 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3499 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3500 case JVMTI_ERROR_NO_MORE_FRAMES :
3501 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3502 case JVMTI_ERROR_OPAQUE_FRAME :
3503 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3504 case JVMTI_ERROR_DUPLICATE :
3505 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3506 case JVMTI_ERROR_NOT_FOUND :
3507 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3508 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3509 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3510 case JVMTI_ERROR_INTERRUPT :
3511 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3512 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3513 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3514 case JVMTI_ERROR_NOT_AVAILABLE :
3515 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3516 case JVMTI_ERROR_ABSENT_INFORMATION :
3517 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3518 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3519 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3520 case JVMTI_ERROR_NATIVE_METHOD :
3521 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3522 case JVMTI_ERROR_INVALID_THREAD :
3523 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3524 case JVMTI_ERROR_INVALID_FIELDID :
3525 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3526 case JVMTI_ERROR_INVALID_METHODID :
3527 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3528 case JVMTI_ERROR_INVALID_LOCATION :
3529 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3530 case JVMTI_ERROR_INVALID_OBJECT :
3531 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3532 case JVMTI_ERROR_INVALID_CLASS :
3533 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3534 case JVMTI_ERROR_TYPE_MISMATCH :
3535 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3536 case JVMTI_ERROR_INVALID_SLOT :
3537 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3538 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3539 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3540 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3541 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3542 case JVMTI_ERROR_INVALID_MONITOR :
3543 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3544 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3545 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3546 case JVMTI_ERROR_INVALID_TYPESTATE :
3547 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3548 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3549 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3550 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3551 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3552 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3553 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3554 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3555 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3556 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3557 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3558 case JVMTI_ERROR_FAILS_VERIFICATION :
3559 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3560 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3561 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3562 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3563 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3564 case JVMTI_ERROR_NAMES_DONT_MATCH :
3565 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3566 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3567 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3568 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3569 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3571 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3573 return JVMTI_ERROR_NONE;
3576 /* GetJLocationFormat **********************************************************
3578 This function describes the representation of jlocation used in this VM.
3580 *******************************************************************************/
3583 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3585 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3586 return JVMTI_ERROR_NONE;
3590 /* GetSystemProperties ********************************************************
3592 The list of VM system property keys which may be used with GetSystemProperty
3595 *******************************************************************************/
3598 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3600 jmethodID mid, moremid;
3601 classinfo *sysclass, *propclass, *enumclass;
3602 java_objectheader *sysprop, *keys, *obj;
3607 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3608 CHECK_PHASE(JVMTI_PHASE_LIVE)
3611 if ((count_ptr == NULL) || (property_ptr == NULL))
3612 return JVMTI_ERROR_NULL_POINTER;
3614 sysclass = load_class_from_sysloader(
3615 utf_new_char_classname ("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();
3625 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3626 if (!sysprop) throw_main_exception_exit();
3628 propclass = sysprop->vftbl->class;
3630 mid = (jmethodID)class_resolvemethod(propclass,
3631 utf_new_char("size"),
3632 utf_new_char("()I"));
3633 if (!mid) throw_main_exception_exit();
3636 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3637 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3639 mid = (jmethodID)class_resolvemethod(propclass,
3640 utf_new_char("keys"),
3641 utf_new_char("()Ljava/util/Enumeration;"));
3642 if (!mid) throw_main_exception_exit();
3644 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3645 enumclass = keys->vftbl->class;
3647 moremid = (jmethodID)class_resolvemethod(enumclass,
3648 utf_new_char("hasMoreElements"),
3649 utf_new_char("()Z"));
3650 if (!moremid) throw_main_exception_exit();
3652 mid = (jmethodID)class_resolvemethod(propclass,
3653 utf_new_char("nextElement"),
3654 utf_new_char("()Ljava/lang/Object;"));
3655 if (!mid) throw_main_exception_exit();
3658 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3659 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3660 ch = javastring_tochar(obj);
3661 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3662 memcpy(*property_ptr[i], ch, strlen (ch));
3663 MFREE(ch,char,strlen(ch)+1);
3667 return JVMTI_ERROR_NONE;
3671 /* GetSystemProperty **********************************************************
3673 Return a VM system property value given the property key.
3675 *******************************************************************************/
3678 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3681 classinfo *sysclass, *propclass;
3682 java_objectheader *sysprop, *obj;
3686 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3687 CHECK_PHASE(JVMTI_PHASE_LIVE)
3690 if ((value_ptr == NULL) || (property == NULL))
3691 return JVMTI_ERROR_NULL_POINTER;
3693 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3694 if (!sysclass) throw_main_exception_exit();
3696 mid = (jmethodID)class_resolvemethod(sysclass,
3697 utf_new_char("getProperties"),
3698 utf_new_char("()Ljava/util/Properties;"));
3699 if (!mid) throw_main_exception_exit();
3701 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3703 propclass = sysprop->vftbl->class;
3705 mid = (jmethodID)class_resolvemethod(propclass,
3706 utf_new_char("getProperty"),
3707 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3708 if (!mid) throw_main_exception_exit();
3710 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3711 NULL, sysprop, mid, javastring_new_from_ascii(property));
3712 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3714 ch = javastring_tochar(obj);
3715 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3716 memcpy(*value_ptr, ch, strlen (ch));
3717 MFREE(ch,char,strlen(ch)+1);
3719 return JVMTI_ERROR_NONE;
3723 /* SetSystemProperty **********************************************************
3725 Set a VM system property value.
3727 *******************************************************************************/
3730 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3733 classinfo *sysclass, *propclass;
3734 java_objectheader *sysprop;
3737 CHECK_PHASE(JVMTI_PHASE_START)
3740 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3741 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3743 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3744 if (!sysclass) throw_main_exception_exit();
3746 mid = (jmethodID)class_resolvemethod(sysclass,
3747 utf_new_char("getProperties"),
3748 utf_new_char("()Ljava/util/Properties;"));
3749 if (!mid) throw_main_exception_exit();
3751 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3753 propclass = sysprop->vftbl->class;
3755 mid = (jmethodID)class_resolvemethod(propclass,
3756 utf_new_char("setProperty"),
3757 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3758 if (!mid) throw_main_exception_exit();
3760 _Jv_JNINativeInterface.CallObjectMethod(
3761 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3763 return JVMTI_ERROR_NONE;
3766 /* GetPhase ********************************************************************
3768 Return the current phase of VM execution
3770 *******************************************************************************/
3773 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3775 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3779 return JVMTI_ERROR_NONE;
3782 /* GetCurrentThreadCpuTimerInfo ************************************************
3786 *******************************************************************************/
3789 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3792 CHECK_PHASE(JVMTI_PHASE_START)
3793 CHECK_PHASE(JVMTI_PHASE_LIVE)
3795 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3797 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3799 return JVMTI_ERROR_NONE;
3802 /* GetCurrentThreadCpuTime ****************************************************
3806 *******************************************************************************/
3809 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3812 CHECK_PHASE(JVMTI_PHASE_START)
3813 CHECK_PHASE(JVMTI_PHASE_LIVE)
3815 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3817 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3818 return JVMTI_ERROR_NONE;
3821 /* GetThreadCpuTimerInfo ******************************************************
3825 *******************************************************************************/
3828 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3831 CHECK_PHASE(JVMTI_PHASE_START)
3832 CHECK_PHASE(JVMTI_PHASE_LIVE)
3834 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3836 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3837 return JVMTI_ERROR_NONE;
3840 /* GetThreadCpuTime ***********************************************************
3844 *******************************************************************************/
3847 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3850 CHECK_PHASE(JVMTI_PHASE_LIVE)
3852 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3853 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3854 return JVMTI_ERROR_NONE;
3857 /* GetTimerInfo ***************************************************************
3859 Get information about the GetTime timer.
3861 *******************************************************************************/
3864 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3866 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3868 info_ptr->max_value = !0x0;
3869 info_ptr->may_skip_forward = true;
3870 info_ptr->may_skip_backward = true;
3871 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3873 return JVMTI_ERROR_NONE;
3876 /* GetTime ********************************************************************
3878 Return the current value of the system timer, in nanoseconds
3880 *******************************************************************************/
3883 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3885 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3888 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3890 if (gettimeofday (&tp, NULL) == -1)
3891 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3893 *nanos_ptr = (jlong) tp.tv_sec;
3895 *nanos_ptr += (tp.tv_usec / 1000);
3897 return JVMTI_ERROR_NONE;
3900 /* GetPotentialCapabilities ***************************************************
3902 Returns the JVM TI features that can potentially be possessed by this
3903 environment at this time.
3905 *******************************************************************************/
3908 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3911 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3912 CHECK_PHASE(JVMTI_PHASE_LIVE)
3915 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3917 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3919 return JVMTI_ERROR_NONE;
3923 #define CHECK_ADD_CAPABILITY(env,CAN) \
3924 if (capabilities_ptr->CAN == 1) { \
3925 if (JVMTI_Capabilities.CAN == 0) \
3926 return JVMTI_ERROR_NOT_AVAILABLE; \
3928 env->capabilities.CAN = 1; \
3931 /* AddCapabilities ************************************************************
3933 Set new capabilities by adding the capabilities pointed to by
3934 capabilities_ptr. All previous capabilities are retained.
3936 *******************************************************************************/
3939 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3941 environment* cacao_env;
3944 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3945 CHECK_PHASE(JVMTI_PHASE_LIVE)
3948 if ((env == NULL) || (capabilities_ptr == NULL))
3949 return JVMTI_ERROR_NULL_POINTER;
3951 cacao_env = (environment*)env;
3953 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3954 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3955 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3956 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3957 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3958 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3959 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3960 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3961 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3962 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3963 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3964 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3965 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3966 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3967 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3968 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3969 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3970 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3971 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3972 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3973 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3974 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3975 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3976 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3977 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3978 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3979 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3980 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3981 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3982 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3983 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3984 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3985 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3988 return JVMTI_ERROR_NONE;
3992 #define CHECK_DEL_CAPABILITY(env,CAN) \
3993 if (capabilities_ptr->CAN == 1) \
3994 env->capabilities.CAN = 0;
3996 /* RelinquishCapabilities *****************************************************
3998 Relinquish the capabilities pointed to by capabilities_ptr.
4000 *******************************************************************************/
4003 RelinquishCapabilities (jvmtiEnv * env,
4004 const jvmtiCapabilities * capabilities_ptr)
4006 environment* cacao_env;
4009 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4010 CHECK_PHASE(JVMTI_PHASE_LIVE)
4013 if ((env == NULL) || (capabilities_ptr == NULL))
4014 return JVMTI_ERROR_NULL_POINTER;
4016 cacao_env = (environment*)env;
4018 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
4019 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
4020 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
4021 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
4022 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
4023 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
4024 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
4025 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
4026 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
4027 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
4028 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
4029 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
4030 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
4031 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
4032 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
4033 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
4034 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
4035 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
4036 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
4037 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
4038 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
4039 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
4040 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
4041 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
4042 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
4043 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
4044 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
4045 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
4046 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
4047 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
4048 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4049 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4050 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4052 return JVMTI_ERROR_NONE;
4055 /* GetAvailableProcessors *****************************************************
4057 Get number of processors available to the virtual machine.
4059 *******************************************************************************/
4062 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4065 CHECK_PHASE(JVMTI_PHASE_START)
4066 CHECK_PHASE(JVMTI_PHASE_LIVE)
4069 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4071 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4073 *processor_count_ptr = 1; /* where do I get this ?*/
4075 return JVMTI_ERROR_NONE;
4078 /* GetEnvironmentLocalStorage **************************************************
4080 Called by the agent to get the value of the JVM TI environment-local storage.
4082 *******************************************************************************/
4085 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4087 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4089 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4091 return JVMTI_ERROR_NONE;
4094 /* SetEnvironmentLocalStorage **************************************************
4096 The VM stores a pointer value associated with each environment. Agents can
4097 allocate memory in which they store environment specific information.
4099 *******************************************************************************/
4102 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4104 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4106 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4108 return JVMTI_ERROR_NONE;
4111 /* AddToBootstrapClassLoaderSearch ********************************************
4113 After the bootstrap class loader unsuccessfully searches for a class, the
4114 specified platform-dependent search path segment will be searched as well.
4116 *******************************************************************************/
4119 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4125 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4128 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4130 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4131 tmp_bcp = MNEW(char, ln);
4132 strcat(tmp_bcp, bootclasspath);
4133 strcat(tmp_bcp, ":");
4134 strcat(tmp_bcp, segment);
4135 MFREE(bootclasspath,char,ln);
4136 bootclasspath = tmp_bcp;
4138 return JVMTI_ERROR_NONE;
4141 /* SetVerboseFlag *************************************************************
4143 Control verbose output. This is the output which typically is sent to stderr
4145 *******************************************************************************/
4148 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4151 case JVMTI_VERBOSE_OTHER:
4152 /* where is this defined ?
4156 case JVMTI_VERBOSE_GC:
4157 opt_verbosegc = value;
4159 case JVMTI_VERBOSE_CLASS:
4160 loadverbose = value;
4162 case JVMTI_VERBOSE_JNI:
4165 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4167 return JVMTI_ERROR_NONE;
4170 /* GetObjectSize **************************************************************
4172 For the object object return the size.
4174 *******************************************************************************/
4177 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4180 CHECK_PHASE(JVMTI_PHASE_START)
4181 CHECK_PHASE(JVMTI_PHASE_LIVE)
4184 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4185 if (!builtin_instanceof(object,class_java_lang_Object))
4186 return JVMTI_ERROR_INVALID_OBJECT;
4188 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4190 return JVMTI_ERROR_NONE;
4194 /* *****************************************************************************
4196 Environment variables
4198 *******************************************************************************/
4200 static jvmtiCapabilities JVMTI_Capabilities = {
4201 0, /* can_tag_objects */
4202 0, /* can_generate_field_modification_events */
4203 0, /* can_generate_field_access_events */
4204 1, /* can_get_bytecodes */
4205 0, /* can_get_synthetic_attribute */
4207 #if defined(ENABLE_THREADS)
4208 1, /* can_get_owned_monitor_info */
4209 1, /* can_get_current_contended_monitor */
4211 0, /* can_get_owned_monitor_info */
4212 0, /* can_get_current_contended_monitor */
4215 0, /* can_get_monitor_info */
4216 0, /* can_pop_frame */
4217 0, /* can_redefine_classes */
4218 0, /* can_signal_thread */
4219 1, /* can_get_source_file_name */
4220 1, /* can_get_line_numbers */
4221 0, /* can_get_source_debug_extension */
4222 0, /* can_access_local_variables */
4223 0, /* can_maintain_original_method_order */
4224 0, /* can_generate_single_step_events */
4225 0, /* can_generate_exception_events */
4226 0, /* can_generate_frame_pop_events */
4227 0, /* can_generate_breakpoint_events */
4228 1, /* can_suspend */
4229 0, /* can_redefine_any_class */
4230 0, /* can_get_current_thread_cpu_time */
4231 0, /* can_get_thread_cpu_time */
4232 0, /* can_generate_method_entry_events */
4233 0, /* can_generate_method_exit_events */
4234 0, /* can_generate_all_class_hook_events */
4235 0, /* can_generate_compiled_method_load_events */
4236 0, /* can_generate_monitor_events */
4237 0, /* can_generate_vm_object_alloc_events */
4238 0, /* can_generate_native_method_bind_events */
4239 0, /* can_generate_garbage_collection_events */
4240 0, /* can_generate_object_free_events */
4243 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4245 &SetEventNotificationMode,
4253 &GetOwnedMonitorInfo,
4254 &GetCurrentContendedMonitor,
4256 &GetTopThreadGroups,
4257 &GetThreadGroupInfo,
4258 &GetThreadGroupChildren,
4280 &RawMonitorNotifyAll,
4284 &SetFieldAccessWatch,
4285 &ClearFieldAccessWatch,
4286 &SetFieldModificationWatch,
4287 &ClearFieldModificationWatch,
4297 &GetImplementedInterfaces,
4302 &GetObjectMonitorUsage,
4304 &GetFieldDeclaringClass,
4308 &GetMethodDeclaringClass,
4309 &GetMethodModifiers,
4313 &GetLineNumberTable,
4315 &GetLocalVariableTable,
4322 &GetClassLoaderClasses,
4333 &GetSourceDebugExtension,
4344 &GetThreadListStackTraces,
4345 &GetThreadLocalStorage,
4346 &SetThreadLocalStorage,
4351 &ForceGarbageCollection,
4352 &IterateOverObjectsReachableFromObject,
4353 &IterateOverReachableObjects,
4355 &IterateOverInstancesOfClass,
4357 &GetObjectsWithTags,
4363 &SetJNIFunctionTable,
4364 &GetJNIFunctionTable,
4367 &GetExtensionFunctions,
4368 &GetExtensionEvents,
4369 &SetExtensionEventCallback,
4370 &DisposeEnvironment,
4372 &GetJLocationFormat,
4373 &GetSystemProperties,
4377 &GetCurrentThreadCpuTimerInfo,
4378 &GetCurrentThreadCpuTime,
4379 &GetThreadCpuTimerInfo,
4383 &GetPotentialCapabilities,
4386 &RelinquishCapabilities,
4387 &GetAvailableProcessors,
4390 &GetEnvironmentLocalStorage,
4391 &SetEnvironmentLocalStorage,
4392 &AddToBootstrapClassLoaderSearch,
4401 void jvmti_set_phase(jvmtiPhase p) {
4404 fprintf (stderr,"set JVMTI phase %d\n",p);
4408 case JVMTI_PHASE_ONLOAD:
4411 case JVMTI_PHASE_PRIMORDIAL:
4414 case JVMTI_PHASE_START:
4416 d.ev = JVMTI_EVENT_VM_START;
4418 case JVMTI_PHASE_LIVE:
4420 d.ev = JVMTI_EVENT_VM_INIT;
4421 jvmti_fireEvent(&d);
4422 /* thread start event for main thread */
4423 d.ev = JVMTI_EVENT_THREAD_START;
4425 case JVMTI_PHASE_DEAD:
4427 d.ev = JVMTI_EVENT_VM_DEATH;
4430 log_text("wrong jvmti phase to be set");
4434 jvmti_fireEvent(&d);
4437 jvmtiEnv* jvmti_new_environment() {
4441 envs = heap_allocate(sizeof(environment),true,NULL);
4445 while (env->next != NULL) env = env->next;
4446 env->next = heap_allocate(sizeof(environment),true,NULL);
4450 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4451 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4452 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4453 sizeof(jvmtiEventModeLL));
4454 /* To possess a capability, the agent must add the capability.*/
4455 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4456 RelinquishCapabilities(&(env->env),&(env->capabilities));
4457 env->EnvironmentLocalStorage = NULL;
4460 /* initialize cacao debugging facilities */
4461 jvmti_cacao_debug_init();
4463 return (jvmtiEnv*)env;
4466 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4472 len = strlen(opt_arg);
4474 /* separate argumtents */
4475 while ((opt_arg[i]!='=')&&(i<len)) i++;
4477 arg = &opt_arg[i+1];
4483 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4484 strncpy(*libname,opt_arg,i);
4488 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4489 strncpy(*libname,"lib",3);
4490 strncpy(&(*libname)[3],opt_arg,i);
4491 strncpy(&(*libname)[i+3],".so",3);
4494 /* try to open the library */
4496 if (!(*handle = lt_dlopen(*libname))) {
4497 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4501 /* resolve Agent_OnLoad function */
4502 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4503 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4507 /* resolve Agent_UnLoad function */
4508 unload = lt_dlsym(*handle, "Agent_Unload");
4511 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4512 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4514 if (retval != 0) exit (retval);
4517 void jvmti_agentunload() {
4518 if (unload != NULL) {
4519 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4520 ((JavaVM*) &_Jv_JNIInvokeInterface);
4525 * These are local overrides for various environment variables in Emacs.
4526 * Please do not remove this and leave it at the end of the file, where
4527 * Emacs will automagically detect them.
4528 * ---------------------------------------------------------------------
4531 * indent-tabs-mode: t
4535 * vim:noexpandtab:sw=4:ts=4: