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