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