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