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