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