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