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 4946 2006-05-24 11:00:38Z motse $
40 #include "native/jni.h"
41 #include "native/native.h"
42 #include "native/jvmti/cacaodbg.h"
43 #include "native/jvmti/jvmti.h"
44 #include "vm/global.h"
45 #include "vm/loader.h"
46 #include "vm/builtin.h"
47 #include "vm/jit/asmpart.h"
49 #include "vm/classcache.h"
51 #include "toolbox/logging.h"
52 #include "vm/options.h"
53 #include "vm/stringlocal.h"
54 #include "mm/memory.h"
55 #include "threads/native/threads.h"
56 #include "threads/native/lock.h"
57 #include "vm/exceptions.h"
58 #include "native/include/java_util_Vector.h"
59 #include "native/include/java_io_PrintStream.h"
60 #include "native/include/java_io_InputStream.h"
61 #include "native/include/java_lang_Cloneable.h"
62 #include "native/include/java_lang_ThreadGroup.h"
63 #include "native/include/java_lang_VMObject.h"
64 #include "native/include/java_lang_VMSystem.h"
65 #include "native/include/java_lang_VMClass.h"
67 #include "boehm-gc/include/gc.h"
70 #include <linux/unistd.h>
72 #include "toolbox/logging.h"
74 #include <sys/types.h>
79 #if defined(ENABLE_THREADS)
80 #include "threads/native/threads.h"
88 typedef struct _environment environment;
89 static environment *envs=NULL;
90 pthread_mutex_t dbgcomlock;
92 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
94 static jvmtiPhase phase;
95 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
96 struct _jvmtiEventModeLL {
99 jvmtiEventModeLL *next;
102 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
103 struct _jvmtiThreadLocalStorage{
106 jvmtiThreadLocalStorage *next;
109 struct _environment {
112 jvmtiEventCallbacks callbacks;
113 /* table for enabled/disabled jvmtiEvents - first element contains global
115 jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
116 jvmtiCapabilities capabilities;
117 void *EnvironmentLocalStorage;
118 jvmtiThreadLocalStorage *tls;
121 static struct jvmtiEnv_struct JVMTI_EnvTable;
122 static jvmtiCapabilities JVMTI_Capabilities;
123 static lt_ptr unload;
125 #define CHECK_PHASE_START if (!(false
126 #define CHECK_PHASE(chkphase) || (phase == chkphase)
127 #define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
128 #define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
129 return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
130 #define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t)== \
131 JVMTI_ERROR_THREAD_NOT_ALIVE) \
132 return JVMTI_ERROR_THREAD_NOT_ALIVE;
137 /* check_thread_is_alive *******************************************************
139 checks if the given thread is alive
141 *******************************************************************************/
142 static jvmtiError check_thread_is_alive(jthread t) {
143 if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
144 if(((java_lang_Thread*) t)->vmThread==NULL)
145 return JVMTI_ERROR_THREAD_NOT_ALIVE;
146 return JVMTI_ERROR_NONE;
149 /* execcallback ***************************************************************
151 executes the registerd callbacks for the given jvmti event with parameter
152 in the data structure.
154 *******************************************************************************/
155 static void execute_callback(jvmtiEvent e, functionptr ec,
156 genericEventData* data) {
157 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
159 fprintf(stderr,"execcallback called (event: %d)\n",e);
162 case JVMTI_EVENT_VM_INIT:
163 if (phase != JVMTI_PHASE_LIVE) return;
164 case JVMTI_EVENT_THREAD_START:
165 case JVMTI_EVENT_THREAD_END:
166 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
167 ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
170 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
171 if ((phase == JVMTI_PHASE_START) ||
172 (phase == JVMTI_PHASE_LIVE) ||
173 (phase == JVMTI_PHASE_PRIMORDIAL))
174 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
179 data->protection_domain,
182 data->new_class_data_len,
183 data->new_class_data);
187 case JVMTI_EVENT_CLASS_PREPARE:
188 case JVMTI_EVENT_CLASS_LOAD:
189 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
190 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
191 data->thread, data->klass);
194 case JVMTI_EVENT_VM_DEATH:
195 if (phase != JVMTI_PHASE_LIVE) return;
196 case JVMTI_EVENT_VM_START:
197 if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
198 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
201 case JVMTI_EVENT_NATIVE_METHOD_BIND:
202 if ((phase == JVMTI_PHASE_START) ||
203 (phase == JVMTI_PHASE_LIVE) ||
204 (phase == JVMTI_PHASE_PRIMORDIAL))
205 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
209 data->new_address_ptr);
213 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
214 if ((phase == JVMTI_PHASE_START) ||
215 (phase == JVMTI_PHASE_LIVE) ||
216 (phase == JVMTI_PHASE_PRIMORDIAL))
217 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
226 if (phase != JVMTI_PHASE_LIVE) return;
228 case JVMTI_EVENT_EXCEPTION:
229 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
235 data->catch_location);
238 case JVMTI_EVENT_EXCEPTION_CATCH:
239 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
246 case JVMTI_EVENT_BREAKPOINT:
247 case JVMTI_EVENT_SINGLE_STEP:
248 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
254 case JVMTI_EVENT_FRAME_POP:
255 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
262 case JVMTI_EVENT_FIELD_ACCESS:
263 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
272 case JVMTI_EVENT_FIELD_MODIFICATION:
274 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
281 data->signature_type,
285 case JVMTI_EVENT_METHOD_ENTRY:
286 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
291 case JVMTI_EVENT_METHOD_EXIT:
292 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
299 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
300 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
309 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
310 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
315 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
316 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
317 case JVMTI_EVENT_DATA_DUMP_REQUEST:
318 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
321 case JVMTI_EVENT_MONITOR_WAIT:
322 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
328 case JVMTI_EVENT_MONITOR_WAITED:
329 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
336 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
337 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
338 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
343 case JVMTI_EVENT_OBJECT_FREE:
344 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
347 case JVMTI_EVENT_VM_OBJECT_ALLOC:
348 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
355 log_text ("unknown event");
362 /* dofireEvent ******************************************************************
364 sends event if it is enabled either globally or for some threads
366 *******************************************************************************/
367 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
369 jvmtiEventModeLL *evm;
374 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
375 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
376 /* test if the event is enable for some threads */
378 if (evm->mode == JVMTI_ENABLE) {
379 data->jvmti_env=&env->env;
380 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
381 execute_callback(e, ec, data);
385 } else { /* event enabled globally */
386 data->jvmti_env=&env->env;
387 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
388 execute_callback(e, ec, data);
396 /* fireEvent ******************************************************************
398 fire event callback with data arguments. This function mainly fills the
401 *******************************************************************************/
402 void jvmti_fireEvent(genericEventData* d) {
404 /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
406 if (d->ev != JVMTI_EVENT_VM_START)
407 thread = jvmti_get_current_thread();
412 dofireEvent(d->ev,d);
416 /* SetEventNotificationMode ****************************************************
418 Control the generation of events
420 *******************************************************************************/
423 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
424 jvmtiEvent event_type, jthread event_thread, ...)
426 environment* cacao_env;
427 jvmtiEventModeLL *ll;
430 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
431 CHECK_PHASE(JVMTI_PHASE_LIVE)
434 if(event_thread != NULL) {
435 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
436 return JVMTI_ERROR_INVALID_THREAD;
437 CHECK_THREAD_IS_ALIVE(event_thread);
441 cacao_env = (environment*) env;
442 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
443 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
445 switch (event_type) { /* check capability and set system breakpoint */
446 case JVMTI_EVENT_EXCEPTION:
447 case JVMTI_EVENT_EXCEPTION_CATCH:
448 CHECK_CAPABILITY(env,can_generate_exception_events)
450 case JVMTI_EVENT_SINGLE_STEP:
451 CHECK_CAPABILITY(env,can_generate_single_step_events)
453 case JVMTI_EVENT_FRAME_POP:
454 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
456 case JVMTI_EVENT_BREAKPOINT:
457 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
459 case JVMTI_EVENT_FIELD_ACCESS:
460 CHECK_CAPABILITY(env,can_generate_field_access_events)
462 case JVMTI_EVENT_FIELD_MODIFICATION:
463 CHECK_CAPABILITY(env,can_generate_field_modification_events)
465 case JVMTI_EVENT_METHOD_ENTRY:
466 CHECK_CAPABILITY(env,can_generate_method_entry_events)
468 case JVMTI_EVENT_METHOD_EXIT:
469 CHECK_CAPABILITY(env, can_generate_method_exit_events)
471 case JVMTI_EVENT_NATIVE_METHOD_BIND:
472 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
474 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
475 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
476 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
478 case JVMTI_EVENT_MONITOR_WAIT:
479 case JVMTI_EVENT_MONITOR_WAITED:
480 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
481 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
482 CHECK_CAPABILITY(env,can_generate_monitor_events)
484 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
485 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
486 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
488 case JVMTI_EVENT_OBJECT_FREE:
489 CHECK_CAPABILITY(env,can_generate_object_free_events)
491 case JVMTI_EVENT_VM_OBJECT_ALLOC:
492 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
494 case JVMTI_EVENT_THREAD_START:
495 jvmti_set_system_breakpoint(THREADSTARTBRK, mode);
497 case JVMTI_EVENT_THREAD_END:
498 jvmti_set_system_breakpoint(THREADENDBRK, mode);
502 /* all other events are required */
503 if ((event_type < JVMTI_EVENT_START_ENUM) ||
504 (event_type > JVMTI_EVENT_END_ENUM))
505 return JVMTI_ERROR_INVALID_EVENT_TYPE;
509 if (event_thread != NULL) {
510 /* thread level control */
511 if ((JVMTI_EVENT_VM_INIT == mode) ||
512 (JVMTI_EVENT_VM_DEATH == mode) ||
513 (JVMTI_EVENT_VM_START == mode) ||
514 (JVMTI_EVENT_THREAD_START == mode) ||
515 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
516 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
517 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
518 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
519 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
520 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
521 while (ll->next != NULL) {
523 if (ll->event_thread == event_thread) {
525 return JVMTI_ERROR_NONE;
528 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
532 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
536 return JVMTI_ERROR_NONE;
539 /* GetAllThreads ***************************************************************
543 *******************************************************************************/
546 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
547 jthread ** threads_ptr)
549 threadobject** threads;
554 CHECK_PHASE(JVMTI_PHASE_LIVE)
557 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
558 return JVMTI_ERROR_NULL_POINTER;
560 retval=jvmti_get_all_threads(threads_count_ptr, &threads);
561 if (retval != JVMTI_ERROR_NONE) return retval;
564 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
566 for (i=0; i<*threads_count_ptr; i++)
567 (*threads_ptr)[i] = threads[i]->o.thread;
569 return JVMTI_ERROR_NONE;
573 /* SuspendThread ***************************************************************
575 Suspend specified thread
577 *******************************************************************************/
580 SuspendThread (jvmtiEnv * env, jthread thread)
583 CHECK_PHASE(JVMTI_PHASE_LIVE)
585 CHECK_CAPABILITY(env,can_suspend);
587 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
588 return JVMTI_ERROR_NOT_AVAILABLE;
590 return JVMTI_ERROR_NONE;
593 /* ResumeThread ***************************************************************
595 Resume a suspended thread
597 *******************************************************************************/
600 ResumeThread (jvmtiEnv * env, jthread thread)
603 CHECK_PHASE(JVMTI_PHASE_LIVE)
605 CHECK_CAPABILITY(env,can_suspend);
607 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
608 return JVMTI_ERROR_NOT_AVAILABLE;
610 return JVMTI_ERROR_NONE;
613 /* StopThread *****************************************************************
615 Send asynchronous exception to the specified thread. Similar to
616 java.lang.Thread.stop(). Used to kill thread.
618 *******************************************************************************/
621 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
624 CHECK_PHASE(JVMTI_PHASE_LIVE)
626 CHECK_CAPABILITY(env,can_signal_thread);
628 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
629 return JVMTI_ERROR_NOT_AVAILABLE;
631 return JVMTI_ERROR_NONE;
634 /* InterruptThread ************************************************************
636 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
638 *******************************************************************************/
641 InterruptThread (jvmtiEnv * env, jthread thread)
644 CHECK_PHASE(JVMTI_PHASE_LIVE)
646 CHECK_CAPABILITY(env,can_signal_thread)
648 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
650 return JVMTI_ERROR_NOT_AVAILABLE;
652 if(!builtin_instanceof(thread,class_java_lang_Thread))
653 return JVMTI_ERROR_INVALID_THREAD;
655 CHECK_THREAD_IS_ALIVE(thread);
657 return JVMTI_ERROR_NONE;
660 /* GetThreadInfo ***************************************************************
662 Get thread information. Details of the specified thread are stored in the
663 jvmtiThreadInfo structure.
665 *******************************************************************************/
668 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
670 java_lang_Thread* th = (java_lang_Thread*)t;
673 CHECK_PHASE(JVMTI_PHASE_LIVE)
675 info_ptr->priority=(jint)th->priority;
676 info_ptr->is_daemon=(jboolean)th->daemon;
677 info_ptr->thread_group=(jthreadGroup)th->group;
678 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
679 info_ptr->name= javastring_tochar((java_objectheader *)th->name);
681 return JVMTI_ERROR_NONE;
684 /* GetOwnedMonitorInfo *********************************************************
686 Get information about the monitors owned by the specified thread
688 *******************************************************************************/
691 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
692 jint * owned_monitor_count_ptr,
693 jobject ** owned_monitors_ptr)
696 java_objectheader **om;
697 lock_record_pool_t* lrp;
699 log_text("GetOwnedMonitorInfo called");
702 CHECK_PHASE(JVMTI_PHASE_LIVE)
704 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
706 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
707 return JVMTI_ERROR_NULL_POINTER;
709 if(!builtin_instanceof(thread,class_java_lang_Thread))
710 return JVMTI_ERROR_INVALID_THREAD;
712 CHECK_THREAD_IS_ALIVE(thread);
714 #if defined(ENABLE_THREADS)
716 om=MNEW(java_objectheader*,size);
718 pthread_mutex_lock(&lock_global_pool_lock);
719 lrp=lock_global_pool;
721 while (lrp != NULL) {
722 for (j=0; j<lrp->header.size; j++) {
723 /* if((lrp->lr[j].owner==(threadobject*)thread)&&
724 (!lrp->lr[j].waiting)) {
726 MREALLOC(om,java_objectheader*,size,size*2);
733 lrp=lrp->header.next;
736 pthread_mutex_unlock(&lock_global_pool_lock);
738 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
739 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
740 MFREE(om,java_objectheader*,size);
742 *owned_monitor_count_ptr = i;
746 return JVMTI_ERROR_NONE;
749 /* GetCurrentContendedMonitor *************************************************
751 Get the object the specified thread waits for.
753 *******************************************************************************/
756 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
757 jobject * monitor_ptr)
760 lock_record_pool_t* lrp;
761 java_objectheader* monitor;
764 CHECK_PHASE(JVMTI_PHASE_LIVE)
766 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
768 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
771 if(!builtin_instanceof(thread,class_java_lang_Thread))
772 return JVMTI_ERROR_INVALID_THREAD;
774 CHECK_THREAD_IS_ALIVE(thread);
777 #if defined(ENABLE_THREADS)
779 pthread_mutex_lock(&lock_global_pool_lock);
781 lrp=lock_global_pool;
783 while ((lrp != NULL)&&(monitor==NULL)) {
784 for (j=0; j<lrp->header.size; j++) {
785 /* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
786 monitor=lrp->lr[j].o;
790 lrp=lrp->header.next;
793 pthread_mutex_unlock(&lock_global_pool_lock);
796 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
797 *monitor_ptr = (jobject)monitor;
801 return JVMTI_ERROR_NONE;
805 jvmtiStartFunction sf;
811 static void *threadstartup(void *t) {
812 runagentparam *rap = (runagentparam*)t;
813 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
817 /* RunAgentThread *************************************************************
819 Starts the execution of an agent thread of the specified native function
820 within the specified thread
822 *******************************************************************************/
825 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
826 const void *arg, jint priority)
828 pthread_attr_t threadattr;
829 struct sched_param sp;
833 CHECK_PHASE(JVMTI_PHASE_LIVE)
836 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
837 return JVMTI_ERROR_INVALID_THREAD;
838 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
839 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
840 (priority > JVMTI_THREAD_MAX_PRIORITY))
841 return JVMTI_ERROR_INVALID_PRIORITY;
843 /* XXX: Threads started with with this function should not be visible to
844 Java programming language queries but are included in JVM TI queries */
847 rap.arg = (void*)arg;
850 #if defined(ENABLE_THREADS)
851 pthread_attr_init(&threadattr);
852 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
853 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
854 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
856 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
857 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
859 pthread_attr_setschedparam(&threadattr,&sp);
860 if (pthread_create(&((threadobject*)
861 thread)->tid, &threadattr, &threadstartup, &rap)) {
862 log_text("pthread_create failed");
867 return JVMTI_ERROR_NONE;
871 /* GetTopThreadGroups *********************************************************
873 Get all top-level thread groups in the VM.
875 *******************************************************************************/
878 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
879 jthreadGroup ** groups_ptr)
881 jint threads_count_ptr;
882 threadobject *threads_ptr;
884 jthreadGroup **tg,*ttgp;
887 CHECK_PHASE(JVMTI_PHASE_LIVE)
890 log_text("GetTopThreadGroups called");
892 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
893 return JVMTI_ERROR_NULL_POINTER;
895 #if defined(ENABLE_THREADS)
896 tg = MNEW(jthreadGroup*,size);
898 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
899 return JVMTI_ERROR_INTERNAL;
901 for (i=0;i<threads_count_ptr;i++){
902 if (threads_ptr[i].o.thread->group == NULL) {
903 log_text("threadgroup not set");
904 return JVMTI_ERROR_INTERNAL;
906 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
909 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
914 MREALLOC(tg,jthreadGroup*,size,size*2);
923 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
924 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
925 MFREE(tg,jthreadGroup*,size);
927 *group_count_ptr = x;
930 return JVMTI_ERROR_NOT_AVAILABLE;
932 return JVMTI_ERROR_NONE;
936 /* GetThreadGroupInfo *********************************************************
938 Get information about the specified thread group.
940 *******************************************************************************/
943 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
944 jvmtiThreadGroupInfo * info_ptr)
948 java_lang_ThreadGroup* grp;
951 CHECK_PHASE(JVMTI_PHASE_LIVE)
954 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
955 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
956 return JVMTI_ERROR_INVALID_THREAD_GROUP;
958 grp = (java_lang_ThreadGroup*)group;
960 info_ptr->parent = (jthreadGroup)
961 Java_java_lang_VMObject_clone(NULL,
962 (jclass)grp->header.vftbl->class,
963 (java_lang_Cloneable*) &grp->parent);
965 name = javastring_tochar((java_objectheader*)grp->name);
967 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
968 strncpy(info_ptr->name,name,size);
969 info_ptr->max_priority= (jint)grp->maxpri;
970 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
972 return JVMTI_ERROR_NONE;
976 /* GetThreadGroupChildren *****************************************************
978 Get the live threads and active subgroups in this thread group.
980 *******************************************************************************/
983 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
984 jint * thread_count_ptr, jthread ** threads_ptr,
985 jint * group_count_ptr, jthreadGroup ** groups_ptr)
987 java_lang_ThreadGroup* tgp;
990 CHECK_PHASE(JVMTI_PHASE_LIVE)
993 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
994 (group_count_ptr == NULL) || (groups_ptr == NULL))
995 return JVMTI_ERROR_NULL_POINTER;
997 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
998 return JVMTI_ERROR_INVALID_THREAD_GROUP;
1000 tgp = (java_lang_ThreadGroup*)group;
1002 *thread_count_ptr = (jint)tgp->threads->elementCount;
1004 *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
1006 memcpy(*threads_ptr, &tgp->threads->elementData,
1007 (*thread_count_ptr)*sizeof(jthread*));
1009 *group_count_ptr = (jint) tgp->groups->elementCount;
1011 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
1013 memcpy(*groups_ptr, &tgp->threads->elementData,
1014 (*group_count_ptr)*sizeof(jthreadGroup*));
1016 return JVMTI_ERROR_NONE;
1020 /* getcacaostacktrace *********************************************************
1022 Helper function that retrives stack trace for specified thread.
1023 Has to take care of suspend/resume issuses
1025 *******************************************************************************/
1026 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1029 log_text("getcacaostacktrace");
1031 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1034 *trace = stacktrace_create(t); */
1036 return JVMTI_ERROR_NONE;
1040 /* GetFrameCount **************************************************************
1043 Get the number of frames in the specified thread's stack.
1045 *******************************************************************************/
1048 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1050 stacktracebuffer* trace;
1054 CHECK_PHASE(JVMTI_PHASE_LIVE)
1057 if(!builtin_instanceof(thread,class_java_lang_Thread))
1058 return JVMTI_ERROR_INVALID_THREAD;
1060 CHECK_THREAD_IS_ALIVE(thread);
1062 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1064 er = getcacaostacktrace(&trace, thread);
1065 if (er==JVMTI_ERROR_NONE) return er;
1067 *count_ptr = trace->used;
1069 return JVMTI_ERROR_NONE;
1073 /* GetThreadState **************************************************************
1075 Get the state of a thread.
1077 *******************************************************************************/
1080 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1082 java_lang_Thread* th = (java_lang_Thread*)thread;
1083 threadobject* t = (threadobject*)th->vmThread;
1086 CHECK_PHASE(JVMTI_PHASE_LIVE)
1089 if(!builtin_instanceof(thread,class_java_lang_Thread))
1090 return JVMTI_ERROR_INVALID_THREAD;
1092 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1094 *thread_state_ptr = 0;
1095 #if defined(ENABLE_THREADS)
1096 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1098 if (((threadobject*)th->vmThread)->tid == 0)
1099 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1102 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1103 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1105 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1106 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1107 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1108 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1109 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1110 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1111 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1112 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1113 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1114 if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1117 return JVMTI_ERROR_INTERNAL;
1120 return JVMTI_ERROR_NONE;
1124 /* GetFrameLocation ************************************************************
1126 Get the location of the instruction currently executing
1128 *******************************************************************************/
1131 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1132 jmethodID * method_ptr, jlocation * location_ptr)
1134 stackframeinfo *sfi;
1138 CHECK_PHASE(JVMTI_PHASE_LIVE)
1141 if(!builtin_instanceof(thread,class_java_lang_Thread))
1142 return JVMTI_ERROR_INVALID_THREAD;
1144 CHECK_THREAD_IS_ALIVE(thread);
1146 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1148 if ((method_ptr == NULL)&&(location_ptr == NULL))
1149 return JVMTI_ERROR_NULL_POINTER;
1151 sfi = ((threadobject*)thread)->_stackframeinfo;
1154 while ((sfi != NULL) && (i<depth)) {
1159 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1161 *method_ptr=(jmethodID)sfi->method;
1162 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1164 return JVMTI_ERROR_NONE;
1168 /* NotifyFramePop *************************************************************
1172 *******************************************************************************/
1175 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1178 CHECK_PHASE(JVMTI_PHASE_LIVE)
1180 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1182 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1183 return JVMTI_ERROR_NONE;
1186 /* GetLocalObject *************************************************************
1190 *******************************************************************************/
1193 GetLocalObject (jvmtiEnv * env,
1194 jthread thread, jint depth, jint slot, jobject * value_ptr)
1197 CHECK_PHASE(JVMTI_PHASE_LIVE)
1199 CHECK_CAPABILITY(env,can_access_local_variables)
1201 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1202 return JVMTI_ERROR_NONE;
1205 /* GetLocalInt ****************************************************************
1209 *******************************************************************************/
1212 GetLocalInt (jvmtiEnv * env,
1213 jthread thread, jint depth, jint slot, jint * value_ptr)
1216 CHECK_PHASE(JVMTI_PHASE_LIVE)
1218 CHECK_CAPABILITY(env,can_access_local_variables)
1219 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1220 return JVMTI_ERROR_NONE;
1223 /* *****************************************************************************
1227 *******************************************************************************/
1230 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1234 CHECK_PHASE(JVMTI_PHASE_LIVE)
1236 CHECK_CAPABILITY(env,can_access_local_variables)
1238 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1239 return JVMTI_ERROR_NONE;
1243 /* *****************************************************************************
1247 *******************************************************************************/
1250 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1254 CHECK_PHASE(JVMTI_PHASE_LIVE)
1256 CHECK_CAPABILITY(env,can_access_local_variables)
1258 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1259 return JVMTI_ERROR_NONE;
1263 /* *****************************************************************************
1267 *******************************************************************************/
1270 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1271 jdouble * value_ptr)
1274 CHECK_PHASE(JVMTI_PHASE_LIVE)
1276 CHECK_CAPABILITY(env,can_access_local_variables)
1278 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1279 return JVMTI_ERROR_NONE;
1283 /* *****************************************************************************
1287 *******************************************************************************/
1290 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1294 CHECK_PHASE(JVMTI_PHASE_LIVE)
1296 CHECK_CAPABILITY(env,can_access_local_variables)
1298 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1299 return JVMTI_ERROR_NONE;
1303 /* *****************************************************************************
1307 *******************************************************************************/
1310 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1314 CHECK_PHASE(JVMTI_PHASE_LIVE)
1316 CHECK_CAPABILITY(env,can_access_local_variables)
1318 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1319 return JVMTI_ERROR_NONE;
1323 /* *****************************************************************************
1327 *******************************************************************************/
1330 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1334 CHECK_PHASE(JVMTI_PHASE_LIVE)
1336 CHECK_CAPABILITY(env,can_access_local_variables)
1338 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1339 return JVMTI_ERROR_NONE;
1343 /* *****************************************************************************
1347 *******************************************************************************/
1350 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1354 CHECK_PHASE(JVMTI_PHASE_LIVE)
1356 CHECK_CAPABILITY(env,can_access_local_variables)
1358 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1359 return JVMTI_ERROR_NONE;
1363 /* *****************************************************************************
1367 *******************************************************************************/
1370 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1374 CHECK_PHASE(JVMTI_PHASE_LIVE)
1376 CHECK_CAPABILITY(env,can_access_local_variables)
1378 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1379 return JVMTI_ERROR_NONE;
1383 /* CreateRawMonitor ***********************************************************
1385 This function creates a new raw monitor.
1387 *******************************************************************************/
1390 CreateRawMonitor (jvmtiEnv * env, const char *name,
1391 jrawMonitorID * monitor_ptr)
1393 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1396 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1397 CHECK_PHASE(JVMTI_PHASE_LIVE)
1400 if ((name == NULL) || (monitor_ptr == NULL))
1401 return JVMTI_ERROR_NULL_POINTER;
1403 #if defined(ENABLE_THREADS)
1404 monitor->name=javastring_new_from_ascii(name);
1406 log_text ("CreateRawMonitor not supported");
1409 return JVMTI_ERROR_NONE;
1413 /* DestroyRawMonitor **********************************************************
1415 This function destroys a raw monitor.
1417 *******************************************************************************/
1420 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1423 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1424 CHECK_PHASE(JVMTI_PHASE_LIVE)
1427 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1428 return JVMTI_ERROR_INVALID_MONITOR;
1430 #if defined(ENABLE_THREADS)
1431 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1432 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1434 lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1436 /* GC will clean monitor up */
1438 log_text ("DestroyRawMonitor not supported");
1441 return JVMTI_ERROR_NONE;
1445 /* RawMonitorEnter ************************************************************
1447 Gain exclusive ownership of a raw monitor
1449 *******************************************************************************/
1452 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1454 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1455 return JVMTI_ERROR_INVALID_MONITOR;
1457 #if defined(ENABLE_THREADS)
1458 builtin_monitorenter((java_objectheader*)monitor->name);
1460 log_text ("RawMonitorEnter not supported");
1463 return JVMTI_ERROR_NONE;
1467 /* RawMonitorExit *************************************************************
1471 *******************************************************************************/
1474 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1476 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1477 return JVMTI_ERROR_INVALID_MONITOR;
1479 #if defined(ENABLE_THREADS)
1480 /* assure current thread owns this monitor */
1481 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1482 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1484 builtin_monitorexit((java_objectheader*)monitor->name);
1486 log_text ("RawMonitorExit not supported");
1489 return JVMTI_ERROR_NONE;
1493 /* RawMonitorWait *************************************************************
1495 Wait for notification of the raw monitor.
1497 *******************************************************************************/
1500 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1502 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1503 return JVMTI_ERROR_INVALID_MONITOR;
1505 #if defined(ENABLE_THREADS)
1506 /* assure current thread owns this monitor */
1507 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1508 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1510 lock_wait_for_object(&monitor->name->header, millis,0);
1511 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1512 return JVMTI_ERROR_INTERRUPT;
1515 log_text ("RawMonitorWait not supported");
1518 return JVMTI_ERROR_NONE;
1522 /* RawMonitorNotify ***********************************************************
1524 Notify one thread waiting on the given monitor.
1526 *******************************************************************************/
1529 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1531 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1532 return JVMTI_ERROR_INVALID_MONITOR;
1534 #if defined(ENABLE_THREADS)
1535 /* assure current thread owns this monitor */
1536 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1537 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1539 lock_notify_object((java_objectheader*)&monitor->name);
1541 log_text ("RawMonitorNotify not supported");
1544 return JVMTI_ERROR_NONE;
1548 /* RawMonitorNotifyAll *********************************************************
1550 Notify all threads waiting on the given monitor.
1552 *******************************************************************************/
1555 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1557 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1558 return JVMTI_ERROR_INVALID_MONITOR;
1560 #if defined(ENABLE_THREADS)
1561 /* assure current thread owns this monitor */
1562 if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
1563 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1565 lock_notify_all_object((java_objectheader*)&monitor->name);
1567 log_text ("RawMonitorNotifyAll not supported");
1570 return JVMTI_ERROR_NONE;
1574 /* SetBreakpoint **************************************************************
1578 *******************************************************************************/
1581 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1584 CHECK_PHASE(JVMTI_PHASE_LIVE)
1586 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1589 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1590 return JVMTI_ERROR_NONE;
1594 /* *****************************************************************************
1598 *******************************************************************************/
1601 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1604 CHECK_PHASE(JVMTI_PHASE_LIVE)
1606 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1608 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1609 return JVMTI_ERROR_NONE;
1613 /* SetFieldAccessWatch ********************************************************
1617 *******************************************************************************/
1620 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1623 CHECK_PHASE(JVMTI_PHASE_LIVE)
1625 CHECK_CAPABILITY(env,can_generate_field_access_events)
1627 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1628 return JVMTI_ERROR_NONE;
1632 /* *****************************************************************************
1636 *******************************************************************************/
1639 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1642 CHECK_PHASE(JVMTI_PHASE_LIVE)
1644 CHECK_CAPABILITY(env,can_generate_field_access_events)
1646 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1647 return JVMTI_ERROR_NONE;
1651 /* *****************************************************************************
1655 *******************************************************************************/
1658 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1661 CHECK_PHASE(JVMTI_PHASE_LIVE)
1663 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1665 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1666 return JVMTI_ERROR_NONE;
1670 /* *****************************************************************************
1674 *******************************************************************************/
1677 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1680 CHECK_PHASE(JVMTI_PHASE_LIVE)
1682 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1684 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1685 return JVMTI_ERROR_NONE;
1689 /* Allocate ********************************************************************
1691 Allocate an area of memory through the JVM TI allocator. The allocated
1692 memory should be freed with Deallocate
1694 *******************************************************************************/
1697 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1700 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1701 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1703 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1704 if (*mem_ptr == NULL)
1705 return JVMTI_ERROR_OUT_OF_MEMORY;
1707 return JVMTI_ERROR_NONE;
1712 /* Deallocate ******************************************************************
1714 Deallocate mem using the JVM TI allocator.
1716 *******************************************************************************/
1719 Deallocate (jvmtiEnv * env, unsigned char *mem)
1721 /* let Boehm GC do the job */
1723 return JVMTI_ERROR_NONE;
1727 /* GetClassSignature ************************************************************
1729 For the class indicated by klass, return the JNI type signature and the
1730 generic signature of the class.
1732 *******************************************************************************/
1735 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1739 CHECK_PHASE(JVMTI_PHASE_START)
1740 CHECK_PHASE(JVMTI_PHASE_LIVE)
1743 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1744 return JVMTI_ERROR_NULL_POINTER;
1746 *signature_ptr = (char*)
1747 heap_allocate(sizeof(char) *
1748 ((classinfo*)klass)->name->blength,true,NULL);
1750 utf_sprint_convert_to_latin1(*signature_ptr, ((classinfo*)klass)->name);
1751 *generic_ptr = NULL;
1753 return JVMTI_ERROR_NONE;
1756 /* GetClassStatus *************************************************************
1758 Get status of the class.
1760 *******************************************************************************/
1763 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1767 CHECK_PHASE(JVMTI_PHASE_START)
1768 CHECK_PHASE(JVMTI_PHASE_LIVE)
1771 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1772 return JVMTI_ERROR_INVALID_CLASS;
1774 if (status_ptr == NULL)
1775 return JVMTI_ERROR_NULL_POINTER;
1777 c = (classinfo*)klass;
1780 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1781 if (c->state&=CLASS_LINKED)
1782 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1784 if (c->state&=CLASS_INITIALIZED)
1785 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1787 if (c->state&=CLASS_ERROR)
1788 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1790 if (c->vftbl->arraydesc != NULL)
1791 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1793 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1794 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1796 return JVMTI_ERROR_NONE;
1800 /* GetSourceFileName **********************************************************
1802 For the class indicated by klass, return the source file name.
1804 *******************************************************************************/
1807 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1812 CHECK_PHASE(JVMTI_PHASE_START)
1813 CHECK_PHASE(JVMTI_PHASE_LIVE)
1815 CHECK_CAPABILITY(env,can_get_source_file_name)
1817 if ((klass == NULL)||(source_name_ptr == NULL))
1818 return JVMTI_ERROR_NULL_POINTER;
1820 size = (((classinfo*)klass)->sourcefile->blength)+1;
1822 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1824 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1825 (*source_name_ptr)[size]='\0';
1827 return JVMTI_ERROR_NONE;
1831 /* GetClassModifiers **********************************************************
1833 For class klass return the access flags
1835 *******************************************************************************/
1838 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1841 CHECK_PHASE(JVMTI_PHASE_START)
1842 CHECK_PHASE(JVMTI_PHASE_LIVE)
1845 if (modifiers_ptr == NULL)
1846 return JVMTI_ERROR_NULL_POINTER;
1848 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1849 return JVMTI_ERROR_INVALID_CLASS;
1851 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1853 return JVMTI_ERROR_NONE;
1857 /* GetClassMethods *************************************************************
1859 For class klass return a count of methods and a list of method IDs
1861 *******************************************************************************/
1864 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1865 jmethodID ** methods_ptr)
1870 CHECK_PHASE(JVMTI_PHASE_START)
1871 CHECK_PHASE(JVMTI_PHASE_LIVE)
1874 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1875 return JVMTI_ERROR_NULL_POINTER;
1877 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1878 return JVMTI_ERROR_INVALID_CLASS;
1880 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1881 *methods_ptr = (jmethodID*)
1882 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1884 for (i=0; i<*method_count_ptr;i++)
1885 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1887 return JVMTI_ERROR_NONE;
1891 /* GetClassFields *************************************************************
1893 For the class indicated by klass, return a count of fields and a list of
1896 *******************************************************************************/
1899 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1900 jfieldID ** fields_ptr)
1903 CHECK_PHASE(JVMTI_PHASE_START)
1904 CHECK_PHASE(JVMTI_PHASE_LIVE)
1907 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1908 return JVMTI_ERROR_NULL_POINTER;
1910 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1911 *fields_ptr = (jfieldID*)
1912 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1914 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1915 sizeof(jfieldID) * (*field_count_ptr));
1917 return JVMTI_ERROR_NONE;
1921 /* GetImplementedInterfaces ***************************************************
1923 Return the direct super-interfaces of this class.
1925 *******************************************************************************/
1928 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1929 jint * interface_count_ptr,
1930 jclass ** interfaces_ptr)
1933 classref_or_classinfo *interfaces;
1937 CHECK_PHASE(JVMTI_PHASE_START)
1938 CHECK_PHASE(JVMTI_PHASE_LIVE)
1941 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1942 return JVMTI_ERROR_NULL_POINTER;
1944 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1945 return JVMTI_ERROR_INVALID_CLASS;
1948 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1950 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1952 interfaces = ((classinfo*)klass)->interfaces;
1953 for (i=0; i<*interface_count_ptr; i++) {
1954 if (IS_CLASSREF(interfaces[i]))
1955 tmp = load_class_bootstrap(interfaces[i].ref->name);
1957 tmp = interfaces[i].cls;
1959 *interfaces_ptr[i]=tmp;
1962 return JVMTI_ERROR_NONE;
1966 /* IsInterface ****************************************************************
1968 Determines whether a class object reference represents an interface.
1970 *******************************************************************************/
1973 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1976 CHECK_PHASE(JVMTI_PHASE_START)
1977 CHECK_PHASE(JVMTI_PHASE_LIVE)
1980 if ((klass == NULL)||(is_interface_ptr == NULL))
1981 return JVMTI_ERROR_NULL_POINTER;
1983 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
1985 return JVMTI_ERROR_NONE;
1988 /* IsArrayClass ***************************************************************
1990 Determines whether a class object reference represents an array.
1992 *******************************************************************************/
1995 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
1998 CHECK_PHASE(JVMTI_PHASE_START)
1999 CHECK_PHASE(JVMTI_PHASE_LIVE)
2002 if (is_array_class_ptr == NULL)
2003 return JVMTI_ERROR_NULL_POINTER;
2005 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2007 return JVMTI_ERROR_NONE;
2011 /* GetClassLoader *************************************************************
2013 For the class indicated by klass, return via classloader_ptr a reference to
2014 the class loader for the class.
2016 *******************************************************************************/
2019 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2022 CHECK_PHASE(JVMTI_PHASE_START)
2023 CHECK_PHASE(JVMTI_PHASE_LIVE)
2026 if ((klass == NULL)||(classloader_ptr == NULL))
2027 return JVMTI_ERROR_NULL_POINTER;
2029 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2031 return JVMTI_ERROR_NONE;
2035 /* GetObjectHashCode **********************************************************
2037 Return hash code for object object
2039 *******************************************************************************/
2042 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2045 CHECK_PHASE(JVMTI_PHASE_START)
2046 CHECK_PHASE(JVMTI_PHASE_LIVE)
2049 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2050 if (!builtin_instanceof(object,class_java_lang_Object))
2051 return JVMTI_ERROR_INVALID_OBJECT;
2053 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2055 return JVMTI_ERROR_NONE;
2059 /* *****************************************************************************
2063 *******************************************************************************/
2066 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2067 jvmtiMonitorUsage * info_ptr)
2070 CHECK_PHASE(JVMTI_PHASE_LIVE)
2072 CHECK_CAPABILITY(env,can_get_monitor_info)
2074 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2075 return JVMTI_ERROR_NONE;
2079 /* GetFieldName ***************************************************************
2081 For the field indicated by klass and field, return the field name and
2084 *******************************************************************************/
2087 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2088 char **name_ptr, char **signature_ptr, char **generic_ptr)
2093 CHECK_PHASE(JVMTI_PHASE_START)
2094 CHECK_PHASE(JVMTI_PHASE_LIVE)
2097 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2098 return JVMTI_ERROR_NULL_POINTER;
2100 size = (((fieldinfo*)field)->name->blength);
2101 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2102 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2104 size = (((fieldinfo*)field)->descriptor->blength);
2105 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2106 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2108 *generic_ptr = NULL;
2110 return JVMTI_ERROR_NONE;
2114 /* GetFieldDeclaringClass *****************************************************
2116 For the field indicated by klass and field return the class that defined it
2117 The declaring class will either be klass, a superclass, or an implemented
2120 *******************************************************************************/
2123 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2124 jclass * declaring_class_ptr)
2127 CHECK_PHASE(JVMTI_PHASE_START)
2128 CHECK_PHASE(JVMTI_PHASE_LIVE)
2131 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2133 return JVMTI_ERROR_NONE;
2137 /* GetFieldModifiers **********************************************************
2139 Return access flags of field field
2141 *******************************************************************************/
2144 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2145 jint * modifiers_ptr)
2148 CHECK_PHASE(JVMTI_PHASE_START)
2149 CHECK_PHASE(JVMTI_PHASE_LIVE)
2152 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2153 return JVMTI_ERROR_INVALID_OBJECT;
2155 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2157 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2159 *modifiers_ptr = ((fieldinfo*)field)->flags;
2161 return JVMTI_ERROR_NONE;
2165 /* IsFieldSynthetic ***********************************************************
2169 *******************************************************************************/
2172 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2173 jboolean * is_synthetic_ptr)
2176 CHECK_PHASE(JVMTI_PHASE_START)
2177 CHECK_PHASE(JVMTI_PHASE_LIVE)
2179 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2181 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2182 return JVMTI_ERROR_NONE;
2186 /* GetMethodName ***************************************************************
2188 For the method indicated by method, return the method name via name_ptr and
2189 method signature via signature_ptr.
2191 *******************************************************************************/
2194 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2195 char **signature_ptr, char **generic_ptr)
2197 methodinfo* m = (methodinfo*)method;
2200 CHECK_PHASE(JVMTI_PHASE_START)
2201 CHECK_PHASE(JVMTI_PHASE_LIVE)
2204 if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2205 || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2208 heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
2209 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2211 *signature_ptr = (char*)
2212 heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
2213 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2215 /* there is no generic signature attribute */
2216 *generic_ptr = NULL;
2218 return JVMTI_ERROR_NONE;
2222 /* GetMethodDeclaringClass *****************************************************
2224 For the method indicated by method, return the class that defined it.
2226 *******************************************************************************/
2229 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2230 jclass * declaring_class_ptr)
2233 CHECK_PHASE(JVMTI_PHASE_START)
2234 CHECK_PHASE(JVMTI_PHASE_LIVE)
2237 if ((method == NULL) || (declaring_class_ptr == NULL))
2238 return JVMTI_ERROR_NULL_POINTER;
2240 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2242 return JVMTI_ERROR_NONE;
2246 /* GetMethodModifiers **********************************************************
2248 For the method indicated by method, return the access flags.
2250 *******************************************************************************/
2253 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2256 CHECK_PHASE(JVMTI_PHASE_START)
2257 CHECK_PHASE(JVMTI_PHASE_LIVE)
2260 if ((method == NULL) || (modifiers_ptr == NULL))
2261 return JVMTI_ERROR_NULL_POINTER;
2263 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2265 return JVMTI_ERROR_NONE;
2269 /* GetMaxLocals ****************************************************************
2271 For the method indicated by method, return the number of local variable slots
2272 used by the method, including the local variables used to pass parameters to
2273 the method on its invocation.
2275 *******************************************************************************/
2278 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2281 CHECK_PHASE(JVMTI_PHASE_START)
2282 CHECK_PHASE(JVMTI_PHASE_LIVE)
2285 if ((method == NULL)||(max_ptr == NULL))
2286 return JVMTI_ERROR_NULL_POINTER;
2288 if (((methodinfo*)method)->flags & ACC_NATIVE)
2289 return JVMTI_ERROR_NATIVE_METHOD;
2291 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2293 return JVMTI_ERROR_NONE;
2298 /* GetArgumentsSize ************************************************************
2300 Return the number of local variable slots used by the method's arguments.
2302 *******************************************************************************/
2305 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2308 CHECK_PHASE(JVMTI_PHASE_START)
2309 CHECK_PHASE(JVMTI_PHASE_LIVE)
2312 if ((method == NULL)||(size_ptr == NULL))
2313 return JVMTI_ERROR_NULL_POINTER;
2315 if (((methodinfo*)method)->flags & ACC_NATIVE)
2316 return JVMTI_ERROR_NATIVE_METHOD;
2318 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2319 return JVMTI_ERROR_NONE;
2324 /* GetLineNumberTable ***********************************************************
2326 Return table of source line number entries for a given method
2328 *******************************************************************************/
2331 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2332 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2337 CHECK_PHASE(JVMTI_PHASE_START)
2338 CHECK_PHASE(JVMTI_PHASE_LIVE)
2340 CHECK_CAPABILITY(env,can_get_line_numbers)
2342 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2343 return JVMTI_ERROR_NULL_POINTER;
2344 if (((methodinfo*)method)->flags & ACC_NATIVE)
2345 return JVMTI_ERROR_NATIVE_METHOD;
2346 if (((methodinfo*)method)->linenumbers == NULL)
2347 return JVMTI_ERROR_ABSENT_INFORMATION;
2349 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2350 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2351 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2354 for (i=0; i < *entry_count_ptr; i++) {
2355 (*table_ptr[i]).start_location =
2356 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2357 (*table_ptr[i]).line_number =
2358 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2361 return JVMTI_ERROR_NONE;
2365 /* GetMethodLocation ***********************************************************
2367 For the method indicated by method, return the beginning and ending addresses
2368 through start_location_ptr and end_location_ptr. In cacao this points to
2369 entry point in machine code and length of machine code
2371 *******************************************************************************/
2374 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2375 jlocation * start_location_ptr,
2376 jlocation * end_location_ptr)
2378 methodinfo* m = (methodinfo*)method;
2381 CHECK_PHASE(JVMTI_PHASE_START)
2382 CHECK_PHASE(JVMTI_PHASE_LIVE)
2385 if ((method == NULL) || (start_location_ptr == NULL) ||
2386 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2388 /* XXX we return the location of the most recent code. Don't know
2389 * if there is a way to teach jvmti that a method can have more
2390 * than one location. -Edwin */
2392 /* XXX Don't know if that's the right way to deal with not-yet-
2393 * compiled methods. -Edwin */
2396 return JVMTI_ERROR_NULL_POINTER;
2398 *start_location_ptr = (jlocation)m->code->mcode;
2399 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2400 return JVMTI_ERROR_NONE;
2404 /* GetLocalVariableTable *******************************************************
2406 Return local variable information.
2408 *******************************************************************************/
2411 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2412 jint * entry_count_ptr,
2413 jvmtiLocalVariableEntry ** table_ptr)
2416 CHECK_PHASE(JVMTI_PHASE_LIVE)
2418 CHECK_CAPABILITY(env,can_access_local_variables)
2420 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2422 return JVMTI_ERROR_NONE;
2426 /* GetBytecode *****************************************************************
2428 For the method indicated by method, return the byte codes that implement the
2431 *******************************************************************************/
2434 GetBytecodes (jvmtiEnv * env, jmethodID method,
2435 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2437 methodinfo* m = (methodinfo*)method;;
2440 CHECK_PHASE(JVMTI_PHASE_START)
2441 CHECK_PHASE(JVMTI_PHASE_LIVE)
2443 CHECK_CAPABILITY(env,can_get_bytecodes)
2445 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2446 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2448 *bytecode_count_ptr = m->jcodelength;
2449 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2450 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2452 return JVMTI_ERROR_NONE;
2456 /* IsMethodNative **************************************************************
2458 For the method indicated by method, return a value indicating whether the
2459 method is a native function
2461 *******************************************************************************/
2464 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2467 CHECK_PHASE(JVMTI_PHASE_START)
2468 CHECK_PHASE(JVMTI_PHASE_LIVE)
2471 if ((method == NULL)||(is_native_ptr == NULL))
2472 return JVMTI_ERROR_NULL_POINTER;
2474 if (((methodinfo*)method)->flags & ACC_NATIVE)
2475 *is_native_ptr = JNI_TRUE;
2477 *is_native_ptr = JNI_FALSE;
2479 return JVMTI_ERROR_NONE;
2483 /* IsMethodSynthetic ***********************************************************
2485 return a value indicating whether the method is synthetic. Synthetic methods
2486 are generated by the compiler but not present in the original source code.
2488 *******************************************************************************/
2491 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2492 jboolean * is_synthetic_ptr)
2495 CHECK_PHASE(JVMTI_PHASE_START)
2496 CHECK_PHASE(JVMTI_PHASE_LIVE)
2498 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2500 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2501 return JVMTI_ERROR_NONE;
2505 /* GetLoadedClasses ************************************************************
2507 Return an array of all classes loaded in the virtual machine.
2509 *******************************************************************************/
2512 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2515 classcache_name_entry *nameentry;
2516 classcache_class_entry *classentry;
2519 CHECK_PHASE(JVMTI_PHASE_LIVE)
2522 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2523 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2527 heap_allocate(sizeof(jclass)*(hashtable_classcache.entries),true,NULL);
2529 /* look in every slot of the hashtable */
2530 for (i=0; i<hashtable_classcache.size; i++) {
2531 nameentry = hashtable_classcache.ptr[i];
2532 while (nameentry != NULL) { /* iterate over hashlink */
2534 /* filter pseudo classes $NEW$,$NULL$,$ARRAYSTUB$ out */
2535 if (nameentry->name->text[0]=='$')
2537 *class_count_ptr -= 1;
2541 classentry = nameentry->classes;
2542 while (classentry != NULL){ /* iterate over classes with same name */
2543 if (classentry->classobj != NULL) { /*get only loaded classes */
2544 assert(j<hashtable_classcache.entries);
2545 (*classes_ptr)[j]=classentry->classobj;
2548 classentry = classentry->next;
2550 nameentry = nameentry->hashlink;
2554 CLASSCACHE_UNLOCK();
2556 *class_count_ptr = j;
2558 return JVMTI_ERROR_NONE;
2562 /* GetClassLoaderClasses *******************************************************
2564 Returns an array of those classes for which this class loader has been
2565 recorded as an initiating loader.
2567 *******************************************************************************/
2570 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2571 jint * class_count_ptr, jclass ** classes_ptr)
2573 log_text("GetClassLoaderClasses called");
2576 CHECK_PHASE(JVMTI_PHASE_LIVE)
2579 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2580 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2582 /* behave like jdk 1.1 and make no distinction between initiating and
2583 defining class loaders */
2585 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2589 /* PopFrame *******************************************************************
2593 *******************************************************************************/
2596 PopFrame (jvmtiEnv * env, jthread thread)
2599 CHECK_PHASE(JVMTI_PHASE_LIVE)
2601 CHECK_CAPABILITY(env,can_pop_frame)
2603 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2604 return JVMTI_ERROR_NONE;
2608 /* RedefineClasses ************************************************************
2612 *******************************************************************************/
2615 RedefineClasses (jvmtiEnv * env, jint class_count,
2616 const jvmtiClassDefinition * class_definitions)
2619 CHECK_PHASE(JVMTI_PHASE_START)
2620 CHECK_PHASE(JVMTI_PHASE_LIVE)
2622 CHECK_CAPABILITY(env,can_redefine_classes)
2623 CHECK_CAPABILITY(env,can_redefine_any_class)
2624 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2625 return JVMTI_ERROR_NONE;
2629 /* GetVersionNumber ***********************************************************
2631 Return the JVM TI version identifier.
2633 *******************************************************************************/
2636 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2638 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2640 *version_ptr = JVMTI_VERSION;
2642 return JVMTI_ERROR_NONE;
2646 /* GetCapabilities ************************************************************
2648 Returns the optional JVM TI features which this environment currently
2651 *******************************************************************************/
2654 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2656 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2658 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2660 return JVMTI_ERROR_NONE;
2664 /* *****************************************************************************
2668 *******************************************************************************/
2671 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2672 char **source_debug_extension_ptr)
2675 CHECK_PHASE(JVMTI_PHASE_START)
2676 CHECK_PHASE(JVMTI_PHASE_LIVE)
2678 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2680 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2681 return JVMTI_ERROR_NONE;
2685 /* IsMethodObsolete ************************************************************
2687 Determine if a method ID refers to an obsolete method version.
2689 *******************************************************************************/
2692 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2693 jboolean * is_obsolete_ptr)
2696 CHECK_PHASE(JVMTI_PHASE_START)
2697 CHECK_PHASE(JVMTI_PHASE_LIVE)
2699 CHECK_CAPABILITY(env,can_redefine_classes)
2701 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2702 return JVMTI_ERROR_NONE;
2706 /* SuspendThreadList **********************************************************
2710 *******************************************************************************/
2713 SuspendThreadList (jvmtiEnv * env, jint request_count,
2714 const jthread * request_list, jvmtiError * results)
2717 CHECK_PHASE(JVMTI_PHASE_START)
2718 CHECK_PHASE(JVMTI_PHASE_LIVE)
2720 CHECK_CAPABILITY(env,can_suspend);
2722 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2724 return JVMTI_ERROR_NONE;
2728 /* ResumeThreadList ***********************************************************
2732 *******************************************************************************/
2735 ResumeThreadList (jvmtiEnv * env, jint request_count,
2736 const jthread * request_list, jvmtiError * results)
2739 CHECK_PHASE(JVMTI_PHASE_LIVE)
2741 CHECK_CAPABILITY(env,can_suspend);
2743 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2745 return JVMTI_ERROR_NONE;
2749 /* GetStackTrace **************************************************************
2751 Get information about the stack of a thread
2753 *******************************************************************************/
2756 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2757 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2760 stacktracebuffer* trace;
2765 CHECK_PHASE(JVMTI_PHASE_LIVE)
2768 if(!builtin_instanceof(thread,class_java_lang_Thread))
2769 return JVMTI_ERROR_INVALID_THREAD;
2771 CHECK_THREAD_IS_ALIVE(thread);
2773 if((count_ptr == NULL)||(frame_buffer == NULL))
2774 return JVMTI_ERROR_NULL_POINTER;
2776 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2778 er = getcacaostacktrace(&trace, thread);
2779 if (er==JVMTI_ERROR_NONE) return er;
2781 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2782 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2784 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2785 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2786 /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
2787 frame_buffer[j].location = 0;
2790 return JVMTI_ERROR_NONE;
2794 /* GetThreadListStackTraces ***************************************************
2796 Get information about the stacks of the supplied threads.
2798 *******************************************************************************/
2801 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2802 const jthread * thread_list,
2803 jint max_frame_count,
2804 jvmtiStackInfo ** stack_info_ptr)
2810 CHECK_PHASE(JVMTI_PHASE_LIVE)
2813 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2814 return JVMTI_ERROR_NULL_POINTER;
2816 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2818 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2820 *stack_info_ptr = (jvmtiStackInfo*)
2821 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2823 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2824 (*stack_info_ptr)[i].thread=thread_list[i];
2825 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2826 (*stack_info_ptr)[i].frame_buffer =
2827 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2828 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2829 (*stack_info_ptr)[i].frame_buffer,
2830 &((*stack_info_ptr)[i].frame_count));
2832 if (er != JVMTI_ERROR_NONE) return er;
2835 return JVMTI_ERROR_NONE;
2839 /* GetAllStackTraces **********************************************************
2841 Get stack traces of all live threads
2843 *******************************************************************************/
2846 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2847 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2849 jthread *threads_ptr;
2853 CHECK_PHASE(JVMTI_PHASE_LIVE)
2856 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2858 /* todo: all threads have to be suspended */
2860 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2861 return JVMTI_ERROR_INTERNAL;
2863 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2864 max_frame_count, stack_info_ptr);
2866 /* todo: resume all threads have to be suspended */
2867 if (er != JVMTI_ERROR_NONE) return er;
2869 return JVMTI_ERROR_NONE;
2873 /* GetThreadLocalStorage ******************************************************
2875 Get the value of the JVM TI thread-local storage.
2877 *******************************************************************************/
2880 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2882 jvmtiThreadLocalStorage *tls;
2885 CHECK_PHASE(JVMTI_PHASE_START)
2886 CHECK_PHASE(JVMTI_PHASE_LIVE)
2890 thread = (jthread) THREADOBJECT;
2892 if (!builtin_instanceof(thread,class_java_lang_Thread))
2893 return JVMTI_ERROR_INVALID_THREAD;
2894 CHECK_THREAD_IS_ALIVE(thread);
2897 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2899 tls = ((environment*)env)->tls;
2900 while ((tls->thread != thread) && (tls != NULL)) {
2904 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2906 *data_ptr = tls->data;
2908 return JVMTI_ERROR_NONE;
2912 /* SetThreadLocalStorage *******************************************************
2914 Stores a pointer value associated with each environment-thread pair. The
2915 value is NULL unless set with this function. Agents can allocate memory in
2916 which they store thread specific information
2918 *******************************************************************************/
2921 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2923 jvmtiThreadLocalStorage *tls, *pre;
2924 environment* env = (environment*)jenv;
2927 CHECK_PHASE(JVMTI_PHASE_START)
2928 CHECK_PHASE(JVMTI_PHASE_LIVE)
2932 thread = (jthread) THREADOBJECT;
2934 if (!builtin_instanceof(thread,class_java_lang_Thread))
2935 return JVMTI_ERROR_INVALID_THREAD;
2936 CHECK_THREAD_IS_ALIVE(thread);
2939 if (env->tls == NULL) {
2940 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2943 while ((tls->thread != thread) && (tls->next != NULL)) {
2946 if (tls->thread != thread) {
2947 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2953 tls->data = (void*)data;
2955 /* remove current tls */
2957 while (pre->next == tls) pre = pre->next;
2958 pre->next = tls->next;
2960 return JVMTI_ERROR_NONE;
2964 /* *****************************************************************************
2968 *******************************************************************************/
2971 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
2974 CHECK_PHASE(JVMTI_PHASE_START)
2975 CHECK_PHASE(JVMTI_PHASE_LIVE)
2977 CHECK_CAPABILITY(env,can_tag_objects)
2979 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2980 return JVMTI_ERROR_NONE;
2983 /* *****************************************************************************
2987 *******************************************************************************/
2990 SetTag (jvmtiEnv * env, jobject object, jlong tag)
2993 CHECK_PHASE(JVMTI_PHASE_START)
2994 CHECK_PHASE(JVMTI_PHASE_LIVE)
2996 CHECK_CAPABILITY(env,can_tag_objects)
2998 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2999 return JVMTI_ERROR_NONE;
3003 /* ForceGarbageCollection *****************************************************
3005 Force boehm-gc to perform a garbage collection
3007 *******************************************************************************/
3010 ForceGarbageCollection (jvmtiEnv * env)
3013 CHECK_PHASE(JVMTI_PHASE_LIVE)
3018 return JVMTI_ERROR_NONE;
3022 /* IterateOverObjectsReachableFromObject **************************************
3026 *******************************************************************************/
3029 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3030 jvmtiObjectReferenceCallback
3031 object_reference_callback,
3035 CHECK_PHASE(JVMTI_PHASE_LIVE)
3037 CHECK_CAPABILITY(env,can_tag_objects)
3039 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3040 return JVMTI_ERROR_NONE;
3044 /* IterateOverReachableObjects ************************************************
3048 *******************************************************************************/
3051 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3053 jvmtiStackReferenceCallback
3055 jvmtiObjectReferenceCallback
3056 object_ref_callback, void *user_data)
3059 CHECK_PHASE(JVMTI_PHASE_LIVE)
3061 CHECK_CAPABILITY(env,can_tag_objects)
3063 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3064 return JVMTI_ERROR_NONE;
3068 /* IterateOverHeap ************************************************************
3072 *******************************************************************************/
3075 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3076 jvmtiHeapObjectCallback heap_object_callback,
3080 CHECK_PHASE(JVMTI_PHASE_LIVE)
3082 CHECK_CAPABILITY(env,can_tag_objects)
3084 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3085 return JVMTI_ERROR_NONE;
3089 /* IterateOverInstancesOfClass ************************************************
3093 *******************************************************************************/
3096 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3097 jvmtiHeapObjectFilter object_filter,
3098 jvmtiHeapObjectCallback
3099 heap_object_callback, void *user_data)
3102 CHECK_PHASE(JVMTI_PHASE_LIVE)
3104 CHECK_CAPABILITY(env,can_tag_objects)
3106 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3107 return JVMTI_ERROR_NONE;
3111 /* *****************************************************************************
3115 *******************************************************************************/
3118 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3119 jint * count_ptr, jobject ** object_result_ptr,
3120 jlong ** tag_result_ptr)
3123 CHECK_PHASE(JVMTI_PHASE_LIVE)
3125 CHECK_CAPABILITY(env,can_tag_objects)
3127 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3128 return JVMTI_ERROR_NONE;
3132 /* SetJNIFunctionTable **********************************************************
3134 Set the JNI function table in all current and future JNI environments
3136 *******************************************************************************/
3139 SetJNIFunctionTable (jvmtiEnv * env,
3140 const jniNativeInterface * function_table)
3143 CHECK_PHASE(JVMTI_PHASE_START)
3144 CHECK_PHASE(JVMTI_PHASE_LIVE)
3147 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3148 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3149 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3150 return JVMTI_ERROR_NONE;
3154 /* GetJNIFunctionTable *********************************************************
3156 Get the JNI function table. The JNI function table is copied into allocated
3159 *******************************************************************************/
3162 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3165 CHECK_PHASE(JVMTI_PHASE_START)
3166 CHECK_PHASE(JVMTI_PHASE_LIVE)
3169 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3170 *function_table = (jniNativeInterface*)
3171 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3172 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3173 return JVMTI_ERROR_NONE;
3177 /* SetEventCallbacks **********************************************************
3179 Set the functions to be called for each event. The callbacks are specified
3180 by supplying a replacement function table.
3182 *******************************************************************************/
3185 SetEventCallbacks (jvmtiEnv * env,
3186 const jvmtiEventCallbacks * callbacks,
3187 jint size_of_callbacks)
3190 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3191 CHECK_PHASE(JVMTI_PHASE_LIVE)
3194 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3196 if (callbacks == NULL) { /* remove the existing callbacks */
3197 memset(&(((environment* )env)->callbacks), 0,
3198 sizeof(jvmtiEventCallbacks));
3201 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3203 return JVMTI_ERROR_NONE;
3207 /* GenerateEvents *************************************************************
3209 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3210 the current state of the VM.
3212 *******************************************************************************/
3215 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3218 CHECK_PHASE(JVMTI_PHASE_LIVE)
3221 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3222 return JVMTI_ERROR_NONE;
3226 /* GetExtensionFunctions ******************************************************
3228 Returns the set of extension functions.
3230 *******************************************************************************/
3233 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3234 jvmtiExtensionFunctionInfo ** extensions)
3237 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3238 CHECK_PHASE(JVMTI_PHASE_LIVE)
3241 if ((extension_count_ptr== NULL)||(extensions == NULL))
3242 return JVMTI_ERROR_NULL_POINTER;
3244 /* cacao has no extended functions yet */
3245 *extension_count_ptr = 0;
3247 return JVMTI_ERROR_NONE;
3251 /* GetExtensionEvents *********************************************************
3253 Returns the set of extension events.
3255 *******************************************************************************/
3258 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3259 jvmtiExtensionEventInfo ** extensions)
3262 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3263 CHECK_PHASE(JVMTI_PHASE_LIVE)
3266 if ((extension_count_ptr== NULL)||(extensions == NULL))
3267 return JVMTI_ERROR_NULL_POINTER;
3269 /* cacao has no extended events yet */
3270 *extension_count_ptr = 0;
3272 return JVMTI_ERROR_NONE;
3276 /* SetExtensionEventCallback **************************************************
3278 Sets the callback function for an extension event and enables the event.
3280 *******************************************************************************/
3283 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3284 jvmtiExtensionEvent callback)
3287 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3288 CHECK_PHASE(JVMTI_PHASE_LIVE)
3291 /* cacao has no extended events yet */
3292 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3296 /* DisposeEnvironment **********************************************************
3298 Shutdown a JVM TI connection created with JNI GetEnv.
3300 *******************************************************************************/
3303 DisposeEnvironment (jvmtiEnv * env)
3305 environment* cacao_env = (environment*)env;
3306 environment* tenvs = envs;
3307 jvmtiThreadLocalStorage *jtls, *tjtls;
3309 if (tenvs != cacao_env) {
3310 while (tenvs->next != cacao_env) {
3311 tenvs = tenvs->next;
3313 tenvs->next = cacao_env->next;
3317 cacao_env->env=NULL;
3318 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3319 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3320 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3321 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3322 cacao_env->EnvironmentLocalStorage = NULL;
3324 jtls = cacao_env->tls;
3325 while (jtls != NULL) {
3330 cacao_env->tls = NULL;
3333 jvmti_cacaodbgserver_quit();
3335 /* let the GC do the rest */
3336 return JVMTI_ERROR_NONE;
3340 /* GetErrorName ***************************************************************
3342 Return the symbolic name for an error code.
3344 *******************************************************************************/
3346 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3347 memcpy(*name_ptr, &str, sizeof(str)); \
3351 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3353 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3356 case JVMTI_ERROR_NONE :
3357 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3358 case JVMTI_ERROR_NULL_POINTER :
3359 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3360 case JVMTI_ERROR_OUT_OF_MEMORY :
3361 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3362 case JVMTI_ERROR_ACCESS_DENIED :
3363 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3364 case JVMTI_ERROR_UNATTACHED_THREAD :
3365 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3366 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3367 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3368 case JVMTI_ERROR_WRONG_PHASE :
3369 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3370 case JVMTI_ERROR_INTERNAL :
3371 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3372 case JVMTI_ERROR_INVALID_PRIORITY :
3373 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3374 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3375 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3376 case JVMTI_ERROR_THREAD_SUSPENDED :
3377 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3378 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3379 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3380 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3381 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3382 case JVMTI_ERROR_NO_MORE_FRAMES :
3383 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3384 case JVMTI_ERROR_OPAQUE_FRAME :
3385 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3386 case JVMTI_ERROR_DUPLICATE :
3387 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3388 case JVMTI_ERROR_NOT_FOUND :
3389 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3390 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3391 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3392 case JVMTI_ERROR_INTERRUPT :
3393 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3394 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3395 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3396 case JVMTI_ERROR_NOT_AVAILABLE :
3397 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3398 case JVMTI_ERROR_ABSENT_INFORMATION :
3399 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3400 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3401 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3402 case JVMTI_ERROR_NATIVE_METHOD :
3403 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3404 case JVMTI_ERROR_INVALID_THREAD :
3405 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3406 case JVMTI_ERROR_INVALID_FIELDID :
3407 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3408 case JVMTI_ERROR_INVALID_METHODID :
3409 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3410 case JVMTI_ERROR_INVALID_LOCATION :
3411 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3412 case JVMTI_ERROR_INVALID_OBJECT :
3413 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3414 case JVMTI_ERROR_INVALID_CLASS :
3415 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3416 case JVMTI_ERROR_TYPE_MISMATCH :
3417 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3418 case JVMTI_ERROR_INVALID_SLOT :
3419 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3420 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3421 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3422 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3423 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3424 case JVMTI_ERROR_INVALID_MONITOR :
3425 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3426 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3427 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3428 case JVMTI_ERROR_INVALID_TYPESTATE :
3429 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3430 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3431 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3432 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3433 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3434 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3435 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3436 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3437 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3438 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3439 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3440 case JVMTI_ERROR_FAILS_VERIFICATION :
3441 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3442 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3443 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3444 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3445 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3446 case JVMTI_ERROR_NAMES_DONT_MATCH :
3447 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3448 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3449 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3450 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3451 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3453 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3455 return JVMTI_ERROR_NONE;
3458 /* GetJLocationFormat **********************************************************
3460 This function describes the representation of jlocation used in this VM.
3462 *******************************************************************************/
3465 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3467 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3468 return JVMTI_ERROR_NONE;
3472 /* GetSystemProperties ********************************************************
3474 The list of VM system property keys which may be used with GetSystemProperty
3477 *******************************************************************************/
3480 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3482 jmethodID mid, moremid;
3483 classinfo *sysclass, *propclass, *enumclass;
3484 java_objectheader *sysprop, *keys, *obj;
3489 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3490 CHECK_PHASE(JVMTI_PHASE_LIVE)
3493 if ((count_ptr == NULL) || (property_ptr == NULL))
3494 return JVMTI_ERROR_NULL_POINTER;
3496 sysclass = load_class_from_sysloader(
3497 utf_new_char_classname ("java/lang/System"));
3499 if (!sysclass) throw_main_exception_exit();
3501 mid = (jmethodID)class_resolvemethod(sysclass,
3502 utf_new_char("getProperties"),
3503 utf_new_char("()Ljava/util/Properties;"));
3504 if (!mid) throw_main_exception_exit();
3507 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3508 if (!sysprop) throw_main_exception_exit();
3510 propclass = sysprop->vftbl->class;
3512 mid = (jmethodID)class_resolvemethod(propclass,
3513 utf_new_char("size"),
3514 utf_new_char("()I"));
3515 if (!mid) throw_main_exception_exit();
3518 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3519 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3521 mid = (jmethodID)class_resolvemethod(propclass,
3522 utf_new_char("keys"),
3523 utf_new_char("()Ljava/util/Enumeration;"));
3524 if (!mid) throw_main_exception_exit();
3526 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3527 enumclass = keys->vftbl->class;
3529 moremid = (jmethodID)class_resolvemethod(enumclass,
3530 utf_new_char("hasMoreElements"),
3531 utf_new_char("()Z"));
3532 if (!moremid) throw_main_exception_exit();
3534 mid = (jmethodID)class_resolvemethod(propclass,
3535 utf_new_char("nextElement"),
3536 utf_new_char("()Ljava/lang/Object;"));
3537 if (!mid) throw_main_exception_exit();
3540 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3541 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3542 ch = javastring_tochar(obj);
3543 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3544 memcpy(*property_ptr[i], ch, strlen (ch));
3545 MFREE(ch,char,strlen(ch)+1);
3549 return JVMTI_ERROR_NONE;
3553 /* GetSystemProperty **********************************************************
3555 Return a VM system property value given the property key.
3557 *******************************************************************************/
3560 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3563 classinfo *sysclass, *propclass;
3564 java_objectheader *sysprop, *obj;
3568 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3569 CHECK_PHASE(JVMTI_PHASE_LIVE)
3572 if ((value_ptr == NULL) || (property == NULL))
3573 return JVMTI_ERROR_NULL_POINTER;
3575 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3576 if (!sysclass) throw_main_exception_exit();
3578 mid = (jmethodID)class_resolvemethod(sysclass,
3579 utf_new_char("getProperties"),
3580 utf_new_char("()Ljava/util/Properties;"));
3581 if (!mid) throw_main_exception_exit();
3583 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3585 propclass = sysprop->vftbl->class;
3587 mid = (jmethodID)class_resolvemethod(propclass,
3588 utf_new_char("getProperty"),
3589 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3590 if (!mid) throw_main_exception_exit();
3592 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3593 NULL, sysprop, mid, javastring_new_from_ascii(property));
3594 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3596 ch = javastring_tochar(obj);
3597 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3598 memcpy(*value_ptr, ch, strlen (ch));
3599 MFREE(ch,char,strlen(ch)+1);
3601 return JVMTI_ERROR_NONE;
3605 /* SetSystemProperty **********************************************************
3607 Set a VM system property value.
3609 *******************************************************************************/
3612 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3615 classinfo *sysclass, *propclass;
3616 java_objectheader *sysprop;
3619 CHECK_PHASE(JVMTI_PHASE_START)
3622 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3623 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3625 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3626 if (!sysclass) throw_main_exception_exit();
3628 mid = (jmethodID)class_resolvemethod(sysclass,
3629 utf_new_char("getProperties"),
3630 utf_new_char("()Ljava/util/Properties;"));
3631 if (!mid) throw_main_exception_exit();
3633 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3635 propclass = sysprop->vftbl->class;
3637 mid = (jmethodID)class_resolvemethod(propclass,
3638 utf_new_char("setProperty"),
3639 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3640 if (!mid) throw_main_exception_exit();
3642 _Jv_JNINativeInterface.CallObjectMethod(
3643 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3645 return JVMTI_ERROR_NONE;
3648 /* GetPhase ********************************************************************
3650 Return the current phase of VM execution
3652 *******************************************************************************/
3655 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3657 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3661 return JVMTI_ERROR_NONE;
3664 /* GetCurrentThreadCpuTimerInfo ************************************************
3668 *******************************************************************************/
3671 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3674 CHECK_PHASE(JVMTI_PHASE_START)
3675 CHECK_PHASE(JVMTI_PHASE_LIVE)
3677 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3679 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3681 return JVMTI_ERROR_NONE;
3684 /* GetCurrentThreadCpuTime ****************************************************
3688 *******************************************************************************/
3691 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3694 CHECK_PHASE(JVMTI_PHASE_START)
3695 CHECK_PHASE(JVMTI_PHASE_LIVE)
3697 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3699 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3700 return JVMTI_ERROR_NONE;
3703 /* GetThreadCpuTimerInfo ******************************************************
3707 *******************************************************************************/
3710 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3713 CHECK_PHASE(JVMTI_PHASE_START)
3714 CHECK_PHASE(JVMTI_PHASE_LIVE)
3716 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3718 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3719 return JVMTI_ERROR_NONE;
3722 /* GetThreadCpuTime ***********************************************************
3726 *******************************************************************************/
3729 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3732 CHECK_PHASE(JVMTI_PHASE_LIVE)
3734 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3735 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3736 return JVMTI_ERROR_NONE;
3739 /* GetTimerInfo ***************************************************************
3741 Get information about the GetTime timer.
3743 *******************************************************************************/
3746 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3748 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3750 info_ptr->max_value = !0x0;
3751 info_ptr->may_skip_forward = true;
3752 info_ptr->may_skip_backward = true;
3753 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3755 return JVMTI_ERROR_NONE;
3758 /* GetTime ********************************************************************
3760 Return the current value of the system timer, in nanoseconds
3762 *******************************************************************************/
3765 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3767 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3770 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3772 if (gettimeofday (&tp, NULL) == -1)
3773 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3775 *nanos_ptr = (jlong) tp.tv_sec;
3777 *nanos_ptr += (tp.tv_usec / 1000);
3779 return JVMTI_ERROR_NONE;
3782 /* GetPotentialCapabilities ***************************************************
3784 Returns the JVM TI features that can potentially be possessed by this
3785 environment at this time.
3787 *******************************************************************************/
3790 GetPotentialCapabilities (jvmtiEnv * env,
3791 jvmtiCapabilities * capabilities_ptr)
3794 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3795 CHECK_PHASE(JVMTI_PHASE_LIVE)
3798 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3800 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3802 return JVMTI_ERROR_NONE;
3806 #define CHECK_ADD_CAPABILITY(env,CAN) \
3807 if (capabilities_ptr->CAN == 1) { \
3808 if (JVMTI_Capabilities.CAN == 0) \
3809 return JVMTI_ERROR_NOT_AVAILABLE; \
3811 env->capabilities.CAN = 1; \
3814 /* AddCapabilities ************************************************************
3816 Set new capabilities by adding the capabilities pointed to by
3817 capabilities_ptr. All previous capabilities are retained.
3819 *******************************************************************************/
3822 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3824 environment* cacao_env;
3827 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3828 CHECK_PHASE(JVMTI_PHASE_LIVE)
3831 if ((env == NULL) || (capabilities_ptr == NULL))
3832 return JVMTI_ERROR_NULL_POINTER;
3834 cacao_env = (environment*)env;
3836 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3837 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3838 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3839 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3840 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3841 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3842 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3843 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3844 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3845 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3846 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3847 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3848 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3849 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3850 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3851 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3852 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3853 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3854 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3855 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3856 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3857 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3858 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3859 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3860 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3861 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3862 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3863 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3864 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3865 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3866 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3867 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3868 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3871 return JVMTI_ERROR_NONE;
3875 #define CHECK_DEL_CAPABILITY(env,CAN) \
3876 if (capabilities_ptr->CAN == 1) \
3877 env->capabilities.CAN = 0;
3879 /* RelinquishCapabilities *****************************************************
3881 Relinquish the capabilities pointed to by capabilities_ptr.
3883 *******************************************************************************/
3886 RelinquishCapabilities (jvmtiEnv * env,
3887 const jvmtiCapabilities * capabilities_ptr)
3889 environment* cacao_env;
3892 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3893 CHECK_PHASE(JVMTI_PHASE_LIVE)
3896 if ((env == NULL) || (capabilities_ptr == NULL))
3897 return JVMTI_ERROR_NULL_POINTER;
3899 cacao_env = (environment*)env;
3901 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3902 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3903 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3904 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3905 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3906 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3907 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3908 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3909 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3910 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3911 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3912 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3913 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3914 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3915 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3916 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3917 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3918 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3919 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3920 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3921 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3922 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3923 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3924 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3925 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3926 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3927 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3928 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3929 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3930 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3931 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3932 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3933 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3935 return JVMTI_ERROR_NONE;
3938 /* *****************************************************************************
3942 *******************************************************************************/
3945 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3948 CHECK_PHASE(JVMTI_PHASE_START)
3949 CHECK_PHASE(JVMTI_PHASE_LIVE)
3952 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3954 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3956 *processor_count_ptr = 1; /* where do I get this ?*/
3958 return JVMTI_ERROR_NONE;
3961 /* GetEnvironmentLocalStorage **************************************************
3963 Called by the agent to get the value of the JVM TI environment-local storage.
3965 *******************************************************************************/
3968 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
3970 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
3972 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
3974 return JVMTI_ERROR_NONE;
3977 /* SetEnvironmentLocalStorage **************************************************
3979 The VM stores a pointer value associated with each environment. Agents can
3980 allocate memory in which they store environment specific information.
3982 *******************************************************************************/
3985 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
3987 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
3989 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
3991 return JVMTI_ERROR_NONE;
3994 /* AddToBootstrapClassLoaderSearch ********************************************
3996 After the bootstrap class loader unsuccessfully searches for a class, the
3997 specified platform-dependent search path segment will be searched as well.
3999 *******************************************************************************/
4002 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4008 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4011 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4013 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4014 tmp_bcp = MNEW(char, ln);
4015 strcat(tmp_bcp, bootclasspath);
4016 strcat(tmp_bcp, ":");
4017 strcat(tmp_bcp, segment);
4018 MFREE(bootclasspath,char,ln);
4019 bootclasspath = tmp_bcp;
4021 return JVMTI_ERROR_NONE;
4024 /* SetVerboseFlag *************************************************************
4026 Control verbose output. This is the output which typically is sent to stderr
4028 *******************************************************************************/
4031 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4034 case JVMTI_VERBOSE_OTHER:
4035 /* where is this defined ?
4039 case JVMTI_VERBOSE_GC:
4040 opt_verbosegc = value;
4042 case JVMTI_VERBOSE_CLASS:
4043 loadverbose = value;
4045 case JVMTI_VERBOSE_JNI:
4048 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4050 return JVMTI_ERROR_NONE;
4053 /* GetObjectSize **************************************************************
4055 For the object object return the size.
4057 *******************************************************************************/
4060 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4063 CHECK_PHASE(JVMTI_PHASE_START)
4064 CHECK_PHASE(JVMTI_PHASE_LIVE)
4067 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4068 if (!builtin_instanceof(object,class_java_lang_Object))
4069 return JVMTI_ERROR_INVALID_OBJECT;
4071 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4073 return JVMTI_ERROR_NONE;
4077 /* *****************************************************************************
4079 Environment variables
4081 *******************************************************************************/
4083 static jvmtiCapabilities JVMTI_Capabilities = {
4084 0, /* can_tag_objects */
4085 0, /* can_generate_field_modification_events */
4086 0, /* can_generate_field_access_events */
4087 1, /* can_get_bytecodes */
4088 0, /* can_get_synthetic_attribute */
4090 #if defined(ENABLE_THREADS)
4091 1, /* can_get_owned_monitor_info */
4092 1, /* can_get_current_contended_monitor */
4094 0, /* can_get_owned_monitor_info */
4095 0, /* can_get_current_contended_monitor */
4098 0, /* can_get_monitor_info */
4099 0, /* can_pop_frame */
4100 0, /* can_redefine_classes */
4101 0, /* can_signal_thread */
4102 1, /* can_get_source_file_name */
4103 1, /* can_get_line_numbers */
4104 0, /* can_get_source_debug_extension */
4105 0, /* can_access_local_variables */
4106 0, /* can_maintain_original_method_order */
4107 0, /* can_generate_single_step_events */
4108 0, /* can_generate_exception_events */
4109 0, /* can_generate_frame_pop_events */
4110 0, /* can_generate_breakpoint_events */
4111 0, /* can_suspend */
4112 0, /* can_redefine_any_class */
4113 0, /* can_get_current_thread_cpu_time */
4114 0, /* can_get_thread_cpu_time */
4115 0, /* can_generate_method_entry_events */
4116 0, /* can_generate_method_exit_events */
4117 0, /* can_generate_all_class_hook_events */
4118 0, /* can_generate_compiled_method_load_events */
4119 0, /* can_generate_monitor_events */
4120 0, /* can_generate_vm_object_alloc_events */
4121 0, /* can_generate_native_method_bind_events */
4122 0, /* can_generate_garbage_collection_events */
4123 0, /* can_generate_object_free_events */
4126 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4128 &SetEventNotificationMode,
4136 &GetOwnedMonitorInfo,
4137 &GetCurrentContendedMonitor,
4139 &GetTopThreadGroups,
4140 &GetThreadGroupInfo,
4141 &GetThreadGroupChildren,
4163 &RawMonitorNotifyAll,
4167 &SetFieldAccessWatch,
4168 &ClearFieldAccessWatch,
4169 &SetFieldModificationWatch,
4170 &ClearFieldModificationWatch,
4180 &GetImplementedInterfaces,
4185 &GetObjectMonitorUsage,
4187 &GetFieldDeclaringClass,
4191 &GetMethodDeclaringClass,
4192 &GetMethodModifiers,
4196 &GetLineNumberTable,
4198 &GetLocalVariableTable,
4205 &GetClassLoaderClasses,
4216 &GetSourceDebugExtension,
4227 &GetThreadListStackTraces,
4228 &GetThreadLocalStorage,
4229 &SetThreadLocalStorage,
4234 &ForceGarbageCollection,
4235 &IterateOverObjectsReachableFromObject,
4236 &IterateOverReachableObjects,
4238 &IterateOverInstancesOfClass,
4240 &GetObjectsWithTags,
4246 &SetJNIFunctionTable,
4247 &GetJNIFunctionTable,
4250 &GetExtensionFunctions,
4251 &GetExtensionEvents,
4252 &SetExtensionEventCallback,
4253 &DisposeEnvironment,
4255 &GetJLocationFormat,
4256 &GetSystemProperties,
4260 &GetCurrentThreadCpuTimerInfo,
4261 &GetCurrentThreadCpuTime,
4262 &GetThreadCpuTimerInfo,
4266 &GetPotentialCapabilities,
4269 &RelinquishCapabilities,
4270 &GetAvailableProcessors,
4273 &GetEnvironmentLocalStorage,
4274 &SetEnvironmentLocalStorage,
4275 &AddToBootstrapClassLoaderSearch,
4284 void jvmti_set_phase(jvmtiPhase p) {
4287 fprintf (stderr,"set JVMTI phase %d\n",p);
4291 case JVMTI_PHASE_ONLOAD:
4294 case JVMTI_PHASE_PRIMORDIAL:
4297 case JVMTI_PHASE_START:
4299 d.ev = JVMTI_EVENT_VM_START;
4301 case JVMTI_PHASE_LIVE:
4303 d.ev = JVMTI_EVENT_VM_INIT;
4304 jvmti_fireEvent(&d);
4305 /* thread start event for main thread */
4306 d.ev = JVMTI_EVENT_THREAD_START;
4308 case JVMTI_PHASE_DEAD:
4310 d.ev = JVMTI_EVENT_VM_DEATH;
4313 log_text("wrong jvmti phase to be set");
4317 jvmti_fireEvent(&d);
4320 jvmtiEnv* jvmti_new_environment() {
4324 envs = heap_allocate(sizeof(environment),true,NULL);
4328 while (env->next != NULL) env = env->next;
4329 env->next = heap_allocate(sizeof(environment),true,NULL);
4333 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4334 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4335 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4336 sizeof(jvmtiEventModeLL));
4337 /* To possess a capability, the agent must add the capability.*/
4338 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4339 RelinquishCapabilities(&(env->env),&(env->capabilities));
4340 env->EnvironmentLocalStorage = NULL;
4343 /* initialize cacao debugging facilities */
4344 jvmti_cacao_debug_init();
4346 return (jvmtiEnv*)env;
4349 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4356 len = strlen(opt_arg);
4358 /* separate argumtents */
4359 while ((opt_arg[i]!='=')&&(i<=len)) i++;
4364 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4365 strncpy(*libname,opt_arg,i-1);
4366 (*libname)[i-1]='\0';
4369 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4370 strncpy(*libname,"lib",3);
4371 strncpy(&(*libname)[3],opt_arg,i-1);
4372 strncpy(&(*libname)[i+2],".so",3);
4375 /* try to open the library */
4377 if (!(*handle = lt_dlopen(*libname))) {
4378 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4382 /* resolve Agent_OnLoad function */
4383 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4384 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4388 /* resolve Agent_UnLoad function */
4389 unload = lt_dlsym(*handle, "Agent_Unload");
4392 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4393 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4395 if (retval != 0) exit (retval);
4398 void jvmti_agentunload() {
4399 if (unload != NULL) {
4400 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4401 ((JavaVM*) &_Jv_JNIInvokeInterface);
4406 * These are local overrides for various environment variables in Emacs.
4407 * Please do not remove this and leave it at the end of the file, where
4408 * Emacs will automagically detect them.
4409 * ---------------------------------------------------------------------
4412 * indent-tabs-mode: t
4416 * vim:noexpandtab:sw=4:ts=4: