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 4944 2006-05-23 15:31:19Z 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,
1741 CHECK_PHASE(JVMTI_PHASE_START)
1742 CHECK_PHASE(JVMTI_PHASE_LIVE)
1745 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1746 return JVMTI_ERROR_NULL_POINTER;
1748 nsize=((classinfo*)klass)->name->blength;
1749 psize=((classinfo*)klass)->packagename->blength;
1751 *signature_ptr = (char*)
1752 heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
1754 *signature_ptr[0]='L';
1755 memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
1756 *signature_ptr[psize+2]='/';
1757 memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
1758 *signature_ptr[nsize+psize+3]=';';
1759 *signature_ptr[nsize+psize+4]='\0';
1761 *generic_ptr = NULL;
1763 return JVMTI_ERROR_NONE;
1766 /* GetClassStatus *************************************************************
1768 Get status of the class.
1770 *******************************************************************************/
1773 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1777 CHECK_PHASE(JVMTI_PHASE_START)
1778 CHECK_PHASE(JVMTI_PHASE_LIVE)
1781 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1782 return JVMTI_ERROR_INVALID_CLASS;
1784 if (status_ptr == NULL)
1785 return JVMTI_ERROR_NULL_POINTER;
1787 c = (classinfo*)klass;
1790 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1791 if (c->state&=CLASS_LINKED)
1792 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1794 if (c->state&=CLASS_INITIALIZED)
1795 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1797 if (c->state&=CLASS_ERROR)
1798 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1800 if (c->vftbl->arraydesc != NULL)
1801 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1803 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1804 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1806 return JVMTI_ERROR_NONE;
1810 /* GetSourceFileName **********************************************************
1812 For the class indicated by klass, return the source file name.
1814 *******************************************************************************/
1817 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1822 CHECK_PHASE(JVMTI_PHASE_START)
1823 CHECK_PHASE(JVMTI_PHASE_LIVE)
1825 CHECK_CAPABILITY(env,can_get_source_file_name)
1827 if ((klass == NULL)||(source_name_ptr == NULL))
1828 return JVMTI_ERROR_NULL_POINTER;
1830 size = (((classinfo*)klass)->sourcefile->blength)+1;
1832 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1834 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1835 (*source_name_ptr)[size]='\0';
1837 return JVMTI_ERROR_NONE;
1841 /* GetClassModifiers **********************************************************
1843 For class klass return the access flags
1845 *******************************************************************************/
1848 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1851 CHECK_PHASE(JVMTI_PHASE_START)
1852 CHECK_PHASE(JVMTI_PHASE_LIVE)
1855 if (modifiers_ptr == NULL)
1856 return JVMTI_ERROR_NULL_POINTER;
1858 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1859 return JVMTI_ERROR_INVALID_CLASS;
1861 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1863 return JVMTI_ERROR_NONE;
1867 /* GetClassMethods *************************************************************
1869 For class klass return a count of methods and a list of method IDs
1871 *******************************************************************************/
1874 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1875 jmethodID ** methods_ptr)
1880 CHECK_PHASE(JVMTI_PHASE_START)
1881 CHECK_PHASE(JVMTI_PHASE_LIVE)
1884 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1885 return JVMTI_ERROR_NULL_POINTER;
1887 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1888 return JVMTI_ERROR_INVALID_CLASS;
1890 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1891 *methods_ptr = (jmethodID*)
1892 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1894 for (i=0; i<*method_count_ptr;i++)
1895 (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
1897 return JVMTI_ERROR_NONE;
1901 /* GetClassFields *************************************************************
1903 For the class indicated by klass, return a count of fields and a list of
1906 *******************************************************************************/
1909 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1910 jfieldID ** fields_ptr)
1913 CHECK_PHASE(JVMTI_PHASE_START)
1914 CHECK_PHASE(JVMTI_PHASE_LIVE)
1917 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1918 return JVMTI_ERROR_NULL_POINTER;
1920 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1921 *fields_ptr = (jfieldID*)
1922 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1924 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1925 sizeof(jfieldID) * (*field_count_ptr));
1927 return JVMTI_ERROR_NONE;
1931 /* GetImplementedInterfaces ***************************************************
1933 Return the direct super-interfaces of this class.
1935 *******************************************************************************/
1938 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1939 jint * interface_count_ptr,
1940 jclass ** interfaces_ptr)
1943 classref_or_classinfo *interfaces;
1947 CHECK_PHASE(JVMTI_PHASE_START)
1948 CHECK_PHASE(JVMTI_PHASE_LIVE)
1951 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1952 return JVMTI_ERROR_NULL_POINTER;
1954 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1955 return JVMTI_ERROR_INVALID_CLASS;
1958 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1960 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1962 interfaces = ((classinfo*)klass)->interfaces;
1963 for (i=0; i<*interface_count_ptr; i++) {
1964 if (IS_CLASSREF(interfaces[i]))
1965 tmp = load_class_bootstrap(interfaces[i].ref->name);
1967 tmp = interfaces[i].cls;
1969 *interfaces_ptr[i]=tmp;
1972 return JVMTI_ERROR_NONE;
1976 /* IsInterface ****************************************************************
1978 Determines whether a class object reference represents an interface.
1980 *******************************************************************************/
1983 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1986 CHECK_PHASE(JVMTI_PHASE_START)
1987 CHECK_PHASE(JVMTI_PHASE_LIVE)
1990 if ((klass == NULL)||(is_interface_ptr == NULL))
1991 return JVMTI_ERROR_NULL_POINTER;
1993 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
1995 return JVMTI_ERROR_NONE;
1998 /* IsArrayClass ***************************************************************
2000 Determines whether a class object reference represents an array.
2002 *******************************************************************************/
2005 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
2008 CHECK_PHASE(JVMTI_PHASE_START)
2009 CHECK_PHASE(JVMTI_PHASE_LIVE)
2012 if (is_array_class_ptr == NULL)
2013 return JVMTI_ERROR_NULL_POINTER;
2015 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
2017 return JVMTI_ERROR_NONE;
2021 /* GetClassLoader *************************************************************
2023 For the class indicated by klass, return via classloader_ptr a reference to
2024 the class loader for the class.
2026 *******************************************************************************/
2029 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2032 CHECK_PHASE(JVMTI_PHASE_START)
2033 CHECK_PHASE(JVMTI_PHASE_LIVE)
2036 if ((klass == NULL)||(classloader_ptr == NULL))
2037 return JVMTI_ERROR_NULL_POINTER;
2039 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2041 return JVMTI_ERROR_NONE;
2045 /* GetObjectHashCode **********************************************************
2047 Return hash code for object object
2049 *******************************************************************************/
2052 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2055 CHECK_PHASE(JVMTI_PHASE_START)
2056 CHECK_PHASE(JVMTI_PHASE_LIVE)
2059 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2060 if (!builtin_instanceof(object,class_java_lang_Object))
2061 return JVMTI_ERROR_INVALID_OBJECT;
2063 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2065 return JVMTI_ERROR_NONE;
2069 /* *****************************************************************************
2073 *******************************************************************************/
2076 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2077 jvmtiMonitorUsage * info_ptr)
2080 CHECK_PHASE(JVMTI_PHASE_LIVE)
2082 CHECK_CAPABILITY(env,can_get_monitor_info)
2084 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2085 return JVMTI_ERROR_NONE;
2089 /* GetFieldName ***************************************************************
2091 For the field indicated by klass and field, return the field name and
2094 *******************************************************************************/
2097 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2098 char **name_ptr, char **signature_ptr, char **generic_ptr)
2103 CHECK_PHASE(JVMTI_PHASE_START)
2104 CHECK_PHASE(JVMTI_PHASE_LIVE)
2107 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2108 return JVMTI_ERROR_NULL_POINTER;
2110 size = (((fieldinfo*)field)->name->blength);
2111 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2112 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2114 size = (((fieldinfo*)field)->descriptor->blength);
2115 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2116 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2118 *generic_ptr = NULL;
2120 return JVMTI_ERROR_NONE;
2124 /* GetFieldDeclaringClass *****************************************************
2126 For the field indicated by klass and field return the class that defined it
2127 The declaring class will either be klass, a superclass, or an implemented
2130 *******************************************************************************/
2133 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2134 jclass * declaring_class_ptr)
2137 CHECK_PHASE(JVMTI_PHASE_START)
2138 CHECK_PHASE(JVMTI_PHASE_LIVE)
2141 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2143 return JVMTI_ERROR_NONE;
2147 /* GetFieldModifiers **********************************************************
2149 Return access flags of field field
2151 *******************************************************************************/
2154 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2155 jint * modifiers_ptr)
2158 CHECK_PHASE(JVMTI_PHASE_START)
2159 CHECK_PHASE(JVMTI_PHASE_LIVE)
2162 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2163 return JVMTI_ERROR_INVALID_OBJECT;
2165 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2167 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2169 *modifiers_ptr = ((fieldinfo*)field)->flags;
2171 return JVMTI_ERROR_NONE;
2175 /* IsFieldSynthetic ***********************************************************
2179 *******************************************************************************/
2182 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2183 jboolean * is_synthetic_ptr)
2186 CHECK_PHASE(JVMTI_PHASE_START)
2187 CHECK_PHASE(JVMTI_PHASE_LIVE)
2189 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2191 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2192 return JVMTI_ERROR_NONE;
2196 /* GetMethodName ***************************************************************
2198 For the method indicated by method, return the method name via name_ptr and
2199 method signature via signature_ptr.
2201 *******************************************************************************/
2204 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2205 char **signature_ptr, char **generic_ptr)
2207 methodinfo* m = (methodinfo*)method;
2210 CHECK_PHASE(JVMTI_PHASE_START)
2211 CHECK_PHASE(JVMTI_PHASE_LIVE)
2214 if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2215 || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2218 heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
2219 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2221 *signature_ptr = (char*)
2222 heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
2223 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2225 /* there is no generic signature attribute */
2226 *generic_ptr = NULL;
2228 return JVMTI_ERROR_NONE;
2232 /* GetMethodDeclaringClass *****************************************************
2234 For the method indicated by method, return the class that defined it.
2236 *******************************************************************************/
2239 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2240 jclass * declaring_class_ptr)
2243 CHECK_PHASE(JVMTI_PHASE_START)
2244 CHECK_PHASE(JVMTI_PHASE_LIVE)
2247 if ((method == NULL) || (declaring_class_ptr == NULL))
2248 return JVMTI_ERROR_NULL_POINTER;
2250 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2252 return JVMTI_ERROR_NONE;
2256 /* GetMethodModifiers **********************************************************
2258 For the method indicated by method, return the access flags.
2260 *******************************************************************************/
2263 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2266 CHECK_PHASE(JVMTI_PHASE_START)
2267 CHECK_PHASE(JVMTI_PHASE_LIVE)
2270 if ((method == NULL) || (modifiers_ptr == NULL))
2271 return JVMTI_ERROR_NULL_POINTER;
2273 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2275 return JVMTI_ERROR_NONE;
2279 /* GetMaxLocals ****************************************************************
2281 For the method indicated by method, return the number of local variable slots
2282 used by the method, including the local variables used to pass parameters to
2283 the method on its invocation.
2285 *******************************************************************************/
2288 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2291 CHECK_PHASE(JVMTI_PHASE_START)
2292 CHECK_PHASE(JVMTI_PHASE_LIVE)
2295 if ((method == NULL)||(max_ptr == NULL))
2296 return JVMTI_ERROR_NULL_POINTER;
2298 if (((methodinfo*)method)->flags & ACC_NATIVE)
2299 return JVMTI_ERROR_NATIVE_METHOD;
2301 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2303 return JVMTI_ERROR_NONE;
2308 /* GetArgumentsSize ************************************************************
2310 Return the number of local variable slots used by the method's arguments.
2312 *******************************************************************************/
2315 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2318 CHECK_PHASE(JVMTI_PHASE_START)
2319 CHECK_PHASE(JVMTI_PHASE_LIVE)
2322 if ((method == NULL)||(size_ptr == NULL))
2323 return JVMTI_ERROR_NULL_POINTER;
2325 if (((methodinfo*)method)->flags & ACC_NATIVE)
2326 return JVMTI_ERROR_NATIVE_METHOD;
2328 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2329 return JVMTI_ERROR_NONE;
2334 /* GetLineNumberTable ***********************************************************
2336 Return table of source line number entries for a given method
2338 *******************************************************************************/
2341 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2342 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2347 CHECK_PHASE(JVMTI_PHASE_START)
2348 CHECK_PHASE(JVMTI_PHASE_LIVE)
2350 CHECK_CAPABILITY(env,can_get_line_numbers)
2352 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2353 return JVMTI_ERROR_NULL_POINTER;
2354 if (((methodinfo*)method)->flags & ACC_NATIVE)
2355 return JVMTI_ERROR_NATIVE_METHOD;
2356 if (((methodinfo*)method)->linenumbers == NULL)
2357 return JVMTI_ERROR_ABSENT_INFORMATION;
2359 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2360 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2361 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2364 for (i=0; i < *entry_count_ptr; i++) {
2365 (*table_ptr[i]).start_location =
2366 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2367 (*table_ptr[i]).line_number =
2368 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2371 return JVMTI_ERROR_NONE;
2375 /* GetMethodLocation ***********************************************************
2377 For the method indicated by method, return the beginning and ending addresses
2378 through start_location_ptr and end_location_ptr. In cacao this points to
2379 entry point in machine code and length of machine code
2381 *******************************************************************************/
2384 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2385 jlocation * start_location_ptr,
2386 jlocation * end_location_ptr)
2388 methodinfo* m = (methodinfo*)method;
2391 CHECK_PHASE(JVMTI_PHASE_START)
2392 CHECK_PHASE(JVMTI_PHASE_LIVE)
2395 if ((method == NULL) || (start_location_ptr == NULL) ||
2396 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2398 /* XXX we return the location of the most recent code. Don't know
2399 * if there is a way to teach jvmti that a method can have more
2400 * than one location. -Edwin */
2402 /* XXX Don't know if that's the right way to deal with not-yet-
2403 * compiled methods. -Edwin */
2406 return JVMTI_ERROR_NULL_POINTER;
2408 *start_location_ptr = (jlocation)m->code->mcode;
2409 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2410 return JVMTI_ERROR_NONE;
2414 /* GetLocalVariableTable *******************************************************
2416 Return local variable information.
2418 *******************************************************************************/
2421 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2422 jint * entry_count_ptr,
2423 jvmtiLocalVariableEntry ** table_ptr)
2426 CHECK_PHASE(JVMTI_PHASE_LIVE)
2428 CHECK_CAPABILITY(env,can_access_local_variables)
2430 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2432 return JVMTI_ERROR_NONE;
2436 /* GetBytecode *****************************************************************
2438 For the method indicated by method, return the byte codes that implement the
2441 *******************************************************************************/
2444 GetBytecodes (jvmtiEnv * env, jmethodID method,
2445 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2447 methodinfo* m = (methodinfo*)method;;
2450 CHECK_PHASE(JVMTI_PHASE_START)
2451 CHECK_PHASE(JVMTI_PHASE_LIVE)
2453 CHECK_CAPABILITY(env,can_get_bytecodes)
2455 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2456 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2458 *bytecode_count_ptr = m->jcodelength;
2459 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2460 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2462 return JVMTI_ERROR_NONE;
2466 /* IsMethodNative **************************************************************
2468 For the method indicated by method, return a value indicating whether the
2469 method is a native function
2471 *******************************************************************************/
2474 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2477 CHECK_PHASE(JVMTI_PHASE_START)
2478 CHECK_PHASE(JVMTI_PHASE_LIVE)
2481 if ((method == NULL)||(is_native_ptr == NULL))
2482 return JVMTI_ERROR_NULL_POINTER;
2484 if (((methodinfo*)method)->flags & ACC_NATIVE)
2485 *is_native_ptr = JNI_TRUE;
2487 *is_native_ptr = JNI_FALSE;
2489 return JVMTI_ERROR_NONE;
2493 /* IsMethodSynthetic ***********************************************************
2495 return a value indicating whether the method is synthetic. Synthetic methods
2496 are generated by the compiler but not present in the original source code.
2498 *******************************************************************************/
2501 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2502 jboolean * is_synthetic_ptr)
2505 CHECK_PHASE(JVMTI_PHASE_START)
2506 CHECK_PHASE(JVMTI_PHASE_LIVE)
2508 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2510 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2511 return JVMTI_ERROR_NONE;
2515 /* GetLoadedClasses ************************************************************
2517 Return an array of all classes loaded in the virtual machine.
2519 *******************************************************************************/
2522 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2527 classcache_name_entry *cne;
2528 classcache_class_entry *cce;
2530 log_text ("GetLoadedClasses called %d ", phase);
2535 *class_count_ptr = 0;
2538 CHECK_PHASE(JVMTI_PHASE_LIVE)
2541 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2542 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2544 log_text ("GetLoadedClasses1");
2548 log_text ("GetLoadedClasses2");
2549 getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
2550 ht = (hashtable*) &data;
2552 log_text ("GetLoadedClasses got ht pointer");
2554 heap_allocate(sizeof(jclass*) * (ht->entries),true,NULL);
2555 fprintf (stderr,"hashtable_classcache.entries = %d\n",ht->entries);
2558 *class_count_ptr = ht->entries;
2559 log_text ("GetLoadedClasses %d", *class_count_ptr);
2561 look in every slot of the hashtable
2562 for (i=0; i<ht->size; i++) {
2565 while (cne != NULL) { iterate over hashlink
2566 getchildproc(&data, cne, sizeof(classcache_name_entry));
2567 cne =(classcache_name_entry*) &data;
2570 while (cce != NULL){ iterate over classes with same name
2571 getchildproc(&data, cce, sizeof(classcache_class_entry));
2572 cce =(classcache_class_entry*) &data;
2574 if (cce->classobj != NULL) { get only loaded classes
2575 assert(j<ht->entries);
2576 * classes_ptr[j]=cce->classobj;
2581 cne = cne->hashlink;
2585 log_text ("GetLoadedClasses continue");
2587 CLASSCACHE_UNLOCK();
2591 log_text ("GetLoadedClasses finished");
2593 return JVMTI_ERROR_NONE;
2597 /* GetClassLoaderClasses *******************************************************
2599 Returns an array of those classes for which this class loader has been
2600 recorded as an initiating loader.
2602 *******************************************************************************/
2605 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2606 jint * class_count_ptr, jclass ** classes_ptr)
2608 log_text("GetClassLoaderClasses called");
2611 CHECK_PHASE(JVMTI_PHASE_LIVE)
2614 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2615 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2617 /* behave like jdk 1.1 and make no distinction between initiating and
2618 defining class loaders */
2620 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2624 /* PopFrame *******************************************************************
2628 *******************************************************************************/
2631 PopFrame (jvmtiEnv * env, jthread thread)
2634 CHECK_PHASE(JVMTI_PHASE_LIVE)
2636 CHECK_CAPABILITY(env,can_pop_frame)
2638 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2639 return JVMTI_ERROR_NONE;
2643 /* RedefineClasses ************************************************************
2647 *******************************************************************************/
2650 RedefineClasses (jvmtiEnv * env, jint class_count,
2651 const jvmtiClassDefinition * class_definitions)
2654 CHECK_PHASE(JVMTI_PHASE_START)
2655 CHECK_PHASE(JVMTI_PHASE_LIVE)
2657 CHECK_CAPABILITY(env,can_redefine_classes)
2658 CHECK_CAPABILITY(env,can_redefine_any_class)
2659 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2660 return JVMTI_ERROR_NONE;
2664 /* GetVersionNumber ***********************************************************
2666 Return the JVM TI version identifier.
2668 *******************************************************************************/
2671 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2673 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2675 *version_ptr = JVMTI_VERSION;
2677 return JVMTI_ERROR_NONE;
2681 /* GetCapabilities ************************************************************
2683 Returns the optional JVM TI features which this environment currently
2686 *******************************************************************************/
2689 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2691 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2693 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2695 return JVMTI_ERROR_NONE;
2699 /* *****************************************************************************
2703 *******************************************************************************/
2706 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2707 char **source_debug_extension_ptr)
2710 CHECK_PHASE(JVMTI_PHASE_START)
2711 CHECK_PHASE(JVMTI_PHASE_LIVE)
2713 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2715 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2716 return JVMTI_ERROR_NONE;
2720 /* IsMethodObsolete ************************************************************
2722 Determine if a method ID refers to an obsolete method version.
2724 *******************************************************************************/
2727 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2728 jboolean * is_obsolete_ptr)
2731 CHECK_PHASE(JVMTI_PHASE_START)
2732 CHECK_PHASE(JVMTI_PHASE_LIVE)
2734 CHECK_CAPABILITY(env,can_redefine_classes)
2736 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2737 return JVMTI_ERROR_NONE;
2741 /* SuspendThreadList **********************************************************
2745 *******************************************************************************/
2748 SuspendThreadList (jvmtiEnv * env, jint request_count,
2749 const jthread * request_list, jvmtiError * results)
2752 CHECK_PHASE(JVMTI_PHASE_START)
2753 CHECK_PHASE(JVMTI_PHASE_LIVE)
2755 CHECK_CAPABILITY(env,can_suspend);
2757 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2759 return JVMTI_ERROR_NONE;
2763 /* ResumeThreadList ***********************************************************
2767 *******************************************************************************/
2770 ResumeThreadList (jvmtiEnv * env, jint request_count,
2771 const jthread * request_list, jvmtiError * results)
2774 CHECK_PHASE(JVMTI_PHASE_LIVE)
2776 CHECK_CAPABILITY(env,can_suspend);
2778 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2780 return JVMTI_ERROR_NONE;
2784 /* GetStackTrace **************************************************************
2786 Get information about the stack of a thread
2788 *******************************************************************************/
2791 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2792 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2795 stacktracebuffer* trace;
2800 CHECK_PHASE(JVMTI_PHASE_LIVE)
2803 if(!builtin_instanceof(thread,class_java_lang_Thread))
2804 return JVMTI_ERROR_INVALID_THREAD;
2806 CHECK_THREAD_IS_ALIVE(thread);
2808 if((count_ptr == NULL)||(frame_buffer == NULL))
2809 return JVMTI_ERROR_NULL_POINTER;
2811 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2813 er = getcacaostacktrace(&trace, thread);
2814 if (er==JVMTI_ERROR_NONE) return er;
2816 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2817 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2819 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2820 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2821 /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
2822 frame_buffer[j].location = 0;
2825 return JVMTI_ERROR_NONE;
2829 /* GetThreadListStackTraces ***************************************************
2831 Get information about the stacks of the supplied threads.
2833 *******************************************************************************/
2836 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2837 const jthread * thread_list,
2838 jint max_frame_count,
2839 jvmtiStackInfo ** stack_info_ptr)
2845 CHECK_PHASE(JVMTI_PHASE_LIVE)
2848 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2849 return JVMTI_ERROR_NULL_POINTER;
2851 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2853 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2855 *stack_info_ptr = (jvmtiStackInfo*)
2856 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2858 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2859 (*stack_info_ptr)[i].thread=thread_list[i];
2860 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2861 (*stack_info_ptr)[i].frame_buffer =
2862 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2863 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2864 (*stack_info_ptr)[i].frame_buffer,
2865 &((*stack_info_ptr)[i].frame_count));
2867 if (er != JVMTI_ERROR_NONE) return er;
2870 return JVMTI_ERROR_NONE;
2874 /* GetAllStackTraces **********************************************************
2876 Get stack traces of all live threads
2878 *******************************************************************************/
2881 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2882 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2884 jthread *threads_ptr;
2888 CHECK_PHASE(JVMTI_PHASE_LIVE)
2891 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2893 /* todo: all threads have to be suspended */
2895 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2896 return JVMTI_ERROR_INTERNAL;
2898 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2899 max_frame_count, stack_info_ptr);
2901 /* todo: resume all threads have to be suspended */
2902 if (er != JVMTI_ERROR_NONE) return er;
2904 return JVMTI_ERROR_NONE;
2908 /* GetThreadLocalStorage ******************************************************
2910 Get the value of the JVM TI thread-local storage.
2912 *******************************************************************************/
2915 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2917 jvmtiThreadLocalStorage *tls;
2920 CHECK_PHASE(JVMTI_PHASE_START)
2921 CHECK_PHASE(JVMTI_PHASE_LIVE)
2925 thread = (jthread) THREADOBJECT;
2927 if (!builtin_instanceof(thread,class_java_lang_Thread))
2928 return JVMTI_ERROR_INVALID_THREAD;
2929 CHECK_THREAD_IS_ALIVE(thread);
2932 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2934 tls = ((environment*)env)->tls;
2935 while ((tls->thread != thread) && (tls != NULL)) {
2939 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2941 *data_ptr = tls->data;
2943 return JVMTI_ERROR_NONE;
2947 /* SetThreadLocalStorage *******************************************************
2949 Stores a pointer value associated with each environment-thread pair. The
2950 value is NULL unless set with this function. Agents can allocate memory in
2951 which they store thread specific information
2953 *******************************************************************************/
2956 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2958 jvmtiThreadLocalStorage *tls, *pre;
2959 environment* env = (environment*)jenv;
2962 CHECK_PHASE(JVMTI_PHASE_START)
2963 CHECK_PHASE(JVMTI_PHASE_LIVE)
2967 thread = (jthread) THREADOBJECT;
2969 if (!builtin_instanceof(thread,class_java_lang_Thread))
2970 return JVMTI_ERROR_INVALID_THREAD;
2971 CHECK_THREAD_IS_ALIVE(thread);
2974 if (env->tls == NULL) {
2975 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2978 while ((tls->thread != thread) && (tls->next != NULL)) {
2981 if (tls->thread != thread) {
2982 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2988 tls->data = (void*)data;
2990 /* remove current tls */
2992 while (pre->next == tls) pre = pre->next;
2993 pre->next = tls->next;
2995 return JVMTI_ERROR_NONE;
2999 /* *****************************************************************************
3003 *******************************************************************************/
3006 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
3009 CHECK_PHASE(JVMTI_PHASE_START)
3010 CHECK_PHASE(JVMTI_PHASE_LIVE)
3012 CHECK_CAPABILITY(env,can_tag_objects)
3014 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3015 return JVMTI_ERROR_NONE;
3018 /* *****************************************************************************
3022 *******************************************************************************/
3025 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3028 CHECK_PHASE(JVMTI_PHASE_START)
3029 CHECK_PHASE(JVMTI_PHASE_LIVE)
3031 CHECK_CAPABILITY(env,can_tag_objects)
3033 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3034 return JVMTI_ERROR_NONE;
3038 /* ForceGarbageCollection *****************************************************
3040 Force boehm-gc to perform a garbage collection
3042 *******************************************************************************/
3045 ForceGarbageCollection (jvmtiEnv * env)
3048 CHECK_PHASE(JVMTI_PHASE_LIVE)
3053 return JVMTI_ERROR_NONE;
3057 /* IterateOverObjectsReachableFromObject **************************************
3061 *******************************************************************************/
3064 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3065 jvmtiObjectReferenceCallback
3066 object_reference_callback,
3070 CHECK_PHASE(JVMTI_PHASE_LIVE)
3072 CHECK_CAPABILITY(env,can_tag_objects)
3074 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3075 return JVMTI_ERROR_NONE;
3079 /* IterateOverReachableObjects ************************************************
3083 *******************************************************************************/
3086 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3088 jvmtiStackReferenceCallback
3090 jvmtiObjectReferenceCallback
3091 object_ref_callback, void *user_data)
3094 CHECK_PHASE(JVMTI_PHASE_LIVE)
3096 CHECK_CAPABILITY(env,can_tag_objects)
3098 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3099 return JVMTI_ERROR_NONE;
3103 /* IterateOverHeap ************************************************************
3107 *******************************************************************************/
3110 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3111 jvmtiHeapObjectCallback heap_object_callback,
3115 CHECK_PHASE(JVMTI_PHASE_LIVE)
3117 CHECK_CAPABILITY(env,can_tag_objects)
3119 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3120 return JVMTI_ERROR_NONE;
3124 /* IterateOverInstancesOfClass ************************************************
3128 *******************************************************************************/
3131 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3132 jvmtiHeapObjectFilter object_filter,
3133 jvmtiHeapObjectCallback
3134 heap_object_callback, void *user_data)
3137 CHECK_PHASE(JVMTI_PHASE_LIVE)
3139 CHECK_CAPABILITY(env,can_tag_objects)
3141 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3142 return JVMTI_ERROR_NONE;
3146 /* *****************************************************************************
3150 *******************************************************************************/
3153 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3154 jint * count_ptr, jobject ** object_result_ptr,
3155 jlong ** tag_result_ptr)
3158 CHECK_PHASE(JVMTI_PHASE_LIVE)
3160 CHECK_CAPABILITY(env,can_tag_objects)
3162 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3163 return JVMTI_ERROR_NONE;
3167 /* SetJNIFunctionTable **********************************************************
3169 Set the JNI function table in all current and future JNI environments
3171 *******************************************************************************/
3174 SetJNIFunctionTable (jvmtiEnv * env,
3175 const jniNativeInterface * function_table)
3178 CHECK_PHASE(JVMTI_PHASE_START)
3179 CHECK_PHASE(JVMTI_PHASE_LIVE)
3182 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3183 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3184 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3185 return JVMTI_ERROR_NONE;
3189 /* GetJNIFunctionTable *********************************************************
3191 Get the JNI function table. The JNI function table is copied into allocated
3194 *******************************************************************************/
3197 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3200 CHECK_PHASE(JVMTI_PHASE_START)
3201 CHECK_PHASE(JVMTI_PHASE_LIVE)
3204 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3205 *function_table = (jniNativeInterface*)
3206 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3207 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3208 return JVMTI_ERROR_NONE;
3212 /* SetEventCallbacks **********************************************************
3214 Set the functions to be called for each event. The callbacks are specified
3215 by supplying a replacement function table.
3217 *******************************************************************************/
3220 SetEventCallbacks (jvmtiEnv * env,
3221 const jvmtiEventCallbacks * callbacks,
3222 jint size_of_callbacks)
3225 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3226 CHECK_PHASE(JVMTI_PHASE_LIVE)
3229 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3231 if (callbacks == NULL) { /* remove the existing callbacks */
3232 memset(&(((environment* )env)->callbacks), 0,
3233 sizeof(jvmtiEventCallbacks));
3236 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3238 return JVMTI_ERROR_NONE;
3242 /* GenerateEvents *************************************************************
3244 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3245 the current state of the VM.
3247 *******************************************************************************/
3250 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3253 CHECK_PHASE(JVMTI_PHASE_LIVE)
3256 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3257 return JVMTI_ERROR_NONE;
3261 /* GetExtensionFunctions ******************************************************
3263 Returns the set of extension functions.
3265 *******************************************************************************/
3268 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3269 jvmtiExtensionFunctionInfo ** extensions)
3272 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3273 CHECK_PHASE(JVMTI_PHASE_LIVE)
3276 if ((extension_count_ptr== NULL)||(extensions == NULL))
3277 return JVMTI_ERROR_NULL_POINTER;
3279 /* cacao has no extended functions yet */
3280 *extension_count_ptr = 0;
3282 return JVMTI_ERROR_NONE;
3286 /* GetExtensionEvents *********************************************************
3288 Returns the set of extension events.
3290 *******************************************************************************/
3293 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3294 jvmtiExtensionEventInfo ** extensions)
3297 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3298 CHECK_PHASE(JVMTI_PHASE_LIVE)
3301 if ((extension_count_ptr== NULL)||(extensions == NULL))
3302 return JVMTI_ERROR_NULL_POINTER;
3304 /* cacao has no extended events yet */
3305 *extension_count_ptr = 0;
3307 return JVMTI_ERROR_NONE;
3311 /* SetExtensionEventCallback **************************************************
3313 Sets the callback function for an extension event and enables the event.
3315 *******************************************************************************/
3318 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3319 jvmtiExtensionEvent callback)
3322 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3323 CHECK_PHASE(JVMTI_PHASE_LIVE)
3326 /* cacao has no extended events yet */
3327 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3331 /* DisposeEnvironment **********************************************************
3333 Shutdown a JVM TI connection created with JNI GetEnv.
3335 *******************************************************************************/
3338 DisposeEnvironment (jvmtiEnv * env)
3340 environment* cacao_env = (environment*)env;
3341 environment* tenvs = envs;
3342 jvmtiThreadLocalStorage *jtls, *tjtls;
3344 if (tenvs != cacao_env) {
3345 while (tenvs->next != cacao_env) {
3346 tenvs = tenvs->next;
3348 tenvs->next = cacao_env->next;
3352 cacao_env->env=NULL;
3353 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3354 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3355 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3356 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3357 cacao_env->EnvironmentLocalStorage = NULL;
3359 jtls = cacao_env->tls;
3360 while (jtls != NULL) {
3365 cacao_env->tls = NULL;
3368 jvmti_cacaodbgserver_quit();
3370 /* let the GC do the rest */
3371 return JVMTI_ERROR_NONE;
3375 /* GetErrorName ***************************************************************
3377 Return the symbolic name for an error code.
3379 *******************************************************************************/
3381 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3382 memcpy(*name_ptr, &str, sizeof(str)); \
3386 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3388 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3391 case JVMTI_ERROR_NONE :
3392 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3393 case JVMTI_ERROR_NULL_POINTER :
3394 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3395 case JVMTI_ERROR_OUT_OF_MEMORY :
3396 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3397 case JVMTI_ERROR_ACCESS_DENIED :
3398 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3399 case JVMTI_ERROR_UNATTACHED_THREAD :
3400 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3401 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3402 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3403 case JVMTI_ERROR_WRONG_PHASE :
3404 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3405 case JVMTI_ERROR_INTERNAL :
3406 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3407 case JVMTI_ERROR_INVALID_PRIORITY :
3408 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3409 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3410 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3411 case JVMTI_ERROR_THREAD_SUSPENDED :
3412 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3413 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3414 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3415 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3416 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3417 case JVMTI_ERROR_NO_MORE_FRAMES :
3418 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3419 case JVMTI_ERROR_OPAQUE_FRAME :
3420 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3421 case JVMTI_ERROR_DUPLICATE :
3422 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3423 case JVMTI_ERROR_NOT_FOUND :
3424 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3425 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3426 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3427 case JVMTI_ERROR_INTERRUPT :
3428 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3429 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3430 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3431 case JVMTI_ERROR_NOT_AVAILABLE :
3432 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3433 case JVMTI_ERROR_ABSENT_INFORMATION :
3434 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3435 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3436 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3437 case JVMTI_ERROR_NATIVE_METHOD :
3438 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3439 case JVMTI_ERROR_INVALID_THREAD :
3440 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3441 case JVMTI_ERROR_INVALID_FIELDID :
3442 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3443 case JVMTI_ERROR_INVALID_METHODID :
3444 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3445 case JVMTI_ERROR_INVALID_LOCATION :
3446 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3447 case JVMTI_ERROR_INVALID_OBJECT :
3448 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3449 case JVMTI_ERROR_INVALID_CLASS :
3450 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3451 case JVMTI_ERROR_TYPE_MISMATCH :
3452 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3453 case JVMTI_ERROR_INVALID_SLOT :
3454 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3455 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3456 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3457 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3458 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3459 case JVMTI_ERROR_INVALID_MONITOR :
3460 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3461 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3462 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3463 case JVMTI_ERROR_INVALID_TYPESTATE :
3464 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3465 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3466 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3467 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3468 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3469 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3470 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3471 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3472 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3473 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3474 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3475 case JVMTI_ERROR_FAILS_VERIFICATION :
3476 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3477 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3478 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3479 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3480 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3481 case JVMTI_ERROR_NAMES_DONT_MATCH :
3482 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3483 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3484 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3485 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3486 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3488 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3490 return JVMTI_ERROR_NONE;
3493 /* GetJLocationFormat **********************************************************
3495 This function describes the representation of jlocation used in this VM.
3497 *******************************************************************************/
3500 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3502 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3503 return JVMTI_ERROR_NONE;
3507 /* GetSystemProperties ********************************************************
3509 The list of VM system property keys which may be used with GetSystemProperty
3512 *******************************************************************************/
3515 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3517 jmethodID mid, moremid;
3518 classinfo *sysclass, *propclass, *enumclass;
3519 java_objectheader *sysprop, *keys, *obj;
3524 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3525 CHECK_PHASE(JVMTI_PHASE_LIVE)
3528 if ((count_ptr == NULL) || (property_ptr == NULL))
3529 return JVMTI_ERROR_NULL_POINTER;
3531 sysclass = load_class_from_sysloader(
3532 utf_new_char_classname ("java/lang/System"));
3534 if (!sysclass) throw_main_exception_exit();
3536 mid = (jmethodID)class_resolvemethod(sysclass,
3537 utf_new_char("getProperties"),
3538 utf_new_char("()Ljava/util/Properties;"));
3539 if (!mid) throw_main_exception_exit();
3542 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3543 if (!sysprop) throw_main_exception_exit();
3545 propclass = sysprop->vftbl->class;
3547 mid = (jmethodID)class_resolvemethod(propclass,
3548 utf_new_char("size"),
3549 utf_new_char("()I"));
3550 if (!mid) throw_main_exception_exit();
3553 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3554 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3556 mid = (jmethodID)class_resolvemethod(propclass,
3557 utf_new_char("keys"),
3558 utf_new_char("()Ljava/util/Enumeration;"));
3559 if (!mid) throw_main_exception_exit();
3561 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3562 enumclass = keys->vftbl->class;
3564 moremid = (jmethodID)class_resolvemethod(enumclass,
3565 utf_new_char("hasMoreElements"),
3566 utf_new_char("()Z"));
3567 if (!moremid) throw_main_exception_exit();
3569 mid = (jmethodID)class_resolvemethod(propclass,
3570 utf_new_char("nextElement"),
3571 utf_new_char("()Ljava/lang/Object;"));
3572 if (!mid) throw_main_exception_exit();
3575 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3576 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3577 ch = javastring_tochar(obj);
3578 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3579 memcpy(*property_ptr[i], ch, strlen (ch));
3580 MFREE(ch,char,strlen(ch)+1);
3584 return JVMTI_ERROR_NONE;
3588 /* GetSystemProperty **********************************************************
3590 Return a VM system property value given the property key.
3592 *******************************************************************************/
3595 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3598 classinfo *sysclass, *propclass;
3599 java_objectheader *sysprop, *obj;
3603 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3604 CHECK_PHASE(JVMTI_PHASE_LIVE)
3607 if ((value_ptr == NULL) || (property == NULL))
3608 return JVMTI_ERROR_NULL_POINTER;
3610 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3611 if (!sysclass) throw_main_exception_exit();
3613 mid = (jmethodID)class_resolvemethod(sysclass,
3614 utf_new_char("getProperties"),
3615 utf_new_char("()Ljava/util/Properties;"));
3616 if (!mid) throw_main_exception_exit();
3618 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3620 propclass = sysprop->vftbl->class;
3622 mid = (jmethodID)class_resolvemethod(propclass,
3623 utf_new_char("getProperty"),
3624 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3625 if (!mid) throw_main_exception_exit();
3627 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3628 NULL, sysprop, mid, javastring_new_from_ascii(property));
3629 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3631 ch = javastring_tochar(obj);
3632 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3633 memcpy(*value_ptr, ch, strlen (ch));
3634 MFREE(ch,char,strlen(ch)+1);
3636 return JVMTI_ERROR_NONE;
3640 /* SetSystemProperty **********************************************************
3642 Set a VM system property value.
3644 *******************************************************************************/
3647 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3650 classinfo *sysclass, *propclass;
3651 java_objectheader *sysprop;
3654 CHECK_PHASE(JVMTI_PHASE_START)
3657 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3658 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3660 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3661 if (!sysclass) throw_main_exception_exit();
3663 mid = (jmethodID)class_resolvemethod(sysclass,
3664 utf_new_char("getProperties"),
3665 utf_new_char("()Ljava/util/Properties;"));
3666 if (!mid) throw_main_exception_exit();
3668 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3670 propclass = sysprop->vftbl->class;
3672 mid = (jmethodID)class_resolvemethod(propclass,
3673 utf_new_char("setProperty"),
3674 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3675 if (!mid) throw_main_exception_exit();
3677 _Jv_JNINativeInterface.CallObjectMethod(
3678 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3680 return JVMTI_ERROR_NONE;
3683 /* GetPhase ********************************************************************
3685 Return the current phase of VM execution
3687 *******************************************************************************/
3690 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3692 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3696 return JVMTI_ERROR_NONE;
3699 /* GetCurrentThreadCpuTimerInfo ************************************************
3703 *******************************************************************************/
3706 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3709 CHECK_PHASE(JVMTI_PHASE_START)
3710 CHECK_PHASE(JVMTI_PHASE_LIVE)
3712 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3714 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3716 return JVMTI_ERROR_NONE;
3719 /* GetCurrentThreadCpuTime ****************************************************
3723 *******************************************************************************/
3726 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3729 CHECK_PHASE(JVMTI_PHASE_START)
3730 CHECK_PHASE(JVMTI_PHASE_LIVE)
3732 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3734 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3735 return JVMTI_ERROR_NONE;
3738 /* GetThreadCpuTimerInfo ******************************************************
3742 *******************************************************************************/
3745 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3748 CHECK_PHASE(JVMTI_PHASE_START)
3749 CHECK_PHASE(JVMTI_PHASE_LIVE)
3751 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3753 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3754 return JVMTI_ERROR_NONE;
3757 /* GetThreadCpuTime ***********************************************************
3761 *******************************************************************************/
3764 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3767 CHECK_PHASE(JVMTI_PHASE_LIVE)
3769 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3770 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3771 return JVMTI_ERROR_NONE;
3774 /* GetTimerInfo ***************************************************************
3776 Get information about the GetTime timer.
3778 *******************************************************************************/
3781 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3783 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3785 info_ptr->max_value = !0x0;
3786 info_ptr->may_skip_forward = true;
3787 info_ptr->may_skip_backward = true;
3788 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3790 return JVMTI_ERROR_NONE;
3793 /* GetTime ********************************************************************
3795 Return the current value of the system timer, in nanoseconds
3797 *******************************************************************************/
3800 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3802 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3805 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3807 if (gettimeofday (&tp, NULL) == -1)
3808 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3810 *nanos_ptr = (jlong) tp.tv_sec;
3812 *nanos_ptr += (tp.tv_usec / 1000);
3814 return JVMTI_ERROR_NONE;
3817 /* GetPotentialCapabilities ***************************************************
3819 Returns the JVM TI features that can potentially be possessed by this
3820 environment at this time.
3822 *******************************************************************************/
3825 GetPotentialCapabilities (jvmtiEnv * env,
3826 jvmtiCapabilities * capabilities_ptr)
3829 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3830 CHECK_PHASE(JVMTI_PHASE_LIVE)
3833 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3835 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3837 return JVMTI_ERROR_NONE;
3841 #define CHECK_ADD_CAPABILITY(env,CAN) \
3842 if (capabilities_ptr->CAN == 1) { \
3843 if (JVMTI_Capabilities.CAN == 0) \
3844 return JVMTI_ERROR_NOT_AVAILABLE; \
3846 env->capabilities.CAN = 1; \
3849 /* AddCapabilities ************************************************************
3851 Set new capabilities by adding the capabilities pointed to by
3852 capabilities_ptr. All previous capabilities are retained.
3854 *******************************************************************************/
3857 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3859 environment* cacao_env;
3862 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3863 CHECK_PHASE(JVMTI_PHASE_LIVE)
3866 if ((env == NULL) || (capabilities_ptr == NULL))
3867 return JVMTI_ERROR_NULL_POINTER;
3869 cacao_env = (environment*)env;
3871 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3872 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3873 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3874 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3875 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3876 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3877 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3878 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3879 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3880 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3881 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3882 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3883 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3884 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3885 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3886 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3887 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3888 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3889 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3890 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3891 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3892 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3893 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3894 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3895 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3896 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3897 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3898 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3899 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3900 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3901 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3902 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3903 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3906 return JVMTI_ERROR_NONE;
3910 #define CHECK_DEL_CAPABILITY(env,CAN) \
3911 if (capabilities_ptr->CAN == 1) \
3912 env->capabilities.CAN = 0;
3914 /* RelinquishCapabilities *****************************************************
3916 Relinquish the capabilities pointed to by capabilities_ptr.
3918 *******************************************************************************/
3921 RelinquishCapabilities (jvmtiEnv * env,
3922 const jvmtiCapabilities * capabilities_ptr)
3924 environment* cacao_env;
3927 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3928 CHECK_PHASE(JVMTI_PHASE_LIVE)
3931 if ((env == NULL) || (capabilities_ptr == NULL))
3932 return JVMTI_ERROR_NULL_POINTER;
3934 cacao_env = (environment*)env;
3936 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3937 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3938 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3939 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3940 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3941 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3942 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3943 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3944 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3945 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3946 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3947 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3948 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3949 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3950 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3951 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3952 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3953 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3954 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3955 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3956 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3957 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3958 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3959 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3960 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3961 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3962 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3963 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3964 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3965 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3966 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3967 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3968 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3970 return JVMTI_ERROR_NONE;
3973 /* *****************************************************************************
3977 *******************************************************************************/
3980 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3983 CHECK_PHASE(JVMTI_PHASE_START)
3984 CHECK_PHASE(JVMTI_PHASE_LIVE)
3987 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3989 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3991 *processor_count_ptr = 1; /* where do I get this ?*/
3993 return JVMTI_ERROR_NONE;
3996 /* GetEnvironmentLocalStorage **************************************************
3998 Called by the agent to get the value of the JVM TI environment-local storage.
4000 *******************************************************************************/
4003 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
4005 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
4007 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
4009 return JVMTI_ERROR_NONE;
4012 /* SetEnvironmentLocalStorage **************************************************
4014 The VM stores a pointer value associated with each environment. Agents can
4015 allocate memory in which they store environment specific information.
4017 *******************************************************************************/
4020 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4022 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4024 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4026 return JVMTI_ERROR_NONE;
4029 /* AddToBootstrapClassLoaderSearch ********************************************
4031 After the bootstrap class loader unsuccessfully searches for a class, the
4032 specified platform-dependent search path segment will be searched as well.
4034 *******************************************************************************/
4037 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4043 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4046 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4048 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4049 tmp_bcp = MNEW(char, ln);
4050 strcat(tmp_bcp, bootclasspath);
4051 strcat(tmp_bcp, ":");
4052 strcat(tmp_bcp, segment);
4053 MFREE(bootclasspath,char,ln);
4054 bootclasspath = tmp_bcp;
4056 return JVMTI_ERROR_NONE;
4059 /* SetVerboseFlag *************************************************************
4061 Control verbose output. This is the output which typically is sent to stderr
4063 *******************************************************************************/
4066 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4069 case JVMTI_VERBOSE_OTHER:
4070 /* where is this defined ?
4074 case JVMTI_VERBOSE_GC:
4075 opt_verbosegc = value;
4077 case JVMTI_VERBOSE_CLASS:
4078 loadverbose = value;
4080 case JVMTI_VERBOSE_JNI:
4083 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4085 return JVMTI_ERROR_NONE;
4088 /* GetObjectSize **************************************************************
4090 For the object object return the size.
4092 *******************************************************************************/
4095 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4098 CHECK_PHASE(JVMTI_PHASE_START)
4099 CHECK_PHASE(JVMTI_PHASE_LIVE)
4102 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4103 if (!builtin_instanceof(object,class_java_lang_Object))
4104 return JVMTI_ERROR_INVALID_OBJECT;
4106 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4108 return JVMTI_ERROR_NONE;
4112 /* *****************************************************************************
4114 Environment variables
4116 *******************************************************************************/
4118 static jvmtiCapabilities JVMTI_Capabilities = {
4119 0, /* can_tag_objects */
4120 0, /* can_generate_field_modification_events */
4121 0, /* can_generate_field_access_events */
4122 1, /* can_get_bytecodes */
4123 0, /* can_get_synthetic_attribute */
4125 #if defined(ENABLE_THREADS)
4126 1, /* can_get_owned_monitor_info */
4127 1, /* can_get_current_contended_monitor */
4129 0, /* can_get_owned_monitor_info */
4130 0, /* can_get_current_contended_monitor */
4133 0, /* can_get_monitor_info */
4134 0, /* can_pop_frame */
4135 0, /* can_redefine_classes */
4136 0, /* can_signal_thread */
4137 1, /* can_get_source_file_name */
4138 1, /* can_get_line_numbers */
4139 0, /* can_get_source_debug_extension */
4140 0, /* can_access_local_variables */
4141 0, /* can_maintain_original_method_order */
4142 0, /* can_generate_single_step_events */
4143 0, /* can_generate_exception_events */
4144 0, /* can_generate_frame_pop_events */
4145 0, /* can_generate_breakpoint_events */
4146 0, /* can_suspend */
4147 0, /* can_redefine_any_class */
4148 0, /* can_get_current_thread_cpu_time */
4149 0, /* can_get_thread_cpu_time */
4150 0, /* can_generate_method_entry_events */
4151 0, /* can_generate_method_exit_events */
4152 0, /* can_generate_all_class_hook_events */
4153 0, /* can_generate_compiled_method_load_events */
4154 0, /* can_generate_monitor_events */
4155 0, /* can_generate_vm_object_alloc_events */
4156 0, /* can_generate_native_method_bind_events */
4157 0, /* can_generate_garbage_collection_events */
4158 0, /* can_generate_object_free_events */
4161 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4163 &SetEventNotificationMode,
4171 &GetOwnedMonitorInfo,
4172 &GetCurrentContendedMonitor,
4174 &GetTopThreadGroups,
4175 &GetThreadGroupInfo,
4176 &GetThreadGroupChildren,
4198 &RawMonitorNotifyAll,
4202 &SetFieldAccessWatch,
4203 &ClearFieldAccessWatch,
4204 &SetFieldModificationWatch,
4205 &ClearFieldModificationWatch,
4215 &GetImplementedInterfaces,
4220 &GetObjectMonitorUsage,
4222 &GetFieldDeclaringClass,
4226 &GetMethodDeclaringClass,
4227 &GetMethodModifiers,
4231 &GetLineNumberTable,
4233 &GetLocalVariableTable,
4240 &GetClassLoaderClasses,
4251 &GetSourceDebugExtension,
4262 &GetThreadListStackTraces,
4263 &GetThreadLocalStorage,
4264 &SetThreadLocalStorage,
4269 &ForceGarbageCollection,
4270 &IterateOverObjectsReachableFromObject,
4271 &IterateOverReachableObjects,
4273 &IterateOverInstancesOfClass,
4275 &GetObjectsWithTags,
4281 &SetJNIFunctionTable,
4282 &GetJNIFunctionTable,
4285 &GetExtensionFunctions,
4286 &GetExtensionEvents,
4287 &SetExtensionEventCallback,
4288 &DisposeEnvironment,
4290 &GetJLocationFormat,
4291 &GetSystemProperties,
4295 &GetCurrentThreadCpuTimerInfo,
4296 &GetCurrentThreadCpuTime,
4297 &GetThreadCpuTimerInfo,
4301 &GetPotentialCapabilities,
4304 &RelinquishCapabilities,
4305 &GetAvailableProcessors,
4308 &GetEnvironmentLocalStorage,
4309 &SetEnvironmentLocalStorage,
4310 &AddToBootstrapClassLoaderSearch,
4319 void jvmti_set_phase(jvmtiPhase p) {
4322 fprintf (stderr,"set JVMTI phase %d\n",p);
4326 case JVMTI_PHASE_ONLOAD:
4329 case JVMTI_PHASE_PRIMORDIAL:
4332 case JVMTI_PHASE_START:
4334 d.ev = JVMTI_EVENT_VM_START;
4336 case JVMTI_PHASE_LIVE:
4338 d.ev = JVMTI_EVENT_VM_INIT;
4339 jvmti_fireEvent(&d);
4340 /* thread start event for main thread */
4341 d.ev = JVMTI_EVENT_THREAD_START;
4343 case JVMTI_PHASE_DEAD:
4345 d.ev = JVMTI_EVENT_VM_DEATH;
4348 log_text("wrong jvmti phase to be set");
4352 jvmti_fireEvent(&d);
4355 jvmtiEnv* jvmti_new_environment() {
4359 envs = heap_allocate(sizeof(environment),true,NULL);
4363 while (env->next != NULL) env = env->next;
4364 env->next = heap_allocate(sizeof(environment),true,NULL);
4368 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4369 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4370 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4371 sizeof(jvmtiEventModeLL));
4372 /* To possess a capability, the agent must add the capability.*/
4373 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4374 RelinquishCapabilities(&(env->env),&(env->capabilities));
4375 env->EnvironmentLocalStorage = NULL;
4378 /* initialize cacao debugging facilities */
4379 jvmti_cacao_debug_init();
4381 return (jvmtiEnv*)env;
4384 void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4391 len = strlen(opt_arg);
4393 /* separate argumtents */
4394 while ((opt_arg[i]!='=')&&(i<=len)) i++;
4399 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4400 strncpy(*libname,opt_arg,i-1);
4401 (*libname)[i-1]='\0';
4404 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4405 strncpy(*libname,"lib",3);
4406 strncpy(&(*libname)[3],opt_arg,i-1);
4407 strncpy(&(*libname)[i+2],".so",3);
4410 /* try to open the library */
4412 if (!(*handle = lt_dlopen(*libname))) {
4413 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4417 /* resolve Agent_OnLoad function */
4418 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4419 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4423 /* resolve Agent_UnLoad function */
4424 unload = lt_dlsym(*handle, "Agent_Unload");
4427 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4428 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4430 if (retval != 0) exit (retval);
4433 void jvmti_agentunload() {
4434 if (unload != NULL) {
4435 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4436 ((JavaVM*) &_Jv_JNIInvokeInterface);
4441 * These are local overrides for various environment variables in Emacs.
4442 * Please do not remove this and leave it at the end of the file, where
4443 * Emacs will automagically detect them.
4444 * ---------------------------------------------------------------------
4447 * indent-tabs-mode: t
4451 * vim:noexpandtab:sw=4:ts=4: