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 4969 2006-05-29 09:41:02Z 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 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
667 return JVMTI_ERROR_NOT_AVAILABLE;
669 if(!builtin_instanceof(thread,class_java_lang_Thread))
670 return JVMTI_ERROR_INVALID_THREAD;
672 CHECK_THREAD_IS_ALIVE(thread);
674 return JVMTI_ERROR_NONE;
677 /* GetThreadInfo ***************************************************************
679 Get thread information. Details of the specified thread are stored in the
680 jvmtiThreadInfo structure.
682 *******************************************************************************/
685 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
687 java_lang_Thread* th = (java_lang_Thread*)t;
690 CHECK_PHASE(JVMTI_PHASE_LIVE)
692 info_ptr->priority=(jint)th->priority;
693 info_ptr->is_daemon=(jboolean)th->daemon;
694 info_ptr->thread_group=(jthreadGroup)th->group;
695 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
696 info_ptr->name= javastring_tochar((java_objectheader *)th->name);
698 return JVMTI_ERROR_NONE;
701 /* GetOwnedMonitorInfo *********************************************************
703 Get information about the monitors owned by the specified thread
705 *******************************************************************************/
708 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
709 jint * owned_monitor_count_ptr,
710 jobject ** owned_monitors_ptr)
713 java_objectheader **om;
714 lock_record_pool_t* lrp;
716 log_text("GetOwnedMonitorInfo called");
719 CHECK_PHASE(JVMTI_PHASE_LIVE)
721 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
723 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
724 return JVMTI_ERROR_NULL_POINTER;
726 if(!builtin_instanceof(thread,class_java_lang_Thread))
727 return JVMTI_ERROR_INVALID_THREAD;
729 CHECK_THREAD_IS_ALIVE(thread);
731 #if defined(ENABLE_THREADS)
733 om=MNEW(java_objectheader*,size);
735 pthread_mutex_lock(&lock_global_pool_lock);
736 lrp=lock_global_pool;
738 while (lrp != NULL) {
739 for (j=0; j<lrp->header.size; j++) {
740 /* if((lrp->lr[j].owner==(threadobject*)thread)&&
741 (!lrp->lr[j].waiting)) {
743 MREALLOC(om,java_objectheader*,size,size*2);
750 lrp=lrp->header.next;
753 pthread_mutex_unlock(&lock_global_pool_lock);
755 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
756 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
757 MFREE(om,java_objectheader*,size);
759 *owned_monitor_count_ptr = i;
763 return JVMTI_ERROR_NONE;
766 /* GetCurrentContendedMonitor *************************************************
768 Get the object the specified thread waits for.
770 *******************************************************************************/
773 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
774 jobject * monitor_ptr)
777 lock_record_pool_t* lrp;
778 java_objectheader* monitor;
781 CHECK_PHASE(JVMTI_PHASE_LIVE)
783 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
785 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
788 if(!builtin_instanceof(thread,class_java_lang_Thread))
789 return JVMTI_ERROR_INVALID_THREAD;
791 CHECK_THREAD_IS_ALIVE(thread);
794 #if defined(ENABLE_THREADS)
796 pthread_mutex_lock(&lock_global_pool_lock);
798 lrp=lock_global_pool;
800 while ((lrp != NULL)&&(monitor==NULL)) {
801 for (j=0; j<lrp->header.size; j++) {
802 /* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
803 monitor=lrp->lr[j].o;
807 lrp=lrp->header.next;
810 pthread_mutex_unlock(&lock_global_pool_lock);
813 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
814 *monitor_ptr = (jobject)monitor;
818 return JVMTI_ERROR_NONE;
822 jvmtiStartFunction sf;
828 static void *threadstartup(void *t) {
829 runagentparam *rap = (runagentparam*)t;
830 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
834 /* RunAgentThread *************************************************************
836 Starts the execution of an agent thread of the specified native function
837 within the specified thread
839 *******************************************************************************/
842 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
843 const void *arg, jint priority)
845 pthread_attr_t threadattr;
846 struct sched_param sp;
850 CHECK_PHASE(JVMTI_PHASE_LIVE)
853 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
854 return JVMTI_ERROR_INVALID_THREAD;
855 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
856 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
857 (priority > JVMTI_THREAD_MAX_PRIORITY))
858 return JVMTI_ERROR_INVALID_PRIORITY;
860 /* XXX: Threads started with with this function should not be visible to
861 Java programming language queries but are included in JVM TI queries */
864 rap.arg = (void*)arg;
867 #if defined(ENABLE_THREADS)
868 pthread_attr_init(&threadattr);
869 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
870 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
871 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
873 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
874 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
876 pthread_attr_setschedparam(&threadattr,&sp);
877 if (pthread_create(&((threadobject*)
878 thread)->tid, &threadattr, &threadstartup, &rap)) {
879 log_text("pthread_create failed");
884 return JVMTI_ERROR_NONE;
888 /* GetTopThreadGroups *********************************************************
890 Get all top-level thread groups in the VM.
892 *******************************************************************************/
895 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
896 jthreadGroup ** groups_ptr)
898 jint threads_count_ptr;
899 threadobject *threads_ptr;
901 jthreadGroup **tg,*ttgp;
904 CHECK_PHASE(JVMTI_PHASE_LIVE)
907 log_text("GetTopThreadGroups called");
909 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
910 return JVMTI_ERROR_NULL_POINTER;
912 #if defined(ENABLE_THREADS)
913 tg = MNEW(jthreadGroup*,size);
915 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
916 return JVMTI_ERROR_INTERNAL;
918 for (i=0;i<threads_count_ptr;i++){
919 if (threads_ptr[i].o.thread->group == NULL) {
920 log_text("threadgroup not set");
921 return JVMTI_ERROR_INTERNAL;
923 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
926 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
931 MREALLOC(tg,jthreadGroup*,size,size*2);
940 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
941 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
942 MFREE(tg,jthreadGroup*,size);
944 *group_count_ptr = x;
947 return JVMTI_ERROR_NOT_AVAILABLE;
949 return JVMTI_ERROR_NONE;
953 /* GetThreadGroupInfo *********************************************************
955 Get information about the specified thread group.
957 *******************************************************************************/
960 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
961 jvmtiThreadGroupInfo * info_ptr)
965 java_lang_ThreadGroup* grp;
968 CHECK_PHASE(JVMTI_PHASE_LIVE)
971 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
972 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
973 return JVMTI_ERROR_INVALID_THREAD_GROUP;
975 grp = (java_lang_ThreadGroup*)group;
977 info_ptr->parent = (jthreadGroup)
978 Java_java_lang_VMObject_clone(NULL,
979 (jclass)grp->header.vftbl->class,
980 (java_lang_Cloneable*) &grp->parent);
982 name = javastring_tochar((java_objectheader*)grp->name);
984 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
985 strncpy(info_ptr->name,name,size);
986 info_ptr->max_priority= (jint)grp->maxpri;
987 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
989 return JVMTI_ERROR_NONE;
993 /* GetThreadGroupChildren *****************************************************
995 Get the live threads and active subgroups in this thread group.
997 *******************************************************************************/
1000 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
1001 jint * thread_count_ptr, jthread ** threads_ptr,
1002 jint * group_count_ptr, jthreadGroup ** groups_ptr)
1004 java_lang_ThreadGroup* tgp;
1007 CHECK_PHASE(JVMTI_PHASE_LIVE)
1010 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
1011 (group_count_ptr == NULL) || (groups_ptr == NULL))
1012 return JVMTI_ERROR_NULL_POINTER;
1014 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
1015 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1017 tgp = (java_lang_ThreadGroup*)group;
1019 *thread_count_ptr = (jint)tgp->threads->elementCount;
1021 *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
1023 memcpy(*threads_ptr, &tgp->threads->elementData,
1024 (*thread_count_ptr)*sizeof(jthread*));
1026 *group_count_ptr = (jint) tgp->groups->elementCount;
1028 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
1030 memcpy(*groups_ptr, &tgp->threads->elementData,
1031 (*group_count_ptr)*sizeof(jthreadGroup*));
1033 return JVMTI_ERROR_NONE;
1037 /* getcacaostacktrace *********************************************************
1039 Helper function that retrives stack trace for specified thread.
1040 Has to take care of suspend/resume issuses
1042 *******************************************************************************/
1043 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1047 t = jvmti_get_current_thread();
1049 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1050 if (t != jvmti_get_current_thread())
1051 /* XXX: todo: take care that the requested thread is in a
1053 return JVMTI_ERROR_INTERNAL;
1056 *trace = stacktrace_create(t);
1058 return JVMTI_ERROR_NONE;
1062 /* GetFrameCount **************************************************************
1065 Get the number of frames in the specified thread's stack.
1067 *******************************************************************************/
1070 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1072 stacktracebuffer* trace;
1076 CHECK_PHASE(JVMTI_PHASE_LIVE)
1079 if (thread != NULL){
1080 if(!builtin_instanceof(thread,class_java_lang_Thread))
1081 return JVMTI_ERROR_INVALID_THREAD;
1083 CHECK_THREAD_IS_ALIVE(thread);
1086 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1088 er = getcacaostacktrace(&trace, thread);
1089 if (er==JVMTI_ERROR_NONE) {
1094 *count_ptr = trace->used;
1097 return JVMTI_ERROR_NONE;
1101 /* GetThreadState **************************************************************
1103 Get the state of a thread.
1105 *******************************************************************************/
1108 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1110 java_lang_Thread* th = (java_lang_Thread*)thread;
1111 threadobject* t = (threadobject*)th->vmThread;
1114 CHECK_PHASE(JVMTI_PHASE_LIVE)
1117 if(!builtin_instanceof(thread,class_java_lang_Thread))
1118 return JVMTI_ERROR_INVALID_THREAD;
1120 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1122 *thread_state_ptr = 0;
1123 #if defined(ENABLE_THREADS)
1124 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1126 if (((threadobject*)th->vmThread)->tid == 0)
1127 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1130 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1131 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1133 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1134 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1135 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1136 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1137 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1138 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1139 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1140 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1141 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1142 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1145 return JVMTI_ERROR_INTERNAL;
1148 return JVMTI_ERROR_NONE;
1152 /* GetFrameLocation ************************************************************
1154 Get the location of the instruction currently executing
1156 *******************************************************************************/
1159 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1160 jmethodID * method_ptr, jlocation * location_ptr)
1162 stackframeinfo *sfi;
1166 CHECK_PHASE(JVMTI_PHASE_LIVE)
1169 if(!builtin_instanceof(thread,class_java_lang_Thread))
1170 return JVMTI_ERROR_INVALID_THREAD;
1172 CHECK_THREAD_IS_ALIVE(thread);
1174 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1176 if ((method_ptr == NULL)&&(location_ptr == NULL))
1177 return JVMTI_ERROR_NULL_POINTER;
1179 sfi = ((threadobject*)thread)->_stackframeinfo;
1182 while ((sfi != NULL) && (i<depth)) {
1187 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1189 *method_ptr=(jmethodID)sfi->method;
1190 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1192 return JVMTI_ERROR_NONE;
1196 /* NotifyFramePop *************************************************************
1200 *******************************************************************************/
1203 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1206 CHECK_PHASE(JVMTI_PHASE_LIVE)
1208 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1210 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1211 return JVMTI_ERROR_NONE;
1214 /* GetLocalObject *************************************************************
1218 *******************************************************************************/
1221 GetLocalObject (jvmtiEnv * env,
1222 jthread thread, jint depth, jint slot, jobject * value_ptr)
1225 CHECK_PHASE(JVMTI_PHASE_LIVE)
1227 CHECK_CAPABILITY(env,can_access_local_variables)
1229 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1230 return JVMTI_ERROR_NONE;
1233 /* GetLocalInt ****************************************************************
1237 *******************************************************************************/
1240 GetLocalInt (jvmtiEnv * env,
1241 jthread thread, jint depth, jint slot, jint * value_ptr)
1244 CHECK_PHASE(JVMTI_PHASE_LIVE)
1246 CHECK_CAPABILITY(env,can_access_local_variables)
1247 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1248 return JVMTI_ERROR_NONE;
1251 /* *****************************************************************************
1255 *******************************************************************************/
1258 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1262 CHECK_PHASE(JVMTI_PHASE_LIVE)
1264 CHECK_CAPABILITY(env,can_access_local_variables)
1266 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1267 return JVMTI_ERROR_NONE;
1271 /* *****************************************************************************
1275 *******************************************************************************/
1278 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1282 CHECK_PHASE(JVMTI_PHASE_LIVE)
1284 CHECK_CAPABILITY(env,can_access_local_variables)
1286 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1287 return JVMTI_ERROR_NONE;
1291 /* *****************************************************************************
1295 *******************************************************************************/
1298 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1299 jdouble * value_ptr)
1302 CHECK_PHASE(JVMTI_PHASE_LIVE)
1304 CHECK_CAPABILITY(env,can_access_local_variables)
1306 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1307 return JVMTI_ERROR_NONE;
1311 /* *****************************************************************************
1315 *******************************************************************************/
1318 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1322 CHECK_PHASE(JVMTI_PHASE_LIVE)
1324 CHECK_CAPABILITY(env,can_access_local_variables)
1326 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1327 return JVMTI_ERROR_NONE;
1331 /* *****************************************************************************
1335 *******************************************************************************/
1338 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1342 CHECK_PHASE(JVMTI_PHASE_LIVE)
1344 CHECK_CAPABILITY(env,can_access_local_variables)
1346 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1347 return JVMTI_ERROR_NONE;
1351 /* *****************************************************************************
1355 *******************************************************************************/
1358 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1362 CHECK_PHASE(JVMTI_PHASE_LIVE)
1364 CHECK_CAPABILITY(env,can_access_local_variables)
1366 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1367 return JVMTI_ERROR_NONE;
1371 /* *****************************************************************************
1375 *******************************************************************************/
1378 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1382 CHECK_PHASE(JVMTI_PHASE_LIVE)
1384 CHECK_CAPABILITY(env,can_access_local_variables)
1386 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1387 return JVMTI_ERROR_NONE;
1391 /* *****************************************************************************
1395 *******************************************************************************/
1398 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1402 CHECK_PHASE(JVMTI_PHASE_LIVE)
1404 CHECK_CAPABILITY(env,can_access_local_variables)
1406 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1407 return JVMTI_ERROR_NONE;
1411 /* CreateRawMonitor ***********************************************************
1413 This function creates a new raw monitor.
1415 *******************************************************************************/
1418 CreateRawMonitor (jvmtiEnv * env, const char *name,
1419 jrawMonitorID * monitor_ptr)
1421 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1424 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1425 CHECK_PHASE(JVMTI_PHASE_LIVE)
1428 if ((name == NULL) || (monitor_ptr == NULL))
1429 return JVMTI_ERROR_NULL_POINTER;
1431 #if defined(ENABLE_THREADS)
1432 monitor->name=javastring_new_from_ascii(name);
1434 log_text ("CreateRawMonitor not supported");
1437 return JVMTI_ERROR_NONE;
1441 /* DestroyRawMonitor **********************************************************
1443 This function destroys a raw monitor.
1445 *******************************************************************************/
1448 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1451 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1452 CHECK_PHASE(JVMTI_PHASE_LIVE)
1455 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1456 return JVMTI_ERROR_INVALID_MONITOR;
1458 #if defined(ENABLE_THREADS)
1459 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1460 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1462 lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1464 /* GC will clean monitor up */
1466 log_text ("DestroyRawMonitor not supported");
1469 return JVMTI_ERROR_NONE;
1473 /* RawMonitorEnter ************************************************************
1475 Gain exclusive ownership of a raw monitor
1477 *******************************************************************************/
1480 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1482 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1483 return JVMTI_ERROR_INVALID_MONITOR;
1485 #if defined(ENABLE_THREADS)
1486 builtin_monitorenter((java_objectheader*)monitor->name);
1488 log_text ("RawMonitorEnter not supported");
1491 return JVMTI_ERROR_NONE;
1495 /* RawMonitorExit *************************************************************
1499 *******************************************************************************/
1502 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1504 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1505 return JVMTI_ERROR_INVALID_MONITOR;
1507 #if defined(ENABLE_THREADS)
1508 /* assure current thread owns this monitor */
1509 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1510 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1512 builtin_monitorexit((java_objectheader*)monitor->name);
1514 log_text ("RawMonitorExit not supported");
1517 return JVMTI_ERROR_NONE;
1521 /* RawMonitorWait *************************************************************
1523 Wait for notification of the raw monitor.
1525 *******************************************************************************/
1528 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1530 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1531 return JVMTI_ERROR_INVALID_MONITOR;
1533 #if defined(ENABLE_THREADS)
1534 /* assure current thread owns this monitor */
1535 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1536 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1538 lock_wait_for_object(&monitor->name->header, millis,0);
1539 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1540 return JVMTI_ERROR_INTERRUPT;
1543 log_text ("RawMonitorWait not supported");
1546 return JVMTI_ERROR_NONE;
1550 /* RawMonitorNotify ***********************************************************
1552 Notify one thread waiting on the given monitor.
1554 *******************************************************************************/
1557 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1559 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1560 return JVMTI_ERROR_INVALID_MONITOR;
1562 #if defined(ENABLE_THREADS)
1563 /* assure current thread owns this monitor */
1564 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1565 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1567 lock_notify_object((java_objectheader*)&monitor->name);
1569 log_text ("RawMonitorNotify not supported");
1572 return JVMTI_ERROR_NONE;
1576 /* RawMonitorNotifyAll *********************************************************
1578 Notify all threads waiting on the given monitor.
1580 *******************************************************************************/
1583 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1585 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1586 return JVMTI_ERROR_INVALID_MONITOR;
1588 #if defined(ENABLE_THREADS)
1589 /* assure current thread owns this monitor */
1590 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1591 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1593 lock_notify_all_object((java_objectheader*)&monitor->name);
1595 log_text ("RawMonitorNotifyAll not supported");
1598 return JVMTI_ERROR_NONE;
1602 /* SetBreakpoint **************************************************************
1606 *******************************************************************************/
1609 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1612 CHECK_PHASE(JVMTI_PHASE_LIVE)
1614 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1617 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1618 return JVMTI_ERROR_NONE;
1622 /* *****************************************************************************
1626 *******************************************************************************/
1629 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1632 CHECK_PHASE(JVMTI_PHASE_LIVE)
1634 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1636 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1637 return JVMTI_ERROR_NONE;
1641 /* SetFieldAccessWatch ********************************************************
1645 *******************************************************************************/
1648 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1651 CHECK_PHASE(JVMTI_PHASE_LIVE)
1653 CHECK_CAPABILITY(env,can_generate_field_access_events)
1655 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1656 return JVMTI_ERROR_NONE;
1660 /* *****************************************************************************
1664 *******************************************************************************/
1667 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1670 CHECK_PHASE(JVMTI_PHASE_LIVE)
1672 CHECK_CAPABILITY(env,can_generate_field_access_events)
1674 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1675 return JVMTI_ERROR_NONE;
1679 /* *****************************************************************************
1683 *******************************************************************************/
1686 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1689 CHECK_PHASE(JVMTI_PHASE_LIVE)
1691 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1693 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1694 return JVMTI_ERROR_NONE;
1698 /* *****************************************************************************
1702 *******************************************************************************/
1705 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1708 CHECK_PHASE(JVMTI_PHASE_LIVE)
1710 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1712 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1713 return JVMTI_ERROR_NONE;
1717 /* Allocate ********************************************************************
1719 Allocate an area of memory through the JVM TI allocator. The allocated
1720 memory should be freed with Deallocate
1722 *******************************************************************************/
1725 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1728 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1729 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1731 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1732 if (*mem_ptr == NULL)
1733 return JVMTI_ERROR_OUT_OF_MEMORY;
1735 return JVMTI_ERROR_NONE;
1740 /* Deallocate ******************************************************************
1742 Deallocate mem using the JVM TI allocator.
1744 *******************************************************************************/
1747 Deallocate (jvmtiEnv * env, unsigned char *mem)
1749 /* let Boehm GC do the job */
1751 return JVMTI_ERROR_NONE;
1755 /* GetClassSignature ************************************************************
1757 For the class indicated by klass, return the JNI type signature and the
1758 generic signature of the class.
1760 *******************************************************************************/
1763 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1767 CHECK_PHASE(JVMTI_PHASE_START)
1768 CHECK_PHASE(JVMTI_PHASE_LIVE)
1771 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1772 return JVMTI_ERROR_NULL_POINTER;
1774 *signature_ptr = (char*)
1775 heap_allocate(sizeof(char) *
1776 ((classinfo*)klass)->name->blength,true,NULL);
1778 utf_sprint_convert_to_latin1(*signature_ptr, ((classinfo*)klass)->name);
1779 *generic_ptr = NULL;
1781 return JVMTI_ERROR_NONE;
1784 /* GetClassStatus *************************************************************
1786 Get status of the class.
1788 *******************************************************************************/
1791 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1795 CHECK_PHASE(JVMTI_PHASE_START)
1796 CHECK_PHASE(JVMTI_PHASE_LIVE)
1799 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1800 return JVMTI_ERROR_INVALID_CLASS;
1802 if (status_ptr == NULL)
1803 return JVMTI_ERROR_NULL_POINTER;
1805 c = (classinfo*)klass;
1808 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1809 if (c->state & CLASS_LINKED)
1810 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1812 if (c->state & CLASS_INITIALIZED)
1813 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1815 if (c->state & CLASS_ERROR)
1816 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1818 if (c->vftbl->arraydesc != NULL)
1819 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1821 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1822 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1824 return JVMTI_ERROR_NONE;
1828 /* GetSourceFileName **********************************************************
1830 For the class indicated by klass, return the source file name.
1832 *******************************************************************************/
1835 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1840 CHECK_PHASE(JVMTI_PHASE_START)
1841 CHECK_PHASE(JVMTI_PHASE_LIVE)
1843 CHECK_CAPABILITY(env,can_get_source_file_name)
1845 if ((klass == NULL)||(source_name_ptr == NULL))
1846 return JVMTI_ERROR_NULL_POINTER;
1848 size = (((classinfo*)klass)->sourcefile->blength)+1;
1850 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1852 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1853 (*source_name_ptr)[size]='\0';
1855 return JVMTI_ERROR_NONE;
1859 /* GetClassModifiers **********************************************************
1861 For class klass return the access flags
1863 *******************************************************************************/
1866 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1869 CHECK_PHASE(JVMTI_PHASE_START)
1870 CHECK_PHASE(JVMTI_PHASE_LIVE)
1873 if (modifiers_ptr == NULL)
1874 return JVMTI_ERROR_NULL_POINTER;
1876 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1877 return JVMTI_ERROR_INVALID_CLASS;
1879 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1881 return JVMTI_ERROR_NONE;
1885 /* GetClassMethods *************************************************************
1887 For class klass return a count of methods and a list of method IDs
1889 *******************************************************************************/
1892 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1893 jmethodID ** methods_ptr)
1898 CHECK_PHASE(JVMTI_PHASE_START)
1899 CHECK_PHASE(JVMTI_PHASE_LIVE)
1902 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1903 return JVMTI_ERROR_NULL_POINTER;
1905 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1906 return JVMTI_ERROR_INVALID_CLASS;
1908 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1909 *methods_ptr = (jmethodID*)
1910 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1912 for (i=0; i<*method_count_ptr;i++)
1913 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1915 return JVMTI_ERROR_NONE;
1919 /* GetClassFields *************************************************************
1921 For the class indicated by klass, return a count of fields and a list of
1924 *******************************************************************************/
1927 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1928 jfieldID ** fields_ptr)
1931 CHECK_PHASE(JVMTI_PHASE_START)
1932 CHECK_PHASE(JVMTI_PHASE_LIVE)
1935 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1936 return JVMTI_ERROR_NULL_POINTER;
1938 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1939 *fields_ptr = (jfieldID*)
1940 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1942 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1943 sizeof(jfieldID) * (*field_count_ptr));
1945 return JVMTI_ERROR_NONE;
1949 /* GetImplementedInterfaces ***************************************************
1951 Return the direct super-interfaces of this class.
1953 *******************************************************************************/
1956 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1957 jint * interface_count_ptr,
1958 jclass ** interfaces_ptr)
1961 classref_or_classinfo *interfaces;
1965 CHECK_PHASE(JVMTI_PHASE_START)
1966 CHECK_PHASE(JVMTI_PHASE_LIVE)
1969 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1970 return JVMTI_ERROR_NULL_POINTER;
1972 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1973 return JVMTI_ERROR_INVALID_CLASS;
1976 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1978 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1980 interfaces = ((classinfo*)klass)->interfaces;
1981 for (i=0; i<*interface_count_ptr; i++) {
1982 if (IS_CLASSREF(interfaces[i]))
1983 tmp = load_class_bootstrap(interfaces[i].ref->name);
1985 tmp = interfaces[i].cls;
1987 *interfaces_ptr[i]=tmp;
1990 return JVMTI_ERROR_NONE;
1994 /* IsInterface ****************************************************************
1996 Determines whether a class object reference represents an interface.
1998 *******************************************************************************/
2001 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
2004 CHECK_PHASE(JVMTI_PHASE_START)
2005 CHECK_PHASE(JVMTI_PHASE_LIVE)
2008 if ((klass == NULL)||(is_interface_ptr == NULL))
2009 return JVMTI_ERROR_NULL_POINTER;
2011 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
2013 return JVMTI_ERROR_NONE;
2016 /* IsArrayClass ***************************************************************
2018 Determines whether a class object reference represents an array.
2020 *******************************************************************************/
2023 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2026 CHECK_PHASE(JVMTI_PHASE_START)
2027 CHECK_PHASE(JVMTI_PHASE_LIVE)
2030 if (is_array_class_ptr == NULL)
2031 return JVMTI_ERROR_NULL_POINTER;
2033 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2035 return JVMTI_ERROR_NONE;
2039 /* GetClassLoader *************************************************************
2041 For the class indicated by klass, return via classloader_ptr a reference to
2042 the class loader for the class.
2044 *******************************************************************************/
2047 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2050 CHECK_PHASE(JVMTI_PHASE_START)
2051 CHECK_PHASE(JVMTI_PHASE_LIVE)
2054 if ((klass == NULL)||(classloader_ptr == NULL))
2055 return JVMTI_ERROR_NULL_POINTER;
2057 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2059 return JVMTI_ERROR_NONE;
2063 /* GetObjectHashCode **********************************************************
2065 Return hash code for object object
2067 *******************************************************************************/
2070 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2073 CHECK_PHASE(JVMTI_PHASE_START)
2074 CHECK_PHASE(JVMTI_PHASE_LIVE)
2077 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2078 if (!builtin_instanceof(object,class_java_lang_Object))
2079 return JVMTI_ERROR_INVALID_OBJECT;
2081 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2083 return JVMTI_ERROR_NONE;
2087 /* *****************************************************************************
2091 *******************************************************************************/
2094 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2095 jvmtiMonitorUsage * info_ptr)
2098 CHECK_PHASE(JVMTI_PHASE_LIVE)
2100 CHECK_CAPABILITY(env,can_get_monitor_info)
2102 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2103 return JVMTI_ERROR_NONE;
2107 /* GetFieldName ***************************************************************
2109 For the field indicated by klass and field, return the field name and
2112 *******************************************************************************/
2115 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2116 char **name_ptr, char **signature_ptr, char **generic_ptr)
2121 CHECK_PHASE(JVMTI_PHASE_START)
2122 CHECK_PHASE(JVMTI_PHASE_LIVE)
2125 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2126 return JVMTI_ERROR_NULL_POINTER;
2128 size = (((fieldinfo*)field)->name->blength);
2129 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2130 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2132 size = (((fieldinfo*)field)->descriptor->blength);
2133 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2134 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2136 *generic_ptr = NULL;
2138 return JVMTI_ERROR_NONE;
2142 /* GetFieldDeclaringClass *****************************************************
2144 For the field indicated by klass and field return the class that defined it
2145 The declaring class will either be klass, a superclass, or an implemented
2148 *******************************************************************************/
2151 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2152 jclass * declaring_class_ptr)
2155 CHECK_PHASE(JVMTI_PHASE_START)
2156 CHECK_PHASE(JVMTI_PHASE_LIVE)
2159 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2161 return JVMTI_ERROR_NONE;
2165 /* GetFieldModifiers **********************************************************
2167 Return access flags of field field
2169 *******************************************************************************/
2172 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2173 jint * modifiers_ptr)
2176 CHECK_PHASE(JVMTI_PHASE_START)
2177 CHECK_PHASE(JVMTI_PHASE_LIVE)
2180 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2181 return JVMTI_ERROR_INVALID_OBJECT;
2183 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2185 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2187 *modifiers_ptr = ((fieldinfo*)field)->flags;
2189 return JVMTI_ERROR_NONE;
2193 /* IsFieldSynthetic ***********************************************************
2197 *******************************************************************************/
2200 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2201 jboolean * is_synthetic_ptr)
2204 CHECK_PHASE(JVMTI_PHASE_START)
2205 CHECK_PHASE(JVMTI_PHASE_LIVE)
2207 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2209 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2210 return JVMTI_ERROR_NONE;
2214 /* GetMethodName ***************************************************************
2216 For the method indicated by method, return the method name via name_ptr and
2217 method signature via signature_ptr.
2219 *******************************************************************************/
2222 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2223 char **signature_ptr, char **generic_ptr)
2225 methodinfo* m = (methodinfo*)method;
2228 CHECK_PHASE(JVMTI_PHASE_START)
2229 CHECK_PHASE(JVMTI_PHASE_LIVE)
2233 if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
2235 if (name_ptr == NULL) {
2237 heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
2238 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2241 if (signature_ptr == NULL) {
2242 *signature_ptr = (char*)
2243 heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
2244 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2247 if (generic_ptr == NULL) {
2248 /* there is no generic signature attribute */
2249 *generic_ptr = NULL;
2252 return JVMTI_ERROR_NONE;
2256 /* GetMethodDeclaringClass *****************************************************
2258 For the method indicated by method, return the class that defined it.
2260 *******************************************************************************/
2263 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2264 jclass * declaring_class_ptr)
2267 CHECK_PHASE(JVMTI_PHASE_START)
2268 CHECK_PHASE(JVMTI_PHASE_LIVE)
2271 if ((method == NULL) || (declaring_class_ptr == NULL))
2272 return JVMTI_ERROR_NULL_POINTER;
2274 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2276 return JVMTI_ERROR_NONE;
2280 /* GetMethodModifiers **********************************************************
2282 For the method indicated by method, return the access flags.
2284 *******************************************************************************/
2287 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2290 CHECK_PHASE(JVMTI_PHASE_START)
2291 CHECK_PHASE(JVMTI_PHASE_LIVE)
2294 if ((method == NULL) || (modifiers_ptr == NULL))
2295 return JVMTI_ERROR_NULL_POINTER;
2297 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2299 return JVMTI_ERROR_NONE;
2303 /* GetMaxLocals ****************************************************************
2305 For the method indicated by method, return the number of local variable slots
2306 used by the method, including the local variables used to pass parameters to
2307 the method on its invocation.
2309 *******************************************************************************/
2312 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2315 CHECK_PHASE(JVMTI_PHASE_START)
2316 CHECK_PHASE(JVMTI_PHASE_LIVE)
2319 if ((method == NULL)||(max_ptr == NULL))
2320 return JVMTI_ERROR_NULL_POINTER;
2322 if (((methodinfo*)method)->flags & ACC_NATIVE)
2323 return JVMTI_ERROR_NATIVE_METHOD;
2325 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2327 return JVMTI_ERROR_NONE;
2332 /* GetArgumentsSize ************************************************************
2334 Return the number of local variable slots used by the method's arguments.
2336 *******************************************************************************/
2339 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2342 CHECK_PHASE(JVMTI_PHASE_START)
2343 CHECK_PHASE(JVMTI_PHASE_LIVE)
2346 if ((method == NULL)||(size_ptr == NULL))
2347 return JVMTI_ERROR_NULL_POINTER;
2349 if (((methodinfo*)method)->flags & ACC_NATIVE)
2350 return JVMTI_ERROR_NATIVE_METHOD;
2352 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2353 return JVMTI_ERROR_NONE;
2358 /* GetLineNumberTable ***********************************************************
2360 Return table of source line number entries for a given method
2362 *******************************************************************************/
2365 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2366 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2371 CHECK_PHASE(JVMTI_PHASE_START)
2372 CHECK_PHASE(JVMTI_PHASE_LIVE)
2374 CHECK_CAPABILITY(env,can_get_line_numbers)
2376 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2377 return JVMTI_ERROR_NULL_POINTER;
2378 if (((methodinfo*)method)->flags & ACC_NATIVE)
2379 return JVMTI_ERROR_NATIVE_METHOD;
2380 if (((methodinfo*)method)->linenumbers == NULL)
2381 return JVMTI_ERROR_ABSENT_INFORMATION;
2383 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2384 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2385 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2388 for (i=0; i < *entry_count_ptr; i++) {
2389 (*table_ptr)[i].start_location =
2390 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2391 (*table_ptr)[i].line_number =
2392 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2395 return JVMTI_ERROR_NONE;
2399 /* GetMethodLocation ***********************************************************
2401 For the method indicated by method, return the beginning and ending addresses
2402 through start_location_ptr and end_location_ptr. In cacao this points to
2403 entry point in machine code and length of machine code
2405 *******************************************************************************/
2408 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2409 jlocation * start_location_ptr,
2410 jlocation * end_location_ptr)
2412 methodinfo* m = (methodinfo*)method;
2415 CHECK_PHASE(JVMTI_PHASE_START)
2416 CHECK_PHASE(JVMTI_PHASE_LIVE)
2419 if ((method == NULL) || (start_location_ptr == NULL) ||
2420 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2422 /* XXX we return the location of the most recent code. Don't know
2423 * if there is a way to teach jvmti that a method can have more
2424 * than one location. -Edwin */
2426 /* XXX Don't know if that's the right way to deal with not-yet-
2427 * compiled methods. -Edwin */
2429 fprintf(stderr,"GetMethodLocation *** XXX todo \n");
2432 return JVMTI_ERROR_INTERNAL;
2434 *start_location_ptr = (jlocation)m->code->mcode;
2435 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2436 return JVMTI_ERROR_NONE;
2440 /* GetLocalVariableTable *******************************************************
2442 Return local variable information.
2444 *******************************************************************************/
2447 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2448 jint * entry_count_ptr,
2449 jvmtiLocalVariableEntry ** table_ptr)
2452 CHECK_PHASE(JVMTI_PHASE_LIVE)
2454 CHECK_CAPABILITY(env,can_access_local_variables)
2456 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2458 return JVMTI_ERROR_NONE;
2462 /* GetBytecode *****************************************************************
2464 For the method indicated by method, return the byte codes that implement the
2467 *******************************************************************************/
2470 GetBytecodes (jvmtiEnv * env, jmethodID method,
2471 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2473 methodinfo* m = (methodinfo*)method;;
2476 CHECK_PHASE(JVMTI_PHASE_START)
2477 CHECK_PHASE(JVMTI_PHASE_LIVE)
2479 CHECK_CAPABILITY(env,can_get_bytecodes)
2481 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2482 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2484 *bytecode_count_ptr = m->jcodelength;
2485 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2486 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2488 return JVMTI_ERROR_NONE;
2492 /* IsMethodNative **************************************************************
2494 For the method indicated by method, return a value indicating whether the
2495 method is a native function
2497 *******************************************************************************/
2500 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2503 CHECK_PHASE(JVMTI_PHASE_START)
2504 CHECK_PHASE(JVMTI_PHASE_LIVE)
2507 if ((method == NULL)||(is_native_ptr == NULL))
2508 return JVMTI_ERROR_NULL_POINTER;
2510 if (((methodinfo*)method)->flags & ACC_NATIVE)
2511 *is_native_ptr = JNI_TRUE;
2513 *is_native_ptr = JNI_FALSE;
2515 return JVMTI_ERROR_NONE;
2519 /* IsMethodSynthetic ***********************************************************
2521 return a value indicating whether the method is synthetic. Synthetic methods
2522 are generated by the compiler but not present in the original source code.
2524 *******************************************************************************/
2527 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2528 jboolean * is_synthetic_ptr)
2531 CHECK_PHASE(JVMTI_PHASE_START)
2532 CHECK_PHASE(JVMTI_PHASE_LIVE)
2534 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2536 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2537 return JVMTI_ERROR_NONE;
2541 /* GetLoadedClasses ************************************************************
2543 Return an array of all classes loaded in the virtual machine.
2545 *******************************************************************************/
2548 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2551 classcache_name_entry *nameentry;
2552 classcache_class_entry *classentry;
2555 CHECK_PHASE(JVMTI_PHASE_LIVE)
2558 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2559 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2563 heap_allocate(sizeof(jclass)*(hashtable_classcache.entries),true,NULL);
2565 /* look in every slot of the hashtable */
2566 for (i=0; i<hashtable_classcache.size; i++) {
2567 nameentry = hashtable_classcache.ptr[i];
2568 while (nameentry != NULL) { /* iterate over hashlink */
2570 /* filter pseudo classes $NEW$,$NULL$,$ARRAYSTUB$ out */
2571 if (nameentry->name->text[0]=='$')
2573 *class_count_ptr -= 1;
2577 classentry = nameentry->classes;
2578 while (classentry != NULL){ /* iterate over classes with same name */
2579 if (classentry->classobj != NULL) { /*get only loaded classes */
2580 assert(j<hashtable_classcache.entries);
2581 (*classes_ptr)[j]=classentry->classobj;
2584 classentry = classentry->next;
2586 nameentry = nameentry->hashlink;
2590 CLASSCACHE_UNLOCK();
2592 *class_count_ptr = j;
2594 return JVMTI_ERROR_NONE;
2598 /* GetClassLoaderClasses *******************************************************
2600 Returns an array of those classes for which this class loader has been
2601 recorded as an initiating loader.
2603 *******************************************************************************/
2606 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2607 jint * class_count_ptr, jclass ** classes_ptr)
2609 log_text("GetClassLoaderClasses called");
2612 CHECK_PHASE(JVMTI_PHASE_LIVE)
2615 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2616 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2618 /* behave like jdk 1.1 and make no distinction between initiating and
2619 defining class loaders */
2621 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2625 /* PopFrame *******************************************************************
2629 *******************************************************************************/
2632 PopFrame (jvmtiEnv * env, jthread thread)
2635 CHECK_PHASE(JVMTI_PHASE_LIVE)
2637 CHECK_CAPABILITY(env,can_pop_frame)
2639 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2640 return JVMTI_ERROR_NONE;
2644 /* RedefineClasses ************************************************************
2648 *******************************************************************************/
2651 RedefineClasses (jvmtiEnv * env, jint class_count,
2652 const jvmtiClassDefinition * class_definitions)
2655 CHECK_PHASE(JVMTI_PHASE_START)
2656 CHECK_PHASE(JVMTI_PHASE_LIVE)
2658 CHECK_CAPABILITY(env,can_redefine_classes)
2659 CHECK_CAPABILITY(env,can_redefine_any_class)
2660 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2661 return JVMTI_ERROR_NONE;
2665 /* GetVersionNumber ***********************************************************
2667 Return the JVM TI version identifier.
2669 *******************************************************************************/
2672 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2674 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2676 *version_ptr = JVMTI_VERSION;
2678 return JVMTI_ERROR_NONE;
2682 /* GetCapabilities ************************************************************
2684 Returns the optional JVM TI features which this environment currently
2687 *******************************************************************************/
2690 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2692 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2694 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2696 return JVMTI_ERROR_NONE;
2700 /* *****************************************************************************
2704 *******************************************************************************/
2707 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2708 char **source_debug_extension_ptr)
2711 CHECK_PHASE(JVMTI_PHASE_START)
2712 CHECK_PHASE(JVMTI_PHASE_LIVE)
2714 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2716 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2717 return JVMTI_ERROR_NONE;
2721 /* IsMethodObsolete ************************************************************
2723 Determine if a method ID refers to an obsolete method version.
2725 *******************************************************************************/
2728 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2729 jboolean * is_obsolete_ptr)
2732 CHECK_PHASE(JVMTI_PHASE_START)
2733 CHECK_PHASE(JVMTI_PHASE_LIVE)
2735 CHECK_CAPABILITY(env,can_redefine_classes)
2737 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2738 return JVMTI_ERROR_NONE;
2742 /* SuspendThreadList **********************************************************
2744 Suspend all threads in the request list.
2746 *******************************************************************************/
2749 SuspendThreadList (jvmtiEnv * env, jint request_count,
2750 const jthread * request_list, jvmtiError * results)
2757 CHECK_PHASE(JVMTI_PHASE_START)
2758 CHECK_PHASE(JVMTI_PHASE_LIVE)
2760 CHECK_CAPABILITY(env,can_suspend);
2762 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2763 if ((request_list==NULL) || (results == NULL))
2764 return JVMTI_ERROR_NULL_POINTER;
2766 me = jvmti_get_current_thread();
2768 for (i=0;i<request_count;i++) {
2769 if (request_list[i] == me)
2772 results[i]=SuspendThread(env, request_list[i]);
2775 if (suspendme != -1)
2776 results[suspendme]=SuspendThread(env, request_list[suspendme]);
2778 return JVMTI_ERROR_NONE;
2782 /* ResumeThreadList ***********************************************************
2784 Resumes all threads in the request list.
2786 *******************************************************************************/
2789 ResumeThreadList (jvmtiEnv * env, jint request_count,
2790 const jthread * request_list, jvmtiError * results)
2795 CHECK_PHASE(JVMTI_PHASE_LIVE)
2797 CHECK_CAPABILITY(env,can_suspend);
2799 if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2800 if ((request_list==NULL) || (results == NULL))
2801 return JVMTI_ERROR_NULL_POINTER;
2803 for (i=0;i<request_count;i++)
2804 results[i]=ResumeThread(env, request_list[i]);
2806 return JVMTI_ERROR_NONE;
2810 /* GetStackTrace **************************************************************
2812 Get information about the stack of a thread
2814 *******************************************************************************/
2817 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2818 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2821 stacktracebuffer* trace;
2826 CHECK_PHASE(JVMTI_PHASE_LIVE)
2829 if (thread != NULL){
2830 if(!builtin_instanceof(thread,class_java_lang_Thread))
2831 return JVMTI_ERROR_INVALID_THREAD;
2833 CHECK_THREAD_IS_ALIVE(thread);
2836 if((count_ptr == NULL)||(frame_buffer == NULL))
2837 return JVMTI_ERROR_NULL_POINTER;
2839 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2841 er = getcacaostacktrace(&trace, thread);
2842 if (er==JVMTI_ERROR_NONE) {
2847 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2848 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2850 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2851 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2852 /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
2853 frame_buffer[j].location = 0;
2858 return JVMTI_ERROR_NONE;
2862 /* GetThreadListStackTraces ***************************************************
2864 Get information about the stacks of the supplied threads.
2866 *******************************************************************************/
2869 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2870 const jthread * thread_list,
2871 jint max_frame_count,
2872 jvmtiStackInfo ** stack_info_ptr)
2878 CHECK_PHASE(JVMTI_PHASE_LIVE)
2881 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2882 return JVMTI_ERROR_NULL_POINTER;
2884 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2886 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2888 *stack_info_ptr = (jvmtiStackInfo*)
2889 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2891 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2892 (*stack_info_ptr)[i].thread=thread_list[i];
2893 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2894 (*stack_info_ptr)[i].frame_buffer =
2895 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2896 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2897 (*stack_info_ptr)[i].frame_buffer,
2898 &((*stack_info_ptr)[i].frame_count));
2900 if (er != JVMTI_ERROR_NONE) return er;
2903 return JVMTI_ERROR_NONE;
2907 /* GetAllStackTraces **********************************************************
2909 Get stack traces of all live threads
2911 *******************************************************************************/
2914 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2915 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2917 jthread *threads_ptr;
2921 CHECK_PHASE(JVMTI_PHASE_LIVE)
2924 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2926 /* todo: all threads have to be suspended */
2928 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2929 return JVMTI_ERROR_INTERNAL;
2931 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2932 max_frame_count, stack_info_ptr);
2934 /* todo: resume all threads have to be suspended */
2935 if (er != JVMTI_ERROR_NONE) return er;
2937 return JVMTI_ERROR_NONE;
2941 /* GetThreadLocalStorage ******************************************************
2943 Get the value of the JVM TI thread-local storage.
2945 *******************************************************************************/
2948 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2950 jvmtiThreadLocalStorage *tls;
2953 CHECK_PHASE(JVMTI_PHASE_START)
2954 CHECK_PHASE(JVMTI_PHASE_LIVE)
2958 thread = (jthread) THREADOBJECT;
2960 if (!builtin_instanceof(thread,class_java_lang_Thread))
2961 return JVMTI_ERROR_INVALID_THREAD;
2962 CHECK_THREAD_IS_ALIVE(thread);
2965 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2967 tls = ((environment*)env)->tls;
2968 while ((tls->thread != thread) && (tls != NULL)) {
2972 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2974 *data_ptr = tls->data;
2976 return JVMTI_ERROR_NONE;
2980 /* SetThreadLocalStorage *******************************************************
2982 Stores a pointer value associated with each environment-thread pair. The
2983 value is NULL unless set with this function. Agents can allocate memory in
2984 which they store thread specific information
2986 *******************************************************************************/
2989 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2991 jvmtiThreadLocalStorage *tls, *pre;
2992 environment* env = (environment*)jenv;
2995 CHECK_PHASE(JVMTI_PHASE_START)
2996 CHECK_PHASE(JVMTI_PHASE_LIVE)
3000 thread = (jthread) THREADOBJECT;
3002 if (!builtin_instanceof(thread,class_java_lang_Thread))
3003 return JVMTI_ERROR_INVALID_THREAD;
3004 CHECK_THREAD_IS_ALIVE(thread);
3007 if (env->tls == NULL) {
3008 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3011 while ((tls->thread != thread) && (tls->next != NULL)) {
3014 if (tls->thread != thread) {
3015 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
3021 tls->data = (void*)data;
3023 /* remove current tls */
3025 while (pre->next == tls) pre = pre->next;
3026 pre->next = tls->next;
3028 return JVMTI_ERROR_NONE;
3032 /* *****************************************************************************
3036 *******************************************************************************/
3039 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3042 CHECK_PHASE(JVMTI_PHASE_START)
3043 CHECK_PHASE(JVMTI_PHASE_LIVE)
3045 CHECK_CAPABILITY(env,can_tag_objects)
3047 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3048 return JVMTI_ERROR_NONE;
3051 /* *****************************************************************************
3055 *******************************************************************************/
3058 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3061 CHECK_PHASE(JVMTI_PHASE_START)
3062 CHECK_PHASE(JVMTI_PHASE_LIVE)
3064 CHECK_CAPABILITY(env,can_tag_objects)
3066 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3067 return JVMTI_ERROR_NONE;
3071 /* ForceGarbageCollection *****************************************************
3073 Force boehm-gc to perform a garbage collection
3075 *******************************************************************************/
3078 ForceGarbageCollection (jvmtiEnv * env)
3081 CHECK_PHASE(JVMTI_PHASE_LIVE)
3086 return JVMTI_ERROR_NONE;
3090 /* IterateOverObjectsReachableFromObject **************************************
3094 *******************************************************************************/
3097 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3098 jvmtiObjectReferenceCallback
3099 object_reference_callback,
3103 CHECK_PHASE(JVMTI_PHASE_LIVE)
3105 CHECK_CAPABILITY(env,can_tag_objects)
3107 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3108 return JVMTI_ERROR_NONE;
3112 /* IterateOverReachableObjects ************************************************
3116 *******************************************************************************/
3119 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3121 jvmtiStackReferenceCallback
3123 jvmtiObjectReferenceCallback
3124 object_ref_callback, void *user_data)
3127 CHECK_PHASE(JVMTI_PHASE_LIVE)
3129 CHECK_CAPABILITY(env,can_tag_objects)
3131 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3132 return JVMTI_ERROR_NONE;
3136 /* IterateOverHeap ************************************************************
3140 *******************************************************************************/
3143 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3144 jvmtiHeapObjectCallback heap_object_callback,
3148 CHECK_PHASE(JVMTI_PHASE_LIVE)
3150 CHECK_CAPABILITY(env,can_tag_objects)
3152 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3153 return JVMTI_ERROR_NONE;
3157 /* IterateOverInstancesOfClass ************************************************
3161 *******************************************************************************/
3164 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3165 jvmtiHeapObjectFilter object_filter,
3166 jvmtiHeapObjectCallback
3167 heap_object_callback, void *user_data)
3170 CHECK_PHASE(JVMTI_PHASE_LIVE)
3172 CHECK_CAPABILITY(env,can_tag_objects)
3174 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3175 return JVMTI_ERROR_NONE;
3179 /* *****************************************************************************
3183 *******************************************************************************/
3186 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3187 jint * count_ptr, jobject ** object_result_ptr,
3188 jlong ** tag_result_ptr)
3191 CHECK_PHASE(JVMTI_PHASE_LIVE)
3193 CHECK_CAPABILITY(env,can_tag_objects)
3195 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3196 return JVMTI_ERROR_NONE;
3200 /* SetJNIFunctionTable **********************************************************
3202 Set the JNI function table in all current and future JNI environments
3204 *******************************************************************************/
3207 SetJNIFunctionTable (jvmtiEnv * env,
3208 const jniNativeInterface * function_table)
3211 CHECK_PHASE(JVMTI_PHASE_START)
3212 CHECK_PHASE(JVMTI_PHASE_LIVE)
3215 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3216 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3217 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3218 return JVMTI_ERROR_NONE;
3222 /* GetJNIFunctionTable *********************************************************
3224 Get the JNI function table. The JNI function table is copied into allocated
3227 *******************************************************************************/
3230 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3233 CHECK_PHASE(JVMTI_PHASE_START)
3234 CHECK_PHASE(JVMTI_PHASE_LIVE)
3237 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3238 *function_table = (jniNativeInterface*)
3239 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3240 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3241 return JVMTI_ERROR_NONE;
3245 /* SetEventCallbacks **********************************************************
3247 Set the functions to be called for each event. The callbacks are specified
3248 by supplying a replacement function table.
3250 *******************************************************************************/
3253 SetEventCallbacks (jvmtiEnv * env,
3254 const jvmtiEventCallbacks * callbacks,
3255 jint size_of_callbacks)
3258 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3259 CHECK_PHASE(JVMTI_PHASE_LIVE)
3262 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3265 if (callbacks == NULL) { /* remove the existing callbacks */
3266 memset(&(((environment* )env)->callbacks), 0,
3267 sizeof(jvmtiEventCallbacks));
3270 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3272 return JVMTI_ERROR_NONE;
3276 /* GenerateEvents *************************************************************
3278 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3279 the current state of the VM.
3281 *******************************************************************************/
3284 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3287 CHECK_PHASE(JVMTI_PHASE_LIVE)
3290 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3291 return JVMTI_ERROR_NONE;
3295 /* GetExtensionFunctions ******************************************************
3297 Returns the set of extension functions.
3299 *******************************************************************************/
3302 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3303 jvmtiExtensionFunctionInfo ** extensions)
3306 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3307 CHECK_PHASE(JVMTI_PHASE_LIVE)
3310 if ((extension_count_ptr== NULL)||(extensions == NULL))
3311 return JVMTI_ERROR_NULL_POINTER;
3313 /* cacao has no extended functions yet */
3314 *extension_count_ptr = 0;
3316 return JVMTI_ERROR_NONE;
3320 /* GetExtensionEvents *********************************************************
3322 Returns the set of extension events.
3324 *******************************************************************************/
3327 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3328 jvmtiExtensionEventInfo ** extensions)
3331 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3332 CHECK_PHASE(JVMTI_PHASE_LIVE)
3335 if ((extension_count_ptr== NULL)||(extensions == NULL))
3336 return JVMTI_ERROR_NULL_POINTER;
3338 /* cacao has no extended events yet */
3339 *extension_count_ptr = 0;
3341 return JVMTI_ERROR_NONE;
3345 /* SetExtensionEventCallback **************************************************
3347 Sets the callback function for an extension event and enables the event.
3349 *******************************************************************************/
3352 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3353 jvmtiExtensionEvent callback)
3356 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3357 CHECK_PHASE(JVMTI_PHASE_LIVE)
3360 /* cacao has no extended events yet */
3361 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3365 /* DisposeEnvironment **********************************************************
3367 Shutdown a JVM TI connection created with JNI GetEnv.
3369 *******************************************************************************/
3372 DisposeEnvironment (jvmtiEnv * env)
3374 environment* cacao_env = (environment*)env;
3375 environment* tenvs = envs;
3376 jvmtiThreadLocalStorage *jtls, *tjtls;
3378 if (tenvs != cacao_env) {
3379 while (tenvs->next != cacao_env) {
3380 tenvs = tenvs->next;
3382 tenvs->next = cacao_env->next;
3386 cacao_env->env=NULL;
3387 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3388 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3389 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3390 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3391 cacao_env->EnvironmentLocalStorage = NULL;
3393 jtls = cacao_env->tls;
3394 while (jtls != NULL) {
3399 cacao_env->tls = NULL;
3402 jvmti_cacaodbgserver_quit();
3404 /* let the GC do the rest */
3405 return JVMTI_ERROR_NONE;
3409 /* GetErrorName ***************************************************************
3411 Return the symbolic name for an error code.
3413 *******************************************************************************/
3415 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3416 memcpy(*name_ptr, &str, sizeof(str)); \
3420 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3422 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3425 case JVMTI_ERROR_NONE :
3426 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3427 case JVMTI_ERROR_NULL_POINTER :
3428 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3429 case JVMTI_ERROR_OUT_OF_MEMORY :
3430 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3431 case JVMTI_ERROR_ACCESS_DENIED :
3432 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3433 case JVMTI_ERROR_UNATTACHED_THREAD :
3434 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3435 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3436 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3437 case JVMTI_ERROR_WRONG_PHASE :
3438 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3439 case JVMTI_ERROR_INTERNAL :
3440 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3441 case JVMTI_ERROR_INVALID_PRIORITY :
3442 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3443 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3444 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3445 case JVMTI_ERROR_THREAD_SUSPENDED :
3446 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3447 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3448 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3449 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3450 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3451 case JVMTI_ERROR_NO_MORE_FRAMES :
3452 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3453 case JVMTI_ERROR_OPAQUE_FRAME :
3454 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3455 case JVMTI_ERROR_DUPLICATE :
3456 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3457 case JVMTI_ERROR_NOT_FOUND :
3458 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3459 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3460 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3461 case JVMTI_ERROR_INTERRUPT :
3462 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3463 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3464 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3465 case JVMTI_ERROR_NOT_AVAILABLE :
3466 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3467 case JVMTI_ERROR_ABSENT_INFORMATION :
3468 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3469 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3470 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3471 case JVMTI_ERROR_NATIVE_METHOD :
3472 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3473 case JVMTI_ERROR_INVALID_THREAD :
3474 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3475 case JVMTI_ERROR_INVALID_FIELDID :
3476 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3477 case JVMTI_ERROR_INVALID_METHODID :
3478 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3479 case JVMTI_ERROR_INVALID_LOCATION :
3480 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3481 case JVMTI_ERROR_INVALID_OBJECT :
3482 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3483 case JVMTI_ERROR_INVALID_CLASS :
3484 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3485 case JVMTI_ERROR_TYPE_MISMATCH :
3486 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3487 case JVMTI_ERROR_INVALID_SLOT :
3488 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3489 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3490 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3491 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3492 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3493 case JVMTI_ERROR_INVALID_MONITOR :
3494 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3495 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3496 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3497 case JVMTI_ERROR_INVALID_TYPESTATE :
3498 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3499 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3500 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3501 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3502 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3503 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3504 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3505 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3506 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3507 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3508 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3509 case JVMTI_ERROR_FAILS_VERIFICATION :
3510 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3511 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3512 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3513 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3514 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3515 case JVMTI_ERROR_NAMES_DONT_MATCH :
3516 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3517 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3518 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3519 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3520 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3522 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3524 return JVMTI_ERROR_NONE;
3527 /* GetJLocationFormat **********************************************************
3529 This function describes the representation of jlocation used in this VM.
3531 *******************************************************************************/
3534 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3536 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3537 return JVMTI_ERROR_NONE;
3541 /* GetSystemProperties ********************************************************
3543 The list of VM system property keys which may be used with GetSystemProperty
3546 *******************************************************************************/
3549 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3551 jmethodID mid, moremid;
3552 classinfo *sysclass, *propclass, *enumclass;
3553 java_objectheader *sysprop, *keys, *obj;
3558 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3559 CHECK_PHASE(JVMTI_PHASE_LIVE)
3562 if ((count_ptr == NULL) || (property_ptr == NULL))
3563 return JVMTI_ERROR_NULL_POINTER;
3565 sysclass = load_class_from_sysloader(
3566 utf_new_char_classname ("java/lang/System"));
3568 if (!sysclass) throw_main_exception_exit();
3570 mid = (jmethodID)class_resolvemethod(sysclass,
3571 utf_new_char("getProperties"),
3572 utf_new_char("()Ljava/util/Properties;"));
3573 if (!mid) throw_main_exception_exit();
3576 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3577 if (!sysprop) throw_main_exception_exit();
3579 propclass = sysprop->vftbl->class;
3581 mid = (jmethodID)class_resolvemethod(propclass,
3582 utf_new_char("size"),
3583 utf_new_char("()I"));
3584 if (!mid) throw_main_exception_exit();
3587 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3588 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3590 mid = (jmethodID)class_resolvemethod(propclass,
3591 utf_new_char("keys"),
3592 utf_new_char("()Ljava/util/Enumeration;"));
3593 if (!mid) throw_main_exception_exit();
3595 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3596 enumclass = keys->vftbl->class;
3598 moremid = (jmethodID)class_resolvemethod(enumclass,
3599 utf_new_char("hasMoreElements"),
3600 utf_new_char("()Z"));
3601 if (!moremid) throw_main_exception_exit();
3603 mid = (jmethodID)class_resolvemethod(propclass,
3604 utf_new_char("nextElement"),
3605 utf_new_char("()Ljava/lang/Object;"));
3606 if (!mid) throw_main_exception_exit();
3609 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3610 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3611 ch = javastring_tochar(obj);
3612 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3613 memcpy(*property_ptr[i], ch, strlen (ch));
3614 MFREE(ch,char,strlen(ch)+1);
3618 return JVMTI_ERROR_NONE;
3622 /* GetSystemProperty **********************************************************
3624 Return a VM system property value given the property key.
3626 *******************************************************************************/
3629 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3632 classinfo *sysclass, *propclass;
3633 java_objectheader *sysprop, *obj;
3637 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3638 CHECK_PHASE(JVMTI_PHASE_LIVE)
3641 if ((value_ptr == NULL) || (property == NULL))
3642 return JVMTI_ERROR_NULL_POINTER;
3644 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3645 if (!sysclass) throw_main_exception_exit();
3647 mid = (jmethodID)class_resolvemethod(sysclass,
3648 utf_new_char("getProperties"),
3649 utf_new_char("()Ljava/util/Properties;"));
3650 if (!mid) throw_main_exception_exit();
3652 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3654 propclass = sysprop->vftbl->class;
3656 mid = (jmethodID)class_resolvemethod(propclass,
3657 utf_new_char("getProperty"),
3658 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3659 if (!mid) throw_main_exception_exit();
3661 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3662 NULL, sysprop, mid, javastring_new_from_ascii(property));
3663 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3665 ch = javastring_tochar(obj);
3666 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3667 memcpy(*value_ptr, ch, strlen (ch));
3668 MFREE(ch,char,strlen(ch)+1);
3670 return JVMTI_ERROR_NONE;
3674 /* SetSystemProperty **********************************************************
3676 Set a VM system property value.
3678 *******************************************************************************/
3681 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3684 classinfo *sysclass, *propclass;
3685 java_objectheader *sysprop;
3688 CHECK_PHASE(JVMTI_PHASE_START)
3691 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3692 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3694 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3695 if (!sysclass) throw_main_exception_exit();
3697 mid = (jmethodID)class_resolvemethod(sysclass,
3698 utf_new_char("getProperties"),
3699 utf_new_char("()Ljava/util/Properties;"));
3700 if (!mid) throw_main_exception_exit();
3702 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3704 propclass = sysprop->vftbl->class;
3706 mid = (jmethodID)class_resolvemethod(propclass,
3707 utf_new_char("setProperty"),
3708 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3709 if (!mid) throw_main_exception_exit();
3711 _Jv_JNINativeInterface.CallObjectMethod(
3712 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3714 return JVMTI_ERROR_NONE;
3717 /* GetPhase ********************************************************************
3719 Return the current phase of VM execution
3721 *******************************************************************************/
3724 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3726 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3730 return JVMTI_ERROR_NONE;
3733 /* GetCurrentThreadCpuTimerInfo ************************************************
3737 *******************************************************************************/
3740 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3743 CHECK_PHASE(JVMTI_PHASE_START)
3744 CHECK_PHASE(JVMTI_PHASE_LIVE)
3746 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3748 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3750 return JVMTI_ERROR_NONE;
3753 /* GetCurrentThreadCpuTime ****************************************************
3757 *******************************************************************************/
3760 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3763 CHECK_PHASE(JVMTI_PHASE_START)
3764 CHECK_PHASE(JVMTI_PHASE_LIVE)
3766 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3768 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3769 return JVMTI_ERROR_NONE;
3772 /* GetThreadCpuTimerInfo ******************************************************
3776 *******************************************************************************/
3779 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3782 CHECK_PHASE(JVMTI_PHASE_START)
3783 CHECK_PHASE(JVMTI_PHASE_LIVE)
3785 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3787 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3788 return JVMTI_ERROR_NONE;
3791 /* GetThreadCpuTime ***********************************************************
3795 *******************************************************************************/
3798 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3801 CHECK_PHASE(JVMTI_PHASE_LIVE)
3803 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3804 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3805 return JVMTI_ERROR_NONE;
3808 /* GetTimerInfo ***************************************************************
3810 Get information about the GetTime timer.
3812 *******************************************************************************/
3815 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3817 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3819 info_ptr->max_value = !0x0;
3820 info_ptr->may_skip_forward = true;
3821 info_ptr->may_skip_backward = true;
3822 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3824 return JVMTI_ERROR_NONE;
3827 /* GetTime ********************************************************************
3829 Return the current value of the system timer, in nanoseconds
3831 *******************************************************************************/
3834 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3836 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3839 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3841 if (gettimeofday (&tp, NULL) == -1)
3842 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3844 *nanos_ptr = (jlong) tp.tv_sec;
3846 *nanos_ptr += (tp.tv_usec / 1000);
3848 return JVMTI_ERROR_NONE;
3851 /* GetPotentialCapabilities ***************************************************
3853 Returns the JVM TI features that can potentially be possessed by this
3854 environment at this time.
3856 *******************************************************************************/
3859 GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
3862 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3863 CHECK_PHASE(JVMTI_PHASE_LIVE)
3866 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3868 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3870 return JVMTI_ERROR_NONE;
3874 #define CHECK_ADD_CAPABILITY(env,CAN) \
3875 if (capabilities_ptr->CAN == 1) { \
3876 if (JVMTI_Capabilities.CAN == 0) \
3877 return JVMTI_ERROR_NOT_AVAILABLE; \
3879 env->capabilities.CAN = 1; \
3882 /* AddCapabilities ************************************************************
3884 Set new capabilities by adding the capabilities pointed to by
3885 capabilities_ptr. All previous capabilities are retained.
3887 *******************************************************************************/
3890 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3892 environment* cacao_env;
3895 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3896 CHECK_PHASE(JVMTI_PHASE_LIVE)
3899 if ((env == NULL) || (capabilities_ptr == NULL))
3900 return JVMTI_ERROR_NULL_POINTER;
3902 cacao_env = (environment*)env;
3904 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3905 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3906 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3907 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3908 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3909 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3910 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3911 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3912 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3913 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3914 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3915 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3916 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3917 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3918 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3919 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3920 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3921 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3922 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3923 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3924 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3925 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3926 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3927 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3928 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3929 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3930 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3931 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3932 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3933 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3934 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3935 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3936 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3939 return JVMTI_ERROR_NONE;
3943 #define CHECK_DEL_CAPABILITY(env,CAN) \
3944 if (capabilities_ptr->CAN == 1) \
3945 env->capabilities.CAN = 0;
3947 /* RelinquishCapabilities *****************************************************
3949 Relinquish the capabilities pointed to by capabilities_ptr.
3951 *******************************************************************************/
3954 RelinquishCapabilities (jvmtiEnv * env,
3955 const jvmtiCapabilities * capabilities_ptr)
3957 environment* cacao_env;
3960 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3961 CHECK_PHASE(JVMTI_PHASE_LIVE)
3964 if ((env == NULL) || (capabilities_ptr == NULL))
3965 return JVMTI_ERROR_NULL_POINTER;
3967 cacao_env = (environment*)env;
3969 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3970 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3971 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3972 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3973 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3974 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3975 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3976 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3977 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3978 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3979 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3980 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3981 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3982 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3983 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3984 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3985 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3986 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3987 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3988 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3989 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3990 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3991 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3992 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3993 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3994 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3995 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3996 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3997 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3998 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3999 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
4000 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
4001 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
4003 return JVMTI_ERROR_NONE;
4006 /* *****************************************************************************
4010 *******************************************************************************/
4013 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
4016 CHECK_PHASE(JVMTI_PHASE_START)
4017 CHECK_PHASE(JVMTI_PHASE_LIVE)
4020 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4022 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
4024 *processor_count_ptr = 1; /* where do I get this ?*/
4026 return JVMTI_ERROR_NONE;
4029 /* GetEnvironmentLocalStorage **************************************************
4031 Called by the agent to get the value of the JVM TI environment-local storage.
4033 *******************************************************************************/
4036 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4038 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4040 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4042 return JVMTI_ERROR_NONE;
4045 /* SetEnvironmentLocalStorage **************************************************
4047 The VM stores a pointer value associated with each environment. Agents can
4048 allocate memory in which they store environment specific information.
4050 *******************************************************************************/
4053 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4055 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4057 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4059 return JVMTI_ERROR_NONE;
4062 /* AddToBootstrapClassLoaderSearch ********************************************
4064 After the bootstrap class loader unsuccessfully searches for a class, the
4065 specified platform-dependent search path segment will be searched as well.
4067 *******************************************************************************/
4070 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4076 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4079 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4081 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4082 tmp_bcp = MNEW(char, ln);
4083 strcat(tmp_bcp, bootclasspath);
4084 strcat(tmp_bcp, ":");
4085 strcat(tmp_bcp, segment);
4086 MFREE(bootclasspath,char,ln);
4087 bootclasspath = tmp_bcp;
4089 return JVMTI_ERROR_NONE;
4092 /* SetVerboseFlag *************************************************************
4094 Control verbose output. This is the output which typically is sent to stderr
4096 *******************************************************************************/
4099 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4102 case JVMTI_VERBOSE_OTHER:
4103 /* where is this defined ?
4107 case JVMTI_VERBOSE_GC:
4108 opt_verbosegc = value;
4110 case JVMTI_VERBOSE_CLASS:
4111 loadverbose = value;
4113 case JVMTI_VERBOSE_JNI:
4116 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4118 return JVMTI_ERROR_NONE;
4121 /* GetObjectSize **************************************************************
4123 For the object object return the size.
4125 *******************************************************************************/
4128 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4131 CHECK_PHASE(JVMTI_PHASE_START)
4132 CHECK_PHASE(JVMTI_PHASE_LIVE)
4135 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4136 if (!builtin_instanceof(object,class_java_lang_Object))
4137 return JVMTI_ERROR_INVALID_OBJECT;
4139 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4141 return JVMTI_ERROR_NONE;
4145 /* *****************************************************************************
4147 Environment variables
4149 *******************************************************************************/
4151 static jvmtiCapabilities JVMTI_Capabilities = {
4152 0, /* can_tag_objects */
4153 0, /* can_generate_field_modification_events */
4154 0, /* can_generate_field_access_events */
4155 1, /* can_get_bytecodes */
4156 0, /* can_get_synthetic_attribute */
4158 #if defined(ENABLE_THREADS)
4159 1, /* can_get_owned_monitor_info */
4160 1, /* can_get_current_contended_monitor */
4162 0, /* can_get_owned_monitor_info */
4163 0, /* can_get_current_contended_monitor */
4166 0, /* can_get_monitor_info */
4167 0, /* can_pop_frame */
4168 0, /* can_redefine_classes */
4169 0, /* can_signal_thread */
4170 1, /* can_get_source_file_name */
4171 1, /* can_get_line_numbers */
4172 0, /* can_get_source_debug_extension */
4173 0, /* can_access_local_variables */
4174 0, /* can_maintain_original_method_order */
4175 0, /* can_generate_single_step_events */
4176 0, /* can_generate_exception_events */
4177 0, /* can_generate_frame_pop_events */
4178 0, /* can_generate_breakpoint_events */
4179 1, /* can_suspend */
4180 0, /* can_redefine_any_class */
4181 0, /* can_get_current_thread_cpu_time */
4182 0, /* can_get_thread_cpu_time */
4183 0, /* can_generate_method_entry_events */
4184 0, /* can_generate_method_exit_events */
4185 0, /* can_generate_all_class_hook_events */
4186 0, /* can_generate_compiled_method_load_events */
4187 0, /* can_generate_monitor_events */
4188 0, /* can_generate_vm_object_alloc_events */
4189 0, /* can_generate_native_method_bind_events */
4190 0, /* can_generate_garbage_collection_events */
4191 0, /* can_generate_object_free_events */
4194 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4196 &SetEventNotificationMode,
4204 &GetOwnedMonitorInfo,
4205 &GetCurrentContendedMonitor,
4207 &GetTopThreadGroups,
4208 &GetThreadGroupInfo,
4209 &GetThreadGroupChildren,
4231 &RawMonitorNotifyAll,
4235 &SetFieldAccessWatch,
4236 &ClearFieldAccessWatch,
4237 &SetFieldModificationWatch,
4238 &ClearFieldModificationWatch,
4248 &GetImplementedInterfaces,
4253 &GetObjectMonitorUsage,
4255 &GetFieldDeclaringClass,
4259 &GetMethodDeclaringClass,
4260 &GetMethodModifiers,
4264 &GetLineNumberTable,
4266 &GetLocalVariableTable,
4273 &GetClassLoaderClasses,
4284 &GetSourceDebugExtension,
4295 &GetThreadListStackTraces,
4296 &GetThreadLocalStorage,
4297 &SetThreadLocalStorage,
4302 &ForceGarbageCollection,
4303 &IterateOverObjectsReachableFromObject,
4304 &IterateOverReachableObjects,
4306 &IterateOverInstancesOfClass,
4308 &GetObjectsWithTags,
4314 &SetJNIFunctionTable,
4315 &GetJNIFunctionTable,
4318 &GetExtensionFunctions,
4319 &GetExtensionEvents,
4320 &SetExtensionEventCallback,
4321 &DisposeEnvironment,
4323 &GetJLocationFormat,
4324 &GetSystemProperties,
4328 &GetCurrentThreadCpuTimerInfo,
4329 &GetCurrentThreadCpuTime,
4330 &GetThreadCpuTimerInfo,
4334 &GetPotentialCapabilities,
4337 &RelinquishCapabilities,
4338 &GetAvailableProcessors,
4341 &GetEnvironmentLocalStorage,
4342 &SetEnvironmentLocalStorage,
4343 &AddToBootstrapClassLoaderSearch,
4352 void jvmti_set_phase(jvmtiPhase p) {
4355 fprintf (stderr,"set JVMTI phase %d\n",p);
4359 case JVMTI_PHASE_ONLOAD:
4362 case JVMTI_PHASE_PRIMORDIAL:
4365 case JVMTI_PHASE_START:
4367 d.ev = JVMTI_EVENT_VM_START;
4369 case JVMTI_PHASE_LIVE:
4371 d.ev = JVMTI_EVENT_VM_INIT;
4372 jvmti_fireEvent(&d);
4373 /* thread start event for main thread */
4374 d.ev = JVMTI_EVENT_THREAD_START;
4376 case JVMTI_PHASE_DEAD:
4378 d.ev = JVMTI_EVENT_VM_DEATH;
4381 log_text("wrong jvmti phase to be set");
4385 jvmti_fireEvent(&d);
4388 jvmtiEnv* jvmti_new_environment() {
4392 envs = heap_allocate(sizeof(environment),true,NULL);
4396 while (env->next != NULL) env = env->next;
4397 env->next = heap_allocate(sizeof(environment),true,NULL);
4401 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4402 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4403 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4404 sizeof(jvmtiEventModeLL));
4405 /* To possess a capability, the agent must add the capability.*/
4406 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4407 RelinquishCapabilities(&(env->env),&(env->capabilities));
4408 env->EnvironmentLocalStorage = NULL;
4411 /* initialize cacao debugging facilities */
4412 jvmti_cacao_debug_init();
4414 return (jvmtiEnv*)env;
4417 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4423 len = strlen(opt_arg);
4425 /* separate argumtents */
4426 while ((opt_arg[i]!='=')&&(i<len)) i++;
4428 arg = &opt_arg[i+1];
4434 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4435 strncpy(*libname,opt_arg,i);
4439 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4440 strncpy(*libname,"lib",3);
4441 strncpy(&(*libname)[3],opt_arg,i);
4442 strncpy(&(*libname)[i+3],".so",3);
4445 /* try to open the library */
4447 if (!(*handle = lt_dlopen(*libname))) {
4448 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4452 /* resolve Agent_OnLoad function */
4453 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4454 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4458 /* resolve Agent_UnLoad function */
4459 unload = lt_dlsym(*handle, "Agent_Unload");
4462 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4463 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4465 if (retval != 0) exit (retval);
4468 void jvmti_agentunload() {
4469 if (unload != NULL) {
4470 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4471 ((JavaVM*) &_Jv_JNIInvokeInterface);
4476 * These are local overrides for various environment variables in Emacs.
4477 * Please do not remove this and leave it at the end of the file, where
4478 * Emacs will automagically detect them.
4479 * ---------------------------------------------------------------------
4482 * indent-tabs-mode: t
4486 * vim:noexpandtab:sw=4:ts=4: