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