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