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