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