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 4892 2006-05-06 18:29:55Z 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 "vm/exceptions.h"
57 #include "native/include/java_util_Vector.h"
58 #include "native/include/java_io_PrintStream.h"
59 #include "native/include/java_io_InputStream.h"
60 #include "native/include/java_lang_Cloneable.h"
61 #include "native/include/java_lang_ThreadGroup.h"
62 #include "native/include/java_lang_VMObject.h"
63 #include "native/include/java_lang_VMSystem.h"
64 #include "native/include/java_lang_VMClass.h"
66 #include "boehm-gc/include/gc.h"
69 #include <linux/unistd.h>
71 #include "toolbox/logging.h"
73 #include <sys/types.h>
78 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
79 #include "threads/native/threads.h"
84 #include "native/jvmti/stacktrace.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 (!(0
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 execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
156 JNIEnv* jni_env = (JNIEnv*)_Jv_env;
158 fprintf(stderr,"execcallback called (event: %d)\n",e);
161 case JVMTI_EVENT_VM_INIT:
162 case JVMTI_EVENT_THREAD_START:
163 case JVMTI_EVENT_THREAD_END:
164 ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
168 case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
169 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
174 data->protection_domain,
177 data->new_class_data_len,
178 data->new_class_data);
182 case JVMTI_EVENT_CLASS_PREPARE:
183 case JVMTI_EVENT_CLASS_LOAD:
184 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
185 data->thread, data->klass);
188 case JVMTI_EVENT_VM_DEATH:
189 case JVMTI_EVENT_VM_START:
190 ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
193 case JVMTI_EVENT_EXCEPTION:
194 ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
200 data->catch_location);
203 case JVMTI_EVENT_EXCEPTION_CATCH:
204 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
211 case JVMTI_EVENT_BREAKPOINT:
212 case JVMTI_EVENT_SINGLE_STEP:
213 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
219 case JVMTI_EVENT_FRAME_POP:
220 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
226 case JVMTI_EVENT_FIELD_ACCESS:
227 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
236 case JVMTI_EVENT_FIELD_MODIFICATION:
237 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
244 data->signature_type,
248 case JVMTI_EVENT_METHOD_ENTRY:
249 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
254 case JVMTI_EVENT_METHOD_EXIT:
255 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
262 case JVMTI_EVENT_NATIVE_METHOD_BIND:
263 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
267 data->new_address_ptr);
270 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
271 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
280 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
281 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
286 case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
287 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
293 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
294 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
295 case JVMTI_EVENT_DATA_DUMP_REQUEST:
296 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
299 case JVMTI_EVENT_MONITOR_WAIT:
300 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
306 case JVMTI_EVENT_MONITOR_WAITED:
307 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
314 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
315 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
316 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
321 case JVMTI_EVENT_OBJECT_FREE:
322 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
325 case JVMTI_EVENT_VM_OBJECT_ALLOC:
326 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
335 log_text ("unknown event");
340 /* dofireEvent ******************************************************************
342 sends event if it is enabled either globally or for some threads
344 *******************************************************************************/
345 static void dofireEvent(jvmtiEvent e, genericEventData* data) {
347 jvmtiEventModeLL *evm;
352 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
353 evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
354 /* test if the event is enable for some threads */
356 if (evm->mode == JVMTI_ENABLE) {
357 data->jvmti_env=&env->env;
358 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
359 execcallback(e, ec, data);
363 } else { /* event enabled globally */
364 data->jvmti_env=&env->env;
365 ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
366 execcallback(e, ec, data);
374 /* fireEvent ******************************************************************
376 fire event callback with data arguments. This function mainly fills the
379 *******************************************************************************/
380 void fireEvent(genericEventData* d) {
382 /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
384 if (d->ev != JVMTI_EVENT_VM_START)
385 thread = getcurrentthread();
389 fprintf (stderr,"jvmti: fireEvent: %d\n",d->ev);
391 dofireEvent(d->ev,d);
393 /* if we need to send a VM_INIT event then also send a THREAD_START event */
394 if (d->ev == JVMTI_EVENT_VM_INIT)
395 dofireEvent(JVMTI_EVENT_THREAD_START,d);
399 /* SetEventNotificationMode ****************************************************
401 Control the generation of events
403 *******************************************************************************/
406 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
407 jvmtiEvent event_type, jthread event_thread, ...)
409 environment* cacao_env;
410 jvmtiEventModeLL *ll;
413 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
414 CHECK_PHASE(JVMTI_PHASE_LIVE)
417 if(event_thread != NULL) {
418 if (!builtin_instanceof(event_thread,class_java_lang_Thread))
419 return JVMTI_ERROR_INVALID_THREAD;
420 CHECK_THREAD_IS_ALIVE(event_thread);
423 cacao_env = (environment*) env;
424 if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
425 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
427 switch (event_type) { /* check capability */
428 case JVMTI_EVENT_EXCEPTION:
429 case JVMTI_EVENT_EXCEPTION_CATCH:
430 CHECK_CAPABILITY(env,can_generate_exception_events)
432 case JVMTI_EVENT_SINGLE_STEP:
433 CHECK_CAPABILITY(env,can_generate_single_step_events)
435 case JVMTI_EVENT_FRAME_POP:
436 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
438 case JVMTI_EVENT_BREAKPOINT:
439 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
441 case JVMTI_EVENT_FIELD_ACCESS:
442 CHECK_CAPABILITY(env,can_generate_field_access_events)
444 case JVMTI_EVENT_FIELD_MODIFICATION:
445 CHECK_CAPABILITY(env,can_generate_field_modification_events)
447 case JVMTI_EVENT_METHOD_ENTRY:
448 CHECK_CAPABILITY(env,can_generate_method_entry_events)
450 case JVMTI_EVENT_METHOD_EXIT:
451 CHECK_CAPABILITY(env, can_generate_method_exit_events)
453 case JVMTI_EVENT_NATIVE_METHOD_BIND:
454 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
456 case JVMTI_EVENT_COMPILED_METHOD_LOAD:
457 case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
458 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
460 case JVMTI_EVENT_MONITOR_WAIT:
461 case JVMTI_EVENT_MONITOR_WAITED:
462 case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
463 case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
464 CHECK_CAPABILITY(env,can_generate_monitor_events)
466 case JVMTI_EVENT_GARBAGE_COLLECTION_START:
467 case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
468 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
470 case JVMTI_EVENT_OBJECT_FREE:
471 CHECK_CAPABILITY(env,can_generate_object_free_events)
473 case JVMTI_EVENT_VM_OBJECT_ALLOC:
474 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
477 /* all other events are required */
478 if ((event_type < JVMTI_EVENT_START_ENUM) ||
479 (event_type > JVMTI_EVENT_END_ENUM))
480 return JVMTI_ERROR_INVALID_EVENT_TYPE;
484 if (event_thread != NULL) {
485 /* thread level control */
486 if ((JVMTI_EVENT_VM_INIT == mode) ||
487 (JVMTI_EVENT_VM_DEATH == mode) ||
488 (JVMTI_EVENT_VM_START == mode) ||
489 (JVMTI_EVENT_THREAD_START == mode) ||
490 (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
491 (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
492 (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
493 (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
494 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
495 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
496 while (ll->next != NULL) {
498 if (ll->event_thread == event_thread) {
500 return JVMTI_ERROR_NONE;
503 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
507 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
511 return JVMTI_ERROR_NONE;
514 /* GetAllThreads ***************************************************************
518 *******************************************************************************/
521 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
522 jthread ** threads_ptr)
524 threadobject** threads;
528 log_text ("GetAllThreads called");
531 CHECK_PHASE(JVMTI_PHASE_LIVE)
534 if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
535 return JVMTI_ERROR_NULL_POINTER;
537 retval=allthreads(threads_count_ptr, &threads);
538 if (retval != JVMTI_ERROR_NONE) return retval;
541 heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
543 for (i=0; i<*threads_count_ptr; i++)
544 (*threads_ptr)[i] = threads[i]->o.thread;
546 return JVMTI_ERROR_NONE;
550 /* SuspendThread ***************************************************************
552 Suspend specified thread
554 *******************************************************************************/
557 SuspendThread (jvmtiEnv * env, jthread thread)
560 CHECK_PHASE(JVMTI_PHASE_LIVE)
562 CHECK_CAPABILITY(env,can_suspend);
564 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
565 return JVMTI_ERROR_NOT_AVAILABLE;
567 return JVMTI_ERROR_NONE;
570 /* ResumeThread ***************************************************************
572 Resume a suspended thread
574 *******************************************************************************/
577 ResumeThread (jvmtiEnv * env, jthread thread)
580 CHECK_PHASE(JVMTI_PHASE_LIVE)
582 CHECK_CAPABILITY(env,can_suspend);
584 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
585 return JVMTI_ERROR_NOT_AVAILABLE;
587 return JVMTI_ERROR_NONE;
590 /* StopThread *****************************************************************
592 Send asynchronous exception to the specified thread. Similar to
593 java.lang.Thread.stop(). Used to kill thread.
595 *******************************************************************************/
598 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
601 CHECK_PHASE(JVMTI_PHASE_LIVE)
603 CHECK_CAPABILITY(env,can_signal_thread);
605 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
606 return JVMTI_ERROR_NOT_AVAILABLE;
608 return JVMTI_ERROR_NONE;
611 /* InterruptThread ************************************************************
613 Interrupt specified thread. Similar to java.lang.Thread.interrupt()
615 *******************************************************************************/
618 InterruptThread (jvmtiEnv * env, jthread thread)
621 CHECK_PHASE(JVMTI_PHASE_LIVE)
623 CHECK_CAPABILITY(env,can_signal_thread)
625 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
627 return JVMTI_ERROR_NOT_AVAILABLE;
629 if(!builtin_instanceof(thread,class_java_lang_Thread))
630 return JVMTI_ERROR_INVALID_THREAD;
632 CHECK_THREAD_IS_ALIVE(thread);
634 return JVMTI_ERROR_NONE;
637 /* GetThreadInfo ***************************************************************
639 Get thread information. Details of the specified thread are stored in the
640 jvmtiThreadInfo structure.
642 *******************************************************************************/
645 GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
647 java_lang_Thread* th = (java_lang_Thread*)t;
649 log_text("GetThreadInfo called");
652 CHECK_PHASE(JVMTI_PHASE_LIVE)
654 info_ptr->priority=(jint)th->priority;
655 info_ptr->is_daemon=(jboolean)th->daemon;
656 info_ptr->thread_group=(jthreadGroup)th->group;
657 info_ptr->context_class_loader=(jobject)th->contextClassLoader;
658 info_ptr->name= javastring_tochar((java_objectheader *)th->name);
660 return JVMTI_ERROR_NONE;
663 /* GetOwnedMonitorInfo *********************************************************
665 Get information about the monitors owned by the specified thread
667 *******************************************************************************/
670 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
671 jint * owned_monitor_count_ptr,
672 jobject ** owned_monitors_ptr)
675 java_objectheader **om;
678 log_text("GetOwnedMonitorInfo called - todo: fix object mapping");
681 CHECK_PHASE(JVMTI_PHASE_LIVE)
683 CHECK_CAPABILITY(env,can_get_owned_monitor_info);
685 if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
686 return JVMTI_ERROR_NULL_POINTER;
688 if(!builtin_instanceof(thread,class_java_lang_Thread))
689 return JVMTI_ERROR_INVALID_THREAD;
691 CHECK_THREAD_IS_ALIVE(thread);
693 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
695 om=MNEW(java_objectheader*,size);
697 pthread_mutex_lock(&pool_lock);
700 while (lrp != NULL) {
701 for (j=0; j<lrp->header.size; j++) {
702 if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
703 (!lrp->lr[j].waiting)) {
705 MREALLOC(om,java_objectheader*,size,size*2);
712 lrp=lrp->header.next;
715 pthread_mutex_unlock(&pool_lock);
717 *owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
718 memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
719 MFREE(om,java_objectheader*,size);
721 *owned_monitor_count_ptr = i;
725 return JVMTI_ERROR_NONE;
728 /* GetCurrentContendedMonitor *************************************************
730 Get the object the specified thread waits for.
732 *******************************************************************************/
735 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
736 jobject * monitor_ptr)
740 java_objectheader* monitor;
743 CHECK_PHASE(JVMTI_PHASE_LIVE)
745 CHECK_CAPABILITY(env, can_get_current_contended_monitor)
747 if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
750 if(!builtin_instanceof(thread,class_java_lang_Thread))
751 return JVMTI_ERROR_INVALID_THREAD;
753 CHECK_THREAD_IS_ALIVE(thread);
756 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
758 pthread_mutex_lock(&pool_lock);
762 while ((lrp != NULL)&&(monitor==NULL)) {
763 for (j=0; j<lrp->header.size; j++) {
764 if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
765 monitor=lrp->lr[j].o;
769 lrp=lrp->header.next;
772 pthread_mutex_unlock(&pool_lock);
775 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
776 *monitor_ptr = (jobject)monitor;
780 return JVMTI_ERROR_NONE;
784 jvmtiStartFunction sf;
790 static void *threadstartup(void *t) {
791 runagentparam *rap = (runagentparam*)t;
792 rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
796 /* RunAgentThread *************************************************************
798 Starts the execution of an agent thread of the specified native function
799 within the specified thread
801 *******************************************************************************/
804 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
805 const void *arg, jint priority)
807 pthread_attr_t threadattr;
808 struct sched_param sp;
812 CHECK_PHASE(JVMTI_PHASE_LIVE)
815 if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
816 return JVMTI_ERROR_INVALID_THREAD;
817 if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
818 if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
819 (priority > JVMTI_THREAD_MAX_PRIORITY))
820 return JVMTI_ERROR_INVALID_PRIORITY;
822 /* XXX: Threads started with with this function should not be visible to
823 Java programming language queries but are included in JVM TI queries */
826 rap.arg = (void*)arg;
829 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
830 pthread_attr_init(&threadattr);
831 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
832 if (priority == JVMTI_THREAD_MIN_PRIORITY) {
833 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
835 if (priority == JVMTI_THREAD_MAX_PRIORITY) {
836 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
838 pthread_attr_setschedparam(&threadattr,&sp);
839 if (pthread_create(&((threadobject*)
840 thread)->info.tid, &threadattr, &threadstartup, &rap)) {
841 log_text("pthread_create failed");
846 return JVMTI_ERROR_NONE;
850 /* GetTopThreadGroups *********************************************************
852 Get all top-level thread groups in the VM.
854 *******************************************************************************/
857 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
858 jthreadGroup ** groups_ptr)
860 jint threads_count_ptr;
861 threadobject *threads_ptr;
863 jthreadGroup **tg,*ttgp;
866 CHECK_PHASE(JVMTI_PHASE_LIVE)
869 log_text("GetTopThreadGroups called");
871 if ((groups_ptr == NULL) || (group_count_ptr == NULL))
872 return JVMTI_ERROR_NULL_POINTER;
874 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
875 tg = MNEW(jthreadGroup*,size);
877 if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
878 return JVMTI_ERROR_INTERNAL;
880 for (i=0;i<threads_count_ptr;i++){
881 if (threads_ptr[i].o.thread->group == NULL) {
882 log_text("threadgroup not set");
883 return JVMTI_ERROR_INTERNAL;
885 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
888 while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
893 MREALLOC(tg,jthreadGroup*,size,size*2);
902 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
903 memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
904 MFREE(tg,jthreadGroup*,size);
906 *group_count_ptr = x;
909 return JVMTI_ERROR_NOT_AVAILABLE;
911 return JVMTI_ERROR_NONE;
915 /* GetThreadGroupInfo *********************************************************
917 Get information about the specified thread group.
919 *******************************************************************************/
922 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
923 jvmtiThreadGroupInfo * info_ptr)
927 java_lang_ThreadGroup* grp;
930 CHECK_PHASE(JVMTI_PHASE_LIVE)
933 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
934 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
935 return JVMTI_ERROR_INVALID_THREAD_GROUP;
937 grp = (java_lang_ThreadGroup*)group;
939 info_ptr->parent = (jthreadGroup)
940 Java_java_lang_VMObject_clone(NULL,
941 (jclass)grp->header.vftbl->class,
942 (java_lang_Cloneable*) &grp->parent);
944 name = javastring_tochar((java_objectheader*)grp->name);
946 info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
947 strncpy(info_ptr->name,name,size);
948 info_ptr->max_priority= (jint)grp->maxpri;
949 info_ptr->is_daemon= (jboolean)grp->daemon_flag;
951 return JVMTI_ERROR_NONE;
955 /* GetThreadGroupChildren *****************************************************
957 Get the live threads and active subgroups in this thread group.
959 *******************************************************************************/
962 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
963 jint * thread_count_ptr, jthread ** threads_ptr,
964 jint * group_count_ptr, jthreadGroup ** groups_ptr)
966 java_lang_ThreadGroup* tgp;
969 CHECK_PHASE(JVMTI_PHASE_LIVE)
972 if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
973 (group_count_ptr == NULL) || (groups_ptr == NULL))
974 return JVMTI_ERROR_NULL_POINTER;
976 if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
977 return JVMTI_ERROR_INVALID_THREAD_GROUP;
979 tgp = (java_lang_ThreadGroup*)group;
981 *thread_count_ptr = (jint)tgp->threads->elementCount;
983 *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
985 memcpy(*threads_ptr, &tgp->threads->elementData,
986 (*thread_count_ptr)*sizeof(jthread*));
988 *group_count_ptr = (jint) tgp->groups->elementCount;
990 *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
992 memcpy(*groups_ptr, &tgp->threads->elementData,
993 (*group_count_ptr)*sizeof(jthreadGroup*));
995 return JVMTI_ERROR_NONE;
999 /* getcacaostacktrace *********************************************************
1001 Helper function that retrives stack trace for specified thread.
1002 Has to take care of suspend/resume issuses
1004 *******************************************************************************/
1005 static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
1008 log_text("getcacaostacktrace");
1010 t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
1013 *trace = stacktrace_create(t); */
1015 return JVMTI_ERROR_NONE;
1019 /* GetFrameCount **************************************************************
1022 Get the number of frames in the specified thread's stack.
1024 *******************************************************************************/
1027 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1029 stacktracebuffer* trace;
1033 CHECK_PHASE(JVMTI_PHASE_LIVE)
1036 if(!builtin_instanceof(thread,class_java_lang_Thread))
1037 return JVMTI_ERROR_INVALID_THREAD;
1039 CHECK_THREAD_IS_ALIVE(thread);
1041 if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1043 er = getcacaostacktrace(&trace, thread);
1044 if (er==JVMTI_ERROR_NONE) return er;
1046 *count_ptr = trace->used;
1048 return JVMTI_ERROR_NONE;
1052 /* GetThreadState **************************************************************
1054 Get the state of a thread.
1056 *******************************************************************************/
1059 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1061 java_lang_Thread* th = (java_lang_Thread*)thread;
1062 threadobject* t = (threadobject*)th->vmThread;
1065 CHECK_PHASE(JVMTI_PHASE_LIVE)
1068 if(!builtin_instanceof(thread,class_java_lang_Thread))
1069 return JVMTI_ERROR_INVALID_THREAD;
1071 if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1073 *thread_state_ptr = 0;
1074 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1075 if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1077 if (((threadobject*)th->vmThread)->info.tid == 0)
1078 *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1081 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1082 if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
1084 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
1085 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
1086 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
1087 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
1088 if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
1089 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
1090 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
1091 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
1092 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
1093 if (t->isSleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
1096 return JVMTI_ERROR_INTERNAL;
1099 return JVMTI_ERROR_NONE;
1103 /* GetFrameLocation ************************************************************
1105 Get the location of the instruction currently executing
1107 *******************************************************************************/
1110 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1111 jmethodID * method_ptr, jlocation * location_ptr)
1113 stackframeinfo *sfi;
1117 CHECK_PHASE(JVMTI_PHASE_LIVE)
1120 if(!builtin_instanceof(thread,class_java_lang_Thread))
1121 return JVMTI_ERROR_INVALID_THREAD;
1123 CHECK_THREAD_IS_ALIVE(thread);
1125 if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1127 if ((method_ptr == NULL)&&(location_ptr == NULL))
1128 return JVMTI_ERROR_NULL_POINTER;
1130 sfi = ((threadobject*)thread)->info._stackframeinfo;
1133 while ((sfi != NULL) && (i<depth)) {
1138 if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1140 *method_ptr=(jmethodID)sfi->method;
1141 *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1143 return JVMTI_ERROR_NONE;
1147 /* NotifyFramePop *************************************************************
1151 *******************************************************************************/
1154 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1157 CHECK_PHASE(JVMTI_PHASE_LIVE)
1159 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1161 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1162 return JVMTI_ERROR_NONE;
1165 /* GetLocalObject *************************************************************
1169 *******************************************************************************/
1172 GetLocalObject (jvmtiEnv * env,
1173 jthread thread, jint depth, jint slot, jobject * value_ptr)
1176 CHECK_PHASE(JVMTI_PHASE_LIVE)
1178 CHECK_CAPABILITY(env,can_access_local_variables)
1180 log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1181 return JVMTI_ERROR_NONE;
1184 /* GetLocalInt ****************************************************************
1188 *******************************************************************************/
1191 GetLocalInt (jvmtiEnv * env,
1192 jthread thread, jint depth, jint slot, jint * value_ptr)
1195 CHECK_PHASE(JVMTI_PHASE_LIVE)
1197 CHECK_CAPABILITY(env,can_access_local_variables)
1198 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1199 return JVMTI_ERROR_NONE;
1202 /* *****************************************************************************
1206 *******************************************************************************/
1209 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1213 CHECK_PHASE(JVMTI_PHASE_LIVE)
1215 CHECK_CAPABILITY(env,can_access_local_variables)
1217 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1218 return JVMTI_ERROR_NONE;
1222 /* *****************************************************************************
1226 *******************************************************************************/
1229 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1233 CHECK_PHASE(JVMTI_PHASE_LIVE)
1235 CHECK_CAPABILITY(env,can_access_local_variables)
1237 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1238 return JVMTI_ERROR_NONE;
1242 /* *****************************************************************************
1246 *******************************************************************************/
1249 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1250 jdouble * value_ptr)
1253 CHECK_PHASE(JVMTI_PHASE_LIVE)
1255 CHECK_CAPABILITY(env,can_access_local_variables)
1257 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1258 return JVMTI_ERROR_NONE;
1262 /* *****************************************************************************
1266 *******************************************************************************/
1269 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1273 CHECK_PHASE(JVMTI_PHASE_LIVE)
1275 CHECK_CAPABILITY(env,can_access_local_variables)
1277 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1278 return JVMTI_ERROR_NONE;
1282 /* *****************************************************************************
1286 *******************************************************************************/
1289 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1293 CHECK_PHASE(JVMTI_PHASE_LIVE)
1295 CHECK_CAPABILITY(env,can_access_local_variables)
1297 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1298 return JVMTI_ERROR_NONE;
1302 /* *****************************************************************************
1306 *******************************************************************************/
1309 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1313 CHECK_PHASE(JVMTI_PHASE_LIVE)
1315 CHECK_CAPABILITY(env,can_access_local_variables)
1317 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1318 return JVMTI_ERROR_NONE;
1322 /* *****************************************************************************
1326 *******************************************************************************/
1329 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1333 CHECK_PHASE(JVMTI_PHASE_LIVE)
1335 CHECK_CAPABILITY(env,can_access_local_variables)
1337 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1338 return JVMTI_ERROR_NONE;
1342 /* *****************************************************************************
1346 *******************************************************************************/
1349 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1353 CHECK_PHASE(JVMTI_PHASE_LIVE)
1355 CHECK_CAPABILITY(env,can_access_local_variables)
1357 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1358 return JVMTI_ERROR_NONE;
1362 /* CreateRawMonitor ***********************************************************
1364 This function creates a new raw monitor.
1366 *******************************************************************************/
1369 CreateRawMonitor (jvmtiEnv * env, const char *name,
1370 jrawMonitorID * monitor_ptr)
1372 struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1375 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1376 CHECK_PHASE(JVMTI_PHASE_LIVE)
1379 if ((name == NULL) || (monitor_ptr == NULL))
1380 return JVMTI_ERROR_NULL_POINTER;
1382 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1383 monitor->name=javastring_new_from_ascii(name);
1385 log_text ("CreateRawMonitor not supported");
1388 return JVMTI_ERROR_NONE;
1392 /* DestroyRawMonitor **********************************************************
1394 This function destroys a raw monitor.
1396 *******************************************************************************/
1399 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1402 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1403 CHECK_PHASE(JVMTI_PHASE_LIVE)
1406 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1407 return JVMTI_ERROR_INVALID_MONITOR;
1409 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1410 if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1411 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1413 monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1415 /* GC will clean monitor up */
1417 log_text ("DestroyRawMonitor not supported");
1420 return JVMTI_ERROR_NONE;
1424 /* RawMonitorEnter ************************************************************
1426 Gain exclusive ownership of a raw monitor
1428 *******************************************************************************/
1431 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1433 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1434 return JVMTI_ERROR_INVALID_MONITOR;
1436 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1437 builtin_monitorenter((java_objectheader*)monitor->name);
1439 log_text ("RawMonitorEnter not supported");
1442 return JVMTI_ERROR_NONE;
1446 /* RawMonitorExit *************************************************************
1450 *******************************************************************************/
1453 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1455 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1456 return JVMTI_ERROR_INVALID_MONITOR;
1458 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1459 /* assure current thread owns this monitor */
1460 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1461 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1463 builtin_monitorexit((java_objectheader*)monitor->name);
1465 log_text ("RawMonitorExit not supported");
1468 return JVMTI_ERROR_NONE;
1472 /* RawMonitorWait *************************************************************
1474 Wait for notification of the raw monitor.
1476 *******************************************************************************/
1479 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1481 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1482 return JVMTI_ERROR_INVALID_MONITOR;
1484 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1485 /* assure current thread owns this monitor */
1486 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1487 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1489 wait_cond_for_object(&monitor->name->header, millis,0);
1490 if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1491 return JVMTI_ERROR_INTERRUPT;
1494 log_text ("RawMonitorWait not supported");
1497 return JVMTI_ERROR_NONE;
1501 /* RawMonitorNotify ***********************************************************
1503 Notify one thread waiting on the given monitor.
1505 *******************************************************************************/
1508 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1510 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1511 return JVMTI_ERROR_INVALID_MONITOR;
1513 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1514 /* assure current thread owns this monitor */
1515 if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1516 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1518 signal_cond_for_object((java_objectheader*)&monitor->name);
1520 log_text ("RawMonitorNotify not supported");
1523 return JVMTI_ERROR_NONE;
1527 /* RawMonitorNotifyAll *********************************************************
1529 Notify all threads waiting on the given monitor.
1531 *******************************************************************************/
1534 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1536 if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1537 return JVMTI_ERROR_INVALID_MONITOR;
1539 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1540 /* assure current thread owns this monitor */
1541 if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1542 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1544 broadcast_cond_for_object((java_objectheader*)&monitor->name);
1546 log_text ("RawMonitorNotifyAll not supported");
1549 return JVMTI_ERROR_NONE;
1553 /* SetBreakpoint **************************************************************
1557 *******************************************************************************/
1560 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1563 CHECK_PHASE(JVMTI_PHASE_LIVE)
1565 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1568 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1569 return JVMTI_ERROR_NONE;
1573 /* *****************************************************************************
1577 *******************************************************************************/
1580 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1583 CHECK_PHASE(JVMTI_PHASE_LIVE)
1585 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1587 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1588 return JVMTI_ERROR_NONE;
1592 /* SetFieldAccessWatch ********************************************************
1596 *******************************************************************************/
1599 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1602 CHECK_PHASE(JVMTI_PHASE_LIVE)
1604 CHECK_CAPABILITY(env,can_generate_field_access_events)
1606 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1607 return JVMTI_ERROR_NONE;
1611 /* *****************************************************************************
1615 *******************************************************************************/
1618 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1621 CHECK_PHASE(JVMTI_PHASE_LIVE)
1623 CHECK_CAPABILITY(env,can_generate_field_access_events)
1625 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1626 return JVMTI_ERROR_NONE;
1630 /* *****************************************************************************
1634 *******************************************************************************/
1637 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1640 CHECK_PHASE(JVMTI_PHASE_LIVE)
1642 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1644 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1645 return JVMTI_ERROR_NONE;
1649 /* *****************************************************************************
1653 *******************************************************************************/
1656 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1659 CHECK_PHASE(JVMTI_PHASE_LIVE)
1661 CHECK_CAPABILITY(env,can_generate_field_modification_events)
1663 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1664 return JVMTI_ERROR_NONE;
1668 /* Allocate ********************************************************************
1670 Allocate an area of memory through the JVM TI allocator. The allocated
1671 memory should be freed with Deallocate
1673 *******************************************************************************/
1676 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1679 if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1680 if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1682 *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1683 if (*mem_ptr == NULL)
1684 return JVMTI_ERROR_OUT_OF_MEMORY;
1686 return JVMTI_ERROR_NONE;
1691 /* Deallocate ******************************************************************
1693 Deallocate mem using the JVM TI allocator.
1695 *******************************************************************************/
1698 Deallocate (jvmtiEnv * env, unsigned char *mem)
1700 /* let Boehm GC do the job */
1701 return JVMTI_ERROR_NONE;
1705 /* GetClassSignature ************************************************************
1707 For the class indicated by klass, return the JNI type signature and the
1708 generic signature of the class.
1710 *******************************************************************************/
1713 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1719 CHECK_PHASE(JVMTI_PHASE_START)
1720 CHECK_PHASE(JVMTI_PHASE_LIVE)
1723 if ((generic_ptr== NULL)||(signature_ptr == NULL))
1724 return JVMTI_ERROR_NULL_POINTER;
1726 nsize=((classinfo*)klass)->name->blength;
1727 psize=((classinfo*)klass)->packagename->blength;
1729 *signature_ptr = (char*)
1730 heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
1732 *signature_ptr[0]='L';
1733 memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
1734 *signature_ptr[psize+2]='/';
1735 memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
1736 *signature_ptr[nsize+psize+3]=';';
1737 *signature_ptr[nsize+psize+4]='\0';
1739 *generic_ptr = NULL;
1741 return JVMTI_ERROR_NONE;
1744 /* GetClassStatus *************************************************************
1746 Get status of the class.
1748 *******************************************************************************/
1751 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1755 CHECK_PHASE(JVMTI_PHASE_START)
1756 CHECK_PHASE(JVMTI_PHASE_LIVE)
1759 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1760 return JVMTI_ERROR_INVALID_CLASS;
1762 if (status_ptr == NULL)
1763 return JVMTI_ERROR_NULL_POINTER;
1765 c = (classinfo*)klass;
1768 /* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1769 if (c->state&=CLASS_LINKED)
1770 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
1772 if (c->state&=CLASS_INITIALIZED)
1773 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1775 if (c->state&=CLASS_ERROR)
1776 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1778 if (c->vftbl->arraydesc != NULL)
1779 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1781 if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
1782 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
1784 return JVMTI_ERROR_NONE;
1788 /* GetSourceFileName **********************************************************
1790 For the class indicated by klass, return the source file name.
1792 *******************************************************************************/
1795 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1800 CHECK_PHASE(JVMTI_PHASE_START)
1801 CHECK_PHASE(JVMTI_PHASE_LIVE)
1803 CHECK_CAPABILITY(env,can_get_source_file_name)
1805 if ((klass == NULL)||(source_name_ptr == NULL))
1806 return JVMTI_ERROR_NULL_POINTER;
1808 size = (((classinfo*)klass)->sourcefile->blength)+1;
1810 *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1812 memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1813 (*source_name_ptr)[size]='\0';
1815 return JVMTI_ERROR_NONE;
1819 /* GetClassModifiers **********************************************************
1821 For class klass return the access flags
1823 *******************************************************************************/
1826 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1829 CHECK_PHASE(JVMTI_PHASE_START)
1830 CHECK_PHASE(JVMTI_PHASE_LIVE)
1833 if (modifiers_ptr == NULL)
1834 return JVMTI_ERROR_NULL_POINTER;
1836 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1837 return JVMTI_ERROR_INVALID_CLASS;
1839 *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1841 return JVMTI_ERROR_NONE;
1845 /* GetClassMethods *************************************************************
1847 For class klass return a count of methods and a list of method IDs
1849 *******************************************************************************/
1852 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1853 jmethodID ** methods_ptr)
1856 CHECK_PHASE(JVMTI_PHASE_START)
1857 CHECK_PHASE(JVMTI_PHASE_LIVE)
1860 if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
1861 return JVMTI_ERROR_NULL_POINTER;
1863 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1864 return JVMTI_ERROR_INVALID_CLASS;
1866 *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1867 *methods_ptr = (jmethodID*)
1868 heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1870 memcpy (*methods_ptr, ((classinfo*)klass)->methods,
1871 sizeof(jmethodID) * (*method_count_ptr));
1873 return JVMTI_ERROR_NONE;
1877 /* GetClassFields *************************************************************
1879 For the class indicated by klass, return a count of fields and a list of
1882 *******************************************************************************/
1885 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1886 jfieldID ** fields_ptr)
1889 CHECK_PHASE(JVMTI_PHASE_START)
1890 CHECK_PHASE(JVMTI_PHASE_LIVE)
1893 if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL))
1894 return JVMTI_ERROR_NULL_POINTER;
1896 *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1897 *fields_ptr = (jfieldID*)
1898 heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1900 memcpy (*fields_ptr, ((classinfo*)klass)->fields,
1901 sizeof(jfieldID) * (*field_count_ptr));
1903 return JVMTI_ERROR_NONE;
1907 /* GetImplementedInterfaces ***************************************************
1909 Return the direct super-interfaces of this class.
1911 *******************************************************************************/
1914 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1915 jint * interface_count_ptr,
1916 jclass ** interfaces_ptr)
1919 classref_or_classinfo *interfaces;
1923 CHECK_PHASE(JVMTI_PHASE_START)
1924 CHECK_PHASE(JVMTI_PHASE_LIVE)
1927 if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1928 return JVMTI_ERROR_NULL_POINTER;
1930 if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1931 return JVMTI_ERROR_INVALID_CLASS;
1934 *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1936 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1938 interfaces = ((classinfo*)klass)->interfaces;
1939 for (i=0; i<*interface_count_ptr; i++) {
1940 if (IS_CLASSREF(interfaces[i]))
1941 tmp = load_class_bootstrap(interfaces[i].ref->name);
1943 tmp = interfaces[i].cls;
1945 *interfaces_ptr[i]=tmp;
1948 return JVMTI_ERROR_NONE;
1952 /* IsInterface ****************************************************************
1954 Determines whether a class object reference represents an interface.
1956 *******************************************************************************/
1959 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1962 CHECK_PHASE(JVMTI_PHASE_START)
1963 CHECK_PHASE(JVMTI_PHASE_LIVE)
1966 if ((klass == NULL)||(is_interface_ptr == NULL))
1967 return JVMTI_ERROR_NULL_POINTER;
1969 *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
1971 return JVMTI_ERROR_NONE;
1974 /* IsArrayClass ***************************************************************
1976 Determines whether a class object reference represents an array.
1978 *******************************************************************************/
1981 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
1984 CHECK_PHASE(JVMTI_PHASE_START)
1985 CHECK_PHASE(JVMTI_PHASE_LIVE)
1988 if (is_array_class_ptr == NULL)
1989 return JVMTI_ERROR_NULL_POINTER;
1991 *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
1993 return JVMTI_ERROR_NONE;
1997 /* GetClassLoader *************************************************************
1999 For the class indicated by klass, return via classloader_ptr a reference to
2000 the class loader for the class.
2002 *******************************************************************************/
2005 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
2008 CHECK_PHASE(JVMTI_PHASE_START)
2009 CHECK_PHASE(JVMTI_PHASE_LIVE)
2012 if ((klass == NULL)||(classloader_ptr == NULL))
2013 return JVMTI_ERROR_NULL_POINTER;
2015 *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
2017 return JVMTI_ERROR_NONE;
2021 /* GetObjectHashCode **********************************************************
2023 Return hash code for object object
2025 *******************************************************************************/
2028 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
2031 CHECK_PHASE(JVMTI_PHASE_START)
2032 CHECK_PHASE(JVMTI_PHASE_LIVE)
2035 if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2036 if (!builtin_instanceof(object,class_java_lang_Object))
2037 return JVMTI_ERROR_INVALID_OBJECT;
2039 *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2041 return JVMTI_ERROR_NONE;
2045 /* *****************************************************************************
2049 *******************************************************************************/
2052 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2053 jvmtiMonitorUsage * info_ptr)
2056 CHECK_PHASE(JVMTI_PHASE_LIVE)
2058 CHECK_CAPABILITY(env,can_get_monitor_info)
2060 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2061 return JVMTI_ERROR_NONE;
2065 /* GetFieldName ***************************************************************
2067 For the field indicated by klass and field, return the field name and
2070 *******************************************************************************/
2073 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2074 char **name_ptr, char **signature_ptr, char **generic_ptr)
2079 CHECK_PHASE(JVMTI_PHASE_START)
2080 CHECK_PHASE(JVMTI_PHASE_LIVE)
2083 if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
2084 return JVMTI_ERROR_NULL_POINTER;
2086 size = (((fieldinfo*)field)->name->blength);
2087 *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2088 memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2090 size = (((fieldinfo*)field)->descriptor->blength);
2091 *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
2092 memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2094 *generic_ptr = NULL;
2096 return JVMTI_ERROR_NONE;
2100 /* GetFieldDeclaringClass *****************************************************
2102 For the field indicated by klass and field return the class that defined it
2103 The declaring class will either be klass, a superclass, or an implemented
2106 *******************************************************************************/
2109 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2110 jclass * declaring_class_ptr)
2113 CHECK_PHASE(JVMTI_PHASE_START)
2114 CHECK_PHASE(JVMTI_PHASE_LIVE)
2117 *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
2119 return JVMTI_ERROR_NONE;
2123 /* GetFieldModifiers **********************************************************
2125 Return access flags of field field
2127 *******************************************************************************/
2130 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2131 jint * modifiers_ptr)
2134 CHECK_PHASE(JVMTI_PHASE_START)
2135 CHECK_PHASE(JVMTI_PHASE_LIVE)
2138 if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2139 return JVMTI_ERROR_INVALID_OBJECT;
2141 if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2143 /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2145 *modifiers_ptr = ((fieldinfo*)field)->flags;
2147 return JVMTI_ERROR_NONE;
2151 /* IsFieldSynthetic ***********************************************************
2155 *******************************************************************************/
2158 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2159 jboolean * is_synthetic_ptr)
2162 CHECK_PHASE(JVMTI_PHASE_START)
2163 CHECK_PHASE(JVMTI_PHASE_LIVE)
2165 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2167 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2168 return JVMTI_ERROR_NONE;
2172 /* GetMethodName ***************************************************************
2174 For the method indicated by method, return the method name via name_ptr and
2175 method signature via signature_ptr.
2177 *******************************************************************************/
2180 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2181 char **signature_ptr, char **generic_ptr)
2183 methodinfo* m = (methodinfo*)method;
2186 CHECK_PHASE(JVMTI_PHASE_START)
2187 CHECK_PHASE(JVMTI_PHASE_LIVE)
2190 if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2191 || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2193 if (m->name == NULL) return JVMTI_ERROR_INTERNAL;
2196 heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
2197 utf_sprint_convert_to_latin1(*name_ptr, m->name);
2199 *signature_ptr = (char*)
2200 heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
2201 utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
2203 /* there is no generic signature attribute */
2204 *generic_ptr = NULL;
2206 return JVMTI_ERROR_NONE;
2210 /* GetMethodDeclaringClass *****************************************************
2212 For the method indicated by method, return the class that defined it.
2214 *******************************************************************************/
2217 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2218 jclass * declaring_class_ptr)
2221 CHECK_PHASE(JVMTI_PHASE_START)
2222 CHECK_PHASE(JVMTI_PHASE_LIVE)
2225 if ((method == NULL) || (declaring_class_ptr == NULL))
2226 return JVMTI_ERROR_NULL_POINTER;
2228 *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2230 return JVMTI_ERROR_NONE;
2234 /* GetMethodModifiers **********************************************************
2236 For the method indicated by method, return the access flags.
2238 *******************************************************************************/
2241 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2244 CHECK_PHASE(JVMTI_PHASE_START)
2245 CHECK_PHASE(JVMTI_PHASE_LIVE)
2248 if ((method == NULL) || (modifiers_ptr == NULL))
2249 return JVMTI_ERROR_NULL_POINTER;
2251 *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2253 return JVMTI_ERROR_NONE;
2257 /* GetMaxLocals ****************************************************************
2259 For the method indicated by method, return the number of local variable slots
2260 used by the method, including the local variables used to pass parameters to
2261 the method on its invocation.
2263 *******************************************************************************/
2266 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2269 CHECK_PHASE(JVMTI_PHASE_START)
2270 CHECK_PHASE(JVMTI_PHASE_LIVE)
2273 if ((method == NULL)||(max_ptr == NULL))
2274 return JVMTI_ERROR_NULL_POINTER;
2276 if (((methodinfo*)method)->flags & ACC_NATIVE)
2277 return JVMTI_ERROR_NATIVE_METHOD;
2279 *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2281 return JVMTI_ERROR_NONE;
2286 /* GetArgumentsSize ************************************************************
2288 Return the number of local variable slots used by the method's arguments.
2290 *******************************************************************************/
2293 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2296 CHECK_PHASE(JVMTI_PHASE_START)
2297 CHECK_PHASE(JVMTI_PHASE_LIVE)
2300 if ((method == NULL)||(size_ptr == NULL))
2301 return JVMTI_ERROR_NULL_POINTER;
2303 if (((methodinfo*)method)->flags & ACC_NATIVE)
2304 return JVMTI_ERROR_NATIVE_METHOD;
2306 /* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
2307 return JVMTI_ERROR_NONE;
2312 /* GetLineNumberTable ***********************************************************
2314 Return table of source line number entries for a given method
2316 *******************************************************************************/
2319 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2320 jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2325 CHECK_PHASE(JVMTI_PHASE_START)
2326 CHECK_PHASE(JVMTI_PHASE_LIVE)
2328 CHECK_CAPABILITY(env,can_get_line_numbers)
2330 if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
2331 return JVMTI_ERROR_NULL_POINTER;
2332 if (((methodinfo*)method)->flags & ACC_NATIVE)
2333 return JVMTI_ERROR_NATIVE_METHOD;
2334 if (((methodinfo*)method)->linenumbers == NULL)
2335 return JVMTI_ERROR_ABSENT_INFORMATION;
2337 *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2338 *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2339 sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2342 for (i=0; i < *entry_count_ptr; i++) {
2343 (*table_ptr[i]).start_location =
2344 (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
2345 (*table_ptr[i]).line_number =
2346 (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2349 return JVMTI_ERROR_NONE;
2353 /* GetMethodLocation ***********************************************************
2355 For the method indicated by method, return the beginning and ending addresses
2356 through start_location_ptr and end_location_ptr. In cacao this points to
2357 entry point in machine code and length of machine code
2359 *******************************************************************************/
2362 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2363 jlocation * start_location_ptr,
2364 jlocation * end_location_ptr)
2366 methodinfo* m = (methodinfo*)method;
2369 CHECK_PHASE(JVMTI_PHASE_START)
2370 CHECK_PHASE(JVMTI_PHASE_LIVE)
2373 if ((method == NULL) || (start_location_ptr == NULL) ||
2374 (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2376 /* XXX we return the location of the most recent code. Don't know
2377 * if there is a way to teach jvmti that a method can have more
2378 * than one location. -Edwin */
2380 /* XXX Don't know if that's the right way to deal with not-yet-
2381 * compiled methods. -Edwin */
2384 return JVMTI_ERROR_NULL_POINTER;
2386 *start_location_ptr = (jlocation)m->code->mcode;
2387 *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
2388 return JVMTI_ERROR_NONE;
2392 /* GetLocalVariableTable *******************************************************
2394 Return local variable information.
2396 *******************************************************************************/
2399 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2400 jint * entry_count_ptr,
2401 jvmtiLocalVariableEntry ** table_ptr)
2404 CHECK_PHASE(JVMTI_PHASE_LIVE)
2406 CHECK_CAPABILITY(env,can_access_local_variables)
2408 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2410 return JVMTI_ERROR_NONE;
2414 /* GetBytecode *****************************************************************
2416 For the method indicated by method, return the byte codes that implement the
2419 *******************************************************************************/
2422 GetBytecodes (jvmtiEnv * env, jmethodID method,
2423 jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2425 methodinfo* m = (methodinfo*)method;;
2428 CHECK_PHASE(JVMTI_PHASE_START)
2429 CHECK_PHASE(JVMTI_PHASE_LIVE)
2431 CHECK_CAPABILITY(env,can_get_bytecodes)
2433 if ((method == NULL) || (bytecode_count_ptr == NULL) ||
2434 (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2436 *bytecode_count_ptr = m->jcodelength;
2437 *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2438 memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2440 return JVMTI_ERROR_NONE;
2444 /* IsMethodNative **************************************************************
2446 For the method indicated by method, return a value indicating whether the
2447 method is a native function
2449 *******************************************************************************/
2452 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2455 CHECK_PHASE(JVMTI_PHASE_START)
2456 CHECK_PHASE(JVMTI_PHASE_LIVE)
2459 if ((method == NULL)||(is_native_ptr == NULL))
2460 return JVMTI_ERROR_NULL_POINTER;
2462 if (((methodinfo*)method)->flags & ACC_NATIVE)
2463 *is_native_ptr = JNI_TRUE;
2465 *is_native_ptr = JNI_FALSE;
2467 return JVMTI_ERROR_NONE;
2471 /* IsMethodSynthetic ***********************************************************
2473 return a value indicating whether the method is synthetic. Synthetic methods
2474 are generated by the compiler but not present in the original source code.
2476 *******************************************************************************/
2479 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2480 jboolean * is_synthetic_ptr)
2483 CHECK_PHASE(JVMTI_PHASE_START)
2484 CHECK_PHASE(JVMTI_PHASE_LIVE)
2486 CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2488 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2489 return JVMTI_ERROR_NONE;
2493 /* GetLoadedClasses ************************************************************
2495 Return an array of all classes loaded in the virtual machine.
2497 *******************************************************************************/
2500 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
2505 classcache_name_entry *cne;
2506 classcache_class_entry *cce;
2508 log_text ("GetLoadedClasses called %d ", phase);
2513 *class_count_ptr = 0;
2516 CHECK_PHASE(JVMTI_PHASE_LIVE)
2519 if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2520 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2522 log_text ("GetLoadedClasses1");
2526 log_text ("GetLoadedClasses2");
2527 getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
2528 ht = (hashtable*) &data;
2530 log_text ("GetLoadedClasses got ht pointer");
2532 heap_allocate(sizeof(jclass*) * (ht->entries),true,NULL);
2533 fprintf (stderr,"hashtable_classcache.entries = %d\n",ht->entries);
2536 *class_count_ptr = ht->entries;
2537 log_text ("GetLoadedClasses %d", *class_count_ptr);
2539 look in every slot of the hashtable
2540 for (i=0; i<ht->size; i++) {
2543 while (cne != NULL) { iterate over hashlink
2544 getchildproc(&data, cne, sizeof(classcache_name_entry));
2545 cne =(classcache_name_entry*) &data;
2548 while (cce != NULL){ iterate over classes with same name
2549 getchildproc(&data, cce, sizeof(classcache_class_entry));
2550 cce =(classcache_class_entry*) &data;
2552 if (cce->classobj != NULL) { get only loaded classes
2553 assert(j<ht->entries);
2554 * classes_ptr[j]=cce->classobj;
2559 cne = cne->hashlink;
2563 log_text ("GetLoadedClasses continue");
2565 CLASSCACHE_UNLOCK();
2569 log_text ("GetLoadedClasses finished");
2571 return JVMTI_ERROR_NONE;
2575 /* GetClassLoaderClasses *******************************************************
2577 Returns an array of those classes for which this class loader has been
2578 recorded as an initiating loader.
2580 *******************************************************************************/
2583 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2584 jint * class_count_ptr, jclass ** classes_ptr)
2586 log_text("GetClassLoaderClasses called");
2589 CHECK_PHASE(JVMTI_PHASE_LIVE)
2592 /* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2593 if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2595 /* behave like jdk 1.1 and make no distinction between initiating and
2596 defining class loaders */
2598 return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2602 /* PopFrame *******************************************************************
2606 *******************************************************************************/
2609 PopFrame (jvmtiEnv * env, jthread thread)
2612 CHECK_PHASE(JVMTI_PHASE_LIVE)
2614 CHECK_CAPABILITY(env,can_pop_frame)
2616 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2617 return JVMTI_ERROR_NONE;
2621 /* RedefineClasses ************************************************************
2625 *******************************************************************************/
2628 RedefineClasses (jvmtiEnv * env, jint class_count,
2629 const jvmtiClassDefinition * class_definitions)
2632 CHECK_PHASE(JVMTI_PHASE_START)
2633 CHECK_PHASE(JVMTI_PHASE_LIVE)
2635 CHECK_CAPABILITY(env,can_redefine_classes)
2636 CHECK_CAPABILITY(env,can_redefine_any_class)
2637 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2638 return JVMTI_ERROR_NONE;
2642 /* GetVersionNumber ***********************************************************
2644 Return the JVM TI version identifier.
2646 *******************************************************************************/
2649 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2651 if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2653 *version_ptr = JVMTI_VERSION_1_0;
2655 return JVMTI_ERROR_NONE;
2659 /* GetCapabilities ************************************************************
2661 Returns the optional JVM TI features which this environment currently
2664 *******************************************************************************/
2667 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2669 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2671 memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2673 return JVMTI_ERROR_NONE;
2677 /* *****************************************************************************
2681 *******************************************************************************/
2684 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2685 char **source_debug_extension_ptr)
2688 CHECK_PHASE(JVMTI_PHASE_START)
2689 CHECK_PHASE(JVMTI_PHASE_LIVE)
2691 CHECK_CAPABILITY(env,can_get_source_debug_extension)
2693 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2694 return JVMTI_ERROR_NONE;
2698 /* IsMethodObsolete ************************************************************
2700 Determine if a method ID refers to an obsolete method version.
2702 *******************************************************************************/
2705 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2706 jboolean * is_obsolete_ptr)
2709 CHECK_PHASE(JVMTI_PHASE_START)
2710 CHECK_PHASE(JVMTI_PHASE_LIVE)
2712 CHECK_CAPABILITY(env,can_redefine_classes)
2714 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2715 return JVMTI_ERROR_NONE;
2719 /* SuspendThreadList **********************************************************
2723 *******************************************************************************/
2726 SuspendThreadList (jvmtiEnv * env, jint request_count,
2727 const jthread * request_list, jvmtiError * results)
2730 CHECK_PHASE(JVMTI_PHASE_START)
2731 CHECK_PHASE(JVMTI_PHASE_LIVE)
2733 CHECK_CAPABILITY(env,can_suspend);
2735 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2737 return JVMTI_ERROR_NONE;
2741 /* ResumeThreadList ***********************************************************
2745 *******************************************************************************/
2748 ResumeThreadList (jvmtiEnv * env, jint request_count,
2749 const jthread * request_list, jvmtiError * results)
2752 CHECK_PHASE(JVMTI_PHASE_LIVE)
2754 CHECK_CAPABILITY(env,can_suspend);
2756 log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2758 return JVMTI_ERROR_NONE;
2762 /* GetStackTrace **************************************************************
2764 Get information about the stack of a thread
2766 *******************************************************************************/
2769 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2770 jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2773 stacktracebuffer* trace;
2778 CHECK_PHASE(JVMTI_PHASE_LIVE)
2781 if(!builtin_instanceof(thread,class_java_lang_Thread))
2782 return JVMTI_ERROR_INVALID_THREAD;
2784 CHECK_THREAD_IS_ALIVE(thread);
2786 if((count_ptr == NULL)||(frame_buffer == NULL))
2787 return JVMTI_ERROR_NULL_POINTER;
2789 if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2791 er = getcacaostacktrace(&trace, thread);
2792 if (er==JVMTI_ERROR_NONE) return er;
2794 if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
2795 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2797 for (i=start_depth, j=0;i<trace->used;i++,j++) {
2798 frame_buffer[j].method = (jmethodID)trace->entries[i].method;
2799 /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
2800 frame_buffer[j].location = 0;
2803 return JVMTI_ERROR_NONE;
2807 /* GetThreadListStackTraces ***************************************************
2809 Get information about the stacks of the supplied threads.
2811 *******************************************************************************/
2814 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2815 const jthread * thread_list,
2816 jint max_frame_count,
2817 jvmtiStackInfo ** stack_info_ptr)
2823 CHECK_PHASE(JVMTI_PHASE_LIVE)
2826 if ((stack_info_ptr == NULL)||(thread_list == NULL))
2827 return JVMTI_ERROR_NULL_POINTER;
2829 if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2831 if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2833 *stack_info_ptr = (jvmtiStackInfo*)
2834 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2836 for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2837 (*stack_info_ptr)[i].thread=thread_list[i];
2838 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2839 (*stack_info_ptr)[i].frame_buffer =
2840 heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2841 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2842 (*stack_info_ptr)[i].frame_buffer,
2843 &((*stack_info_ptr)[i].frame_count));
2845 if (er != JVMTI_ERROR_NONE) return er;
2848 return JVMTI_ERROR_NONE;
2852 /* GetAllStackTraces **********************************************************
2854 Get stack traces of all live threads
2856 *******************************************************************************/
2859 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2860 jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2862 jthread *threads_ptr;
2866 CHECK_PHASE(JVMTI_PHASE_LIVE)
2869 if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2871 /* todo: all threads have to be suspended */
2873 if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2874 return JVMTI_ERROR_INTERNAL;
2876 GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2877 max_frame_count, stack_info_ptr);
2879 /* todo: resume all threads have to be suspended */
2880 if (er != JVMTI_ERROR_NONE) return er;
2882 return JVMTI_ERROR_NONE;
2886 /* GetThreadLocalStorage ******************************************************
2888 Get the value of the JVM TI thread-local storage.
2890 *******************************************************************************/
2893 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2895 jvmtiThreadLocalStorage *tls;
2898 CHECK_PHASE(JVMTI_PHASE_START)
2899 CHECK_PHASE(JVMTI_PHASE_LIVE)
2903 thread = (jthread) THREADOBJECT;
2905 if (!builtin_instanceof(thread,class_java_lang_Thread))
2906 return JVMTI_ERROR_INVALID_THREAD;
2907 CHECK_THREAD_IS_ALIVE(thread);
2910 if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2912 tls = ((environment*)env)->tls;
2913 while ((tls->thread != thread) && (tls != NULL)) {
2917 if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2919 *data_ptr = tls->data;
2921 return JVMTI_ERROR_NONE;
2925 /* SetThreadLocalStorage *******************************************************
2927 Stores a pointer value associated with each environment-thread pair. The
2928 value is NULL unless set with this function. Agents can allocate memory in
2929 which they store thread specific information
2931 *******************************************************************************/
2934 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2936 jvmtiThreadLocalStorage *tls, *pre;
2937 environment* env = (environment*)jenv;
2940 CHECK_PHASE(JVMTI_PHASE_START)
2941 CHECK_PHASE(JVMTI_PHASE_LIVE)
2945 thread = (jthread) THREADOBJECT;
2947 if (!builtin_instanceof(thread,class_java_lang_Thread))
2948 return JVMTI_ERROR_INVALID_THREAD;
2949 CHECK_THREAD_IS_ALIVE(thread);
2952 if (env->tls == NULL) {
2953 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2956 while ((tls->thread != thread) && (tls->next != NULL)) {
2959 if (tls->thread != thread) {
2960 tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2966 tls->data = (void*)data;
2968 /* remove current tls */
2970 while (pre->next == tls) pre = pre->next;
2971 pre->next = tls->next;
2973 return JVMTI_ERROR_NONE;
2977 /* *****************************************************************************
2981 *******************************************************************************/
2984 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
2987 CHECK_PHASE(JVMTI_PHASE_START)
2988 CHECK_PHASE(JVMTI_PHASE_LIVE)
2990 CHECK_CAPABILITY(env,can_tag_objects)
2992 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2993 return JVMTI_ERROR_NONE;
2996 /* *****************************************************************************
3000 *******************************************************************************/
3003 SetTag (jvmtiEnv * env, jobject object, jlong tag)
3006 CHECK_PHASE(JVMTI_PHASE_START)
3007 CHECK_PHASE(JVMTI_PHASE_LIVE)
3009 CHECK_CAPABILITY(env,can_tag_objects)
3011 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3012 return JVMTI_ERROR_NONE;
3016 /* ForceGarbageCollection *****************************************************
3018 Force boehm-gc to perform a garbage collection
3020 *******************************************************************************/
3023 ForceGarbageCollection (jvmtiEnv * env)
3026 CHECK_PHASE(JVMTI_PHASE_LIVE)
3031 return JVMTI_ERROR_NONE;
3035 /* IterateOverObjectsReachableFromObject **************************************
3039 *******************************************************************************/
3042 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
3043 jvmtiObjectReferenceCallback
3044 object_reference_callback,
3048 CHECK_PHASE(JVMTI_PHASE_LIVE)
3050 CHECK_CAPABILITY(env,can_tag_objects)
3052 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3053 return JVMTI_ERROR_NONE;
3057 /* IterateOverReachableObjects ************************************************
3061 *******************************************************************************/
3064 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
3066 jvmtiStackReferenceCallback
3068 jvmtiObjectReferenceCallback
3069 object_ref_callback, void *user_data)
3072 CHECK_PHASE(JVMTI_PHASE_LIVE)
3074 CHECK_CAPABILITY(env,can_tag_objects)
3076 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3077 return JVMTI_ERROR_NONE;
3081 /* IterateOverHeap ************************************************************
3085 *******************************************************************************/
3088 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3089 jvmtiHeapObjectCallback heap_object_callback,
3093 CHECK_PHASE(JVMTI_PHASE_LIVE)
3095 CHECK_CAPABILITY(env,can_tag_objects)
3097 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3098 return JVMTI_ERROR_NONE;
3102 /* IterateOverInstancesOfClass ************************************************
3106 *******************************************************************************/
3109 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3110 jvmtiHeapObjectFilter object_filter,
3111 jvmtiHeapObjectCallback
3112 heap_object_callback, void *user_data)
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 /* *****************************************************************************
3128 *******************************************************************************/
3131 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3132 jint * count_ptr, jobject ** object_result_ptr,
3133 jlong ** tag_result_ptr)
3136 CHECK_PHASE(JVMTI_PHASE_LIVE)
3138 CHECK_CAPABILITY(env,can_tag_objects)
3140 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3141 return JVMTI_ERROR_NONE;
3145 /* SetJNIFunctionTable **********************************************************
3147 Set the JNI function table in all current and future JNI environments
3149 *******************************************************************************/
3152 SetJNIFunctionTable (jvmtiEnv * env,
3153 const jniNativeInterface * function_table)
3156 CHECK_PHASE(JVMTI_PHASE_START)
3157 CHECK_PHASE(JVMTI_PHASE_LIVE)
3160 if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3161 _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3162 memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
3163 return JVMTI_ERROR_NONE;
3167 /* GetJNIFunctionTable *********************************************************
3169 Get the JNI function table. The JNI function table is copied into allocated
3172 *******************************************************************************/
3175 GetJNIFunctionTable (jvmtiEnv * env, 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 *function_table = (jniNativeInterface*)
3184 heap_allocate(sizeof(jniNativeInterface),true,NULL);
3185 memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
3186 return JVMTI_ERROR_NONE;
3190 /* SetEventCallbacks **********************************************************
3192 Set the functions to be called for each event. The callbacks are specified
3193 by supplying a replacement function table.
3195 *******************************************************************************/
3198 SetEventCallbacks (jvmtiEnv * env,
3199 const jvmtiEventCallbacks * callbacks,
3200 jint size_of_callbacks)
3203 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3204 CHECK_PHASE(JVMTI_PHASE_LIVE)
3207 if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3209 if (callbacks == NULL) { /* remove the existing callbacks */
3210 memset(&(((environment* )env)->callbacks), 0,
3211 sizeof(jvmtiEventCallbacks));
3214 memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3216 return JVMTI_ERROR_NONE;
3220 /* GenerateEvents *************************************************************
3222 Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
3223 the current state of the VM.
3225 *******************************************************************************/
3228 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3231 CHECK_PHASE(JVMTI_PHASE_LIVE)
3234 log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3235 return JVMTI_ERROR_NONE;
3239 /* GetExtensionFunctions ******************************************************
3241 Returns the set of extension functions.
3243 *******************************************************************************/
3246 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3247 jvmtiExtensionFunctionInfo ** extensions)
3250 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3251 CHECK_PHASE(JVMTI_PHASE_LIVE)
3254 if ((extension_count_ptr== NULL)||(extensions == NULL))
3255 return JVMTI_ERROR_NULL_POINTER;
3257 /* cacao has no extended functions yet */
3258 *extension_count_ptr = 0;
3260 return JVMTI_ERROR_NONE;
3264 /* GetExtensionEvents *********************************************************
3266 Returns the set of extension events.
3268 *******************************************************************************/
3271 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3272 jvmtiExtensionEventInfo ** extensions)
3275 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3276 CHECK_PHASE(JVMTI_PHASE_LIVE)
3279 if ((extension_count_ptr== NULL)||(extensions == NULL))
3280 return JVMTI_ERROR_NULL_POINTER;
3282 /* cacao has no extended events yet */
3283 *extension_count_ptr = 0;
3285 return JVMTI_ERROR_NONE;
3289 /* SetExtensionEventCallback **************************************************
3291 Sets the callback function for an extension event and enables the event.
3293 *******************************************************************************/
3296 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3297 jvmtiExtensionEvent callback)
3300 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3301 CHECK_PHASE(JVMTI_PHASE_LIVE)
3304 /* cacao has no extended events yet */
3305 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3309 /* DisposeEnvironment **********************************************************
3311 Shutdown a JVM TI connection created with JNI GetEnv.
3313 *******************************************************************************/
3316 DisposeEnvironment (jvmtiEnv * env)
3318 environment* cacao_env = (environment*)env;
3319 environment* tenvs = envs;
3320 jvmtiThreadLocalStorage *jtls, *tjtls;
3322 if (tenvs != cacao_env) {
3323 while (tenvs->next != cacao_env) {
3324 tenvs = tenvs->next;
3326 tenvs->next = cacao_env->next;
3330 cacao_env->env=NULL;
3331 memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
3332 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3333 memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
3334 (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3335 cacao_env->EnvironmentLocalStorage = NULL;
3337 jtls = cacao_env->tls;
3338 while (jtls != NULL) {
3343 cacao_env->tls = NULL;
3346 pthread_mutex_lock(&dbgcomlock);
3348 if (dbgcom->running == 0) {
3351 pthread_mutex_unlock(&dbgcomlock);
3353 /* let the GC do the rest */
3354 return JVMTI_ERROR_NONE;
3358 /* GetErrorName ***************************************************************
3360 Return the symbolic name for an error code.
3362 *******************************************************************************/
3364 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3365 memcpy(*name_ptr, &str, sizeof(str)); \
3369 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3371 if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3374 case JVMTI_ERROR_NONE :
3375 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3376 case JVMTI_ERROR_NULL_POINTER :
3377 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER");
3378 case JVMTI_ERROR_OUT_OF_MEMORY :
3379 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3380 case JVMTI_ERROR_ACCESS_DENIED :
3381 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3382 case JVMTI_ERROR_UNATTACHED_THREAD :
3383 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3384 case JVMTI_ERROR_INVALID_ENVIRONMENT :
3385 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT");
3386 case JVMTI_ERROR_WRONG_PHASE :
3387 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3388 case JVMTI_ERROR_INTERNAL :
3389 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3390 case JVMTI_ERROR_INVALID_PRIORITY :
3391 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3392 case JVMTI_ERROR_THREAD_NOT_SUSPENDED :
3393 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3394 case JVMTI_ERROR_THREAD_SUSPENDED :
3395 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3396 case JVMTI_ERROR_THREAD_NOT_ALIVE :
3397 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3398 case JVMTI_ERROR_CLASS_NOT_PREPARED :
3399 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3400 case JVMTI_ERROR_NO_MORE_FRAMES :
3401 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3402 case JVMTI_ERROR_OPAQUE_FRAME :
3403 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3404 case JVMTI_ERROR_DUPLICATE :
3405 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3406 case JVMTI_ERROR_NOT_FOUND :
3407 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3408 case JVMTI_ERROR_NOT_MONITOR_OWNER :
3409 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3410 case JVMTI_ERROR_INTERRUPT :
3411 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3412 case JVMTI_ERROR_UNMODIFIABLE_CLASS :
3413 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3414 case JVMTI_ERROR_NOT_AVAILABLE :
3415 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3416 case JVMTI_ERROR_ABSENT_INFORMATION :
3417 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3418 case JVMTI_ERROR_INVALID_EVENT_TYPE :
3419 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3420 case JVMTI_ERROR_NATIVE_METHOD :
3421 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3422 case JVMTI_ERROR_INVALID_THREAD :
3423 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3424 case JVMTI_ERROR_INVALID_FIELDID :
3425 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3426 case JVMTI_ERROR_INVALID_METHODID :
3427 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3428 case JVMTI_ERROR_INVALID_LOCATION :
3429 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3430 case JVMTI_ERROR_INVALID_OBJECT :
3431 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3432 case JVMTI_ERROR_INVALID_CLASS :
3433 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3434 case JVMTI_ERROR_TYPE_MISMATCH :
3435 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3436 case JVMTI_ERROR_INVALID_SLOT :
3437 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3438 case JVMTI_ERROR_MUST_POSSESS_CAPABILITY :
3439 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3440 case JVMTI_ERROR_INVALID_THREAD_GROUP :
3441 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3442 case JVMTI_ERROR_INVALID_MONITOR :
3443 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3444 case JVMTI_ERROR_ILLEGAL_ARGUMENT :
3445 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3446 case JVMTI_ERROR_INVALID_TYPESTATE :
3447 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3448 case JVMTI_ERROR_UNSUPPORTED_VERSION :
3449 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3450 case JVMTI_ERROR_INVALID_CLASS_FORMAT :
3451 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3452 case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION :
3453 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3454 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED :
3455 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3456 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED :
3457 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3458 case JVMTI_ERROR_FAILS_VERIFICATION :
3459 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3460 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED :
3461 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3462 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED :
3463 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3464 case JVMTI_ERROR_NAMES_DONT_MATCH :
3465 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3466 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED :
3467 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3468 case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED :
3469 COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3471 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3473 return JVMTI_ERROR_NONE;
3476 /* GetJLocationFormat **********************************************************
3478 This function describes the representation of jlocation used in this VM.
3480 *******************************************************************************/
3483 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3485 *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3486 return JVMTI_ERROR_NONE;
3490 /* GetSystemProperties ********************************************************
3492 The list of VM system property keys which may be used with GetSystemProperty
3495 *******************************************************************************/
3498 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3500 jmethodID mid, moremid;
3501 classinfo *sysclass, *propclass, *enumclass;
3502 java_objectheader *sysprop, *keys, *obj;
3507 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3508 CHECK_PHASE(JVMTI_PHASE_LIVE)
3511 if ((count_ptr == NULL) || (property_ptr == NULL))
3512 return JVMTI_ERROR_NULL_POINTER;
3514 sysclass = load_class_from_sysloader(
3515 utf_new_char_classname ("java/lang/System"));
3517 if (!sysclass) throw_main_exception_exit();
3519 mid = (jmethodID)class_resolvemethod(sysclass,
3520 utf_new_char("getProperties"),
3521 utf_new_char("()Ljava/util/Properties;"));
3522 if (!mid) throw_main_exception_exit();
3525 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
3526 if (!sysprop) throw_main_exception_exit();
3528 propclass = sysprop->vftbl->class;
3530 mid = (jmethodID)class_resolvemethod(propclass,
3531 utf_new_char("size"),
3532 utf_new_char("()I"));
3533 if (!mid) throw_main_exception_exit();
3536 _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
3537 *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3539 mid = (jmethodID)class_resolvemethod(propclass,
3540 utf_new_char("keys"),
3541 utf_new_char("()Ljava/util/Enumeration;"));
3542 if (!mid) throw_main_exception_exit();
3544 keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
3545 enumclass = keys->vftbl->class;
3547 moremid = (jmethodID)class_resolvemethod(enumclass,
3548 utf_new_char("hasMoreElements"),
3549 utf_new_char("()Z"));
3550 if (!moremid) throw_main_exception_exit();
3552 mid = (jmethodID)class_resolvemethod(propclass,
3553 utf_new_char("nextElement"),
3554 utf_new_char("()Ljava/lang/Object;"));
3555 if (!mid) throw_main_exception_exit();
3558 while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3559 obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
3560 ch = javastring_tochar(obj);
3561 *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3562 memcpy(*property_ptr[i], ch, strlen (ch));
3563 MFREE(ch,char,strlen(ch)+1);
3567 return JVMTI_ERROR_NONE;
3571 /* GetSystemProperty **********************************************************
3573 Return a VM system property value given the property key.
3575 *******************************************************************************/
3578 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3581 classinfo *sysclass, *propclass;
3582 java_objectheader *sysprop, *obj;
3586 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3587 CHECK_PHASE(JVMTI_PHASE_LIVE)
3590 if ((value_ptr == NULL) || (property == NULL))
3591 return JVMTI_ERROR_NULL_POINTER;
3593 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3594 if (!sysclass) throw_main_exception_exit();
3596 mid = (jmethodID)class_resolvemethod(sysclass,
3597 utf_new_char("getProperties"),
3598 utf_new_char("()Ljava/util/Properties;"));
3599 if (!mid) throw_main_exception_exit();
3601 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3603 propclass = sysprop->vftbl->class;
3605 mid = (jmethodID)class_resolvemethod(propclass,
3606 utf_new_char("getProperty"),
3607 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3608 if (!mid) throw_main_exception_exit();
3610 obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
3611 NULL, sysprop, mid, javastring_new_from_ascii(property));
3612 if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3614 ch = javastring_tochar(obj);
3615 *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3616 memcpy(*value_ptr, ch, strlen (ch));
3617 MFREE(ch,char,strlen(ch)+1);
3619 return JVMTI_ERROR_NONE;
3623 /* SetSystemProperty **********************************************************
3625 Set a VM system property value.
3627 *******************************************************************************/
3630 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3633 classinfo *sysclass, *propclass;
3634 java_objectheader *sysprop;
3637 CHECK_PHASE(JVMTI_PHASE_START)
3640 if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3641 if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3643 sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3644 if (!sysclass) throw_main_exception_exit();
3646 mid = (jmethodID)class_resolvemethod(sysclass,
3647 utf_new_char("getProperties"),
3648 utf_new_char("()Ljava/util/Properties;"));
3649 if (!mid) throw_main_exception_exit();
3651 sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3653 propclass = sysprop->vftbl->class;
3655 mid = (jmethodID)class_resolvemethod(propclass,
3656 utf_new_char("setProperty"),
3657 utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3658 if (!mid) throw_main_exception_exit();
3660 _Jv_JNINativeInterface.CallObjectMethod(
3661 NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
3663 return JVMTI_ERROR_NONE;
3666 /* GetPhase ********************************************************************
3668 Return the current phase of VM execution
3670 *******************************************************************************/
3673 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3675 if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3679 return JVMTI_ERROR_NONE;
3682 /* GetCurrentThreadCpuTimerInfo ************************************************
3686 *******************************************************************************/
3689 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3692 CHECK_PHASE(JVMTI_PHASE_START)
3693 CHECK_PHASE(JVMTI_PHASE_LIVE)
3695 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3697 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3699 return JVMTI_ERROR_NONE;
3702 /* GetCurrentThreadCpuTime ****************************************************
3706 *******************************************************************************/
3709 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3712 CHECK_PHASE(JVMTI_PHASE_START)
3713 CHECK_PHASE(JVMTI_PHASE_LIVE)
3715 CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
3717 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3718 return JVMTI_ERROR_NONE;
3721 /* GetThreadCpuTimerInfo ******************************************************
3725 *******************************************************************************/
3728 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3731 CHECK_PHASE(JVMTI_PHASE_START)
3732 CHECK_PHASE(JVMTI_PHASE_LIVE)
3734 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3736 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3737 return JVMTI_ERROR_NONE;
3740 /* GetThreadCpuTime ***********************************************************
3744 *******************************************************************************/
3747 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3750 CHECK_PHASE(JVMTI_PHASE_LIVE)
3752 CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3753 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3754 return JVMTI_ERROR_NONE;
3757 /* GetTimerInfo ***************************************************************
3759 Get information about the GetTime timer.
3761 *******************************************************************************/
3764 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3766 if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3768 info_ptr->max_value = !0x0;
3769 info_ptr->may_skip_forward = true;
3770 info_ptr->may_skip_backward = true;
3771 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3773 return JVMTI_ERROR_NONE;
3776 /* GetTime ********************************************************************
3778 Return the current value of the system timer, in nanoseconds
3780 *******************************************************************************/
3783 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3785 /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3788 if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3790 if (gettimeofday (&tp, NULL) == -1)
3791 _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
3793 *nanos_ptr = (jlong) tp.tv_sec;
3795 *nanos_ptr += (tp.tv_usec / 1000);
3797 return JVMTI_ERROR_NONE;
3800 /* GetPotentialCapabilities ***************************************************
3802 Returns the JVM TI features that can potentially be possessed by this
3803 environment at this time.
3805 *******************************************************************************/
3808 GetPotentialCapabilities (jvmtiEnv * env,
3809 jvmtiCapabilities * capabilities_ptr)
3812 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3813 CHECK_PHASE(JVMTI_PHASE_LIVE)
3816 if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3818 memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3820 return JVMTI_ERROR_NONE;
3824 #define CHECK_ADD_CAPABILITY(env,CAN) \
3825 if ((capabilities_ptr->CAN == 1) && \
3826 (JVMTI_Capabilities.CAN == 0)) \
3827 return JVMTI_ERROR_NOT_AVAILABLE; \
3828 env->capabilities.CAN = 1;
3830 /* AddCapabilities ************************************************************
3832 Set new capabilities by adding the capabilities pointed to by
3833 capabilities_ptr. All previous capabilities are retained.
3835 *******************************************************************************/
3838 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3840 environment* cacao_env;
3843 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3844 CHECK_PHASE(JVMTI_PHASE_LIVE)
3847 if ((env == NULL) || (capabilities_ptr == NULL))
3848 return JVMTI_ERROR_NULL_POINTER;
3850 cacao_env = (environment*)env;
3852 CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3853 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3854 CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3855 CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3856 CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3857 CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3858 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3859 CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3860 CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3861 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3862 CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3863 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3864 CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3865 CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3866 CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3867 CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3868 CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3869 CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3870 CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3871 CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3872 CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3873 CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3874 CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3875 CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3876 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3877 CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3878 CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3879 CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3880 CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3881 CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3882 CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3883 CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3884 CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3887 return JVMTI_ERROR_NONE;
3891 #define CHECK_DEL_CAPABILITY(env,CAN) \
3892 if (capabilities_ptr->CAN == 1) \
3893 env->capabilities.CAN = 0;
3895 /* RelinquishCapabilities *****************************************************
3897 Relinquish the capabilities pointed to by capabilities_ptr.
3899 *******************************************************************************/
3902 RelinquishCapabilities (jvmtiEnv * env,
3903 const jvmtiCapabilities * capabilities_ptr)
3905 environment* cacao_env;
3908 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3909 CHECK_PHASE(JVMTI_PHASE_LIVE)
3912 if ((env == NULL) || (capabilities_ptr == NULL))
3913 return JVMTI_ERROR_NULL_POINTER;
3915 cacao_env = (environment*)env;
3917 CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3918 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3919 CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3920 CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3921 CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3922 CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3923 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3924 CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3925 CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3926 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3927 CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3928 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3929 CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3930 CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3931 CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3932 CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3933 CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3934 CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3935 CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3936 CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3937 CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3938 CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3939 CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3940 CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3941 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3942 CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3943 CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3944 CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3945 CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3946 CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3947 CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3948 CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3949 CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3951 return JVMTI_ERROR_NONE;
3954 /* *****************************************************************************
3958 *******************************************************************************/
3961 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3964 CHECK_PHASE(JVMTI_PHASE_START)
3965 CHECK_PHASE(JVMTI_PHASE_LIVE)
3968 if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3970 log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3972 *processor_count_ptr = 1; /* where do I get this ?*/
3974 return JVMTI_ERROR_NONE;
3977 /* GetEnvironmentLocalStorage **************************************************
3979 Called by the agent to get the value of the JVM TI environment-local storage.
3981 *******************************************************************************/
3984 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
3986 if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
3988 *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
3990 return JVMTI_ERROR_NONE;
3993 /* SetEnvironmentLocalStorage **************************************************
3995 The VM stores a pointer value associated with each environment. Agents can
3996 allocate memory in which they store environment specific information.
3998 *******************************************************************************/
4001 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
4003 if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
4005 ((environment*)env)->EnvironmentLocalStorage = (void*) data;
4007 return JVMTI_ERROR_NONE;
4010 /* AddToBootstrapClassLoaderSearch ********************************************
4012 After the bootstrap class loader unsuccessfully searches for a class, the
4013 specified platform-dependent search path segment will be searched as well.
4015 *******************************************************************************/
4018 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
4024 CHECK_PHASE(JVMTI_PHASE_ONLOAD)
4027 if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
4029 ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
4030 tmp_bcp = MNEW(char, ln);
4031 strcat(tmp_bcp, bootclasspath);
4032 strcat(tmp_bcp, ":");
4033 strcat(tmp_bcp, segment);
4034 MFREE(bootclasspath,char,ln);
4035 bootclasspath = tmp_bcp;
4037 return JVMTI_ERROR_NONE;
4040 /* SetVerboseFlag *************************************************************
4042 Control verbose output. This is the output which typically is sent to stderr
4044 *******************************************************************************/
4047 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
4050 case JVMTI_VERBOSE_OTHER:
4051 /* where is this defined ?
4055 case JVMTI_VERBOSE_GC:
4056 opt_verbosegc = value;
4058 case JVMTI_VERBOSE_CLASS:
4059 loadverbose = value;
4061 case JVMTI_VERBOSE_JNI:
4064 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
4066 return JVMTI_ERROR_NONE;
4069 /* GetObjectSize **************************************************************
4071 For the object object return the size.
4073 *******************************************************************************/
4076 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
4079 CHECK_PHASE(JVMTI_PHASE_START)
4080 CHECK_PHASE(JVMTI_PHASE_LIVE)
4083 if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
4084 if (!builtin_instanceof(object,class_java_lang_Object))
4085 return JVMTI_ERROR_INVALID_OBJECT;
4087 *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
4089 return JVMTI_ERROR_NONE;
4093 /* *****************************************************************************
4095 Environment variables
4097 *******************************************************************************/
4099 static jvmtiCapabilities JVMTI_Capabilities = {
4100 0, /* can_tag_objects */
4101 0, /* can_generate_field_modification_events */
4102 0, /* can_generate_field_access_events */
4103 1, /* can_get_bytecodes */
4104 0, /* can_get_synthetic_attribute */
4106 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4107 1, /* can_get_owned_monitor_info */
4108 1, /* can_get_current_contended_monitor */
4110 0, /* can_get_owned_monitor_info */
4111 0, /* can_get_current_contended_monitor */
4114 0, /* can_get_monitor_info */
4115 0, /* can_pop_frame */
4116 0, /* can_redefine_classes */
4117 0, /* can_signal_thread */
4118 1, /* can_get_source_file_name */
4119 1, /* can_get_line_numbers */
4120 0, /* can_get_source_debug_extension */
4121 0, /* can_access_local_variables */
4122 0, /* can_maintain_original_method_order */
4123 0, /* can_generate_single_step_events */
4124 0, /* can_generate_exception_events */
4125 0, /* can_generate_frame_pop_events */
4126 0, /* can_generate_breakpoint_events */
4127 0, /* can_suspend */
4128 0, /* can_redefine_any_class */
4129 0, /* can_get_current_thread_cpu_time */
4130 0, /* can_get_thread_cpu_time */
4131 0, /* can_generate_method_entry_events */
4132 0, /* can_generate_method_exit_events */
4133 0, /* can_generate_all_class_hook_events */
4134 0, /* can_generate_compiled_method_load_events */
4135 0, /* can_generate_monitor_events */
4136 0, /* can_generate_vm_object_alloc_events */
4137 0, /* can_generate_native_method_bind_events */
4138 0, /* can_generate_garbage_collection_events */
4139 0, /* can_generate_object_free_events */
4142 static struct jvmtiEnv_struct JVMTI_EnvTable = {
4144 &SetEventNotificationMode,
4152 &GetOwnedMonitorInfo,
4153 &GetCurrentContendedMonitor,
4155 &GetTopThreadGroups,
4156 &GetThreadGroupInfo,
4157 &GetThreadGroupChildren,
4179 &RawMonitorNotifyAll,
4183 &SetFieldAccessWatch,
4184 &ClearFieldAccessWatch,
4185 &SetFieldModificationWatch,
4186 &ClearFieldModificationWatch,
4196 &GetImplementedInterfaces,
4201 &GetObjectMonitorUsage,
4203 &GetFieldDeclaringClass,
4207 &GetMethodDeclaringClass,
4208 &GetMethodModifiers,
4212 &GetLineNumberTable,
4214 &GetLocalVariableTable,
4221 &GetClassLoaderClasses,
4232 &GetSourceDebugExtension,
4243 &GetThreadListStackTraces,
4244 &GetThreadLocalStorage,
4245 &SetThreadLocalStorage,
4250 &ForceGarbageCollection,
4251 &IterateOverObjectsReachableFromObject,
4252 &IterateOverReachableObjects,
4254 &IterateOverInstancesOfClass,
4256 &GetObjectsWithTags,
4262 &SetJNIFunctionTable,
4263 &GetJNIFunctionTable,
4266 &GetExtensionFunctions,
4267 &GetExtensionEvents,
4268 &SetExtensionEventCallback,
4269 &DisposeEnvironment,
4271 &GetJLocationFormat,
4272 &GetSystemProperties,
4276 &GetCurrentThreadCpuTimerInfo,
4277 &GetCurrentThreadCpuTime,
4278 &GetThreadCpuTimerInfo,
4282 &GetPotentialCapabilities,
4285 &RelinquishCapabilities,
4286 &GetAvailableProcessors,
4289 &GetEnvironmentLocalStorage,
4290 &SetEnvironmentLocalStorage,
4291 &AddToBootstrapClassLoaderSearch,
4300 void set_jvmti_phase(jvmtiPhase p) {
4303 fprintf (stderr,"set JVMTI phase %d\n",p);
4307 case JVMTI_PHASE_ONLOAD:
4310 case JVMTI_PHASE_PRIMORDIAL:
4313 case JVMTI_PHASE_START:
4315 d.ev = JVMTI_EVENT_VM_START;
4316 /* this event is sent during start or live phase */
4317 log_text("set sysbrk in setthreadobj");
4318 setsysbrkpt(SETTHREADOBJECTBRK,(void*)&setthreadobject);
4320 case JVMTI_PHASE_LIVE:
4322 d.ev = JVMTI_EVENT_VM_INIT;
4324 case JVMTI_PHASE_DEAD:
4326 d.ev = JVMTI_EVENT_VM_DEATH;
4329 log_text("wrong jvmti phase to be set");
4336 jvmtiEnv* new_jvmtienv() {
4342 envs = heap_allocate(sizeof(environment),true,NULL);
4346 while (env->next != NULL) env = env->next;
4347 env->next = heap_allocate(sizeof(environment),true,NULL);
4351 env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
4352 memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
4353 memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4354 sizeof(jvmtiEventModeLL));
4355 /* To possess a capability, the agent must add the capability.*/
4356 memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
4357 RelinquishCapabilities(&(env->env),&(env->capabilities));
4358 env->EnvironmentLocalStorage = NULL;
4361 /* start new cacaodbgserver if needed*/
4362 pthread_mutex_lock(&dbgcomlock);
4363 if (dbgcom == NULL) {
4364 dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);
4365 dbgcom->running = 1;
4366 dbgcom->breakpointhandler = (void*)cacaobreakpointhandler;
4368 if (dbgserver == (-1)) {
4369 log_text("cacaodbgserver fork error");
4372 if (dbgserver == 0) {
4373 comaddr = MNEW(char,11);
4374 snprintf(comaddr,11,"%p",dbgcom);
4375 if (execlp("cacaodbgserver","cacaodbgserver",comaddr,(char *) NULL) == -1) {
4376 log_text("unable to execute cacaodbgserver");
4384 pthread_mutex_unlock(&dbgcomlock);
4388 return (jvmtiEnv*)env;
4391 void agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
4398 len = strlen(opt_arg);
4400 /* separate argumtents */
4401 while ((opt_arg[i]!='=')&&(i<=len)) i++;
4406 *libname=heap_allocate(sizeof(char)*i,true,NULL);
4407 strncpy(*libname,opt_arg,i-1);
4408 (*libname)[i-1]='\0';
4411 *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
4412 strncpy(*libname,"lib",3);
4413 strncpy(&(*libname)[3],opt_arg,i-1);
4414 strncpy(&(*libname)[i+2],".so",3);
4417 /* try to open the library */
4419 if (!(*handle = lt_dlopen(*libname))) {
4420 fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
4424 /* resolve Agent_OnLoad function */
4425 if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
4426 fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
4430 /* resolve Agent_UnLoad function */
4431 unload = lt_dlsym(*handle, "Agent_Unload");
4434 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4435 onload) ((JavaVM *) _Jv_jvm, arg, NULL);
4437 if (retval != 0) exit (retval);
4440 void agentunload() {
4441 if (unload != NULL) {
4442 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
4443 ((JavaVM*) &_Jv_JNIInvokeInterface);
4448 * These are local overrides for various environment variables in Emacs.
4449 * Please do not remove this and leave it at the end of the file, where
4450 * Emacs will automagically detect them.
4451 * ---------------------------------------------------------------------
4454 * indent-tabs-mode: t
4458 * vim:noexpandtab:sw=4:ts=4: