91312887a4d95ceccf08199324c6b3167a69333c
[cacao.git] / src / native / jvmti / jvmti.c
1 /* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine Tool 
2                               Interface functions
3
4    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
5    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
6    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
7    Institut f. Computersprachen - TU Wien
8
9    This file is part of CACAO.
10
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.
15
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.
20
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., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Author: Martin Platter
29
30    Changes:             
31
32    
33    $Id: jvmti.c 3588 2005-11-06 14:01:10Z motse $
34
35 */
36
37 #include <assert.h>
38
39 #include "native/jni.h"
40 #include "native/jvmti/jvmti.h"
41 #include "vm/global.h"
42 #include "vm/loader.h"
43 #include "vm/builtin.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/classcache.h"
46 #include "mm/boehm.h"
47 #include "toolbox/logging.h"
48 #include "vm/options.h"
49 #include "cacao/cacao.h"
50 #include "vm/stringlocal.h"
51 #include "mm/memory.h"
52 #include "threads/native/threads.h"
53 #include "vm/exceptions.h"
54 #include "native/include/java_util_Vector.h"
55 #include "native/include/java_io_PrintStream.h"
56 #include "native/include/java_io_InputStream.h"
57 #include "native/include/java_lang_Cloneable.h"
58 #include "native/include/java_lang_ThreadGroup.h"
59 #include "native/include/java_lang_VMObject.h"
60 #include "native/include/java_lang_VMSystem.h"
61 #include "native/include/java_lang_VMClass.h"
62 #include "vm/jit/stacktrace.h"
63
64 #include <string.h>
65 #include <linux/unistd.h>
66 #include <sys/time.h>
67 #include "toolbox/logging.h"
68 #include <stdlib.h>
69 #include <sys/types.h>
70 #include <sys/wait.h>
71 #include <signal.h>
72 #include <ltdl.h>
73
74 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
75 #include "threads/native/threads.h"
76 #include <sched.h>
77 #include <pthread.h>
78 #endif 
79
80 #include "dbg.h"
81
82 typedef struct _environment environment;
83 environment *envs=NULL;
84
85 extern const struct JNIInvokeInterface JNI_JavaVMTable;
86
87 static jvmtiPhase phase; 
88 typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
89 struct _jvmtiEventModeLL {
90         jvmtiEventMode mode;
91         jthread event_thread;
92         jvmtiEventModeLL *next;
93 };
94
95 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
96 struct _jvmtiThreadLocalStorage{
97         jthread thread;
98         jvmtiThreadLocalStorage *next;
99         void *data;
100 };
101
102 struct _environment {
103     jvmtiEnv env;
104     jvmtiEventCallbacks callbacks;
105     /* table for enabled/disabled jvmtiEvents - first element contains global 
106            behavior */
107     jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM]; 
108     jvmtiCapabilities capabilities;
109     void *EnvironmentLocalStorage;
110         jvmtiThreadLocalStorage *tls;
111         environment *next;
112 };
113
114
115 static jvmtiEnv JVMTI_EnvTable;
116 static jvmtiCapabilities JVMTI_Capabilities;
117 static lt_ptr unload;
118
119 #define CHECK_PHASE_START  if (!(0 
120 #define CHECK_PHASE(chkphase) || (phase == chkphase)
121 #define CHECK_PHASE_END  )) return JVMTI_ERROR_WRONG_PHASE
122 #define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
123                                      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
124 #define CHECK_THREAD_IS_ALIVE(t) if((((java_lang_Thread*)t)->vmThread==NULL)&& \
125                                     (((java_lang_Thread*)t)->group==NULL)) \
126                                         return JVMTI_ERROR_THREAD_NOT_ALIVE;
127
128
129
130 static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
131         JNIEnv* jni_env = ptr_env;
132
133         switch (e) {
134         case JVMTI_EVENT_VM_INIT:
135     case JVMTI_EVENT_THREAD_START:
136     case JVMTI_EVENT_THREAD_END: 
137                 ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
138                 break;
139
140
141     case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
142                 ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env, 
143                                                                                    jni_env, 
144                                                                                    data->klass,
145                                                                                    data->object,
146                                                                                    data->name,
147                                                                                    data->protection_domain,
148                                                                                    data->jint1,
149                                                                                    data->class_data,
150                                                                                    data->new_class_data_len,
151                                                                                    data->new_class_data);
152                 break;
153
154
155     case JVMTI_EVENT_CLASS_PREPARE: 
156     case JVMTI_EVENT_CLASS_LOAD:
157                 ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env, 
158                                                                    data->thread, data->klass);
159                 break;
160
161     case JVMTI_EVENT_VM_DEATH:
162     case JVMTI_EVENT_VM_START: 
163                 ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
164                 break;
165
166     case JVMTI_EVENT_EXCEPTION:
167                 ((jvmtiEventException)ec) (data->jvmti_env, jni_env, 
168                                                                    data->thread, 
169                                                                    data->method, 
170                                                                    data->location,
171                                                                    data->object,
172                                                                    data->catch_method,
173                                                                    data->catch_location);
174                 break;
175                 
176     case JVMTI_EVENT_EXCEPTION_CATCH:
177                 ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env, 
178                                                                                 data->thread, 
179                                                                                 data->method, 
180                                                                                 data->location,
181                                                                                 data->object);
182                 break;
183
184     case JVMTI_EVENT_BREAKPOINT:
185     case JVMTI_EVENT_SINGLE_STEP: 
186                 ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env, 
187                                                                         data->thread, 
188                                                                         data->method, 
189                                                                         data->location);
190                 break;
191
192     case JVMTI_EVENT_FRAME_POP:
193                 ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env, 
194                                                                   data->thread, 
195                                                                   data->method, 
196                                                                   data->b);
197                 break;
198
199     case JVMTI_EVENT_FIELD_ACCESS: 
200                 ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env, 
201                                                                          data->thread, 
202                                                                          data->method, 
203                                                                          data->location,
204                                                                          data->klass,
205                                                                          data->object,
206                                                                          data->field);
207                 break;
208
209     case JVMTI_EVENT_FIELD_MODIFICATION:
210                 ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env, 
211                                                                                    data->thread, 
212                                                                                    data->method, 
213                                                                                    data->location,
214                                                                                    data->klass,
215                                                                                    data->object,
216                                                                                    data->field,
217                                                                                    data->signature_type,
218                                                                                    data->value);
219                 break;
220
221     case JVMTI_EVENT_METHOD_ENTRY:
222                 ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env, 
223                                                                          data->thread, 
224                                                                          data->method);
225                 break;
226
227     case JVMTI_EVENT_METHOD_EXIT: 
228                 ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env, 
229                                                                         data->thread, 
230                                                                         data->method,
231                                                                         data->b,
232                                                                         data->value);
233                 break;
234
235     case JVMTI_EVENT_NATIVE_METHOD_BIND:
236                 ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env, 
237                                                                                   data->thread, 
238                                                                                   data->method,
239                                                                                   data->address,
240                                                                                   data->new_address_ptr);
241                 break;
242
243     case JVMTI_EVENT_COMPILED_METHOD_LOAD:
244                 ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env, 
245                                                                                         data->method,
246                                                                                         data->jint1,
247                                                                                         data->address,
248                                                                                         data->jint2,
249                                                                                         data->map,
250                                                                                         data->compile_info);
251                 break;
252                 
253     case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
254                 ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
255                                                                                           data->method,
256                                                                                           data->address);
257                 break;
258
259     case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
260                 ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
261                                                                                           data->name,
262                                                                                           data->address,
263                                                                                           data->jint1);
264                 break;
265
266     case JVMTI_EVENT_GARBAGE_COLLECTION_START:
267     case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
268     case JVMTI_EVENT_DATA_DUMP_REQUEST: 
269                 ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
270                 break;
271
272     case JVMTI_EVENT_MONITOR_WAIT:
273                 ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env, 
274                                                                          data->thread, 
275                                                                          data->object,
276                                                                          data->jlong);
277                 break;
278
279     case JVMTI_EVENT_MONITOR_WAITED:
280                 ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env, 
281                                                                            data->thread, 
282                                                                            data->object,
283                                                                            data->b);
284                 break;
285
286
287     case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
288     case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
289                 ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env, 
290                                                                                            data->thread, 
291                                                                                            data->object);
292                 break;
293
294     case JVMTI_EVENT_OBJECT_FREE: 
295                 ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
296                 break;
297
298     case JVMTI_EVENT_VM_OBJECT_ALLOC:
299                 ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env, 
300                                                                            data->thread, 
301                                                                            data->object,
302                                                                            data->klass,
303                                                                            data->jlong);
304                 break;
305
306
307         default:
308                 log_text ("unknown event");
309         }
310 }
311
312 /* fireEvent **************************************************************
313
314    fire event callback with data arguments.
315
316 *******************************************************************************/
317
318 void fireEvent(jvmtiEvent e, genericEventData* data) {
319         environment* env;
320         jvmtiEventModeLL *evm;
321         jthread thread;
322
323         functionptr ec;
324     /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
325
326         thread = (jthread)THREADOBJECT;
327
328         data->thread = thread;
329
330         env = envs;
331         while (env!=NULL) {
332
333                 if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
334                         evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
335             /* test if the event is enable for some threads */
336                         while (evm!=NULL) { 
337                                 if (evm->mode == JVMTI_ENABLE) {
338                                         data->jvmti_env=&env->env;
339                                         ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
340                                         execcallback(e, ec, data);
341                                 }
342                                 evm=evm->next;
343                         }
344                 } else { /* event enabled globally */
345                         data->jvmti_env=&env->env;
346                         ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
347                         execcallback(e, ec, data);
348                 }
349                 
350                 env=env->next;
351         }
352 }
353
354
355
356 /* getchildproc ***************************************************************
357
358    Get data from child process
359
360 *******************************************************************************/
361 static long getchildproc (void *ptr) {
362         if (debuggee > 0) {
363         /* get data from child process */
364                 return GETMEM(debuggee,ptr);
365         } else {
366                 return *((long*)ptr);
367         }
368 }
369
370
371
372 /* SetEventNotificationMode ****************************************************
373
374    Control the generation of events
375
376 *******************************************************************************/
377
378 jvmtiError
379 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
380                           jvmtiEvent event_type, jthread event_thread, ...)
381 {
382         environment* cacao_env;
383         jvmtiEventModeLL *ll;
384
385     CHECK_PHASE_START
386     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
387     CHECK_PHASE(JVMTI_PHASE_LIVE)
388     CHECK_PHASE_END;
389
390         if((event_thread != NULL)&&
391            (!builtin_instanceof(event_thread,class_java_lang_Thread))) 
392                 return JVMTI_ERROR_INVALID_THREAD;
393
394         CHECK_THREAD_IS_ALIVE(event_thread);
395         
396         cacao_env = (environment*) env;    
397         if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
398                 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
399
400         if ((event_type < JVMTI_EVENT_START_ENUM) ||
401                 (event_type > JVMTI_EVENT_END_ENUM))
402                 return JVMTI_ERROR_INVALID_EVENT_TYPE;
403         
404         
405         switch (event_type) { /* check capability */
406     case JVMTI_EVENT_EXCEPTION:
407         case JVMTI_EVENT_EXCEPTION_CATCH:
408                 CHECK_CAPABILITY(env,can_generate_exception_events)
409                 break;
410     case JVMTI_EVENT_SINGLE_STEP:
411                 CHECK_CAPABILITY(env,can_generate_single_step_events)
412                 break;
413     case JVMTI_EVENT_FRAME_POP:
414                 CHECK_CAPABILITY(env,can_generate_frame_pop_events)
415                 break;
416     case JVMTI_EVENT_BREAKPOINT:
417                 CHECK_CAPABILITY(env,can_generate_breakpoint_events)
418                 break;
419     case JVMTI_EVENT_FIELD_ACCESS:
420                 CHECK_CAPABILITY(env,can_generate_field_access_events)
421                 break;
422     case JVMTI_EVENT_FIELD_MODIFICATION:
423                 CHECK_CAPABILITY(env,can_generate_field_modification_events)
424                 break;
425     case JVMTI_EVENT_METHOD_ENTRY:
426                 CHECK_CAPABILITY(env,can_generate_method_entry_events)
427                 break;
428     case JVMTI_EVENT_METHOD_EXIT:
429                 CHECK_CAPABILITY(env, can_generate_method_exit_events)
430                 break;
431     case JVMTI_EVENT_NATIVE_METHOD_BIND:
432                 CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
433                 break;
434     case JVMTI_EVENT_COMPILED_METHOD_LOAD:
435     case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
436                 CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
437                 break;
438     case JVMTI_EVENT_MONITOR_WAIT:
439     case JVMTI_EVENT_MONITOR_WAITED:
440     case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
441     case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
442                 CHECK_CAPABILITY(env,can_generate_monitor_events)
443                 break;
444     case JVMTI_EVENT_GARBAGE_COLLECTION_START:
445         case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
446                 CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
447                 break;
448     case JVMTI_EVENT_OBJECT_FREE:
449                 CHECK_CAPABILITY(env,can_generate_object_free_events)
450                 break;
451     case JVMTI_EVENT_VM_OBJECT_ALLOC:
452                 CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
453                 break;
454         default:
455                 /* all other events are required */
456                 break;
457         }
458
459         if (event_thread != NULL) {
460                 /* thread level control */
461                 if ((JVMTI_EVENT_VM_INIT == mode) ||
462                         (JVMTI_EVENT_VM_DEATH == mode) ||
463                         (JVMTI_EVENT_VM_START == mode) ||
464                         (JVMTI_EVENT_THREAD_START == mode) ||
465                         (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
466                         (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
467                         (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
468                         (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
469                         return JVMTI_ERROR_ILLEGAL_ARGUMENT;
470                 ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
471                 while (ll->next != NULL) {
472                         ll = ll->next;
473                         if (ll->event_thread == event_thread) {
474                                 ll->mode=mode;
475                                 return JVMTI_ERROR_NONE;
476                         }
477                 }
478                 ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
479                 ll->next->mode=mode;            
480         } else {
481                 /* global control */
482                 cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
483         }
484
485         
486     return JVMTI_ERROR_NONE;
487 }
488
489
490 /* GetAllThreads ***************************************************************
491
492    Get all live threads
493
494 *******************************************************************************/
495
496 jvmtiError
497 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
498                jthread ** threads_ptr)
499 {
500     int i = 0; 
501     threadobject* thread;
502
503     CHECK_PHASE_START
504     CHECK_PHASE(JVMTI_PHASE_LIVE)
505     CHECK_PHASE_END;
506
507     if ((threads_count_ptr == NULL) || (threads_ptr == NULL)) 
508         return JVMTI_ERROR_NULL_POINTER;
509
510 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
511     thread = mainthreadobj;
512     do {
513         if((thread->o.thread->vmThread==NULL)&& (thread->o.thread->group==NULL)) 
514                    i++; /* count only live threads */
515                    thread = thread->info.prev;
516         } while (thread != mainthreadobj);
517     
518     *threads_count_ptr = i;
519         
520     *threads_ptr = (jthread*) heap_allocate(sizeof(jthread) * i,true,NULL);
521     i=0;
522     do {
523         memcpy(*threads_ptr[i],thread,sizeof(jthread));
524         thread = thread->info.prev;
525         i++;
526     } while (thread != mainthreadobj);
527 #else
528         return JVMTI_ERROR_NOT_AVAILABLE;
529 #endif
530
531     return JVMTI_ERROR_NONE;
532 }
533
534
535 /* SuspendThread ***************************************************************
536
537    Suspend specified thread
538
539 *******************************************************************************/
540
541 jvmtiError
542 SuspendThread (jvmtiEnv * env, jthread thread)
543 {
544         CHECK_PHASE_START
545         CHECK_PHASE(JVMTI_PHASE_LIVE)
546         CHECK_PHASE_END;
547     CHECK_CAPABILITY(env,can_suspend)
548     
549 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
550         suspendThread((thread *) thread->thread);
551 #endif
552
553     return JVMTI_ERROR_NONE;
554 }
555
556 /* ResumeThread ***************************************************************
557
558    Resume a suspended thread
559
560 *******************************************************************************/
561
562 jvmtiError
563 ResumeThread (jvmtiEnv * env, jthread thread)
564 {
565     CHECK_PHASE_START
566     CHECK_PHASE(JVMTI_PHASE_LIVE)
567     CHECK_PHASE_END;
568     CHECK_CAPABILITY(env,can_suspend)
569
570 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
571         resumeThread((thread *) this->thread);
572 #endif
573
574     return JVMTI_ERROR_NONE;
575 }
576
577 /* StopThread *****************************************************************
578
579    Send asynchronous exception to the specified thread. Similar to 
580    java.lang.Thread.stop(). Used to kill thread.
581
582 *******************************************************************************/
583
584 jvmtiError
585 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
586 {
587         CHECK_PHASE_START
588     CHECK_PHASE(JVMTI_PHASE_LIVE)
589     CHECK_PHASE_END;
590     CHECK_CAPABILITY(env,can_signal_thread)
591         
592   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
593     return JVMTI_ERROR_NONE;
594 }
595
596 /* InterruptThread ************************************************************
597
598    Interrupt specified thread. Similar to java.lang.Thread.interrupt()
599
600 *******************************************************************************/
601
602 jvmtiError
603 InterruptThread (jvmtiEnv * env, jthread thread)
604 {
605         CHECK_PHASE_START
606     CHECK_PHASE(JVMTI_PHASE_LIVE)
607     CHECK_PHASE_END;
608     CHECK_CAPABILITY(env,can_signal_thread)
609
610         if(!builtin_instanceof(thread,class_java_lang_Thread))
611                 return JVMTI_ERROR_INVALID_THREAD;
612
613         CHECK_THREAD_IS_ALIVE(thread);        
614
615 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
616         interruptThread((java_lang_VMThread*)thread);
617 #else
618         return JVMTI_ERROR_NOT_AVAILABLE;
619 #endif
620
621     return JVMTI_ERROR_NONE;
622 }
623
624 /* GetThreadInfo ***************************************************************
625
626    Get thread information. Details of the specified thread are stored in the 
627    jvmtiThreadInfo structure.
628
629 *******************************************************************************/
630
631 jvmtiError
632 GetThreadInfo (jvmtiEnv * env, jthread th, jvmtiThreadInfo * info_ptr)
633 {
634         java_lang_Thread* t = (java_lang_Thread*)th;
635         int size;
636         char* name;
637
638     CHECK_PHASE_START
639     CHECK_PHASE(JVMTI_PHASE_LIVE)
640     CHECK_PHASE_END;
641         
642         name = javastring_tochar((java_objectheader*)t->name);
643         size = strlen(name);
644         info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
645         strncpy(info_ptr->name,name,size);
646         info_ptr->priority=(jint)t->priority;
647         info_ptr->is_daemon=(jboolean)t->daemon;
648         info_ptr->thread_group=(jthreadGroup)t->group;
649         info_ptr->context_class_loader=(jobject)t->contextClassLoader;
650
651     return JVMTI_ERROR_NONE;
652 }
653
654 /* GetOwnedMonitorInfo *********************************************************
655
656    Get information about the monitors owned by the specified thread
657
658 *******************************************************************************/
659
660 jvmtiError
661 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
662                      jint * owned_monitor_count_ptr,
663                      jobject ** owned_monitors_ptr)
664 {
665         int i,j,size=20;
666         jobject* om;
667         lockRecordPool* lrp;
668
669         CHECK_PHASE_START
670     CHECK_PHASE(JVMTI_PHASE_LIVE)
671     CHECK_PHASE_END;
672     CHECK_CAPABILITY(env,can_get_owned_monitor_info);
673
674         if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL)) 
675                 return JVMTI_ERROR_NULL_POINTER;
676
677         if(!builtin_instanceof(thread,class_java_lang_Thread))
678                 return JVMTI_ERROR_INVALID_THREAD;
679
680         CHECK_THREAD_IS_ALIVE(thread);
681
682 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
683
684         om=MNEW(java_objectheader*,size);
685
686         pthread_mutex_lock(&pool_lock);
687
688         lrp=global_pool;
689
690         while (lrp != NULL) {
691                 for (j=0; j<lrp->header.size; j++) {
692                         if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
693                            (!lrp->lr[j].waiting)) {
694                                 if (i>=size) {
695                                         MREALLOC(om,java_objectheader*,size,size*2);
696                                         size=size*2;
697                                 }
698                                 om[i]=lrp->lr[j].o;
699                                 i++;
700                         }
701                 }
702                 lrp=lrp->header.next;
703         }
704
705         pthread_mutex_unlock(&pool_lock);
706
707         *owned_monitors_ptr     = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
708         memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
709         MFREE(om,java_objectheader*,size);
710
711         *owned_monitor_count_ptr = i;
712
713 #endif
714
715     return JVMTI_ERROR_NONE;
716 }
717
718 /* GetCurrentContendedMonitor *************************************************
719
720    Get the object the specified thread waits for.
721
722 *******************************************************************************/
723
724 jvmtiError
725 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
726                             jobject * monitor_ptr)
727 {
728         int j;
729         lockRecordPool* lrp;
730         java_objectheader* monitor;
731
732         CHECK_PHASE_START
733     CHECK_PHASE(JVMTI_PHASE_LIVE)
734     CHECK_PHASE_END;
735         CHECK_CAPABILITY(env, can_get_current_contended_monitor)
736         
737         if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
738         *monitor_ptr=NULL;
739
740         if(!builtin_instanceof(thread,class_java_lang_Thread))
741                 return JVMTI_ERROR_INVALID_THREAD;
742
743         CHECK_THREAD_IS_ALIVE(thread);
744
745
746 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
747
748         pthread_mutex_lock(&pool_lock);
749
750         lrp=global_pool;
751
752         while ((lrp != NULL)&&(monitor==NULL)) {
753                 for (j=0; j<lrp->header.size; j++) {
754                         if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
755                                 monitor=lrp->lr[j].o;
756                                 break;
757                         }
758                 }
759                 lrp=lrp->header.next;
760         }
761
762         pthread_mutex_unlock(&pool_lock);
763
764         if (monitor!=NULL) {
765                 *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
766                 *monitor_ptr = (jobject)monitor;
767         }
768
769 #endif
770     return JVMTI_ERROR_NONE;
771 }
772
773 typedef struct {
774         jvmtiStartFunction sf;
775         jvmtiEnv* jvmti_env;
776         void* arg;
777 } runagentparam;
778
779
780 static void *threadstartup(void *t) {
781         runagentparam *rap = (runagentparam*)t;
782         rap->sf(rap->jvmti_env,ptr_env,rap->arg);
783         return NULL;
784 }
785
786 /* RunAgentThread *************************************************************
787
788    Starts the execution of an agent thread of the specified native function 
789    within the specified thread
790
791 *******************************************************************************/
792
793 jvmtiError
794 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
795                 const void *arg, jint priority)
796 {
797         pthread_attr_t threadattr;
798         struct sched_param sp;
799         runagentparam rap;
800
801         CHECK_PHASE_START
802     CHECK_PHASE(JVMTI_PHASE_LIVE)
803     CHECK_PHASE_END;
804
805         if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread))) 
806                 return JVMTI_ERROR_INVALID_THREAD;
807         if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
808         if ((priority < JVMTI_THREAD_MIN_PRIORITY) || (priority > JVMTI_THREAD_MAX_PRIORITY)) 
809                 return JVMTI_ERROR_INVALID_PRIORITY;
810
811         rap.sf = proc;
812         rap.arg = (void*)arg;
813         rap.jvmti_env = env;
814
815 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
816         pthread_attr_init(&threadattr);
817         pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
818         if (priority == JVMTI_THREAD_MIN_PRIORITY) {
819                 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
820         }
821         if (priority == JVMTI_THREAD_MAX_PRIORITY) {
822                 sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
823         }
824         pthread_attr_setschedparam(&threadattr,&sp);
825         if (pthread_create(&((threadobject*) thread)->info.tid, &threadattr, &threadstartup, &rap)) {
826                 log_text("pthread_create failed");
827                 assert(0);
828         }
829 #endif
830
831     return JVMTI_ERROR_NONE;
832 }
833
834
835 /* GetTopThreadGroups *********************************************************
836
837    Get all top-level thread groups in the VM.
838
839 *******************************************************************************/
840
841 jvmtiError
842 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
843                     jthreadGroup ** groups_ptr)
844 {
845         jint threads_count_ptr;
846         threadobject *threads_ptr;
847         int i,j,x,size=20;
848         jthreadGroup **tg,*ttgp;
849
850     CHECK_PHASE_START
851     CHECK_PHASE(JVMTI_PHASE_LIVE)
852     CHECK_PHASE_END;
853
854     if ((groups_ptr == NULL) || (group_count_ptr == NULL)) 
855         return JVMTI_ERROR_NULL_POINTER;
856
857 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
858         tg = MNEW(jthreadGroup*,size);
859         x = 0;
860         if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
861                 return JVMTI_ERROR_INTERNAL;
862
863         for (i=0;i<threads_count_ptr;i++){
864                 if (threads_ptr[i].o.thread->group == NULL) {
865                         log_text("threadgroup not set");
866                         return JVMTI_ERROR_INTERNAL;
867                 }
868                 ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
869                 if (ttgp == NULL) {
870                         j=0;
871                         while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
872                                 j++;
873                         }
874
875                         if (j == x) {
876                                 if (x >= size){
877                                         MREALLOC(tg,jthreadGroup*,size,size*2);
878                                         size=size*2;
879                                 }
880                                 tg[x]=ttgp;
881                                 x++;
882                         }
883                 }
884         }
885
886         *groups_ptr     = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
887         memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
888         MFREE(tg,jthreadGroup*,size);
889
890         *group_count_ptr = x;
891
892 #else
893         return JVMTI_ERROR_NOT_AVAILABLE;
894 #endif
895     return JVMTI_ERROR_NONE;
896 }
897
898
899 /* GetThreadGroupInfo *********************************************************
900
901    Get information about the specified thread group.
902
903 *******************************************************************************/
904
905 jvmtiError
906 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
907                     jvmtiThreadGroupInfo * info_ptr)
908 {
909         int size;
910         char* name;
911         java_lang_ThreadGroup* grp;
912         
913         CHECK_PHASE_START
914     CHECK_PHASE(JVMTI_PHASE_LIVE)
915     CHECK_PHASE_END;
916         
917         if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
918         if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
919                 return JVMTI_ERROR_INVALID_THREAD_GROUP;
920
921         grp = (java_lang_ThreadGroup*)group;
922         
923         info_ptr->parent = (jthreadGroup) 
924                 Java_java_lang_VMObject_clone(NULL, 
925                                                                           (jclass)grp->header.vftbl->class,
926                                                                           (java_lang_Cloneable*) &grp->parent);
927
928         name = javastring_tochar((java_objectheader*)grp->name);
929         size = strlen(name);
930         info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
931         strncpy(info_ptr->name,name,size);
932         info_ptr->max_priority= (jint)grp->maxpri;
933         info_ptr->is_daemon= (jboolean)grp->daemon_flag;
934         
935     return JVMTI_ERROR_NONE;
936 }
937
938
939 /* GetThreadGroupChildren *****************************************************
940
941    Get the live threads and active subgroups in this thread group. 
942
943 *******************************************************************************/
944
945 jvmtiError
946 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
947                         jint * thread_count_ptr, jthread ** threads_ptr,
948                         jint * group_count_ptr, jthreadGroup ** groups_ptr)
949 {
950         java_lang_ThreadGroup* tgp;
951
952     CHECK_PHASE_START
953     CHECK_PHASE(JVMTI_PHASE_LIVE)
954     CHECK_PHASE_END;
955         
956         if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
957                 (group_count_ptr == NULL) || (groups_ptr == NULL)) 
958         return JVMTI_ERROR_NULL_POINTER;
959
960         if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
961                 return JVMTI_ERROR_INVALID_THREAD_GROUP;
962
963         tgp = (java_lang_ThreadGroup*)group;
964
965         *thread_count_ptr = (jint)tgp->threads->elementCount;
966
967         *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
968
969         memcpy(*threads_ptr, &tgp->threads->elementData, 
970                    (*thread_count_ptr)*sizeof(jthread*));
971
972         *group_count_ptr = (jint) tgp->groups->elementCount;
973
974         *groups_ptr     = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);    
975
976         memcpy(*groups_ptr, &tgp->threads->elementData,
977                    (*group_count_ptr)*sizeof(jthreadGroup*));
978
979     return JVMTI_ERROR_NONE;
980 }
981
982
983 /* getcacaostacktrace *********************************************************
984
985    Helper function that retrives stack trace for specified thread. 
986    Has to take care of suspend/resume issuses
987
988 *******************************************************************************/
989
990 static jvmtiError getcacaostacktrace(stackTraceBuffer** trace, jthread thread) {
991
992         /* todo: suspend specified thread */
993 /*      
994         if (!cacao_stacktrace_fillInStackTrace((void**)trace,&stackTraceCollector, (threadobject*)thread)) 
995                 return JVMTI_ERROR_INTERNAL;
996 */
997         /* todo: resume specified thread */
998         log_text("todo: stacktraces");
999     return JVMTI_ERROR_NONE;
1000 }
1001
1002
1003 /* GetFrameCount **************************************************************
1004
1005    Get the number of frames in the specified thread's stack.
1006
1007 *******************************************************************************/
1008
1009 jvmtiError
1010 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
1011 {
1012         stackTraceBuffer* trace;
1013         jvmtiError er;
1014
1015         CHECK_PHASE_START
1016     CHECK_PHASE(JVMTI_PHASE_LIVE)
1017     CHECK_PHASE_END;
1018     
1019         if(!builtin_instanceof(thread,class_java_lang_Thread))
1020                 return JVMTI_ERROR_INVALID_THREAD;
1021
1022         CHECK_THREAD_IS_ALIVE(thread);
1023         
1024         if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1025
1026         er = getcacaostacktrace(&trace, thread);
1027         if (er==JVMTI_ERROR_NONE) return er;
1028
1029         *count_ptr = trace->size;
1030
1031     return JVMTI_ERROR_NONE;
1032 }
1033
1034
1035 /* GetThreadState **************************************************************
1036
1037    Get the state of a thread. 
1038
1039 *******************************************************************************/
1040
1041 jvmtiError
1042 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
1043 {
1044         java_lang_Thread* th = (java_lang_Thread*)thread;
1045     CHECK_PHASE_START
1046     CHECK_PHASE(JVMTI_PHASE_LIVE)
1047     CHECK_PHASE_END;
1048         
1049         if(!builtin_instanceof(thread,class_java_lang_Thread))
1050                 return JVMTI_ERROR_INVALID_THREAD;
1051
1052         if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1053
1054         *thread_state_ptr = 0;
1055 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1056         if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
1057                 /* not alive */
1058                 if (((threadobject*)th->vmThread)->info.tid == 0)
1059                         *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
1060         } else {
1061                 /* alive */
1062                 *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
1063                 if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED; /* todo */
1064                 /* todo */
1065         }
1066 #else
1067         return JVMTI_ERROR_INTERNAL;
1068 #endif
1069
1070     return JVMTI_ERROR_NONE;
1071 }
1072
1073
1074 /* GetFrameLocation ************************************************************
1075
1076    Get the location of the instruction currently executing
1077
1078 *******************************************************************************/
1079
1080 jvmtiError
1081 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
1082                   jmethodID * method_ptr, jlocation * location_ptr)
1083 {
1084         stackframeinfo   *sfi;
1085         int i;
1086                 
1087         CHECK_PHASE_START
1088     CHECK_PHASE(JVMTI_PHASE_LIVE)
1089     CHECK_PHASE_END;
1090         
1091         if(!builtin_instanceof(thread,class_java_lang_Thread))
1092                 return JVMTI_ERROR_INVALID_THREAD;
1093
1094         CHECK_THREAD_IS_ALIVE(thread);
1095
1096         if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1097
1098         if ((method_ptr == NULL)&&(location_ptr == NULL)) 
1099                 return JVMTI_ERROR_NULL_POINTER;
1100         
1101         sfi = ((threadobject*)thread)->info._stackframeinfo;
1102         
1103         i = 0;
1104         while ((sfi != NULL) && (i<depth)) {
1105                 sfi = sfi->prev;
1106                 i++;
1107         }
1108         
1109         if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
1110
1111         *method_ptr=(jmethodID)sfi->method;
1112         *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
1113         
1114     return JVMTI_ERROR_NONE;
1115 }
1116
1117
1118 /* NotifyFramePop *************************************************************
1119
1120    
1121
1122 *******************************************************************************/
1123
1124 jvmtiError
1125 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
1126 {
1127         CHECK_PHASE_START
1128     CHECK_PHASE(JVMTI_PHASE_LIVE)
1129     CHECK_PHASE_END;
1130     CHECK_CAPABILITY(env,can_generate_frame_pop_events)
1131         
1132   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
1133     return JVMTI_ERROR_NONE;
1134 }
1135
1136 /* GetLocalObject *************************************************************
1137
1138    
1139
1140 *******************************************************************************/
1141
1142 jvmtiError
1143 GetLocalObject (jvmtiEnv * env,
1144                 jthread thread, jint depth, jint slot, jobject * value_ptr)
1145 {
1146         CHECK_PHASE_START
1147     CHECK_PHASE(JVMTI_PHASE_LIVE)
1148     CHECK_PHASE_END;
1149         CHECK_CAPABILITY(env,can_access_local_variables)
1150
1151   log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
1152     return JVMTI_ERROR_NONE;
1153 }
1154
1155 /* GetLocalInt ****************************************************************
1156
1157    
1158
1159 *******************************************************************************/
1160
1161 jvmtiError
1162 GetLocalInt (jvmtiEnv * env,
1163              jthread thread, jint depth, jint slot, jint * value_ptr)
1164 {
1165         CHECK_PHASE_START
1166     CHECK_PHASE(JVMTI_PHASE_LIVE)
1167     CHECK_PHASE_END;
1168         CHECK_CAPABILITY(env,can_access_local_variables)        
1169   log_text ("JVMTI-Call: TBD OPTIONAL  IMPLEMENT ME!!!");
1170     return JVMTI_ERROR_NONE;
1171 }
1172
1173 /* *****************************************************************************
1174
1175    
1176
1177 *******************************************************************************/
1178
1179 jvmtiError
1180 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1181               jlong * value_ptr)
1182 {
1183         CHECK_PHASE_START
1184     CHECK_PHASE(JVMTI_PHASE_LIVE)
1185     CHECK_PHASE_END;
1186         CHECK_CAPABILITY(env,can_access_local_variables)        
1187         
1188   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1189     return JVMTI_ERROR_NONE;
1190 }
1191
1192
1193 /* *****************************************************************************
1194
1195    
1196
1197 *******************************************************************************/
1198
1199 jvmtiError
1200 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1201                jfloat * value_ptr)
1202 {
1203     CHECK_PHASE_START
1204     CHECK_PHASE(JVMTI_PHASE_LIVE)
1205     CHECK_PHASE_END;
1206         CHECK_CAPABILITY(env,can_access_local_variables)        
1207         
1208   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1209     return JVMTI_ERROR_NONE;
1210 }
1211
1212
1213 /* *****************************************************************************
1214
1215    
1216
1217 *******************************************************************************/
1218
1219 jvmtiError
1220 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1221                 jdouble * value_ptr)
1222 {
1223     CHECK_PHASE_START
1224     CHECK_PHASE(JVMTI_PHASE_LIVE)
1225     CHECK_PHASE_END;
1226         CHECK_CAPABILITY(env,can_access_local_variables)        
1227         
1228   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1229     return JVMTI_ERROR_NONE;
1230 }
1231
1232
1233 /* *****************************************************************************
1234
1235    
1236
1237 *******************************************************************************/
1238
1239 jvmtiError
1240 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1241                 jobject value)
1242 {
1243         CHECK_PHASE_START
1244     CHECK_PHASE(JVMTI_PHASE_LIVE)
1245     CHECK_PHASE_END;
1246         CHECK_CAPABILITY(env,can_access_local_variables)
1247     
1248   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1249     return JVMTI_ERROR_NONE;
1250 }
1251
1252
1253 /* *****************************************************************************
1254
1255    
1256
1257 *******************************************************************************/
1258
1259 jvmtiError
1260 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1261              jint value)
1262 {
1263         CHECK_PHASE_START
1264     CHECK_PHASE(JVMTI_PHASE_LIVE)
1265     CHECK_PHASE_END;
1266         CHECK_CAPABILITY(env,can_access_local_variables)
1267         
1268   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1269     return JVMTI_ERROR_NONE;
1270 }
1271
1272
1273 /* *****************************************************************************
1274
1275    
1276
1277 *******************************************************************************/
1278
1279 jvmtiError
1280 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1281               jlong value)
1282 {
1283         CHECK_PHASE_START
1284     CHECK_PHASE(JVMTI_PHASE_LIVE)
1285     CHECK_PHASE_END;
1286         CHECK_CAPABILITY(env,can_access_local_variables)
1287         
1288   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1289     return JVMTI_ERROR_NONE;
1290 }
1291
1292
1293 /* *****************************************************************************
1294
1295    
1296
1297 *******************************************************************************/
1298
1299 jvmtiError
1300 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1301                jfloat value)
1302 {
1303         CHECK_PHASE_START
1304     CHECK_PHASE(JVMTI_PHASE_LIVE)
1305     CHECK_PHASE_END;
1306         CHECK_CAPABILITY(env,can_access_local_variables)
1307         
1308   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1309     return JVMTI_ERROR_NONE;
1310 }
1311
1312
1313 /* *****************************************************************************
1314
1315    
1316
1317 *******************************************************************************/
1318
1319 jvmtiError
1320 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
1321                 jdouble value)
1322 {
1323         CHECK_PHASE_START
1324     CHECK_PHASE(JVMTI_PHASE_LIVE)
1325     CHECK_PHASE_END;
1326         CHECK_CAPABILITY(env,can_access_local_variables)
1327     
1328          log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1329     return JVMTI_ERROR_NONE;
1330 }
1331
1332
1333 /* CreateRawMonitor ***********************************************************
1334
1335    This function creates a new raw monitor.
1336
1337 *******************************************************************************/
1338
1339 jvmtiError
1340 CreateRawMonitor (jvmtiEnv * env, const char *name,
1341                   jrawMonitorID * monitor_ptr)
1342 {
1343         struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
1344                 
1345         CHECK_PHASE_START
1346     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1347     CHECK_PHASE(JVMTI_PHASE_LIVE)
1348     CHECK_PHASE_END;
1349         
1350         if ((name == NULL) || (monitor_ptr == NULL)) 
1351                 return JVMTI_ERROR_NULL_POINTER;
1352
1353 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1354         monitor->name=javastring_new_char(name);
1355 #else
1356         log_text ("CreateRawMonitor not supported");
1357 #endif
1358
1359     return JVMTI_ERROR_NONE;
1360 }
1361
1362
1363 /* DestroyRawMonitor **********************************************************
1364
1365    This function destroys a raw monitor.   
1366
1367 *******************************************************************************/
1368
1369 jvmtiError
1370 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
1371 {
1372         CHECK_PHASE_START
1373     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
1374     CHECK_PHASE(JVMTI_PHASE_LIVE)
1375     CHECK_PHASE_END;
1376
1377         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1378                 return JVMTI_ERROR_INVALID_MONITOR;
1379
1380 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1381         if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1382                 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1383         
1384         monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
1385
1386         /* GC will clean monitor up */
1387 #else
1388         log_text ("DestroyRawMonitor not supported");
1389 #endif
1390
1391         return JVMTI_ERROR_NONE;
1392 }
1393
1394
1395 /* RawMonitorEnter ************************************************************
1396
1397   Gain exclusive ownership of a raw monitor
1398
1399 *******************************************************************************/
1400
1401 jvmtiError
1402 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
1403 {
1404         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1405                 return JVMTI_ERROR_INVALID_MONITOR;
1406
1407 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1408         builtin_monitorenter((java_objectheader*)monitor->name);        
1409 #else
1410         log_text ("RawMonitorEnter not supported");
1411 #endif
1412
1413     return JVMTI_ERROR_NONE;
1414 }
1415
1416
1417 /* RawMonitorExit *************************************************************
1418
1419    Release raw monitor
1420
1421 *******************************************************************************/
1422
1423 jvmtiError
1424 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
1425 {
1426         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1427                 return JVMTI_ERROR_INVALID_MONITOR;
1428
1429 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1430         /* assure current thread owns this monitor */
1431         if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1432                 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1433
1434         builtin_monitorexit((java_objectheader*)monitor->name);
1435 #else
1436         log_text ("RawMonitorExit not supported");
1437 #endif
1438
1439     return JVMTI_ERROR_NONE;
1440 }
1441
1442
1443 /* RawMonitorWait *************************************************************
1444
1445    Wait for notification of the raw monitor.
1446
1447 *******************************************************************************/
1448
1449 jvmtiError
1450 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
1451 {
1452         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1453                 return JVMTI_ERROR_INVALID_MONITOR;
1454
1455 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1456         /* assure current thread owns this monitor */
1457         if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
1458                 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1459
1460         wait_cond_for_object(&monitor->name->header, millis,0);
1461         if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
1462                 return JVMTI_ERROR_INTERRUPT;
1463
1464 #else
1465         log_text ("RawMonitorWait not supported");
1466 #endif
1467
1468     return JVMTI_ERROR_NONE;
1469 }
1470
1471
1472 /* RawMonitorNotify ***********************************************************
1473
1474  Notify one thread waiting on the given monitor.
1475
1476 *******************************************************************************/
1477
1478 jvmtiError
1479 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
1480 {
1481         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1482                 return JVMTI_ERROR_INVALID_MONITOR;
1483
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;
1488
1489         signal_cond_for_object((java_objectheader*)&monitor->name);
1490 #else
1491         log_text ("RawMonitorNotify not supported");
1492 #endif
1493
1494     return JVMTI_ERROR_NONE;
1495 }
1496
1497
1498 /* RawMonitorNotifyAll *********************************************************
1499
1500  Notify all threads waiting on the given monitor.   
1501
1502 *******************************************************************************/
1503
1504 jvmtiError
1505 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
1506 {
1507         if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
1508                 return JVMTI_ERROR_INVALID_MONITOR;
1509
1510 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1511         /* assure current thread owns this monitor */
1512         if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
1513                 return JVMTI_ERROR_NOT_MONITOR_OWNER;
1514
1515         broadcast_cond_for_object((java_objectheader*)&monitor->name);
1516 #else
1517         log_text ("RawMonitorNotifyAll not supported");
1518 #endif
1519
1520     return JVMTI_ERROR_NONE;
1521 }
1522
1523
1524 /* SetBreakpoint **************************************************************
1525
1526    
1527
1528 *******************************************************************************/
1529
1530 jvmtiError
1531 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1532 {
1533         CHECK_PHASE_START
1534     CHECK_PHASE(JVMTI_PHASE_LIVE)
1535     CHECK_PHASE_END;
1536         CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1537         
1538   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1539     return JVMTI_ERROR_NONE;
1540 }
1541
1542
1543 /* *****************************************************************************
1544
1545    
1546
1547 *******************************************************************************/
1548
1549 jvmtiError
1550 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
1551 {
1552         CHECK_PHASE_START
1553     CHECK_PHASE(JVMTI_PHASE_LIVE)
1554     CHECK_PHASE_END;
1555         CHECK_CAPABILITY(env,can_generate_breakpoint_events)
1556         
1557   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1558     return JVMTI_ERROR_NONE;
1559 }
1560
1561
1562 /* SetFieldAccessWatch ********************************************************
1563
1564    
1565
1566 *******************************************************************************/
1567
1568 jvmtiError
1569 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1570 {
1571         CHECK_PHASE_START
1572     CHECK_PHASE(JVMTI_PHASE_LIVE)
1573     CHECK_PHASE_END;
1574         CHECK_CAPABILITY(env,can_generate_field_access_events)
1575         
1576   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1577     return JVMTI_ERROR_NONE;
1578 }
1579
1580
1581 /* *****************************************************************************
1582
1583    
1584
1585 *******************************************************************************/
1586
1587 jvmtiError
1588 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1589 {
1590         CHECK_PHASE_START
1591     CHECK_PHASE(JVMTI_PHASE_LIVE)
1592     CHECK_PHASE_END;
1593         CHECK_CAPABILITY(env,can_generate_field_access_events)
1594         
1595   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1596     return JVMTI_ERROR_NONE;
1597 }
1598
1599
1600 /* *****************************************************************************
1601
1602    
1603
1604 *******************************************************************************/
1605
1606 jvmtiError
1607 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1608 {
1609         CHECK_PHASE_START
1610     CHECK_PHASE(JVMTI_PHASE_LIVE)
1611     CHECK_PHASE_END;
1612         CHECK_CAPABILITY(env,can_generate_field_modification_events)
1613         
1614   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1615     return JVMTI_ERROR_NONE;
1616 }
1617
1618
1619 /* *****************************************************************************
1620
1621    
1622
1623 *******************************************************************************/
1624
1625 jvmtiError
1626 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
1627 {
1628         CHECK_PHASE_START
1629     CHECK_PHASE(JVMTI_PHASE_LIVE)
1630     CHECK_PHASE_END;
1631         CHECK_CAPABILITY(env,can_generate_field_modification_events)
1632         
1633   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
1634     return JVMTI_ERROR_NONE;
1635 }
1636
1637
1638 /* Allocate ********************************************************************
1639
1640    Allocate an area of memory through the JVM TI allocator. The allocated 
1641    memory should be freed with Deallocate
1642
1643 *******************************************************************************/
1644
1645 jvmtiError
1646 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
1647 {
1648     
1649     if (mem_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
1650     if (size < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
1651
1652     *mem_ptr = heap_allocate(sizeof(size),true,NULL);
1653     if (*mem_ptr == NULL) 
1654         return JVMTI_ERROR_OUT_OF_MEMORY;
1655     else
1656         return JVMTI_ERROR_NONE;
1657     
1658 }
1659
1660
1661 /* Deallocate ******************************************************************
1662
1663    Deallocate mem using the JVM TI allocator.
1664
1665 *******************************************************************************/
1666
1667 jvmtiError
1668 Deallocate (jvmtiEnv * env, unsigned char *mem)
1669 {
1670     /* let Boehm GC do the job */
1671     return JVMTI_ERROR_NONE;
1672 }
1673
1674
1675 /* GetClassSignature ************************************************************
1676
1677    For the class indicated by klass, return the JNI type signature and the 
1678    generic signature of the class.
1679
1680 *******************************************************************************/
1681
1682 jvmtiError
1683 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
1684                    char **generic_ptr)
1685 {
1686     int nsize,psize;
1687
1688     CHECK_PHASE_START
1689     CHECK_PHASE(JVMTI_PHASE_START)
1690     CHECK_PHASE(JVMTI_PHASE_LIVE)
1691     CHECK_PHASE_END;
1692        
1693     if ((generic_ptr== NULL)||(signature_ptr == NULL)) 
1694         return JVMTI_ERROR_NULL_POINTER;
1695
1696     nsize=((classinfo*)klass)->name->blength;
1697     psize=((classinfo*)klass)->packagename->blength;
1698
1699     *signature_ptr = (char*) 
1700         heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
1701
1702     *signature_ptr[0]='L';
1703     memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
1704     *signature_ptr[psize+2]='/';
1705     memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
1706     *signature_ptr[nsize+psize+3]=';';
1707     *signature_ptr[nsize+psize+4]='\0';
1708
1709     *generic_ptr = NULL;
1710
1711     return JVMTI_ERROR_NONE;
1712 }
1713
1714 /* GetClassStatus *************************************************************
1715
1716    Get status of the class.
1717
1718 *******************************************************************************/
1719
1720 jvmtiError
1721 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
1722 {
1723         classinfo *c;
1724     CHECK_PHASE_START
1725     CHECK_PHASE(JVMTI_PHASE_START)
1726     CHECK_PHASE(JVMTI_PHASE_LIVE)
1727     CHECK_PHASE_END;
1728
1729         if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1730                 return JVMTI_ERROR_INVALID_CLASS; 
1731
1732     if (status_ptr == NULL) 
1733         return JVMTI_ERROR_NULL_POINTER;
1734
1735         c = (classinfo*)klass;
1736         *status_ptr = 0;        
1737
1738 /*      if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
1739 /*      if () *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;  ? */
1740
1741         if (c->initialized) 
1742                 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
1743
1744         if (c->erroneous_state) 
1745                 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
1746
1747         if (c->vftbl->arraydesc != NULL) 
1748                 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
1749
1750         if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c)) 
1751                 *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE; 
1752
1753     return JVMTI_ERROR_NONE;
1754 }
1755
1756
1757 /* GetSourceFileName **********************************************************
1758
1759    For the class indicated by klass, return the source file name.
1760
1761 *******************************************************************************/
1762
1763 jvmtiError
1764 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
1765 {
1766     int size; 
1767
1768     CHECK_PHASE_START
1769     CHECK_PHASE(JVMTI_PHASE_START)
1770     CHECK_PHASE(JVMTI_PHASE_LIVE)
1771     CHECK_PHASE_END;
1772         CHECK_CAPABILITY(env,can_get_source_file_name)
1773         
1774     if ((klass == NULL)||(source_name_ptr == NULL)) 
1775         return JVMTI_ERROR_NULL_POINTER;
1776     
1777     size = (((classinfo*)klass)->sourcefile->blength);
1778
1779     *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
1780     
1781     memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
1782
1783     return JVMTI_ERROR_NONE;
1784 }
1785
1786
1787 /* GetClassModifiers **********************************************************
1788
1789    For class klass return the access flags
1790
1791 *******************************************************************************/
1792
1793 jvmtiError
1794 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
1795 {
1796         CHECK_PHASE_START
1797     CHECK_PHASE(JVMTI_PHASE_START)
1798     CHECK_PHASE(JVMTI_PHASE_LIVE)
1799     CHECK_PHASE_END;
1800         
1801         if (modifiers_ptr == NULL)
1802                 return JVMTI_ERROR_NULL_POINTER;        
1803
1804         if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1805                 return JVMTI_ERROR_INVALID_CLASS;
1806
1807         *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
1808         
1809     return JVMTI_ERROR_NONE;
1810 }
1811
1812
1813 /* GetClassMethods *************************************************************
1814
1815    For class klass return a count of methods and a list of method IDs
1816
1817 *******************************************************************************/
1818
1819 jvmtiError
1820 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
1821                  jmethodID ** methods_ptr)
1822 {
1823     CHECK_PHASE_START
1824     CHECK_PHASE(JVMTI_PHASE_START)
1825     CHECK_PHASE(JVMTI_PHASE_LIVE)
1826     CHECK_PHASE_END;
1827         
1828     if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL)) 
1829         return JVMTI_ERROR_NULL_POINTER;
1830
1831         if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1832                 return JVMTI_ERROR_INVALID_CLASS;
1833
1834     *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
1835     *methods_ptr = (jmethodID*) 
1836         heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
1837     
1838     memcpy (*methods_ptr, ((classinfo*)klass)->methods, 
1839             sizeof(jmethodID) * (*method_count_ptr));
1840     
1841     return JVMTI_ERROR_NONE;
1842 }
1843
1844
1845 /* GetClassFields *************************************************************
1846
1847    For the class indicated by klass, return a count of fields and a list of 
1848    field IDs.
1849
1850 *******************************************************************************/
1851
1852 jvmtiError
1853 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
1854                 jfieldID ** fields_ptr)
1855 {
1856     CHECK_PHASE_START
1857     CHECK_PHASE(JVMTI_PHASE_START)
1858     CHECK_PHASE(JVMTI_PHASE_LIVE)
1859     CHECK_PHASE_END;
1860         
1861     if ((klass == NULL)||(fields_ptr == NULL)||(field_count_ptr == NULL)) 
1862         return JVMTI_ERROR_NULL_POINTER;
1863
1864     *field_count_ptr = (jint)((classinfo*)klass)->fieldscount;
1865     *fields_ptr = (jfieldID*) 
1866         heap_allocate(sizeof(jfieldID) * (*field_count_ptr),true,NULL);
1867     
1868     memcpy (*fields_ptr, ((classinfo*)klass)->fields, 
1869             sizeof(jfieldID) * (*field_count_ptr));
1870     
1871     return JVMTI_ERROR_NONE;
1872 }
1873
1874
1875 /* GetImplementedInterfaces ***************************************************
1876
1877    Return the direct super-interfaces of this class.
1878
1879 *******************************************************************************/
1880
1881 jvmtiError
1882 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
1883                           jint * interface_count_ptr,
1884                           jclass ** interfaces_ptr)
1885 {
1886         int i;
1887         classref_or_classinfo *interfaces;
1888         classinfo *tmp;
1889
1890         CHECK_PHASE_START
1891     CHECK_PHASE(JVMTI_PHASE_START)
1892     CHECK_PHASE(JVMTI_PHASE_LIVE)
1893     CHECK_PHASE_END;
1894
1895         if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
1896                 return JVMTI_ERROR_NULL_POINTER;        
1897
1898         if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
1899                 return JVMTI_ERROR_INVALID_CLASS;
1900
1901                 
1902     *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
1903     *interfaces_ptr = 
1904                 heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
1905
1906         interfaces = ((classinfo*)klass)->interfaces;
1907         for (i=0; i<*interface_count_ptr; i++) {
1908                 if (IS_CLASSREF(interfaces[i]))
1909                         tmp = load_class_bootstrap(interfaces[i].ref->name);
1910                 else
1911                         tmp = interfaces[i].cls;
1912                 
1913                 *interfaces_ptr[i]=tmp;
1914         }
1915
1916     return JVMTI_ERROR_NONE;
1917 }
1918
1919
1920 /* IsInterface ****************************************************************
1921
1922    Determines whether a class object reference represents an interface.
1923
1924 *******************************************************************************/
1925
1926 jvmtiError
1927 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
1928 {
1929     CHECK_PHASE_START
1930     CHECK_PHASE(JVMTI_PHASE_START)
1931     CHECK_PHASE(JVMTI_PHASE_LIVE)
1932     CHECK_PHASE_END;
1933         
1934     if ((klass == NULL)||(is_interface_ptr == NULL)) 
1935         return JVMTI_ERROR_NULL_POINTER;
1936     
1937     *is_interface_ptr = (((classinfo*)klass)->flags & ACC_INTERFACE);
1938
1939     return JVMTI_ERROR_NONE;
1940 }
1941
1942 /* IsArrayClass ***************************************************************
1943
1944    Determines whether a class object reference represents an array.
1945
1946 *******************************************************************************/
1947
1948 jvmtiError
1949 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
1950 {
1951     CHECK_PHASE_START
1952     CHECK_PHASE(JVMTI_PHASE_START)
1953     CHECK_PHASE(JVMTI_PHASE_LIVE)
1954     CHECK_PHASE_END;
1955         
1956     if (is_array_class_ptr == NULL) 
1957         return JVMTI_ERROR_NULL_POINTER;
1958
1959     *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
1960
1961     return JVMTI_ERROR_NONE;
1962 }
1963
1964
1965 /* GetClassLoader *************************************************************
1966
1967    For the class indicated by klass, return via classloader_ptr a reference to 
1968    the class loader for the class.
1969
1970 *******************************************************************************/
1971
1972 jvmtiError
1973 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
1974 {
1975     CHECK_PHASE_START
1976     CHECK_PHASE(JVMTI_PHASE_START)
1977     CHECK_PHASE(JVMTI_PHASE_LIVE)
1978     CHECK_PHASE_END;
1979         
1980     if ((klass == NULL)||(classloader_ptr == NULL)) 
1981         return JVMTI_ERROR_NULL_POINTER;
1982
1983     *classloader_ptr = (jobject)((classinfo*)klass)->classloader;
1984  
1985     return JVMTI_ERROR_NONE;
1986 }
1987
1988
1989 /* GetObjectHashCode **********************************************************
1990
1991    Return hash code for object object
1992
1993 *******************************************************************************/
1994
1995 jvmtiError
1996 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
1997 {
1998         CHECK_PHASE_START
1999     CHECK_PHASE(JVMTI_PHASE_START)
2000     CHECK_PHASE(JVMTI_PHASE_LIVE)
2001     CHECK_PHASE_END;
2002    
2003         if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2004         if (!builtin_instanceof(object,class_java_lang_Object))
2005                 return JVMTI_ERROR_INVALID_OBJECT;
2006      
2007         *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
2008
2009     return JVMTI_ERROR_NONE;
2010 }
2011
2012
2013 /* *****************************************************************************
2014
2015    
2016
2017 *******************************************************************************/
2018
2019 jvmtiError
2020 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
2021                        jvmtiMonitorUsage * info_ptr)
2022 {
2023         CHECK_PHASE_START
2024     CHECK_PHASE(JVMTI_PHASE_LIVE)
2025     CHECK_PHASE_END;
2026     CHECK_CAPABILITY(env,can_get_monitor_info)
2027         
2028   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2029     return JVMTI_ERROR_NONE;
2030 }
2031
2032
2033 /* GetFieldName ***************************************************************
2034
2035    For the field indicated by klass and field, return the field name and 
2036    signature.
2037
2038 *******************************************************************************/
2039
2040 jvmtiError
2041 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
2042               char **name_ptr, char **signature_ptr, char **generic_ptr)
2043 {
2044     int size; 
2045
2046     CHECK_PHASE_START
2047     CHECK_PHASE(JVMTI_PHASE_START)
2048     CHECK_PHASE(JVMTI_PHASE_LIVE)
2049     CHECK_PHASE_END;
2050         
2051     if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL)) 
2052         return JVMTI_ERROR_NULL_POINTER;
2053     
2054     size = (((fieldinfo*)field)->name->blength);
2055     *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
2056     memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
2057
2058     size = (((fieldinfo*)field)->descriptor->blength);
2059     *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
2060     memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
2061
2062     *generic_ptr = NULL;
2063
2064     return JVMTI_ERROR_NONE;
2065 }
2066
2067
2068 /* GetFieldDeclaringClass *****************************************************
2069
2070    For the field indicated by klass and field return the class that defined it 
2071    The declaring class will either be klass, a superclass, or an implemented 
2072    interface.
2073
2074 *******************************************************************************/
2075
2076 jvmtiError
2077 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
2078                         jclass * declaring_class_ptr)
2079 {
2080     CHECK_PHASE_START
2081     CHECK_PHASE(JVMTI_PHASE_START)
2082     CHECK_PHASE(JVMTI_PHASE_LIVE)
2083     CHECK_PHASE_END;
2084         
2085     /* todo: how do I find declaring class other then iterate over all fields in all classes ?*/
2086   log_text ("JVMTI-Call: IMPLEMENT ME!!!");
2087  
2088     return JVMTI_ERROR_NONE;
2089 }
2090
2091
2092 /* GetFieldModifiers **********************************************************
2093
2094    Return access flags of field field 
2095
2096 *******************************************************************************/
2097
2098 jvmtiError
2099 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
2100                    jint * modifiers_ptr)
2101 {
2102         CHECK_PHASE_START
2103     CHECK_PHASE(JVMTI_PHASE_START)
2104     CHECK_PHASE(JVMTI_PHASE_LIVE)
2105     CHECK_PHASE_END;
2106         
2107         if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
2108                 return JVMTI_ERROR_INVALID_OBJECT;
2109
2110         if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2111  
2112         /* todo: JVMTI_ERROR_INVALID_FIELDID; */
2113         
2114         *modifiers_ptr = ((fieldinfo*)field)->flags;
2115         
2116     return JVMTI_ERROR_NONE;
2117 }
2118
2119
2120 /* IsFieldSynthetic ***********************************************************
2121
2122    
2123
2124 *******************************************************************************/
2125
2126 jvmtiError
2127 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
2128                   jboolean * is_synthetic_ptr)
2129 {
2130         CHECK_PHASE_START
2131     CHECK_PHASE(JVMTI_PHASE_START)
2132     CHECK_PHASE(JVMTI_PHASE_LIVE)
2133     CHECK_PHASE_END;
2134     CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2135         
2136   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2137     return JVMTI_ERROR_NONE;
2138 }
2139
2140
2141 /* GetMethodName ***************************************************************
2142
2143    For the method indicated by method, return the method name via name_ptr and 
2144    method signature via signature_ptr.
2145
2146 *******************************************************************************/
2147
2148 jvmtiError
2149 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
2150                char **signature_ptr, char **generic_ptr)
2151 {
2152     methodinfo* m = (methodinfo*)method;
2153
2154     CHECK_PHASE_START
2155     CHECK_PHASE(JVMTI_PHASE_START)
2156     CHECK_PHASE(JVMTI_PHASE_LIVE)
2157     CHECK_PHASE_END;
2158
2159     if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
2160         || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2161
2162     *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
2163     memcpy(*name_ptr, m->name->text, m->name->blength);
2164
2165     *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
2166     memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
2167     
2168     /* there is no generic signature attribute */
2169     *generic_ptr = NULL;
2170
2171     return JVMTI_ERROR_NONE;
2172 }
2173
2174
2175 /* GetMethodDeclaringClass *****************************************************
2176
2177   For the method indicated by method, return the class that defined it.
2178
2179 *******************************************************************************/
2180
2181 jvmtiError
2182 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
2183                          jclass * declaring_class_ptr)
2184 {
2185     CHECK_PHASE_START
2186     CHECK_PHASE(JVMTI_PHASE_START)
2187     CHECK_PHASE(JVMTI_PHASE_LIVE)
2188     CHECK_PHASE_END;
2189      
2190     if ((method == NULL) || (declaring_class_ptr == NULL)) 
2191         return JVMTI_ERROR_NULL_POINTER;
2192     
2193     *declaring_class_ptr = (jclass)((methodinfo*)method)->class;
2194     
2195     return JVMTI_ERROR_NONE;
2196 }
2197
2198
2199 /* GetMethodModifiers **********************************************************
2200
2201    For the method indicated by method, return the access flags.
2202
2203 *******************************************************************************/
2204
2205 jvmtiError
2206 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
2207 {
2208     CHECK_PHASE_START
2209     CHECK_PHASE(JVMTI_PHASE_START)
2210     CHECK_PHASE(JVMTI_PHASE_LIVE)
2211     CHECK_PHASE_END;
2212         
2213     if ((method == NULL) || (modifiers_ptr == NULL)) 
2214         return JVMTI_ERROR_NULL_POINTER;
2215
2216     *modifiers_ptr = (jint) (((methodinfo*)method)->flags);
2217
2218     return JVMTI_ERROR_NONE;
2219 }
2220
2221
2222 /* GetMaxLocals ****************************************************************
2223
2224    For the method indicated by method, return the number of local variable slots 
2225    used by the method, including the local variables used to pass parameters to 
2226    the method on its invocation.
2227
2228 *******************************************************************************/
2229
2230 jvmtiError
2231 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
2232 {
2233     CHECK_PHASE_START
2234     CHECK_PHASE(JVMTI_PHASE_START)
2235     CHECK_PHASE(JVMTI_PHASE_LIVE)
2236     CHECK_PHASE_END;
2237         
2238     if ((method == NULL)||(max_ptr == NULL)) 
2239         return JVMTI_ERROR_NULL_POINTER;    
2240     
2241     if (((methodinfo*)method)->flags & ACC_NATIVE)  
2242         return JVMTI_ERROR_NATIVE_METHOD;
2243    
2244     *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
2245
2246     return JVMTI_ERROR_NONE;
2247 }
2248
2249
2250
2251 /* GetArgumentsSize ************************************************************
2252
2253    Return the number of local variable slots used by the method's arguments.
2254
2255 *******************************************************************************/
2256
2257 jvmtiError
2258 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
2259 {
2260     CHECK_PHASE_START
2261     CHECK_PHASE(JVMTI_PHASE_START)
2262     CHECK_PHASE(JVMTI_PHASE_LIVE)
2263     CHECK_PHASE_END;
2264
2265     if ((method == NULL)||(size_ptr == NULL)) 
2266         return JVMTI_ERROR_NULL_POINTER;    
2267     
2268     if (((methodinfo*)method)->flags & ACC_NATIVE)  
2269         return JVMTI_ERROR_NATIVE_METHOD;
2270
2271     *size_ptr = (jint)((methodinfo*)method)->paramcount;
2272     return JVMTI_ERROR_NONE;
2273 }
2274
2275
2276
2277 /* GetLineNumberTable ***********************************************************
2278
2279    Return table of source line number entries for a given method
2280
2281 *******************************************************************************/
2282
2283 jvmtiError
2284 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
2285                     jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
2286 {
2287     int i;
2288
2289     CHECK_PHASE_START
2290     CHECK_PHASE(JVMTI_PHASE_START)
2291     CHECK_PHASE(JVMTI_PHASE_LIVE)
2292     CHECK_PHASE_END;
2293     CHECK_CAPABILITY(env,can_get_line_numbers)
2294    
2295     if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL)) 
2296         return JVMTI_ERROR_NULL_POINTER;    
2297     if (((methodinfo*)method)->flags & ACC_NATIVE)  
2298         return JVMTI_ERROR_NATIVE_METHOD;
2299     if (((methodinfo*)method)->linenumbers == NULL) 
2300         return JVMTI_ERROR_ABSENT_INFORMATION;
2301
2302     *entry_count_ptr= (jint)((methodinfo*)method)->linenumbercount;
2303     *table_ptr = (jvmtiLineNumberEntry*) heap_allocate(
2304         sizeof(jvmtiLineNumberEntry) * (*entry_count_ptr),true,NULL);
2305
2306
2307     for (i=0; i < *entry_count_ptr; i++) {
2308         (*table_ptr[i]).start_location = 
2309             (jlocation) method->linenumbers[i].start_pc;
2310         (*table_ptr[i]).line_number = 
2311             (jint) ((methodinfo*)method)->linenumbers[i].line_number;
2312     }
2313     
2314     return JVMTI_ERROR_NONE;
2315 }
2316
2317
2318 /* GetMethodLocation ***********************************************************
2319
2320    For the method indicated by method, return the beginning and ending addresses 
2321    through start_location_ptr and end_location_ptr. In cacao this points to 
2322    entry point in machine code and length of machine code
2323
2324 *******************************************************************************/
2325
2326 jvmtiError
2327 GetMethodLocation (jvmtiEnv * env, jmethodID method,
2328                    jlocation * start_location_ptr,
2329                    jlocation * end_location_ptr)
2330 {
2331     methodinfo* m = (methodinfo*)method;
2332
2333     CHECK_PHASE_START
2334     CHECK_PHASE(JVMTI_PHASE_START)
2335     CHECK_PHASE(JVMTI_PHASE_LIVE)
2336     CHECK_PHASE_END;
2337
2338     if ((method == NULL) || (start_location_ptr == NULL) || 
2339         (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2340     
2341     *start_location_ptr = (jlocation)m->mcode;
2342     *end_location_ptr = (jlocation)(m->mcode)+m->mcodelength;
2343     return JVMTI_ERROR_NONE;
2344 }
2345
2346
2347 /* GetLocalVariableTable *******************************************************
2348
2349    Return local variable information.
2350
2351 *******************************************************************************/
2352
2353 jvmtiError
2354 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
2355                        jint * entry_count_ptr,
2356                        jvmtiLocalVariableEntry ** table_ptr)
2357 {
2358     CHECK_PHASE_START
2359     CHECK_PHASE(JVMTI_PHASE_LIVE)
2360     CHECK_PHASE_END;
2361     CHECK_CAPABILITY(env,can_access_local_variables)
2362         
2363   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2364
2365     return JVMTI_ERROR_NONE;
2366 }
2367
2368
2369 /* GetBytecode *****************************************************************
2370
2371    For the method indicated by method, return the byte codes that implement the 
2372    method.
2373
2374 *******************************************************************************/
2375
2376 jvmtiError
2377 GetBytecodes (jvmtiEnv * env, jmethodID method,
2378               jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
2379 {
2380     methodinfo* m = (methodinfo*)method;;
2381
2382     CHECK_PHASE_START
2383     CHECK_PHASE(JVMTI_PHASE_START)
2384     CHECK_PHASE(JVMTI_PHASE_LIVE)
2385     CHECK_PHASE_END;
2386     CHECK_CAPABILITY(env,can_get_bytecodes)
2387         
2388     if ((method == NULL) || (bytecode_count_ptr == NULL) || 
2389         (bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
2390
2391     *bytecode_count_ptr = m->jcodelength;
2392     *bytecodes_ptr = (unsigned char*)heap_allocate(m->jcodelength,true,NULL);
2393     memcpy(*bytecodes_ptr, m->jcode, m->jcodelength);
2394
2395     return JVMTI_ERROR_NONE;
2396 }
2397
2398
2399 /* IsMethodNative **************************************************************
2400
2401    For the method indicated by method, return a value indicating whether the 
2402    method is a native function
2403
2404 *******************************************************************************/
2405
2406 jvmtiError
2407 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
2408 {
2409     CHECK_PHASE_START
2410     CHECK_PHASE(JVMTI_PHASE_START)
2411     CHECK_PHASE(JVMTI_PHASE_LIVE)
2412     CHECK_PHASE_END;
2413     
2414     if ((method == NULL)||(is_native_ptr == NULL)) 
2415         return JVMTI_ERROR_NULL_POINTER;    
2416
2417     if (((methodinfo*)method)->flags & ACC_NATIVE) 
2418         *is_native_ptr = JNI_TRUE;
2419     else
2420         *is_native_ptr = JNI_FALSE;
2421
2422     return JVMTI_ERROR_NONE;
2423 }
2424
2425
2426 /* IsMethodSynthetic ***********************************************************
2427
2428    return a value indicating whether the method is synthetic. Synthetic methods 
2429    are generated by the compiler but not present in the original source code.
2430
2431 *******************************************************************************/
2432
2433 jvmtiError
2434 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
2435                    jboolean * is_synthetic_ptr)
2436 {
2437     CHECK_PHASE_START
2438     CHECK_PHASE(JVMTI_PHASE_START)
2439     CHECK_PHASE(JVMTI_PHASE_LIVE)
2440     CHECK_PHASE_END;
2441         CHECK_CAPABILITY(env,can_get_synthetic_attribute)
2442
2443   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2444     return JVMTI_ERROR_NONE;
2445 }
2446
2447
2448 /* GetLoadedClasses ************************************************************
2449
2450    Return an array of all classes loaded in the virtual machine.
2451
2452 *******************************************************************************/
2453
2454 jvmtiError
2455 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr,
2456                   jclass ** classes_ptr)
2457 {
2458         int i,j;
2459         classcache_name_entry *cne;
2460         classcache_class_entry *cce;
2461     CHECK_PHASE_START
2462     CHECK_PHASE(JVMTI_PHASE_LIVE)
2463     CHECK_PHASE_END;
2464
2465     if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2466     if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2467
2468         tables_lock();
2469
2470         *classes_ptr = heap_allocate(sizeof(jclass*)*classcache_hash.entries,true,NULL);
2471         *class_count_ptr = classcache_hash.entries;
2472         j=0;
2473     /* look in every slot of the hashtable */
2474         for (i=0; i<classcache_hash.size; i++) { 
2475                 cne =(classcache_name_entry*) classcache_hash.ptr[i];
2476                 while (cne != NULL) { /* iterate over hashlink */
2477                         cce = cne->classes;
2478                         while (cce != NULL){ /* iterate over classes with same name */
2479                                 if (cce->classobj != NULL) { /* get only loaded classes */
2480                                         assert(j<classcache_hash.entries);
2481                                         *classes_ptr[j]=cce->classobj;
2482                                         j++;
2483                                 }
2484                                 cce = cce->next;
2485                         }
2486                         cne = cne->hashlink;
2487                 }
2488         }
2489
2490         tables_unlock();
2491
2492     return JVMTI_ERROR_NONE;
2493 }
2494
2495
2496 /* GetClassLoaderClasses *******************************************************
2497
2498    Returns an array of those classes for which this class loader has been 
2499    recorded as an initiating loader.
2500
2501 *******************************************************************************/
2502
2503 jvmtiError
2504 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
2505                        jint * class_count_ptr, jclass ** classes_ptr)
2506 {
2507     CHECK_PHASE_START
2508     CHECK_PHASE(JVMTI_PHASE_LIVE)
2509     CHECK_PHASE_END;
2510
2511 /*    if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2512           if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
2513         
2514         /* behave like jdk 1.1 and make no distinction between initiating and 
2515            defining class loaders */
2516         
2517     return GetLoadedClasses(env, class_count_ptr, classes_ptr);
2518 }
2519
2520
2521 /* PopFrame *******************************************************************
2522
2523    
2524
2525 *******************************************************************************/
2526
2527 jvmtiError
2528 PopFrame (jvmtiEnv * env, jthread thread)
2529 {
2530     CHECK_PHASE_START
2531     CHECK_PHASE(JVMTI_PHASE_LIVE)
2532     CHECK_PHASE_END;
2533     CHECK_CAPABILITY(env,can_pop_frame)
2534         
2535                 log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2536     return JVMTI_ERROR_NONE;
2537 }
2538
2539
2540 /* RedefineClasses ************************************************************
2541
2542    
2543
2544 *******************************************************************************/
2545
2546 jvmtiError
2547 RedefineClasses (jvmtiEnv * env, jint class_count,
2548                  const jvmtiClassDefinition * class_definitions)
2549 {
2550         CHECK_PHASE_START
2551     CHECK_PHASE(JVMTI_PHASE_START)
2552     CHECK_PHASE(JVMTI_PHASE_LIVE)
2553     CHECK_PHASE_END;
2554         CHECK_CAPABILITY(env,can_redefine_classes)    
2555         CHECK_CAPABILITY(env,can_redefine_any_class)
2556   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2557     return JVMTI_ERROR_NONE;
2558 }
2559
2560
2561 /* GetVersionNumber ***********************************************************
2562
2563    Return the JVM TI version identifier.   
2564
2565 *******************************************************************************/
2566
2567 jvmtiError
2568 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
2569 {
2570     if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2571
2572     *version_ptr = JVMTI_VERSION_1_0;
2573     
2574     return JVMTI_ERROR_NONE;
2575 }
2576
2577
2578 /* GetCapabilities ************************************************************
2579
2580    Returns the optional JVM TI features which this environment currently 
2581    possesses.
2582
2583 *******************************************************************************/
2584
2585 jvmtiError
2586 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
2587 {
2588     if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2589
2590     memcpy(capabilities_ptr, &(((environment*) env)->capabilities), sizeof(JVMTI_Capabilities));
2591
2592     return JVMTI_ERROR_NONE;
2593 }
2594
2595
2596 /* *****************************************************************************
2597
2598    
2599
2600 *******************************************************************************/
2601
2602 jvmtiError
2603 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
2604                          char **source_debug_extension_ptr)
2605 {
2606     CHECK_PHASE_START
2607     CHECK_PHASE(JVMTI_PHASE_START)
2608     CHECK_PHASE(JVMTI_PHASE_LIVE)
2609     CHECK_PHASE_END;
2610         CHECK_CAPABILITY(env,can_get_source_debug_extension)
2611         
2612     log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2613     return JVMTI_ERROR_NONE;
2614 }
2615
2616
2617 /* IsMethodObsolete ************************************************************
2618
2619    Determine if a method ID refers to an obsolete method version. 
2620
2621 *******************************************************************************/
2622
2623 jvmtiError
2624 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
2625                   jboolean * is_obsolete_ptr)
2626 {
2627     CHECK_PHASE_START
2628     CHECK_PHASE(JVMTI_PHASE_START)
2629     CHECK_PHASE(JVMTI_PHASE_LIVE)
2630     CHECK_PHASE_END;
2631         CHECK_CAPABILITY(env,can_redefine_classes)        
2632
2633     log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2634     return JVMTI_ERROR_NONE;
2635 }
2636
2637
2638 /* *****************************************************************************
2639
2640    
2641
2642 *******************************************************************************/
2643
2644 jvmtiError
2645 SuspendThreadList (jvmtiEnv * env, jint request_count,
2646                    const jthread * request_list, jvmtiError * results)
2647 {
2648     CHECK_PHASE_START
2649     CHECK_PHASE(JVMTI_PHASE_START)
2650     CHECK_PHASE(JVMTI_PHASE_LIVE)
2651     CHECK_PHASE_END;
2652     CHECK_CAPABILITY(env,can_suspend)
2653         
2654   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2655     return JVMTI_ERROR_NONE;
2656 }
2657
2658
2659 /* *****************************************************************************
2660
2661    
2662
2663 *******************************************************************************/
2664
2665 jvmtiError
2666 ResumeThreadList (jvmtiEnv * env, jint request_count,
2667                   const jthread * request_list, jvmtiError * results)
2668 {
2669         CHECK_PHASE_START
2670     CHECK_PHASE(JVMTI_PHASE_LIVE)
2671     CHECK_PHASE_END;
2672     CHECK_CAPABILITY(env,can_suspend)
2673         
2674   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
2675     return JVMTI_ERROR_NONE;
2676 }
2677
2678
2679 /* GetStackTrace **************************************************************
2680
2681    Get information about the stack of a thread
2682
2683 *******************************************************************************/
2684
2685 jvmtiError
2686 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
2687                jint max_frame_count, jvmtiFrameInfo * frame_buffer,
2688                jint * count_ptr)
2689 {
2690         stackTraceBuffer* trace;
2691         jvmtiError er;
2692         int i,j;
2693
2694         CHECK_PHASE_START
2695     CHECK_PHASE(JVMTI_PHASE_LIVE)
2696     CHECK_PHASE_END;
2697     
2698         if(!builtin_instanceof(thread,class_java_lang_Thread))
2699                 return JVMTI_ERROR_INVALID_THREAD;
2700
2701         CHECK_THREAD_IS_ALIVE(thread);
2702
2703         if((count_ptr == NULL)||(frame_buffer == NULL)) 
2704                 return JVMTI_ERROR_NULL_POINTER;
2705
2706         if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2707
2708         er = getcacaostacktrace(&trace, thread);
2709         if (er==JVMTI_ERROR_NONE) return er;
2710
2711         if ((trace->size >= start_depth) || ((trace->size * -1) > start_depth)) 
2712                 return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2713         
2714         for (i=start_depth, j=0;i<trace->size;i++,j++) {
2715                 frame_buffer[j].method = (jmethodID)trace[i].start->method;
2716         /* todo: location MachinePC not avilable - Linenumber not expected */
2717                 frame_buffer[j].location = 0;
2718         }
2719         
2720     return JVMTI_ERROR_NONE;
2721 }
2722
2723
2724 /* GetThreadListStackTraces ***************************************************
2725
2726    Get information about the stacks of the supplied threads.
2727
2728 *******************************************************************************/
2729
2730 jvmtiError
2731 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
2732                           const jthread * thread_list,
2733                           jint max_frame_count,
2734                           jvmtiStackInfo ** stack_info_ptr)
2735 {
2736         int i;
2737         jvmtiError er;
2738         
2739         CHECK_PHASE_START
2740     CHECK_PHASE(JVMTI_PHASE_LIVE)
2741     CHECK_PHASE_END;
2742         
2743         if ((stack_info_ptr == NULL)||(thread_list == NULL)) 
2744                 return JVMTI_ERROR_NULL_POINTER;
2745
2746         if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2747
2748         if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
2749
2750         *stack_info_ptr = (jvmtiStackInfo*) 
2751                 heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
2752
2753         for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
2754                 (*stack_info_ptr)[i].thread=thread_list[i];
2755                 GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
2756                 (*stack_info_ptr)[i].frame_buffer = 
2757                         heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
2758                 er = GetStackTrace(env,thread_list[i],0,max_frame_count,
2759                                                    (*stack_info_ptr)[i].frame_buffer,
2760                                                    &((*stack_info_ptr)[i].frame_count));
2761
2762                 if (er != JVMTI_ERROR_NONE) return er;
2763         }
2764
2765     return JVMTI_ERROR_NONE;
2766 }
2767
2768
2769 /* GetAllStackTraces **********************************************************
2770
2771    Get stack traces of all live threads
2772
2773 *******************************************************************************/
2774
2775 jvmtiError
2776 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
2777                    jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
2778 {
2779         jthread *threads_ptr;
2780         jvmtiError er;
2781
2782         CHECK_PHASE_START
2783     CHECK_PHASE(JVMTI_PHASE_LIVE)
2784     CHECK_PHASE_END;
2785     
2786         if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2787     
2788         /* todo: all threads have to be suspended */ 
2789
2790         if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
2791                 return JVMTI_ERROR_INTERNAL;
2792
2793         GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
2794                                                          max_frame_count, stack_info_ptr);
2795
2796         /* todo: resume all threads have to be suspended */ 
2797         if (er != JVMTI_ERROR_NONE) return er;
2798
2799     return JVMTI_ERROR_NONE;
2800 }
2801
2802
2803 /* GetThreadLocalStorage ******************************************************
2804
2805    Get the value of the JVM TI thread-local storage.
2806
2807 *******************************************************************************/
2808
2809 jvmtiError
2810 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
2811 {
2812         jvmtiThreadLocalStorage *tls;
2813
2814         CHECK_PHASE_START
2815     CHECK_PHASE(JVMTI_PHASE_START)
2816     CHECK_PHASE(JVMTI_PHASE_LIVE)
2817     CHECK_PHASE_END;
2818
2819         if(thread == NULL)
2820                 thread = (jthread) THREADOBJECT;
2821         else {
2822                 if (!builtin_instanceof(thread,class_java_lang_Thread)) 
2823                         return JVMTI_ERROR_INVALID_THREAD;
2824                 CHECK_THREAD_IS_ALIVE(thread);
2825         }
2826
2827         if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
2828
2829         tls = ((environment*)env)->tls;
2830         while ((tls->thread != thread) && (tls != NULL)) {
2831                 tls = tls->next;
2832         }
2833         
2834         if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
2835         
2836         *data_ptr = tls->data;
2837         
2838     return JVMTI_ERROR_NONE;
2839 }
2840
2841
2842 /* SetThreadLocalStorage *******************************************************
2843
2844    Stores a pointer value associated with each environment-thread pair. The 
2845    value is NULL unless set with this function. Agents can allocate memory in 
2846    which they store thread specific information
2847
2848 *******************************************************************************/
2849
2850 jvmtiError
2851 SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
2852 {
2853         jvmtiThreadLocalStorage *tls, *pre;
2854         environment* env = (environment*)jenv;
2855
2856         CHECK_PHASE_START
2857     CHECK_PHASE(JVMTI_PHASE_START)
2858     CHECK_PHASE(JVMTI_PHASE_LIVE)
2859     CHECK_PHASE_END;
2860         
2861         if(thread == NULL)
2862                 thread = (jthread) THREADOBJECT;
2863         else {
2864                 if (!builtin_instanceof(thread,class_java_lang_Thread)) 
2865                         return JVMTI_ERROR_INVALID_THREAD;
2866                 CHECK_THREAD_IS_ALIVE(thread);
2867         }
2868         
2869         if (env->tls == NULL) {
2870                 tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2871         } else {
2872                 tls = env->tls;
2873                 while ((tls->thread != thread) && (tls->next != NULL)) {
2874                         tls = tls->next;
2875                 }
2876                 if (tls->thread != thread) {
2877                         tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
2878                         tls = tls->next;
2879                 }
2880         }
2881         
2882         if (data != NULL) {
2883                 tls->data = (void*)data;
2884         } else { 
2885                 /* remove current tls */
2886                 pre = env->tls;
2887                 while (pre->next == tls) pre = pre->next;
2888                 pre->next = tls->next;
2889         }
2890     return JVMTI_ERROR_NONE;
2891 }
2892
2893
2894 /* *****************************************************************************
2895
2896    
2897
2898 *******************************************************************************/
2899
2900 jvmtiError
2901 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
2902 {
2903         CHECK_PHASE_START
2904     CHECK_PHASE(JVMTI_PHASE_START)
2905     CHECK_PHASE(JVMTI_PHASE_LIVE)
2906     CHECK_PHASE_END;
2907         CHECK_CAPABILITY(env,can_tag_objects)
2908     
2909   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2910     return JVMTI_ERROR_NONE;
2911 }
2912
2913 /* *****************************************************************************
2914
2915    
2916
2917 *******************************************************************************/
2918
2919 jvmtiError
2920 SetTag (jvmtiEnv * env, jobject object, jlong tag)
2921 {
2922         CHECK_PHASE_START
2923     CHECK_PHASE(JVMTI_PHASE_START)
2924     CHECK_PHASE(JVMTI_PHASE_LIVE)
2925     CHECK_PHASE_END;
2926         CHECK_CAPABILITY(env,can_tag_objects)
2927         
2928   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2929     return JVMTI_ERROR_NONE;
2930 }
2931
2932
2933 /* ForceGarbageCollection *****************************************************
2934
2935    Force boehm-gc to perform a garbage collection
2936
2937 *******************************************************************************/
2938
2939 jvmtiError
2940 ForceGarbageCollection (jvmtiEnv * env)
2941 {
2942         CHECK_PHASE_START
2943     CHECK_PHASE(JVMTI_PHASE_LIVE)
2944     CHECK_PHASE_END;
2945
2946         gc_call();        
2947
2948     return JVMTI_ERROR_NONE;
2949 }
2950
2951
2952 /* IterateOverObjectsReachableFromObject **************************************
2953
2954    
2955
2956 *******************************************************************************/
2957
2958 jvmtiError
2959 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
2960                                        jvmtiObjectReferenceCallback
2961                                        object_reference_callback,
2962                                        void *user_data)
2963 {
2964         CHECK_PHASE_START
2965     CHECK_PHASE(JVMTI_PHASE_LIVE)
2966     CHECK_PHASE_END;
2967         CHECK_CAPABILITY(env,can_tag_objects)
2968         
2969   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2970     return JVMTI_ERROR_NONE;
2971 }
2972
2973
2974 /* IterateOverReachableObjects ************************************************
2975
2976    
2977
2978 *******************************************************************************/
2979
2980 jvmtiError
2981 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
2982                              heap_root_callback,
2983                              jvmtiStackReferenceCallback
2984                              stack_ref_callback,
2985                              jvmtiObjectReferenceCallback
2986                              object_ref_callback, void *user_data)
2987 {
2988         CHECK_PHASE_START
2989     CHECK_PHASE(JVMTI_PHASE_LIVE)
2990     CHECK_PHASE_END;
2991         CHECK_CAPABILITY(env,can_tag_objects)
2992     
2993   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
2994     return JVMTI_ERROR_NONE;
2995 }
2996
2997
2998 /* IterateOverHeap ************************************************************
2999
3000    
3001
3002 *******************************************************************************/
3003
3004 jvmtiError
3005 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
3006                  jvmtiHeapObjectCallback heap_object_callback,
3007                  void *user_data)
3008 {
3009         CHECK_PHASE_START
3010     CHECK_PHASE(JVMTI_PHASE_LIVE)
3011     CHECK_PHASE_END;
3012         CHECK_CAPABILITY(env,can_tag_objects)
3013     
3014   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3015     return JVMTI_ERROR_NONE;
3016 }
3017
3018
3019 /* IterateOverInstancesOfClass ************************************************
3020
3021    
3022
3023 *******************************************************************************/
3024
3025 jvmtiError
3026 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
3027                              jvmtiHeapObjectFilter object_filter,
3028                              jvmtiHeapObjectCallback
3029                              heap_object_callback, void *user_data)
3030 {
3031         CHECK_PHASE_START
3032     CHECK_PHASE(JVMTI_PHASE_LIVE)
3033     CHECK_PHASE_END;
3034         CHECK_CAPABILITY(env,can_tag_objects)
3035    
3036   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3037     return JVMTI_ERROR_NONE;
3038 }
3039
3040
3041 /* *****************************************************************************
3042
3043    
3044
3045 *******************************************************************************/
3046
3047 jvmtiError
3048 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
3049                     jint * count_ptr, jobject ** object_result_ptr,
3050                     jlong ** tag_result_ptr)
3051 {
3052         CHECK_PHASE_START
3053     CHECK_PHASE(JVMTI_PHASE_LIVE)
3054     CHECK_PHASE_END;
3055         CHECK_CAPABILITY(env,can_tag_objects)
3056         
3057   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3058     return JVMTI_ERROR_NONE;
3059 }
3060
3061
3062 /* SetJNIFunctionTable **********************************************************
3063
3064    Set the JNI function table in all current and future JNI environments
3065
3066 *******************************************************************************/
3067
3068 jvmtiError
3069 SetJNIFunctionTable (jvmtiEnv * env,
3070                      const jniNativeInterface * function_table)
3071
3072     CHECK_PHASE_START
3073     CHECK_PHASE(JVMTI_PHASE_START)
3074     CHECK_PHASE(JVMTI_PHASE_LIVE)
3075     CHECK_PHASE_END;;
3076     
3077     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3078     ptr_env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
3079     memcpy(ptr_env, function_table, sizeof(jniNativeInterface));
3080     return JVMTI_ERROR_NONE;
3081 }
3082
3083
3084 /* GetJNIFunctionTable *********************************************************
3085
3086    Get the JNI function table. The JNI function table is copied into allocated 
3087    memory.
3088
3089 *******************************************************************************/
3090
3091 jvmtiError
3092 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
3093 {
3094     CHECK_PHASE_START
3095     CHECK_PHASE(JVMTI_PHASE_START)
3096     CHECK_PHASE(JVMTI_PHASE_LIVE)
3097     CHECK_PHASE_END;
3098
3099     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
3100     *function_table = (jniNativeInterface*)
3101         heap_allocate(sizeof(jniNativeInterface),true,NULL);
3102     memcpy(*function_table, ptr_env, sizeof(jniNativeInterface));
3103     return JVMTI_ERROR_NONE;
3104 }
3105
3106
3107 /* SetEventCallbacks **********************************************************
3108
3109    Set the functions to be called for each event. The callbacks are specified 
3110    by supplying a replacement function table.
3111
3112 *******************************************************************************/
3113
3114 jvmtiError
3115 SetEventCallbacks (jvmtiEnv * env,
3116                    const jvmtiEventCallbacks * callbacks,
3117                    jint size_of_callbacks)
3118 {
3119     CHECK_PHASE_START
3120     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3121     CHECK_PHASE(JVMTI_PHASE_LIVE)
3122     CHECK_PHASE_END;
3123
3124     if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3125     
3126     if (callbacks == NULL) { /* remove the existing callbacks */
3127         memset(&(((environment* )env)->callbacks), 0, 
3128                            sizeof(jvmtiEventCallbacks));
3129     }
3130
3131     memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
3132
3133     return JVMTI_ERROR_NONE;
3134 }
3135
3136
3137 /* GenerateEvents *************************************************************
3138
3139    Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent 
3140    the current state of the VM.
3141
3142 *******************************************************************************/
3143
3144 jvmtiError
3145 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
3146 {
3147     CHECK_PHASE_START
3148     CHECK_PHASE(JVMTI_PHASE_LIVE)
3149     CHECK_PHASE_END;
3150         
3151   log_text ("JVMTI-Call: IMPLEMENT ME!!!");
3152     return JVMTI_ERROR_NONE;
3153 }
3154
3155
3156 /* GetExtensionFunctions ******************************************************
3157
3158    Returns the set of extension functions.
3159
3160 *******************************************************************************/
3161
3162 jvmtiError
3163 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
3164                        jvmtiExtensionFunctionInfo ** extensions)
3165 {
3166     CHECK_PHASE_START
3167     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3168     CHECK_PHASE(JVMTI_PHASE_LIVE)
3169     CHECK_PHASE_END;
3170         
3171     if ((extension_count_ptr== NULL)||(extensions == NULL)) 
3172         return JVMTI_ERROR_NULL_POINTER;
3173
3174     /* cacao has no extended functions yet */
3175     *extension_count_ptr = 0;
3176
3177     return JVMTI_ERROR_NONE;
3178 }
3179
3180
3181 /* GetExtensionEvents *********************************************************
3182
3183    Returns the set of extension events.
3184
3185 *******************************************************************************/
3186
3187 jvmtiError
3188 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
3189                     jvmtiExtensionEventInfo ** extensions)
3190 {
3191     CHECK_PHASE_START
3192     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3193     CHECK_PHASE(JVMTI_PHASE_LIVE)
3194     CHECK_PHASE_END;
3195         
3196     if ((extension_count_ptr== NULL)||(extensions == NULL)) 
3197         return JVMTI_ERROR_NULL_POINTER;
3198
3199     /* cacao has no extended events yet */
3200     *extension_count_ptr = 0;
3201
3202     return JVMTI_ERROR_NONE;
3203 }
3204
3205
3206 /* SetExtensionEventCallback **************************************************
3207
3208    Sets the callback function for an extension event and enables the event.
3209
3210 *******************************************************************************/
3211
3212 jvmtiError
3213 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
3214                            jvmtiExtensionEvent callback)
3215 {
3216     CHECK_PHASE_START
3217     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3218     CHECK_PHASE(JVMTI_PHASE_LIVE)
3219     CHECK_PHASE_END;
3220
3221     /* cacao has no extended events yet */
3222     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3223 }
3224
3225
3226 /* DisposeEnvironment **********************************************************
3227
3228    Shutdown a JVM TI connection created with JNI GetEnv.
3229
3230 *******************************************************************************/
3231
3232 jvmtiError
3233 DisposeEnvironment (jvmtiEnv * env)
3234 {
3235         environment* cacao_env = (environment*)env;
3236         environment* tenvs = envs;
3237     memset(&((cacao_env)->events[0]),0,sizeof(jvmtiEventModeLL)*
3238                    (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
3239     (cacao_env)->EnvironmentLocalStorage = NULL;
3240         
3241         if (tenvs!=cacao_env) {
3242                 while (tenvs->next != cacao_env) {
3243                         tenvs = tenvs->next;
3244                 }
3245                 tenvs->next = cacao_env->next;
3246         } else
3247                 envs = NULL;
3248
3249     /* let Boehm GC do the rest */
3250     return JVMTI_ERROR_NONE;
3251 }
3252
3253
3254 /* GetErrorName ***************************************************************
3255
3256    Return the symbolic name for an error code.
3257
3258 *******************************************************************************/
3259
3260 #define COPY_RESPONSE(name_ptr,str) *name_ptr = (char*) heap_allocate(sizeof(str),true,NULL); \
3261                                     memcpy(*name_ptr, &str, sizeof(str)); \
3262                                     break
3263
3264 jvmtiError
3265 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
3266 {
3267     if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3268
3269     switch (error) {
3270     case JVMTI_ERROR_NONE : 
3271         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NONE");
3272     case JVMTI_ERROR_NULL_POINTER : 
3273         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NULL_POINTER"); 
3274     case JVMTI_ERROR_OUT_OF_MEMORY : 
3275         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OUT_OF_MEMORY");
3276     case JVMTI_ERROR_ACCESS_DENIED : 
3277         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ACCESS_DENIED");
3278     case JVMTI_ERROR_UNATTACHED_THREAD : 
3279         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNATTACHED_THREAD");
3280     case JVMTI_ERROR_INVALID_ENVIRONMENT : 
3281         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_ENVIRONMENT"); 
3282     case JVMTI_ERROR_WRONG_PHASE : 
3283         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_WRONG_PHASE");
3284     case JVMTI_ERROR_INTERNAL : 
3285         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERNAL");
3286     case JVMTI_ERROR_INVALID_PRIORITY : 
3287         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_PRIORITY");
3288     case JVMTI_ERROR_THREAD_NOT_SUSPENDED : 
3289         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_SUSPENDED");
3290     case JVMTI_ERROR_THREAD_SUSPENDED : 
3291         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_SUSPENDED");
3292     case JVMTI_ERROR_THREAD_NOT_ALIVE : 
3293         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_THREAD_NOT_ALIVE");
3294     case JVMTI_ERROR_CLASS_NOT_PREPARED : 
3295         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CLASS_NOT_PREPARED");
3296     case JVMTI_ERROR_NO_MORE_FRAMES : 
3297         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NO_MORE_FRAMES");
3298     case JVMTI_ERROR_OPAQUE_FRAME : 
3299         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_OPAQUE_FRAME");
3300     case JVMTI_ERROR_DUPLICATE : 
3301         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_DUPLICATE");
3302     case JVMTI_ERROR_NOT_FOUND : 
3303         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_FOUND");
3304     case JVMTI_ERROR_NOT_MONITOR_OWNER : 
3305         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_MONITOR_OWNER");
3306     case JVMTI_ERROR_INTERRUPT : 
3307         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INTERRUPT");
3308     case JVMTI_ERROR_UNMODIFIABLE_CLASS : 
3309         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNMODIFIABLE_CLASS");
3310     case JVMTI_ERROR_NOT_AVAILABLE : 
3311         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NOT_AVAILABLE");
3312     case JVMTI_ERROR_ABSENT_INFORMATION : 
3313         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ABSENT_INFORMATION");
3314     case JVMTI_ERROR_INVALID_EVENT_TYPE : 
3315         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_EVENT_TYPE");
3316     case JVMTI_ERROR_NATIVE_METHOD : 
3317         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NATIVE_METHOD");
3318     case JVMTI_ERROR_INVALID_THREAD : 
3319         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD");
3320     case JVMTI_ERROR_INVALID_FIELDID : 
3321         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_FIELDID");
3322     case JVMTI_ERROR_INVALID_METHODID : 
3323         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_METHODID");
3324     case JVMTI_ERROR_INVALID_LOCATION : 
3325         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_LOCATION");
3326     case JVMTI_ERROR_INVALID_OBJECT : 
3327         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_OBJECT");
3328     case JVMTI_ERROR_INVALID_CLASS : 
3329         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS");
3330     case JVMTI_ERROR_TYPE_MISMATCH : 
3331         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_TYPE_MISMATCH");
3332     case JVMTI_ERROR_INVALID_SLOT : 
3333         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_SLOT");
3334     case JVMTI_ERROR_MUST_POSSESS_CAPABILITY : 
3335         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
3336     case JVMTI_ERROR_INVALID_THREAD_GROUP : 
3337         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_THREAD_GROUP");
3338     case JVMTI_ERROR_INVALID_MONITOR : 
3339         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_MONITOR");
3340     case JVMTI_ERROR_ILLEGAL_ARGUMENT : 
3341         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_ILLEGAL_ARGUMENT");
3342     case JVMTI_ERROR_INVALID_TYPESTATE : 
3343         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_TYPESTATE");
3344     case JVMTI_ERROR_UNSUPPORTED_VERSION : 
3345         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_VERSION");
3346     case JVMTI_ERROR_INVALID_CLASS_FORMAT : 
3347         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_INVALID_CLASS_FORMAT");
3348     case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION : 
3349         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
3350     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED : 
3351         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
3352     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED : 
3353         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
3354     case JVMTI_ERROR_FAILS_VERIFICATION : 
3355         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_FAILS_VERIFICATION");
3356     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED : 
3357         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
3358     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED : 
3359         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
3360     case JVMTI_ERROR_NAMES_DONT_MATCH : 
3361         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_NAMES_DONT_MATCH");
3362     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED : 
3363         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
3364     case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED : 
3365         COPY_RESPONSE (name_ptr, "JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
3366     default:
3367         return JVMTI_ERROR_ILLEGAL_ARGUMENT;
3368     }
3369     return JVMTI_ERROR_NONE;
3370 }
3371
3372 /* GetJLocationFormat **********************************************************
3373
3374    This function describes the representation of jlocation used in this VM.
3375
3376 *******************************************************************************/
3377
3378 jvmtiError
3379 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
3380 {
3381     *format_ptr = JVMTI_JLOCATION_MACHINEPC;
3382     return JVMTI_ERROR_NONE;
3383 }
3384
3385
3386 /* GetSystemProperties ********************************************************
3387
3388    The list of VM system property keys which may be used with GetSystemProperty 
3389    is returned.
3390
3391 *******************************************************************************/
3392
3393 jvmtiError
3394 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
3395 {
3396     jmethodID mid;
3397     jmethodID moremid;
3398     classinfo *sysclass, *propclass, *enumclass;
3399     java_objectheader *sysprop, *keys, *obj;
3400     char* ch;
3401     int i;
3402
3403     CHECK_PHASE_START
3404     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3405     CHECK_PHASE(JVMTI_PHASE_LIVE)
3406     CHECK_PHASE_END;
3407
3408     if ((count_ptr == NULL) || (property_ptr == NULL)) 
3409         return JVMTI_ERROR_NULL_POINTER;
3410
3411     sysclass = load_class_from_sysloader(
3412         utf_new_char_classname ("java/lang/System"));
3413
3414     if (!sysclass) throw_main_exception_exit();
3415
3416     mid = class_resolvemethod(sysclass, 
3417                               utf_new_char("getProperties"),
3418                               utf_new_char("()Ljava/util/Properties;"));
3419     if (!mid) throw_main_exception_exit();
3420
3421
3422     sysprop = asm_calljavafunction(mid, sysclass, NULL, NULL, NULL);
3423     if (!sysprop) throw_main_exception_exit();
3424
3425     propclass = sysprop->vftbl->class;
3426
3427     mid = class_resolvemethod(propclass, 
3428                               utf_new_char("size"),
3429                               utf_new_char("()I"));
3430     if (!mid) throw_main_exception_exit();
3431
3432     *count_ptr = 
3433         JNI_JNIEnvTable.CallIntMethod(NULL, sysprop, mid);
3434     *property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
3435
3436     mid = class_resolvemethod(propclass, 
3437                               utf_new_char("keys"),
3438                               utf_new_char("()Ljava/util/Enumeration;"));
3439     if (!mid) throw_main_exception_exit();
3440
3441     keys = JNI_JNIEnvTable.CallObjectMethod(NULL, sysprop, mid);
3442     enumclass = keys->vftbl->class;
3443         
3444     moremid = class_resolvemethod(enumclass, 
3445                                   utf_new_char("hasMoreElements"),
3446                                   utf_new_char("()Z"));
3447     if (!moremid) throw_main_exception_exit();
3448
3449     mid = class_resolvemethod(propclass, 
3450                               utf_new_char("nextElement"),
3451                               utf_new_char("()Ljava/lang/Object;"));
3452     if (!mid) throw_main_exception_exit();
3453
3454     i = 0;
3455     while (JNI_JNIEnvTable.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
3456         obj = JNI_JNIEnvTable.CallObjectMethod(NULL, keys, mid);
3457         ch = javastring_tochar(obj);
3458         *property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3459         memcpy(*property_ptr[i], ch, strlen (ch));
3460         MFREE(ch,char,strlen(ch)+1);
3461         i++;
3462     }
3463
3464     return JVMTI_ERROR_NONE;
3465 }
3466
3467
3468 /* GetSystemProperty **********************************************************
3469
3470    Return a VM system property value given the property key.
3471
3472 *******************************************************************************/
3473
3474 jvmtiError
3475 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
3476 {
3477     jmethodID mid;
3478     classinfo *sysclass, *propclass;
3479     java_objectheader *sysprop, *obj;
3480     char* ch;
3481
3482     CHECK_PHASE_START
3483     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3484     CHECK_PHASE(JVMTI_PHASE_LIVE)
3485     CHECK_PHASE_END;
3486
3487     if ((value_ptr == NULL) || (property == NULL)) 
3488         return JVMTI_ERROR_NULL_POINTER;
3489
3490     sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3491     if (!sysclass) throw_main_exception_exit();
3492
3493     mid = class_resolvemethod(sysclass, 
3494                               utf_new_char("getProperties"),
3495                               utf_new_char("()Ljava/util/Properties;"));
3496     if (!mid) throw_main_exception_exit();
3497
3498     sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3499
3500     propclass = sysprop->vftbl->class;
3501
3502     mid = class_resolvemethod(propclass, 
3503                               utf_new_char("getProperty"),
3504                               utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
3505     if (!mid) throw_main_exception_exit();
3506
3507     obj = (java_objectheader*)JNI_JNIEnvTable.CallObjectMethod(
3508         NULL, sysprop, mid, javastring_new_char(property));
3509     if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
3510
3511     ch = javastring_tochar(obj);
3512     *value_ptr = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
3513     memcpy(*value_ptr, ch, strlen (ch));
3514     MFREE(ch,char,strlen(ch)+1);       
3515
3516     return JVMTI_ERROR_NONE;
3517 }
3518
3519
3520 /* SetSystemProperty **********************************************************
3521
3522    Set a VM system property value.
3523
3524 *******************************************************************************/
3525
3526 jvmtiError
3527 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
3528 {
3529     jmethodID mid;
3530     classinfo *sysclass, *propclass;
3531     java_objectheader *sysprop;
3532
3533     CHECK_PHASE_START
3534     CHECK_PHASE(JVMTI_PHASE_START)
3535     CHECK_PHASE_END;
3536         
3537     if (property == NULL) return JVMTI_ERROR_NULL_POINTER;
3538     if (value == NULL) return JVMTI_ERROR_NOT_AVAILABLE;
3539
3540     sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
3541     if (!sysclass) throw_main_exception_exit();
3542
3543     mid = class_resolvemethod(sysclass, 
3544                               utf_new_char("getProperties"),
3545                               utf_new_char("()Ljava/util/Properties;"));
3546     if (!mid) throw_main_exception_exit();
3547
3548     sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
3549
3550     propclass = sysprop->vftbl->class;
3551
3552     mid = class_resolvemethod(propclass, 
3553                               utf_new_char("setProperty"),
3554                               utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
3555     if (!mid) throw_main_exception_exit();
3556
3557     JNI_JNIEnvTable.CallObjectMethod(
3558         NULL, sysprop, mid, javastring_new_char(property),javastring_new_char(value));
3559     
3560     return JVMTI_ERROR_NONE;
3561 }
3562
3563 /* GetPhase ********************************************************************
3564
3565    Return the current phase of VM execution
3566
3567 *******************************************************************************/
3568
3569 jvmtiError
3570 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
3571 {
3572     if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3573     
3574     *phase_ptr = phase;
3575
3576     return JVMTI_ERROR_NONE;
3577 }
3578
3579 /* GetCurrentThreadCpuTimerInfo ************************************************
3580
3581    
3582
3583 *******************************************************************************/
3584
3585 jvmtiError
3586 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3587 {
3588         CHECK_PHASE_START
3589     CHECK_PHASE(JVMTI_PHASE_START)
3590     CHECK_PHASE(JVMTI_PHASE_LIVE)
3591     CHECK_PHASE_END;
3592         CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)     
3593
3594   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3595
3596     return JVMTI_ERROR_NONE;
3597 }
3598
3599 /* GetCurrentThreadCpuTime ****************************************************
3600
3601    
3602
3603 *******************************************************************************/
3604
3605 jvmtiError
3606 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
3607 {
3608         CHECK_PHASE_START
3609     CHECK_PHASE(JVMTI_PHASE_START)
3610     CHECK_PHASE(JVMTI_PHASE_LIVE)
3611     CHECK_PHASE_END;
3612         CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)     
3613         
3614   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3615     return JVMTI_ERROR_NONE;
3616 }
3617
3618 /* GetThreadCpuTimerInfo ******************************************************
3619
3620    
3621
3622 *******************************************************************************/
3623
3624 jvmtiError
3625 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3626 {
3627         CHECK_PHASE_START
3628     CHECK_PHASE(JVMTI_PHASE_START)
3629     CHECK_PHASE(JVMTI_PHASE_LIVE)
3630     CHECK_PHASE_END;
3631         CHECK_CAPABILITY(env,can_get_thread_cpu_time)
3632     
3633   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3634     return JVMTI_ERROR_NONE;
3635 }
3636
3637 /* GetThreadCpuTime ***********************************************************
3638
3639    
3640
3641 *******************************************************************************/
3642
3643 jvmtiError
3644 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
3645 {
3646         CHECK_PHASE_START
3647     CHECK_PHASE(JVMTI_PHASE_LIVE)
3648     CHECK_PHASE_END;
3649         CHECK_CAPABILITY(env,can_get_thread_cpu_time)        
3650   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
3651     return JVMTI_ERROR_NONE;
3652 }
3653
3654 /* GetTimerInfo ***************************************************************
3655
3656    Get information about the GetTime timer.    
3657
3658 *******************************************************************************/
3659
3660 jvmtiError
3661 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
3662 {
3663     if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3664
3665     info_ptr->max_value = !0x0;
3666         info_ptr->may_skip_forward = true;
3667         info_ptr->may_skip_backward = true;
3668         info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
3669    
3670     return JVMTI_ERROR_NONE;
3671 }
3672
3673 /* GetTime ********************************************************************
3674
3675    Return the current value of the system timer, in nanoseconds
3676
3677 *******************************************************************************/
3678
3679 jvmtiError
3680 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
3681 {
3682     /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
3683     struct timeval tp;
3684     
3685     if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3686
3687     if (gettimeofday (&tp, NULL) == -1)
3688         JNI_JNIEnvTable.FatalError (NULL, "gettimeofday call failed.");
3689     
3690     *nanos_ptr = (jlong) tp.tv_sec;
3691     *nanos_ptr *= 1000;
3692     *nanos_ptr += (tp.tv_usec / 1000);
3693
3694     return JVMTI_ERROR_NONE;
3695 }
3696
3697 /* GetPotentialCapabilities ***************************************************
3698
3699    Returns the JVM TI features that can potentially be possessed by this 
3700    environment at this time.
3701
3702 *******************************************************************************/
3703
3704 jvmtiError
3705 GetPotentialCapabilities (jvmtiEnv * env,
3706                           jvmtiCapabilities * capabilities_ptr)
3707 {
3708     CHECK_PHASE_START
3709     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3710     CHECK_PHASE(JVMTI_PHASE_LIVE)
3711     CHECK_PHASE_END;
3712         
3713     if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3714
3715     memcpy(capabilities_ptr, &JVMTI_Capabilities, sizeof(JVMTI_Capabilities));
3716
3717     return JVMTI_ERROR_NONE;
3718 }
3719
3720
3721 #define CHECK_ADD_CAPABILITY(env,CAN)      \
3722         if ((capabilities_ptr->CAN == 1) && \
3723            (JVMTI_Capabilities.CAN == 0))   \
3724            return JVMTI_ERROR_NOT_AVAILABLE; \
3725         env->capabilities.CAN = 1;
3726
3727 /* AddCapabilities ************************************************************
3728
3729    Set new capabilities by adding the capabilities pointed to by 
3730    capabilities_ptr. All previous capabilities are retained.
3731
3732 *******************************************************************************/
3733
3734 jvmtiError
3735 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
3736 {
3737     environment* cacao_env;
3738
3739     CHECK_PHASE_START
3740     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3741     CHECK_PHASE(JVMTI_PHASE_LIVE)
3742     CHECK_PHASE_END;
3743         
3744     if ((env == NULL) || (capabilities_ptr == NULL)) 
3745         return JVMTI_ERROR_NULL_POINTER;
3746     
3747     cacao_env = (environment*)env;
3748     
3749     CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
3750     CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
3751     CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
3752     CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
3753     CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3754     CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3755     CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3756     CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
3757     CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
3758     CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
3759     CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
3760     CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
3761     CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
3762     CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
3763     CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
3764     CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
3765     CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
3766     CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
3767     CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3768     CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3769     CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
3770     CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
3771     CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3772     CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3773     CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
3774     CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
3775     CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3776     CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3777     CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
3778     CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3779     CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3780     CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3781     CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
3782
3783
3784     return JVMTI_ERROR_NONE;    
3785 }
3786
3787
3788 #define CHECK_DEL_CAPABILITY(env,CAN)      \
3789         if (capabilities_ptr->CAN == 1) \
3790            env->capabilities.CAN = 0;
3791
3792 /* RelinquishCapabilities *****************************************************
3793
3794    Relinquish the capabilities pointed to by capabilities_ptr.
3795
3796 *******************************************************************************/
3797
3798 jvmtiError
3799 RelinquishCapabilities (jvmtiEnv * env,
3800                         const jvmtiCapabilities * capabilities_ptr)
3801 {
3802     environment* cacao_env;
3803     
3804     CHECK_PHASE_START
3805     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3806     CHECK_PHASE(JVMTI_PHASE_LIVE)
3807     CHECK_PHASE_END;
3808         
3809     if ((env == NULL) || (capabilities_ptr == NULL)) 
3810         return JVMTI_ERROR_NULL_POINTER;
3811
3812     cacao_env = (environment*)env;
3813
3814     CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
3815     CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
3816     CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
3817     CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
3818     CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
3819     CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
3820     CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
3821     CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
3822     CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
3823     CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
3824     CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
3825     CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
3826     CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
3827     CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
3828     CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
3829     CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
3830     CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
3831     CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
3832     CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
3833     CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
3834     CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
3835     CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
3836     CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
3837     CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
3838     CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
3839     CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
3840     CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
3841     CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
3842     CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
3843     CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
3844     CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
3845     CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
3846     CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
3847
3848     return JVMTI_ERROR_NONE;
3849 }
3850
3851 /* *****************************************************************************
3852
3853    
3854
3855 *******************************************************************************/
3856
3857 jvmtiError
3858 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
3859 {
3860         CHECK_PHASE_START
3861     CHECK_PHASE(JVMTI_PHASE_START)
3862     CHECK_PHASE(JVMTI_PHASE_LIVE)
3863     CHECK_PHASE_END;
3864     
3865         if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3866
3867         log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
3868         
3869         *processor_count_ptr = 1; /* where do I get this ?*/
3870         
3871     return JVMTI_ERROR_NONE;
3872 }
3873
3874 /* GetEnvironmentLocalStorage **************************************************
3875
3876    Called by the agent to get the value of the JVM TI environment-local storage.
3877
3878 *******************************************************************************/
3879
3880 jvmtiError
3881 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
3882 {
3883     if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
3884
3885     *data_ptr = ((environment*)env)->EnvironmentLocalStorage;
3886
3887     return JVMTI_ERROR_NONE;
3888 }
3889
3890 /* SetEnvironmentLocalStorage **************************************************
3891
3892    The VM stores a pointer value associated with each environment. Agents can 
3893    allocate memory in which they store environment specific information.
3894
3895 *******************************************************************************/
3896
3897 jvmtiError
3898 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
3899 {
3900     if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
3901
3902     ((environment*)env)->EnvironmentLocalStorage = (void*) data;
3903
3904     return JVMTI_ERROR_NONE;
3905 }
3906
3907 /* AddToBootstrapClassLoaderSearch ********************************************
3908
3909    After the bootstrap class loader unsuccessfully searches for a class, the 
3910    specified platform-dependent search path segment will be searched as well.
3911
3912 *******************************************************************************/
3913
3914 jvmtiError
3915 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
3916 {
3917     char* tmp_bcp;
3918     int ln;
3919
3920     CHECK_PHASE_START
3921     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
3922     CHECK_PHASE_END;
3923
3924     if (segment == NULL) return JVMTI_ERROR_NULL_POINTER;
3925
3926     ln = strlen(bootclasspath) + strlen(":") + strlen(segment);
3927     tmp_bcp = MNEW(char, ln);
3928     strcat(tmp_bcp, bootclasspath);
3929     strcat(tmp_bcp, ":");
3930     strcat(tmp_bcp, segment);
3931     MFREE(bootclasspath,char,ln);
3932     bootclasspath = tmp_bcp;
3933
3934     return JVMTI_ERROR_NONE;
3935 }
3936
3937 /* SetVerboseFlag *************************************************************
3938
3939    Control verbose output. This is the output which typically is sent to stderr
3940
3941 *******************************************************************************/
3942
3943 jvmtiError
3944 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
3945 {
3946     switch (flag) {
3947     case JVMTI_VERBOSE_OTHER: 
3948         runverbose = value;
3949         break;
3950     case JVMTI_VERBOSE_GC: 
3951         opt_verbosegc = value;
3952         break;
3953     case JVMTI_VERBOSE_CLASS: 
3954         loadverbose = value;
3955         break;
3956     case JVMTI_VERBOSE_JNI: 
3957         break;
3958     default:
3959         return JVMTI_ERROR_ILLEGAL_ARGUMENT;            
3960     }
3961     return JVMTI_ERROR_NONE;
3962 }
3963
3964 /* GetObjectSize **************************************************************
3965
3966    For the object object return the size.
3967
3968 *******************************************************************************/
3969
3970 jvmtiError
3971 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
3972 {
3973     CHECK_PHASE_START
3974     CHECK_PHASE(JVMTI_PHASE_START)
3975     CHECK_PHASE(JVMTI_PHASE_LIVE)
3976     CHECK_PHASE_END;
3977
3978         if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
3979         if (!builtin_instanceof(object,class_java_lang_Object))
3980                 return JVMTI_ERROR_INVALID_OBJECT;
3981
3982         *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
3983
3984     return JVMTI_ERROR_NONE;
3985 }
3986
3987
3988 /* *****************************************************************************
3989
3990    Environment variables
3991
3992 *******************************************************************************/
3993
3994 static jvmtiCapabilities JVMTI_Capabilities = {
3995   0,                            /* can_tag_objects */
3996   0,                            /* can_generate_field_modification_events */
3997   0,                            /* can_generate_field_access_events */
3998   1,                            /* can_get_bytecodes */
3999   0,                            /* can_get_synthetic_attribute */
4000
4001 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4002   1,                            /* can_get_owned_monitor_info */
4003   1,                            /* can_get_current_contended_monitor */
4004 #else
4005   0,                            /* can_get_owned_monitor_info */
4006   0,                            /* can_get_current_contended_monitor */
4007 #endif
4008
4009   0,                            /* can_get_monitor_info */
4010   0,                            /* can_pop_frame */
4011   0,                            /* can_redefine_classes */
4012 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4013   1,                            /* can_signal_thread */
4014 #else
4015   0,                            /* can_signal_thread */
4016 #endif
4017   1,                            /* can_get_source_file_name */
4018   1,                            /* can_get_line_numbers */
4019   0,                            /* can_get_source_debug_extension */
4020   0,                            /* can_access_local_variables */
4021   0,                            /* can_maintain_original_method_order */
4022   0,                            /* can_generate_single_step_events */
4023   0,                            /* can_generate_exception_events */
4024   0,                            /* can_generate_frame_pop_events */
4025   0,                            /* can_generate_breakpoint_events */
4026 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4027   1,                            /* can_suspend */
4028 #else
4029   0,                            /* can_suspend */
4030 #endif
4031   0,                            /* can_redefine_any_class */
4032   0,                            /* can_get_current_thread_cpu_time */
4033   0,                            /* can_get_thread_cpu_time */
4034   0,                            /* can_generate_method_entry_events */
4035   0,                            /* can_generate_method_exit_events */
4036   0,                            /* can_generate_all_class_hook_events */
4037   0,                            /* can_generate_compiled_method_load_events */
4038   0,                            /* can_generate_monitor_events */
4039   0,                            /* can_generate_vm_object_alloc_events */
4040   0,                            /* can_generate_native_method_bind_events */
4041   0,                            /* can_generate_garbage_collection_events */
4042   0,                            /* can_generate_object_free_events */
4043 };
4044
4045 static jvmtiEnv JVMTI_EnvTable = {
4046     NULL,
4047     &SetEventNotificationMode,
4048     NULL,
4049     &GetAllThreads,
4050     &SuspendThread,
4051     &ResumeThread,
4052     &StopThread,
4053     &InterruptThread,
4054     &GetThreadInfo,
4055     &GetOwnedMonitorInfo,
4056     &GetCurrentContendedMonitor,
4057     &RunAgentThread,
4058     &GetTopThreadGroups,
4059     &GetThreadGroupInfo,
4060     &GetThreadGroupChildren,
4061     &GetFrameCount,
4062     &GetThreadState,
4063     NULL,
4064     &GetFrameLocation,
4065     &NotifyFramePop,
4066     &GetLocalObject,
4067     &GetLocalInt,
4068     &GetLocalLong,
4069     &GetLocalFloat,
4070     &GetLocalDouble,
4071     &SetLocalObject,
4072     &SetLocalInt,
4073     &SetLocalLong,
4074     &SetLocalFloat,
4075     &SetLocalDouble,
4076     &CreateRawMonitor,
4077     &DestroyRawMonitor,
4078     &RawMonitorEnter,
4079     &RawMonitorExit,
4080     &RawMonitorWait,
4081     &RawMonitorNotify,
4082     &RawMonitorNotifyAll,
4083     &SetBreakpoint,
4084     &ClearBreakpoint,
4085     NULL,
4086     &SetFieldAccessWatch,
4087     &ClearFieldAccessWatch,
4088     &SetFieldModificationWatch,
4089     &ClearFieldModificationWatch,
4090     NULL,
4091     &Allocate,
4092     &Deallocate,
4093     &GetClassSignature,
4094     &GetClassStatus,
4095     &GetSourceFileName,
4096     &GetClassModifiers,
4097     &GetClassMethods,
4098     &GetClassFields,
4099     &GetImplementedInterfaces,
4100     &IsInterface,
4101     &IsArrayClass,
4102     &GetClassLoader, 
4103     &GetObjectHashCode, 
4104     &GetObjectMonitorUsage, 
4105     &GetFieldName, 
4106     &GetFieldDeclaringClass, 
4107     &GetFieldModifiers, 
4108     &IsFieldSynthetic, 
4109     &GetMethodName, 
4110     &GetMethodDeclaringClass, 
4111     &GetMethodModifiers, 
4112     NULL,
4113     &GetMaxLocals, 
4114     &GetArgumentsSize, 
4115     &GetLineNumberTable, 
4116     &GetMethodLocation, 
4117     &GetLocalVariableTable, 
4118     NULL,
4119     NULL,
4120     &GetBytecodes, 
4121     &IsMethodNative, 
4122     &IsMethodSynthetic, 
4123     &GetLoadedClasses, 
4124     &GetClassLoaderClasses, 
4125     &PopFrame, 
4126     NULL,
4127     NULL,
4128     NULL,
4129     NULL,
4130     NULL,
4131     NULL,
4132     &RedefineClasses, 
4133     &GetVersionNumber, 
4134     &GetCapabilities, 
4135     &GetSourceDebugExtension, 
4136     &IsMethodObsolete, 
4137     &SuspendThreadList, 
4138     &ResumeThreadList, 
4139     NULL,
4140     NULL,
4141     NULL,
4142     NULL,
4143     NULL,
4144     NULL,
4145     &GetAllStackTraces, 
4146     &GetThreadListStackTraces, 
4147     &GetThreadLocalStorage, 
4148     &SetThreadLocalStorage, 
4149     &GetStackTrace, 
4150     NULL,
4151     &GetTag, 
4152     &SetTag, 
4153     &ForceGarbageCollection,
4154     &IterateOverObjectsReachableFromObject, 
4155     &IterateOverReachableObjects, 
4156     &IterateOverHeap, 
4157     &IterateOverInstancesOfClass, 
4158     NULL,
4159     &GetObjectsWithTags, 
4160     NULL,
4161     NULL,
4162     NULL,
4163     NULL,
4164     NULL,
4165     &SetJNIFunctionTable, 
4166     &GetJNIFunctionTable, 
4167     &SetEventCallbacks, 
4168     &GenerateEvents, 
4169     &GetExtensionFunctions, 
4170     &GetExtensionEvents, 
4171     &SetExtensionEventCallback, 
4172     &DisposeEnvironment,
4173     &GetErrorName, 
4174     &GetJLocationFormat, 
4175     &GetSystemProperties, 
4176     &GetSystemProperty, 
4177     &SetSystemProperty, 
4178     &GetPhase, 
4179     &GetCurrentThreadCpuTimerInfo, 
4180     &GetCurrentThreadCpuTime, 
4181     &GetThreadCpuTimerInfo, 
4182     &GetThreadCpuTime, 
4183     &GetTimerInfo, 
4184     &GetTime, 
4185     &GetPotentialCapabilities, 
4186     NULL,
4187     &AddCapabilities,
4188     &RelinquishCapabilities,
4189     &GetAvailableProcessors,
4190     NULL,
4191     NULL,
4192     &GetEnvironmentLocalStorage,
4193     &SetEnvironmentLocalStorage,
4194     &AddToBootstrapClassLoaderSearch,
4195     &SetVerboseFlag,
4196     NULL,
4197     NULL,
4198     NULL,
4199     &GetObjectSize
4200 };
4201
4202 void set_jvmti_phase(jvmtiPhase p) {
4203         genericEventData d;
4204         jvmtiEvent e;
4205
4206     phase = p;
4207     switch (p) {
4208     case JVMTI_PHASE_ONLOAD:
4209         /* nothing to be done */
4210         return;
4211     case JVMTI_PHASE_PRIMORDIAL:
4212         /* nothing to be done */
4213         return;
4214     case JVMTI_PHASE_START: 
4215                 e = JVMTI_EVENT_VM_START;
4216         break;
4217     case JVMTI_PHASE_LIVE: 
4218                 e = JVMTI_EVENT_VM_INIT;
4219         break;
4220     case JVMTI_PHASE_DEAD:
4221                 e = JVMTI_EVENT_VM_DEATH;
4222         break;
4223     }
4224
4225         fireEvent(e,&d);
4226 }
4227
4228 jvmtiEnv* new_jvmtienv() {
4229     environment* env;
4230
4231         env = envs;
4232         if (env != NULL) 
4233                 while (env->next!=NULL) {
4234                         env=env->next;
4235                 }
4236         env = heap_allocate(sizeof(environment),true,NULL);
4237     memcpy(&(env->env),&JVMTI_EnvTable,sizeof(jvmtiEnv));
4238         memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
4239                    sizeof(jvmtiEventModeLL));
4240     /* To possess a capability, the agent must add the capability.*/
4241     memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
4242     RelinquishCapabilities(&(env->env),&(env->capabilities));
4243     env->EnvironmentLocalStorage = NULL;
4244         env->tls = NULL;
4245         return &(env->env);
4246 }
4247
4248 void agentload(char* opt_arg) {
4249         lt_dlhandle  handle;
4250         lt_ptr       onload;
4251         char *libname, *arg;
4252         int i=0,len;
4253         jint retval;
4254         
4255         len = strlen(opt_arg);
4256         
4257         while ((opt_arg[i]!='=')&&(i<len)) i++;
4258         
4259         libname=MNEW(char,i);
4260         strncpy(libname,opt_arg,i-1);
4261         libname[i-1]='\0';
4262
4263         arg=MNEW(char, len-i);
4264         strcpy(arg,&opt_arg[i+1]);
4265
4266         /* try to open the library */
4267
4268         if (!(handle = lt_dlopen(libname)))
4269                 return;
4270
4271         /* resolve Agent_OnLoad function */
4272         onload = lt_dlsym(handle, "Agent_OnLoad");
4273         if (onload == NULL) {
4274                 fprintf(stderr, "unable to load Agent_OnLoad function in %s\n", libname);
4275                 exit(1);
4276         }
4277
4278         /* resolve Agent_UnLoad function */
4279         unload = lt_dlsym(handle, "Agent_Unload");
4280
4281         retval = 
4282                 ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
4283                  onload) ((JavaVM*) &JNI_JavaVMTable, arg, NULL);
4284         
4285         MFREE(libname,char,i);
4286         MFREE(arg,char,len-i);
4287         
4288         if (retval != 0) exit (retval);
4289
4290         /* todo: native_library_hash_add(name, (java_objectheader *) loader, handle); */
4291 }
4292
4293 void agentunload() {
4294         if (unload != NULL) {
4295                 ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload) 
4296                         ((JavaVM*) &JNI_JavaVMTable);
4297         }
4298 }
4299
4300 /*
4301  * These are local overrides for various environment variables in Emacs.
4302  * Please do not remove this and leave it at the end of the file, where
4303  * Emacs will automagically detect them.
4304  * ---------------------------------------------------------------------
4305  * Local variables:
4306  * mode: c
4307  * indent-tabs-mode: t
4308  * c-basic-offset: 4
4309  * tab-width: 4
4310  * End:
4311  */