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