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