* Removed all Id tags.
[cacao.git] / src / native / jvmti / jvmti.c
index d4e673d4ff1f1eb02c4439bf7037ec45b4b807ea..f4d613d389d500551cba4b2537f64341c5cf231a 100644 (file)
    Author: Martin Platter
 
    Changes: Edwin Steiner
-
+            Samuel Vinson
+            Christan Thalinger
    
-   $Id: jvmti.c 4661 2006-03-21 00:04:59Z motse $
-
 */
 
+
+#include "config.h"
+
 #include <assert.h>
+#include <string.h>
+#include <linux/unistd.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ltdl.h>
+#include <unistd.h>
+#include <sched.h>
 
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/jvmti/cacaodbg.h"
 #include "native/jvmti/jvmti.h"
+#include "vm/jit/stacktrace.h"
 #include "vm/global.h"
 #include "vm/loader.h"
 #include "vm/builtin.h"
 #include "vm/jit/asmpart.h"
 #include "vm/class.h"
 #include "vm/classcache.h"
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
 #include "toolbox/logging.h"
 #include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "mm/memory.h"
 #include "threads/native/threads.h"
+#include "threads/native/lock.h"
 #include "vm/exceptions.h"
 #include "native/include/java_util_Vector.h"
 #include "native/include/java_io_PrintStream.h"
 #include "native/include/java_lang_VMSystem.h"
 #include "native/include/java_lang_VMClass.h"
 #include "vm/suck.h"
-#include  "boehm-gc/include/gc.h"
-
-#include <string.h>
-#include <linux/unistd.h>
-#include <sys/time.h>
-#include "toolbox/logging.h"
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/user.h>
-#include <signal.h>
-#include <ltdl.h>
+#include "boehm-gc/include/gc.h"
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
 #include "threads/native/threads.h"
 #include <sched.h>
 #include <pthread.h>
 
 #include "dbg.h"
 
+
 typedef struct _environment environment;
-environment *envs=NULL;
+static environment *envs=NULL;
+pthread_mutex_t dbgcomlock;
 
 extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
 
@@ -99,12 +102,13 @@ struct _jvmtiEventModeLL {
 typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
 struct _jvmtiThreadLocalStorage{
        jthread thread;
-       jvmtiThreadLocalStorage *next;
        void *data;
+       jvmtiThreadLocalStorage *next;
 };
 
 struct _environment {
     jvmtiEnv env;
+       environment *next;
     jvmtiEventCallbacks callbacks;
     /* table for enabled/disabled jvmtiEvents - first element contains global 
           behavior */
@@ -112,20 +116,20 @@ struct _environment {
     jvmtiCapabilities capabilities;
     void *EnvironmentLocalStorage;
        jvmtiThreadLocalStorage *tls;
-       environment *next;
 };
 
 static struct jvmtiEnv_struct JVMTI_EnvTable;
 static jvmtiCapabilities JVMTI_Capabilities;
 static lt_ptr unload;
 
-#define CHECK_PHASE_START  if (!(0 
+#define CHECK_PHASE_START  if (!(false 
 #define CHECK_PHASE(chkphase) || (phase == chkphase)
 #define CHECK_PHASE_END  )) return JVMTI_ERROR_WRONG_PHASE
-#define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
+#define CHECK_CAPABILITY(env,CAP) if(((environment*)                            \
+                                                                                env)->capabilities.CAP == 0)           \
                                      return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t)== \
-                                  JVMTI_ERROR_THREAD_NOT_ALIVE) \
+#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) ==                 \
+                                  JVMTI_ERROR_THREAD_NOT_ALIVE)                 \
                                        return JVMTI_ERROR_THREAD_NOT_ALIVE;
 
 
@@ -137,37 +141,37 @@ static lt_ptr unload;
 
 *******************************************************************************/
 static jvmtiError check_thread_is_alive(jthread t) {
-       char* data;
-       java_lang_Thread* th;
-       if(t==NULL) 
-               return JVMTI_ERROR_THREAD_NOT_ALIVE;
-       getchildproc(&data, t, sizeof(java_lang_Thread));
-       th = (java_lang_Thread*)data;
-       if(th->vmThread==NULL) 
+       if(t == NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
+       if(((java_lang_Thread*) t)->vmThread == NULL) 
                return JVMTI_ERROR_THREAD_NOT_ALIVE;
        return JVMTI_ERROR_NONE;
 }
 
-/* execcallback ***************************************************************
+/* execute_callback ************************************************************
 
    executes the registerd callbacks for the given jvmti event with parameter
    in the data structure.
 
 *******************************************************************************/
-static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
-       JNIEnv* jni_env = (JNIEnv*)&_Jv_JNINativeInterface;
+static void execute_callback(jvmtiEvent e, functionptr ec, 
+                                                        genericEventData* data) {
+       JNIEnv* jni_env = (JNIEnv*)_Jv_env;
 
        fprintf(stderr,"execcallback called (event: %d)\n",e);
 
        switch (e) {
        case JVMTI_EVENT_VM_INIT:
+               if (phase != JVMTI_PHASE_LIVE) return;
     case JVMTI_EVENT_THREAD_START:
     case JVMTI_EVENT_THREAD_END: 
-               ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+                       ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
                break;
 
-
     case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
                ((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env, 
                                                                                   jni_env, 
                                                                                   data->klass,
@@ -178,163 +182,187 @@ static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
                                                                                   data->class_data,
                                                                                   data->new_class_data_len,
                                                                                   data->new_class_data);
+
+               /* if class data has been modified use it as class data for other agents 
+                  waiting for the same event */
+               if (data->new_class_data != NULL) {
+                       data->jint1 = *(data->new_class_data_len);
+                       data->class_data = *(data->new_class_data); 
+               }
                break;
 
 
     case JVMTI_EVENT_CLASS_PREPARE: 
     case JVMTI_EVENT_CLASS_LOAD:
-               ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env, 
-                                                                  data->thread, data->klass);
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+                       ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env, 
+                                                                          data->thread, data->klass);
                break;
 
     case JVMTI_EVENT_VM_DEATH:
+               if (phase != JVMTI_PHASE_LIVE) return;
     case JVMTI_EVENT_VM_START: 
+               if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
                ((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
                break;
 
-    case JVMTI_EVENT_EXCEPTION:
-               ((jvmtiEventException)ec) (data->jvmti_env, jni_env, 
-                                                                  data->thread, 
-                                                                  data->method, 
-                                                                  data->location,
-                                                                  data->object,
-                                                                  data->catch_method,
-                                                                  data->catch_location);
-               break;
-               
-    case JVMTI_EVENT_EXCEPTION_CATCH:
-               ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env, 
-                                                                               data->thread, 
-                                                                               data->method, 
-                                                                               data->location,
-                                                                               data->object);
-               break;
-
-    case JVMTI_EVENT_BREAKPOINT:
-    case JVMTI_EVENT_SINGLE_STEP: 
-               ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env, 
-                                                                       data->thread, 
-                                                                       data->method, 
-                                                                       data->location);
-               break;
-
-    case JVMTI_EVENT_FRAME_POP:
-               ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env, 
-                                                                 data->thread, 
-                                                                 data->method, 
-                                                                 data->b);
-               break;
-
-    case JVMTI_EVENT_FIELD_ACCESS: 
-               ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env, 
-                                                                        data->thread, 
-                                                                        data->method, 
-                                                                        data->location,
-                                                                        data->klass,
-                                                                        data->object,
-                                                                        data->field);
-               break;
-
-    case JVMTI_EVENT_FIELD_MODIFICATION:
-               ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env, 
-                                                                                  data->thread, 
-                                                                                  data->method, 
-                                                                                  data->location,
-                                                                                  data->klass,
-                                                                                  data->object,
-                                                                                  data->field,
-                                                                                  data->signature_type,
-                                                                                  data->value);
-               break;
-
-    case JVMTI_EVENT_METHOD_ENTRY:
-               ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env, 
-                                                                        data->thread, 
-                                                                        data->method);
-               break;
-
-    case JVMTI_EVENT_METHOD_EXIT: 
-               ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env, 
-                                                                       data->thread, 
-                                                                       data->method,
-                                                                       data->b,
-                                                                       data->value);
-               break;
-
     case JVMTI_EVENT_NATIVE_METHOD_BIND:
-               ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env, 
-                                                                                 data->thread, 
-                                                                                 data->method,
-                                                                                 data->address,
-                                                                                 data->new_address_ptr);
-               break;
-
-    case JVMTI_EVENT_COMPILED_METHOD_LOAD:
-               ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env, 
-                                                                                       data->method,
-                                                                                       data->jint1,
-                                                                                       data->address,
-                                                                                       data->jint2,
-                                                                                       data->map,
-                                                                                       data->compile_info);
-               break;
-               
-    case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
-               ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
+                       ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env, 
+                                                                                         data->thread, 
                                                                                          data->method,
-                                                                                         data->address);
+                                                                                         data->address,
+                                                                                         data->new_address_ptr);
                break;
+       
 
     case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
-               ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
-                                                                                         data->name,
-                                                                                         data->address,
-                                                                                         data->jint1);
+               if ((phase == JVMTI_PHASE_START) || 
+                       (phase == JVMTI_PHASE_LIVE)  ||
+                       (phase == JVMTI_PHASE_PRIMORDIAL))
+                       ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
+                                                                                                 data->name,
+                                                                                                 data->address,
+                                                                                                 data->jint1);
                break;
 
-    case JVMTI_EVENT_GARBAGE_COLLECTION_START:
-    case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
-    case JVMTI_EVENT_DATA_DUMP_REQUEST: 
-               ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
-               break;
 
-    case JVMTI_EVENT_MONITOR_WAIT:
-               ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env, 
-                                                                        data->thread, 
-                                                                        data->object,
-                                                                        data->jlong);
-               break;
 
-    case JVMTI_EVENT_MONITOR_WAITED:
-               ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env, 
+       default:
+               if (phase != JVMTI_PHASE_LIVE) return;
+               switch (e) {
+               case JVMTI_EVENT_EXCEPTION:                     
+                       ((jvmtiEventException)ec) (data->jvmti_env, jni_env, 
                                                                           data->thread, 
+                                                                          data->method, 
+                                                                          data->location,
                                                                           data->object,
-                                                                          data->b);
-               break;
-
-
-    case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
-    case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
-               ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env, 
+                                                                          data->catch_method,
+                                                                          data->catch_location);
+                       break;
+                       
+               case JVMTI_EVENT_EXCEPTION_CATCH:
+                       ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env, 
+                                                                                       data->thread, 
+                                                                                       data->method, 
+                                                                                       data->location,
+                                                                                       data->object);
+                       break;
+
+               case JVMTI_EVENT_BREAKPOINT:
+               case JVMTI_EVENT_SINGLE_STEP:
+                       ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env, 
+                                                                               data->thread, 
+                                                                               data->method, 
+                                                                               data->location);
+                       break;
+
+               case JVMTI_EVENT_FRAME_POP:
+                       ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env, 
+                                                                         data->thread, 
+                                                                         data->method, 
+                                                                         data->b);
+                       break;
+
+
+               case JVMTI_EVENT_FIELD_ACCESS: 
+                       ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->method, 
+                                                                                data->location,
+                                                                                data->klass,
+                                                                                data->object,
+                                                                                data->field);
+                       break;
+
+               case JVMTI_EVENT_FIELD_MODIFICATION:
+
+                       ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env, 
                                                                                           data->thread, 
-                                                                                          data->object);
-               break;
+                                                                                          data->method, 
+                                                                                          data->location,
+                                                                                          data->klass,
+                                                                                          data->object,
+                                                                                          data->field,
+                                                                                          data->signature_type,
+                                                                                          data->value);
+                       break;
+
+               case JVMTI_EVENT_METHOD_ENTRY:
+                       ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->method);
+                       break;
+
+               case JVMTI_EVENT_METHOD_EXIT: 
+                       ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env, 
+                                                                               data->thread, 
+                                                                               data->method,
+                                                                               data->b,
+                                                                               data->value);
+                       break;
+
+               case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+                       ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env, 
+                                                                                               data->method,
+                                                                                               data->jint1,
+                                                                                               data->address,
+                                                                                               data->jint2,
+                                                                                               data->map,
+                                                                                               data->compile_info);
+                       break;
+               
+               case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+                       ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+                                                                                                 data->method,
+                                                                                                 data->address);
+                       break;
+
+               case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+               case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+               case JVMTI_EVENT_DATA_DUMP_REQUEST: 
+                       ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
+                       break;
+
+               case JVMTI_EVENT_MONITOR_WAIT:
+                       ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env, 
+                                                                                data->thread, 
+                                                                                data->object,
+                                                                                data->jlong);
+                       break;
+
+               case JVMTI_EVENT_MONITOR_WAITED:
+                       ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env, 
+                                                                                  data->thread, 
+                                                                                  data->object,
+                                                                                  data->b);
+                       break;
 
-    case JVMTI_EVENT_OBJECT_FREE: 
-               ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
-               break;
 
-    case JVMTI_EVENT_VM_OBJECT_ALLOC:
-               ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env, 
-                                                                          data->thread, 
-                                                                          data->object,
-                                                                          data->klass,
-                                                                          data->jlong);
-               break;
+               case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+               case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+                       ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+                                                                                                  data->thread, 
+                                                                                                  data->object);
+                       break;
 
+               case JVMTI_EVENT_OBJECT_FREE: 
+                       ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
+                       break;
 
-       default:
-               log_text ("unknown event");
+               case JVMTI_EVENT_VM_OBJECT_ALLOC:
+                       ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env, 
+                                                                                  data->thread, 
+                                                                                  data->object,
+                                                                                  data->klass,
+                                                                                  data->jlong);
+                       break;
+               default:
+                       log_text ("unknown event");
+               }
+               break;
        }
 }
 
@@ -350,22 +378,25 @@ static void dofireEvent(jvmtiEvent e, genericEventData* data) {
        functionptr ec;
 
        env = envs;
-       while (env!=NULL) {
+       while (env != NULL) {
                if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
                        evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
             /* test if the event is enable for some threads */
-                       while (evm!=NULL) { 
+                       while (evm != NULL) { 
                                if (evm->mode == JVMTI_ENABLE) {
-                                       data->jvmti_env=&env->env;
-                                       ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
-                                       execcallback(e, ec, data);
+                                       ec = ((functionptr*)
+                                                 (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
+                                       if (ec != NULL) {
+                                               data->jvmti_env=&env->env;
+                                               execute_callback(e, ec, data);
+                                       }
                                }
                                evm=evm->next;
                        }
                } else { /* event enabled globally */
                        data->jvmti_env=&env->env;
                        ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
-                       execcallback(e, ec, data);
+                       if (ec != NULL) execute_callback(e, ec, data);
                }
                
                env=env->next;
@@ -379,23 +410,18 @@ static void dofireEvent(jvmtiEvent e, genericEventData* data) {
    missing EventData.
 
 *******************************************************************************/
-void fireEvent(genericEventData* d) {
+void jvmti_fireEvent(genericEventData* d) {
        jthread thread;
-    /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
+    /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
 
-       if (d->ev != JVMTI_EVENT_VM_START)
-               thread = (jthread)getcurrentthread();
-       else
+       if (d->ev == JVMTI_EVENT_VM_START)
                thread = NULL;
+       else
+               thread = jvmti_get_current_thread();
+
 
-       fprintf (stderr,"debugger: fireEvent: %d\n",d->ev);
        d->thread = thread;
        dofireEvent(d->ev,d);
-
-       fprintf (stderr,"debugger: fireEvent 2\n");
-       /* if we need to send a VM_INIT event then also send a THREAD_START event */
-       if (d->ev == JVMTI_EVENT_VM_INIT) 
-               dofireEvent(JVMTI_EVENT_THREAD_START,d);
 }
 
 
@@ -405,7 +431,7 @@ void fireEvent(genericEventData* d) {
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
                          jvmtiEvent event_type, jthread event_thread, ...)
 {
@@ -427,12 +453,7 @@ SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
        if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
                return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 
-       if ((event_type < JVMTI_EVENT_START_ENUM) ||
-               (event_type > JVMTI_EVENT_END_ENUM))
-               return JVMTI_ERROR_INVALID_EVENT_TYPE;
-       
-       
-       switch (event_type) { /* check capability */
+       switch (event_type) { /* check capability and set system breakpoint */
     case JVMTI_EVENT_EXCEPTION:
        case JVMTI_EVENT_EXCEPTION_CATCH:
                CHECK_CAPABILITY(env,can_generate_exception_events)
@@ -483,9 +504,13 @@ SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
                break;
        default:
                /* all other events are required */
+               if ((event_type < JVMTI_EVENT_START_ENUM) ||
+                       (event_type > JVMTI_EVENT_END_ENUM))
+                       return JVMTI_ERROR_INVALID_EVENT_TYPE;          
                break;
        }
 
+
        if (event_thread != NULL) {
                /* thread level control */
                if ((JVMTI_EVENT_VM_INIT == mode) ||
@@ -522,16 +547,14 @@ SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
               jthread ** threads_ptr)
 {
-       threadobject* threads;
+       threadobject** threads;
        int i;
        jvmtiError retval;
        
-       log_text ("GetAllThreads called");
-
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
@@ -539,14 +562,14 @@ GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
     if ((threads_count_ptr == NULL) || (threads_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
-       retval=allthreads(threads_count_ptr,&threads);
+       retval=jvmti_get_all_threads(threads_count_ptr, &threads);
        if (retval != JVMTI_ERROR_NONE) return retval;
 
        *threads_ptr = 
                heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
 
-       for (i=0; i<*threads_count_ptr; i++) 
-               (*threads_ptr)[i] = threadobject2jthread(&threads[i]);
+       for (i=0; i<*threads_count_ptr; i++)
+               (*threads_ptr)[i] = threads[i]->o.thread;
  
     return JVMTI_ERROR_NONE;
 }
@@ -558,24 +581,23 @@ GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SuspendThread (jvmtiEnv * env, jthread thread)
 {
        CHECK_PHASE_START
        CHECK_PHASE(JVMTI_PHASE_LIVE)
        CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
     
-/*    
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       suspend_thread((thread *) thread->thread);
-#endif
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       suspend_thread((threadobject*) thread);
-#endif
-*/
+       if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+       if (!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+       CHECK_THREAD_IS_ALIVE(thread);
 
+    /* threads_suspend_thread will implement suspend
+          threads_suspend_thread (
+          (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
+       
     return JVMTI_ERROR_NONE;
 }
 
@@ -585,23 +607,23 @@ SuspendThread (jvmtiEnv * env, jthread thread)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ResumeThread (jvmtiEnv * env, jthread thread)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
+    CHECK_CAPABILITY(env,can_suspend);
 
-/*
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       resume_thread((thread *) this->thread);
-#endif
+       if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+       if (!builtin_instanceof(thread,class_java_lang_Thread))
+               return JVMTI_ERROR_INVALID_THREAD;
+       CHECK_THREAD_IS_ALIVE(thread);
+
+    /* threads_resume_thread will implement resume
+          threads_resume_thread (
+          (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       resume_thread((threadobject*) thread);
-#endif
-*/
     return JVMTI_ERROR_NONE;
 }
 
@@ -612,15 +634,17 @@ ResumeThread (jvmtiEnv * env, jthread thread)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 StopThread (jvmtiEnv * env, jthread thread, jobject exception)
 {
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_signal_thread)
+    CHECK_CAPABILITY(env,can_signal_thread);
         
-  log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+       log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+       return JVMTI_ERROR_NOT_AVAILABLE;
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -630,7 +654,7 @@ StopThread (jvmtiEnv * env, jthread thread, jobject exception)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 InterruptThread (jvmtiEnv * env, jthread thread)
 {
        CHECK_PHASE_START
@@ -638,18 +662,19 @@ InterruptThread (jvmtiEnv * env, jthread thread)
     CHECK_PHASE_END;
     CHECK_CAPABILITY(env,can_signal_thread)
 
+#if defined(ENABLE_THREADS)
        if(!builtin_instanceof(thread,class_java_lang_Thread))
                return JVMTI_ERROR_INVALID_THREAD;
 
-       CHECK_THREAD_IS_ALIVE(thread);        
+       CHECK_THREAD_IS_ALIVE(thread);
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-/*     interruptThread((java_lang_VMThread*)thread);*/
+       threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
+
+
+    return JVMTI_ERROR_NONE;
 #else
        return JVMTI_ERROR_NOT_AVAILABLE;
 #endif
-
-    return JVMTI_ERROR_NONE;
 }
 
 /* GetThreadInfo ***************************************************************
@@ -659,96 +684,94 @@ InterruptThread (jvmtiEnv * env, jthread thread)
 
 *******************************************************************************/
 
-jvmtiError
-GetThreadInfo (jvmtiEnv * env, jthread th, jvmtiThreadInfo * info_ptr)
+static jvmtiError
+GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
 {
-       int size;
-       char* data;
-       struct java_lang_Thread *t;
+       utf *name;
+       java_lang_Thread* th = (java_lang_Thread*)t;
 
-       log_text("GetThreadInfo called");
 
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-       getchildproc(&data,th,sizeof(struct java_lang_Thread));
-       t = (java_lang_Thread*)data;
-       info_ptr->priority=(jint)t->priority;
-       info_ptr->is_daemon=(jboolean)t->daemon;
-       info_ptr->thread_group=(jthreadGroup)t->group;
-       info_ptr->context_class_loader=(jobject)t->contextClassLoader;
-       getchildproc(&data,t->name,sizeof(struct java_lang_String));
-       size = ((struct java_lang_String*)data)->count;
-       getchildproc(&(info_ptr->name),((struct java_lang_String*)data)->value,size);
-       info_ptr->name[size]='\0';
+       info_ptr->priority=(jint)th->priority;
+       info_ptr->is_daemon=(jboolean)th->daemon;
+       info_ptr->thread_group=(jthreadGroup)th->group;
+       info_ptr->context_class_loader=(jobject)th->contextClassLoader;
 
+       name = javastring_toutf(th->name,false);
+       info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
+       utf_sprint_convert_to_latin1(info_ptr->name, name);
 
     return JVMTI_ERROR_NONE;
 }
 
 /* GetOwnedMonitorInfo *********************************************************
 
-   Get information about the monitors owned by the specified thread
+   Gets all  monitors owned by the specified thread
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
                     jint * owned_monitor_count_ptr,
                     jobject ** owned_monitors_ptr)
 {
        int i,j,size=20;
        java_objectheader **om;
-       lockRecordPool* lrp;
-       char *data;
-
-       log_text("GetOwnedMonitorInfo called");
+       lock_record_pool_t* lrp;
+       threadobject* t;
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
     CHECK_CAPABILITY(env,can_get_owned_monitor_info);
 
-       if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL)) 
+       if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL)) 
                return JVMTI_ERROR_NULL_POINTER;
 
-       if(!builtin_instanceof(thread,class_java_lang_Thread))
-               return JVMTI_ERROR_INVALID_THREAD;
-
-       CHECK_THREAD_IS_ALIVE(thread);
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               t = (threadobject*) thread;
+       }
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
 
        om=MNEW(java_objectheader*,size);
 
-       stopdebuggee();
-
-       /* global_pool is in the same place in the child process memory because the
-          the child is a copy of this process */
-       getchildproc(&data, &global_pool,sizeof(lockRecordPool*));
-       lrp=(lockRecordPool*)data;
+       pthread_mutex_lock(&lock_global_pool_lock);
+       lrp=lock_global_pool;
 
+       /* iterate over all lock record pools */
        while (lrp != NULL) {
+               /* iterate over every lock record in a pool */
                for (j=0; j<lrp->header.size; j++) {
-                       if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
-                          (!lrp->lr[j].waiting)) {
-                               if (i>=size) {
-                                       MREALLOC(om,java_objectheader*,size,size*2);
-                                       size=size*2;
+                       /* if the lock record is owned by the given thread add it to 
+                          the result array */
+                       if(lrp->lr[j].owner == t) {
+                               if (i >= size) {
+                                       MREALLOC(om, java_objectheader*, size, size * 2);
+                                       size = size * 2;
                                }
-                               om[i]=lrp->lr[j].o;
+                               om[i] = lrp->lr[j].obj;
                                i++;
-                       }
+                               }
                }
                lrp=lrp->header.next;
        }
 
-       pthread_mutex_unlock(&pool_lock);
+       pthread_mutex_unlock(&lock_global_pool_lock);
 
-       *owned_monitors_ptr     = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
-       memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
-       MFREE(om,java_objectheader*,size);
+       *owned_monitors_ptr     = 
+               heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
+       memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
+       MFREE(om, java_objectheader*, size);
 
        *owned_monitor_count_ptr = i;
 
@@ -763,50 +786,58 @@ GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
                            jobject * monitor_ptr)
 {
        int j;
-       lockRecordPool* lrp;
-       java_objectheader* monitor;
+       lock_record_pool_t* lrp;
+       threadobject* t;
+       lock_waiter_t* waiter;
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
        CHECK_CAPABILITY(env, can_get_current_contended_monitor)
         
-       if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
+       if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
        *monitor_ptr=NULL;
 
-       if(!builtin_instanceof(thread,class_java_lang_Thread))
-               return JVMTI_ERROR_INVALID_THREAD;
-
-       CHECK_THREAD_IS_ALIVE(thread);
-
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               t = (threadobject*) thread;
+       }
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
 
-       pthread_mutex_lock(&pool_lock);
+       pthread_mutex_lock(&lock_global_pool_lock);
 
-       lrp=global_pool;
+       lrp=lock_global_pool;
 
-       while ((lrp != NULL)&&(monitor==NULL)) {
+       /* iterate over all lock record pools */
+       while ((lrp != NULL) && (*monitor_ptr == NULL)) {
+               /* iterate over every lock record in a pool */
                for (j=0; j<lrp->header.size; j++) {
-                       if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
-                               monitor=lrp->lr[j].o;
-                               break;
-                       }
+                       /* iterate over every thread that is wait on this lock record */
+                       waiter = lrp->lr[j].waiters;
+                       while (waiter != NULL) 
+                               /* if the waiting thread equals to the given thread we are 
+                                  done. Stop iterateting. */
+                               if(waiter->waiter == t) {
+                                       *monitor_ptr=lrp->lr[j].obj;
+                                       break;
+                               }
                }
                lrp=lrp->header.next;
        }
 
-       pthread_mutex_unlock(&pool_lock);
+       pthread_mutex_unlock(&lock_global_pool_lock);
 
-       if (monitor!=NULL) {
-               *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
-               *monitor_ptr = (jobject)monitor;
-       }
 
 #endif
     return JVMTI_ERROR_NONE;
@@ -821,7 +852,7 @@ typedef struct {
 
 static void *threadstartup(void *t) {
        runagentparam *rap = (runagentparam*)t;
-       rap->sf(rap->jvmti_env,&_Jv_JNINativeInterface,rap->arg);
+       rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
        return NULL;
 }
 
@@ -832,7 +863,7 @@ static void *threadstartup(void *t) {
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
                const void *arg, jint priority)
 {
@@ -851,11 +882,14 @@ RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
                (priority > JVMTI_THREAD_MAX_PRIORITY)) 
                return JVMTI_ERROR_INVALID_PRIORITY;
 
+       /* XXX:  Threads started with this function should not be visible to 
+          Java programming language queries but are included in JVM TI queries */
+
        rap.sf = proc;
        rap.arg = (void*)arg;
        rap.jvmti_env = env;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        pthread_attr_init(&threadattr);
        pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
        if (priority == JVMTI_THREAD_MIN_PRIORITY) {
@@ -866,7 +900,7 @@ RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
        }
        pthread_attr_setschedparam(&threadattr,&sp);
        if (pthread_create(&((threadobject*) 
-                                                thread)->info.tid, &threadattr, &threadstartup, &rap)) {
+                                                thread)->tid, &threadattr, &threadstartup, &rap)) {
                log_text("pthread_create failed");
                assert(0);
        }
@@ -882,7 +916,7 @@ RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
                    jthreadGroup ** groups_ptr)
 {
@@ -898,7 +932,7 @@ GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
     if ((groups_ptr == NULL) || (group_count_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        tg = MNEW(jthreadGroup*,size);
        x = 0;
        if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
@@ -915,7 +949,6 @@ GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
                        while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
                                j++;
                        }
-
                        if (j == x) {
                                if (x >= size){
                                        MREALLOC(tg,jthreadGroup*,size,size*2);
@@ -946,7 +979,7 @@ GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
                    jvmtiThreadGroupInfo * info_ptr)
 {
@@ -986,7 +1019,7 @@ GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
                        jint * thread_count_ptr, jthread ** threads_ptr,
                        jint * group_count_ptr, jthreadGroup ** groups_ptr)
@@ -1008,14 +1041,16 @@ GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
 
        *thread_count_ptr = (jint)tgp->threads->elementCount;
 
-       *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
+       *threads_ptr = 
+               heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
 
        memcpy(*threads_ptr, &tgp->threads->elementData, 
-                  (*thread_count_ptr)*sizeof(jthread*));
+                  (*thread_count_ptr)*sizeof(java_objectarray*));
 
        *group_count_ptr = (jint) tgp->groups->elementCount;
 
-       *groups_ptr     = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);    
+       *groups_ptr     = 
+               heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);       
 
        memcpy(*groups_ptr, &tgp->threads->elementData,
                   (*group_count_ptr)*sizeof(jthreadGroup*));
@@ -1027,14 +1062,26 @@ GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
 /* getcacaostacktrace *********************************************************
 
    Helper function that retrives stack trace for specified thread. 
-   Has to take care of suspend/resume issuses
-
+   
 *******************************************************************************/
-static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
-
-       log_text("getcacaostacktrace");
 
+static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
+       threadobject *t;
+       bool resume;
        
+       if (thread == NULL) {
+               t = jvmti_get_current_thread();
+               *trace = stacktrace_create(t);
+       } else {
+               t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
+/*             if (t != jvmti_get_current_thread())
+                       resume = threads_suspend_thread_if_running(thread);
+    
+               *trace = stacktrace_create(thread );
+               
+               if (resume)
+               threads_resume_thread ( thread );*/
+       }
 
     return JVMTI_ERROR_NONE;
 }
@@ -1042,32 +1089,40 @@ static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
 
 /* GetFrameCount **************************************************************
 
-   Get the number of frames in the specified thread's stack.
+
+   Get the number of frames in the specified thread's stack. Calling function
+   has to take care of suspending/resuming thread.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
 {
-       char* trace;
+       stacktracebuffer* trace;
        jvmtiError er;
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
     
-       if(!builtin_instanceof(thread,class_java_lang_Thread))
-               return JVMTI_ERROR_INVALID_THREAD;
+       if (thread != NULL){
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
 
-       CHECK_THREAD_IS_ALIVE(thread);
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
        
        if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
 
        er = getcacaostacktrace(&trace, thread);
-       if (er==JVMTI_ERROR_NONE) return er;
+       if (er == JVMTI_ERROR_NONE) {
+               heap_free(trace);
+               return er;
+       }
 
-/*     todo: *count_ptr = trace->size;*/
+       *count_ptr = trace->used;
 
+       heap_free(trace);
     return JVMTI_ERROR_NONE;
 }
 
@@ -1078,7 +1133,7 @@ GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
 {
        java_lang_Thread* th = (java_lang_Thread*)thread;
@@ -1094,16 +1149,16 @@ GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
        if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
 
        *thread_state_ptr = 0;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
+#if defined(ENABLE_THREADS)
+       if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
                /* not alive */
-               if (((threadobject*)th->vmThread)->info.tid == 0)
+               if (((threadobject*)th->vmThread)->tid == 0)
                        *thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
        } else {
                /* alive */
                *thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
                if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
-               /* todo */
+               /* XXX todo -  info not available */
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
@@ -1113,7 +1168,7 @@ GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
                if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
-               if (t->isSleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
+               if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
        }
 #else
        return JVMTI_ERROR_INTERNAL;
@@ -1129,28 +1184,34 @@ GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
                  jmethodID * method_ptr, jlocation * location_ptr)
 {
        stackframeinfo   *sfi;
        int i;
+       threadobject* th;
                
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-       if(!builtin_instanceof(thread,class_java_lang_Thread))
-               return JVMTI_ERROR_INVALID_THREAD;
-
-       CHECK_THREAD_IS_ALIVE(thread);
+       if (thread == NULL) {
+               th = jvmti_get_current_thread();
+       } else {
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
+               
+               CHECK_THREAD_IS_ALIVE(thread);
+               th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
+       }
 
        if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 
        if ((method_ptr == NULL)&&(location_ptr == NULL)) 
                return JVMTI_ERROR_NULL_POINTER;
        
-       sfi = ((threadobject*)thread)->info._stackframeinfo;
+       sfi = th->_stackframeinfo;
        
        i = 0;
        while ((sfi != NULL) && (i<depth)) {
@@ -1173,7 +1234,7 @@ GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
 {
        CHECK_PHASE_START
@@ -1191,7 +1252,7 @@ NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalObject (jvmtiEnv * env,
                jthread thread, jint depth, jint slot, jobject * value_ptr)
 {
@@ -1210,7 +1271,7 @@ GetLocalObject (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalInt (jvmtiEnv * env,
             jthread thread, jint depth, jint slot, jint * value_ptr)
 {
@@ -1228,7 +1289,7 @@ GetLocalInt (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
              jlong * value_ptr)
 {
@@ -1248,7 +1309,7 @@ GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
               jfloat * value_ptr)
 {
@@ -1268,7 +1329,7 @@ GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jdouble * value_ptr)
 {
@@ -1288,7 +1349,7 @@ GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jobject value)
 {
@@ -1308,7 +1369,7 @@ SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
             jint value)
 {
@@ -1328,7 +1389,7 @@ SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
              jlong value)
 {
@@ -1348,7 +1409,7 @@ SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
               jfloat value)
 {
@@ -1368,7 +1429,7 @@ SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
                jdouble value)
 {
@@ -1388,7 +1449,7 @@ SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 CreateRawMonitor (jvmtiEnv * env, const char *name,
                  jrawMonitorID * monitor_ptr)
 {
@@ -1402,8 +1463,8 @@ CreateRawMonitor (jvmtiEnv * env, const char *name,
        if ((name == NULL) || (monitor_ptr == NULL)) 
                return JVMTI_ERROR_NULL_POINTER;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       monitor->name=javastring_new_char(name);
+#if defined(ENABLE_THREADS)
+       monitor->name=javastring_new_from_ascii(name);
 #else
        log_text ("CreateRawMonitor not supported");
 #endif
@@ -1418,7 +1479,7 @@ CreateRawMonitor (jvmtiEnv * env, const char *name,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
 {
        CHECK_PHASE_START
@@ -1429,13 +1490,13 @@ DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+#if defined(ENABLE_THREADS)
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
                return JVMTI_ERROR_NOT_MONITOR_OWNER;
        
-       monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
+       lock_monitor_exit((java_objectheader *) monitor->name);
 
-       /* GC will clean monitor up */
+       heap_free(monitor);
 #else
        log_text ("DestroyRawMonitor not supported");
 #endif
@@ -1450,14 +1511,14 @@ DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
 {
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       builtin_monitorenter((java_objectheader*)monitor->name);        
+#if defined(ENABLE_THREADS)
+       lock_monitor_enter((java_objectheader *) monitor->name);
 #else
        log_text ("RawMonitorEnter not supported");
 #endif
@@ -1472,18 +1533,18 @@ RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
 {
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        /* assure current thread owns this monitor */
-       if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
                return JVMTI_ERROR_NOT_MONITOR_OWNER;
 
-       builtin_monitorexit((java_objectheader*)monitor->name);
+       lock_monitor_exit((java_objectheader *) monitor->name);
 #else
        log_text ("RawMonitorExit not supported");
 #endif
@@ -1498,18 +1559,18 @@ RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
 {
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        /* assure current thread owns this monitor */
-       if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
                return JVMTI_ERROR_NOT_MONITOR_OWNER;
 
-       wait_cond_for_object(&monitor->name->header, millis,0);
+       lock_wait_for_object(&monitor->name->header, millis,0);
        if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
                return JVMTI_ERROR_INTERRUPT;
 
@@ -1527,18 +1588,18 @@ RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
 {
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        /* assure current thread owns this monitor */
-       if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
                return JVMTI_ERROR_NOT_MONITOR_OWNER;
 
-       signal_cond_for_object((java_objectheader*)&monitor->name);
+       lock_notify_object((java_objectheader*)&monitor->name);
 #else
        log_text ("RawMonitorNotify not supported");
 #endif
@@ -1553,18 +1614,18 @@ RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
 {
        if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
                return JVMTI_ERROR_INVALID_MONITOR;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
        /* assure current thread owns this monitor */
-       if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+       if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
                return JVMTI_ERROR_NOT_MONITOR_OWNER;
 
-       broadcast_cond_for_object((java_objectheader*)&monitor->name);
+       lock_notify_all_object((java_objectheader*)&monitor->name);
 #else
        log_text ("RawMonitorNotifyAll not supported");
 #endif
@@ -1579,14 +1640,14 @@ RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 {
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
        CHECK_CAPABILITY(env,can_generate_breakpoint_events)
-        
+
                /* addbrkpt */
   log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
@@ -1599,7 +1660,7 @@ SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 {
        CHECK_PHASE_START
@@ -1618,7 +1679,7 @@ ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
        CHECK_PHASE_START
@@ -1637,7 +1698,7 @@ SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
        CHECK_PHASE_START
@@ -1656,7 +1717,7 @@ ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
        CHECK_PHASE_START
@@ -1675,7 +1736,7 @@ SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 {
        CHECK_PHASE_START
@@ -1695,7 +1756,7 @@ ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
 {
     
@@ -1717,10 +1778,11 @@ Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 Deallocate (jvmtiEnv * env, unsigned char *mem)
 {
     /* let Boehm GC do the job */
+       heap_free(mem);
     return JVMTI_ERROR_NONE;
 }
 
@@ -1732,34 +1794,29 @@ Deallocate (jvmtiEnv * env, unsigned char *mem)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
                   char **generic_ptr)
 {
-    int nsize,psize;
-
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-       
-    if ((generic_ptr== NULL)||(signature_ptr == NULL)) 
-        return JVMTI_ERROR_NULL_POINTER;
-
-    nsize=((classinfo*)klass)->name->blength;
-    psize=((classinfo*)klass)->packagename->blength;
-
-    *signature_ptr = (char*) 
-        heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
+    
+       if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
+       if (!builtin_instanceof(klass,class_java_lang_Class))
+               return JVMTI_ERROR_INVALID_CLASS;
 
-    *signature_ptr[0]='L';
-    memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
-    *signature_ptr[psize+2]='/';
-    memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
-    *signature_ptr[nsize+psize+3]=';';
-    *signature_ptr[nsize+psize+4]='\0';
+       if (signature_ptr != NULL) {
+               *signature_ptr = (char*)
+                       heap_allocate(sizeof(char) * 
+                                                 utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
+               
+               utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
+       }
 
-    *generic_ptr = NULL;
+       if (generic_ptr!= NULL)
+               *generic_ptr = NULL;
 
     return JVMTI_ERROR_NONE;
 }
@@ -1770,7 +1827,7 @@ GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
 {
        classinfo *c;
@@ -1789,13 +1846,13 @@ GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
        *status_ptr = 0;        
 
 /*     if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
-       if (c->state&=CLASS_LINKED) 
+       if (c->state & CLASS_LINKED) 
                *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
 
-       if (c->state&=CLASS_INITIALIZED) 
+       if (c->state & CLASS_INITIALIZED) 
                *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
 
-       if (c->state&=CLASS_ERROR) 
+       if (c->state & CLASS_ERROR) 
                *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
 
        if (c->vftbl->arraydesc != NULL) 
@@ -1814,7 +1871,7 @@ GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
 {
     int size; 
@@ -1828,7 +1885,7 @@ GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
     if ((klass == NULL)||(source_name_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
     
-    size = (((classinfo*)klass)->sourcefile->blength)+1;
+    size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
 
     *source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
     
@@ -1845,7 +1902,7 @@ GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
 {
        CHECK_PHASE_START
@@ -1871,15 +1928,17 @@ GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
                 jmethodID ** methods_ptr)
 {
-    CHECK_PHASE_START
+       int i;
+
+       CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
+       
     if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
@@ -1889,10 +1948,10 @@ GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
     *method_count_ptr = (jint)((classinfo*)klass)->methodscount;
     *methods_ptr = (jmethodID*) 
         heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
-    
-    memcpy (*methods_ptr, ((classinfo*)klass)->methods, 
-            sizeof(jmethodID) * (*method_count_ptr));
-    
+
+    for (i=0; i<*method_count_ptr;i++)
+               (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -1904,7 +1963,7 @@ GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
                jfieldID ** fields_ptr)
 {
@@ -1933,7 +1992,7 @@ GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
                          jint * interface_count_ptr,
                          jclass ** interfaces_ptr)
@@ -1978,7 +2037,7 @@ GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
 {
     CHECK_PHASE_START
@@ -2000,7 +2059,7 @@ IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
 {
     CHECK_PHASE_START
@@ -2024,7 +2083,7 @@ IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
 {
     CHECK_PHASE_START
@@ -2047,7 +2106,7 @@ GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
 {
        CHECK_PHASE_START
@@ -2071,7 +2130,7 @@ GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
                       jvmtiMonitorUsage * info_ptr)
 {
@@ -2092,7 +2151,7 @@ GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
              char **name_ptr, char **signature_ptr, char **generic_ptr)
 {
@@ -2102,19 +2161,29 @@ GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL)) 
-        return JVMTI_ERROR_NULL_POINTER;
+
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
     
-    size = (((fieldinfo*)field)->name->blength);
-    *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
-    memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
+    if (name_ptr != NULL) {
+               size = utf_bytes(((fieldinfo*)field)->name)+1;
+               *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
+               utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
+       }
 
-    size = (((fieldinfo*)field)->descriptor->blength);
-    *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);    
-    memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
+       if (signature_ptr != NULL) {
+               size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
+               *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL); 
+               utf_sprint_convert_to_latin1(*signature_ptr, 
+                                                                        ((fieldinfo*)field)->descriptor);
+       }
 
-    *generic_ptr = NULL;
+       if (generic_ptr != NULL) 
+               *generic_ptr = NULL;
 
     return JVMTI_ERROR_NONE;
 }
@@ -2128,7 +2197,7 @@ GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
                        jclass * declaring_class_ptr)
 {
@@ -2136,9 +2205,18 @@ GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-    /* todo: how do I find declaring class other then iterate over all fields in all classes ?*/
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;     
+
+    if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+       *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
  
     return JVMTI_ERROR_NONE;
 }
@@ -2150,7 +2228,7 @@ GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
                   jint * modifiers_ptr)
 {
@@ -2158,14 +2236,17 @@ GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-       if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
-               return JVMTI_ERROR_INVALID_OBJECT;
+
+       if (klass == NULL) 
+               return JVMTI_ERROR_INVALID_CLASS;
+       else 
+               if (!builtin_instanceof(klass,class_java_lang_Class))
+                       return JVMTI_ERROR_INVALID_CLASS;
+
+    if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
 
        if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
  
-       /* todo: JVMTI_ERROR_INVALID_FIELDID; */
-       
        *modifiers_ptr = ((fieldinfo*)field)->flags;
        
     return JVMTI_ERROR_NONE;
@@ -2178,7 +2259,7 @@ GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
                  jboolean * is_synthetic_ptr)
 {
@@ -2200,7 +2281,7 @@ IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
               char **signature_ptr, char **generic_ptr)
 {
@@ -2211,17 +2292,25 @@ GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
-        || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
 
-    *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
-    memcpy(*name_ptr, m->name->text, m->name->blength);
+       if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
 
-    *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
-    memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
-    
-    /* there is no generic signature attribute */
-    *generic_ptr = NULL;
+       if (name_ptr != NULL) {
+               *name_ptr = (char*)
+                       heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
+               utf_sprint_convert_to_latin1(*name_ptr, m->name);
+       }
+       
+       if (signature_ptr != NULL) {
+               *signature_ptr = (char*)
+                       heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
+               utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
+       }
+
+       if (generic_ptr != NULL) {
+        /* there is no generic signature attribute */
+               *generic_ptr = NULL;
+       }
 
     return JVMTI_ERROR_NONE;
 }
@@ -2233,7 +2322,7 @@ GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
                         jclass * declaring_class_ptr)
 {
@@ -2257,7 +2346,7 @@ GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
 {
     CHECK_PHASE_START
@@ -2282,7 +2371,7 @@ GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
 {
     CHECK_PHASE_START
@@ -2295,7 +2384,7 @@ GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
     
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
-   
     *max_ptr = (jint) ((methodinfo*)method)->maxlocals;
 
     return JVMTI_ERROR_NONE;
@@ -2309,7 +2398,7 @@ GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
 {
     CHECK_PHASE_START
@@ -2323,19 +2412,19 @@ GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
 
-/* todo    *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
+    *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
     return JVMTI_ERROR_NONE;
 }
 
 
 
-/* GetLineNumberTable ***********************************************************
+/* GetLineNumberTable **********************************************************
 
    Return table of source line number entries for a given method
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLineNumberTable (jvmtiEnv * env, jmethodID method,
                    jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
 {
@@ -2349,8 +2438,10 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
    
     if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;    
+
     if (((methodinfo*)method)->flags & ACC_NATIVE)  
         return JVMTI_ERROR_NATIVE_METHOD;
+
     if (((methodinfo*)method)->linenumbers == NULL) 
         return JVMTI_ERROR_ABSENT_INFORMATION;
 
@@ -2360,9 +2451,9 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
 
 
     for (i=0; i < *entry_count_ptr; i++) {
-        (*table_ptr[i]).start_location = 
+        (*table_ptr)[i].start_location = 
             (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
-        (*table_ptr[i]).line_number = 
+        (*table_ptr)[i].line_number = 
             (jint) ((methodinfo*)method)->linenumbers[i].line_number;
     }
     
@@ -2378,7 +2469,7 @@ GetLineNumberTable (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetMethodLocation (jvmtiEnv * env, jmethodID method,
                   jlocation * start_location_ptr,
                   jlocation * end_location_ptr)
@@ -2390,8 +2481,13 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if ((method == NULL) || (start_location_ptr == NULL) || 
-        (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
+       if (method == NULL)     return JVMTI_ERROR_INVALID_METHODID;
+
+       if (((methodinfo*)method)->flags & ACC_NATIVE) 
+               return JVMTI_ERROR_NATIVE_METHOD;
+
+    if ((start_location_ptr == NULL) || (end_location_ptr == NULL)) 
+       return JVMTI_ERROR_NULL_POINTER;
     
        /* XXX we return the location of the most recent code. Don't know
         * if there is a way to teach jvmti that a method can have more
@@ -2399,11 +2495,17 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
 
        /* XXX Don't know if that's the right way to deal with not-yet-
         * compiled methods. -Edwin */
-       if (!m->code)
-               return JVMTI_ERROR_NULL_POINTER;
-       
+
+    fprintf(stderr,"GetMethodLocation *** XXX todo \n");
+
+
+       /* -1 states location information is not available */
+    *start_location_ptr = (jlocation)-1;
+    *end_location_ptr = (jlocation)-1;
+
+/*     
     *start_location_ptr = (jlocation)m->code->mcode;
-    *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
+    *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
     return JVMTI_ERROR_NONE;
 }
 
@@ -2414,7 +2516,7 @@ GetMethodLocation (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
                       jint * entry_count_ptr,
                       jvmtiLocalVariableEntry ** table_ptr)
@@ -2437,7 +2539,7 @@ GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetBytecodes (jvmtiEnv * env, jmethodID method,
              jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
 {
@@ -2467,7 +2569,7 @@ GetBytecodes (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
 {
     CHECK_PHASE_START
@@ -2494,7 +2596,7 @@ IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
                   jboolean * is_synthetic_ptr)
 {
@@ -2515,70 +2617,20 @@ IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
 {
-       int i,j;
-       char* data;
-       hashtable* ht;
-       classcache_name_entry *cne;
-       classcache_class_entry *cce;
-
-       log_text ("GetLoadedClasses called");
-
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-    if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-    if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-
-       log_text ("GetLoadedClasses1");
-
-       stopdebuggee();
-       log_text ("GetLoadedClasses2");
-       /* hashtable_classcache is in the same place in the child process memory 
-          because the child is a copy of this process */
-       getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
-       ht = (hashtable*) &data;
-
-       log_text ("GetLoadedClasses got ht pointer");
-       *classes_ptr = 
-               heap_allocate(sizeof(jclass*) * (ht->entries),true,NULL);
-       fprintf (stderr,"hashtable_classcache.entries = %d\n",ht->entries);
-       fflush(stderr);
-
-       *class_count_ptr = ht->entries;
-       j=0;
-    /* look in every slot of the hashtable */
-       for (i=0; i<ht->size; i++) { 
-               cne = ht->ptr[i];
-
-               while (cne != NULL) { /* iterate over hashlink */
-                       getchildproc(&data, cne, sizeof(classcache_name_entry));
-                       cne =(classcache_name_entry*) &data;
-
-                       cce = cne->classes;
-                       while (cce != NULL){ /* iterate over classes with same name */
-                               getchildproc(&data, cce, sizeof(classcache_class_entry));
-                               cce =(classcache_class_entry*) &data;
-                               
-                               if (cce->classobj != NULL) { /* get only loaded classes */
-                                       assert(j<ht->entries);
-                                       *classes_ptr[j]=cce->classobj;
-                                       j++;
-                               }
-                               cce = cce->next;
-                       }
-                       cne = cne->hashlink;
-               }
-       }
-
-       log_text ("GetLoadedClasses continue");
+    if (class_count_ptr == NULL)
+               return JVMTI_ERROR_NULL_POINTER;
 
-       contdebuggee(0);
+    if (classes_ptr == NULL)
+               return JVMTI_ERROR_NULL_POINTER;
 
-       log_text ("GetLoadedClasses finished");
+       classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
 
     return JVMTI_ERROR_NONE;
 }
@@ -2591,7 +2643,7 @@ GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
                       jint * class_count_ptr, jclass ** classes_ptr)
 {
@@ -2601,8 +2653,8 @@ GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
 
-/*    if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-         if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
+    if ((class_count_ptr == NULL) || (classes_ptr == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
         
        /* behave like jdk 1.1 and make no distinction between initiating and 
           defining class loaders */
@@ -2617,7 +2669,7 @@ GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 PopFrame (jvmtiEnv * env, jthread thread)
 {
     CHECK_PHASE_START
@@ -2636,7 +2688,7 @@ PopFrame (jvmtiEnv * env, jthread thread)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RedefineClasses (jvmtiEnv * env, jint class_count,
                 const jvmtiClassDefinition * class_definitions)
 {
@@ -2646,6 +2698,7 @@ RedefineClasses (jvmtiEnv * env, jint class_count,
     CHECK_PHASE_END;
        CHECK_CAPABILITY(env,can_redefine_classes)    
        CHECK_CAPABILITY(env,can_redefine_any_class)
+
   log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
     return JVMTI_ERROR_NONE;
 }
@@ -2657,12 +2710,12 @@ RedefineClasses (jvmtiEnv * env, jint class_count,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
 {
     if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
 
-    *version_ptr = JVMTI_VERSION_1_0;
+    *version_ptr = JVMTI_VERSION;
     
     return JVMTI_ERROR_NONE;
 }
@@ -2675,7 +2728,7 @@ GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 {
     if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -2692,7 +2745,7 @@ GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
                         char **source_debug_extension_ptr)
 {
@@ -2713,7 +2766,7 @@ GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IsMethodObsolete (jvmtiEnv * env, jmethodID method,
                  jboolean * is_obsolete_ptr)
 {
@@ -2728,43 +2781,70 @@ IsMethodObsolete (jvmtiEnv * env, jmethodID method,
 }
 
 
-/* *****************************************************************************
-
+/* SuspendThreadList **********************************************************
    
+   Suspend all threads in the request list.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SuspendThreadList (jvmtiEnv * env, jint request_count,
                   const jthread * request_list, jvmtiError * results)
 {
+       int i;
+       int suspendme = -1;
+       jthread me;
+
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_START)
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
-        
-  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_suspend);
+    
+       if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+       if ((request_list == NULL) || (results == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       me = jvmti_get_current_thread();
+
+       for (i=0;i<request_count;i++) {
+               if (request_list[i] == me) 
+                       suspendme = i;
+               else 
+                       results[i]=SuspendThread(env, request_list[i]);
+       }
+
+       if (suspendme != -1) 
+               results[suspendme]=SuspendThread(env, request_list[suspendme]);
+
     return JVMTI_ERROR_NONE;
 }
 
 
-/* *****************************************************************************
+/* ResumeThreadList ***********************************************************
 
-   
+   Resumes all threads in the request list.   
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ResumeThreadList (jvmtiEnv * env, jint request_count,
                  const jthread * request_list, jvmtiError * results)
 {
+       int i;
+
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-    CHECK_CAPABILITY(env,can_suspend)
-        
-  log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+    CHECK_CAPABILITY(env,can_suspend);
+    
+       if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+       if ((request_list == NULL) || (results == NULL)) 
+               return JVMTI_ERROR_NULL_POINTER;
+
+       for (i=0;i<request_count;i++) 
+                       results[i]=ResumeThread(env, request_list[i]);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -2775,23 +2855,25 @@ ResumeThreadList (jvmtiEnv * env, jint request_count,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
               jint max_frame_count, jvmtiFrameInfo * frame_buffer,
               jint * count_ptr)
 {
-       char* trace;
+       stacktracebuffer* trace;
        jvmtiError er;
-/*     int i,j;*/
+       int i,j;
 
        CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
     
-       if(!builtin_instanceof(thread,class_java_lang_Thread))
-               return JVMTI_ERROR_INVALID_THREAD;
+       if (thread != NULL){
+               if(!builtin_instanceof(thread,class_java_lang_Thread))
+                       return JVMTI_ERROR_INVALID_THREAD;
 
-       CHECK_THREAD_IS_ALIVE(thread);
+               CHECK_THREAD_IS_ALIVE(thread);
+       }
 
        if((count_ptr == NULL)||(frame_buffer == NULL)) 
                return JVMTI_ERROR_NULL_POINTER;
@@ -2799,16 +2881,21 @@ GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
        if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 
        er = getcacaostacktrace(&trace, thread);
-       if (er==JVMTI_ERROR_NONE) return er;
+       if (er == JVMTI_ERROR_NONE) {
+               heap_free(trace);
+               return er;
+       }
 
-/*     todo: if ((trace->size >= start_depth) || ((trace->size * -1) > start_depth)) 
-       return JVMTI_ERROR_ILLEGAL_ARGUMENT; */
+       if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth)) 
+               return JVMTI_ERROR_ILLEGAL_ARGUMENT; 
        
-/*     for (i=start_depth, j=0;i<trace->size;i++,j++) {
-               frame_buffer[j].method = (jmethodID)trace[i].start->method;
-         todo: location MachinePC not avilable - Linenumber not expected 
+       for (i=start_depth, j=0;i<trace->used;i++,j++) {
+               frame_buffer[j].method = (jmethodID)trace->entries[i].method;
+        /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
                frame_buffer[j].location = 0;
-               }*/
+               }
+
+       heap_free(trace);
        
     return JVMTI_ERROR_NONE;
 }
@@ -2820,7 +2907,7 @@ GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
                          const jthread * thread_list,
                          jint max_frame_count,
@@ -2865,7 +2952,7 @@ GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
                   jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
 {
@@ -2878,15 +2965,12 @@ GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
     
        if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
     
-       /* todo: all threads have to be suspended */ 
-
        if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
                return JVMTI_ERROR_INTERNAL;
 
        GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
                                                         max_frame_count, stack_info_ptr);
 
-       /* todo: resume all threads have to be suspended */ 
        if (er != JVMTI_ERROR_NONE) return er;
 
     return JVMTI_ERROR_NONE;
@@ -2899,7 +2983,7 @@ GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
 {
        jvmtiThreadLocalStorage *tls;
@@ -2990,7 +3074,7 @@ SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
 {
        CHECK_PHASE_START
@@ -3009,7 +3093,7 @@ GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetTag (jvmtiEnv * env, jobject object, jlong tag)
 {
        CHECK_PHASE_START
@@ -3029,7 +3113,7 @@ SetTag (jvmtiEnv * env, jobject object, jlong tag)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 ForceGarbageCollection (jvmtiEnv * env)
 {
        CHECK_PHASE_START
@@ -3048,7 +3132,7 @@ ForceGarbageCollection (jvmtiEnv * env)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
                                       jvmtiObjectReferenceCallback
                                       object_reference_callback,
@@ -3070,7 +3154,7 @@ IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
                             heap_root_callback,
                             jvmtiStackReferenceCallback
@@ -3094,7 +3178,7 @@ IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
                 jvmtiHeapObjectCallback heap_object_callback,
                 void *user_data)
@@ -3115,7 +3199,7 @@ IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
                             jvmtiHeapObjectFilter object_filter,
                             jvmtiHeapObjectCallback
@@ -3137,7 +3221,7 @@ IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
                    jint * count_ptr, jobject ** object_result_ptr,
                    jlong ** tag_result_ptr)
@@ -3158,7 +3242,7 @@ GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetJNIFunctionTable (jvmtiEnv * env,
                     const jniNativeInterface * function_table)
 { 
@@ -3169,7 +3253,7 @@ SetJNIFunctionTable (jvmtiEnv * env,
     
     if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
     _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
-    memcpy(_Jv_env->env, function_table, sizeof(jniNativeInterface));
+    memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
     return JVMTI_ERROR_NONE;
 }
 
@@ -3181,7 +3265,7 @@ SetJNIFunctionTable (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
 {
     CHECK_PHASE_START
@@ -3204,7 +3288,7 @@ GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEventCallbacks (jvmtiEnv * env,
                   const jvmtiEventCallbacks * callbacks,
                   jint size_of_callbacks)
@@ -3216,6 +3300,7 @@ SetEventCallbacks (jvmtiEnv * env,
 
     if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
 
+
        if (callbacks == NULL) { /* remove the existing callbacks */
         memset(&(((environment* )env)->callbacks), 0, 
                           sizeof(jvmtiEventCallbacks));
@@ -3234,14 +3319,14 @@ SetEventCallbacks (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
-        
-  log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+       CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
+
     return JVMTI_ERROR_NONE;
 }
 
@@ -3252,7 +3337,7 @@ GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
                       jvmtiExtensionFunctionInfo ** extensions)
 {
@@ -3261,7 +3346,7 @@ GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-    if ((extension_count_ptr== NULL)||(extensions == NULL)) 
+    if ((extension_count_ptr == NULL)||(extensions == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
     /* cacao has no extended functions yet */
@@ -3277,7 +3362,7 @@ GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
                    jvmtiExtensionEventInfo ** extensions)
 {
@@ -3286,7 +3371,7 @@ GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
     CHECK_PHASE(JVMTI_PHASE_LIVE)
     CHECK_PHASE_END;
         
-    if ((extension_count_ptr== NULL)||(extensions == NULL)) 
+    if ((extension_count_ptr == NULL)||(extensions == NULL)) 
         return JVMTI_ERROR_NULL_POINTER;
 
     /* cacao has no extended events yet */
@@ -3302,7 +3387,7 @@ GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
                           jvmtiExtensionEvent callback)
 {
@@ -3322,16 +3407,14 @@ SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 DisposeEnvironment (jvmtiEnv * env)
 {
        environment* cacao_env = (environment*)env;
        environment* tenvs = envs;
-    memset(&((cacao_env)->events[0]),0,sizeof(jvmtiEventModeLL)*
-                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
-    (cacao_env)->EnvironmentLocalStorage = NULL;
-       
-       if (tenvs!=cacao_env) {
+       jvmtiThreadLocalStorage *jtls, *tjtls;
+
+       if (tenvs != cacao_env) {
                while (tenvs->next != cacao_env) {
                        tenvs = tenvs->next;
                }
@@ -3339,7 +3422,25 @@ DisposeEnvironment (jvmtiEnv * env)
        } else
                envs = NULL;
 
-    /* let Boehm GC do the rest */
+       cacao_env->env=NULL;
+    memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
+                  (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+    cacao_env->EnvironmentLocalStorage = NULL;
+
+       jtls = cacao_env->tls;
+       while (jtls != NULL) {
+               tjtls = jtls;
+               jtls = jtls->next;
+               tjtls->next = NULL;
+       }
+       cacao_env->tls = NULL;
+
+
+       jvmti_cacaodbgserver_quit();
+
+    /* let the GC do the rest */
     return JVMTI_ERROR_NONE;
 }
 
@@ -3354,7 +3455,7 @@ DisposeEnvironment (jvmtiEnv * env)
                                     memcpy(*name_ptr, &str, sizeof(str)); \
                                     break
 
-jvmtiError
+static jvmtiError
 GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
 {
     if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -3468,10 +3569,10 @@ GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
 {
-    *format_ptr = JVMTI_JLOCATION_MACHINEPC;
+    *format_ptr = JVMTI_JLOCATION_OTHER;
     return JVMTI_ERROR_NONE;
 }
 
@@ -3483,7 +3584,7 @@ GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
 {
        jmethodID mid, moremid;
@@ -3563,7 +3664,7 @@ GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
 {
     jmethodID mid;
@@ -3597,7 +3698,7 @@ GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
     if (!mid) throw_main_exception_exit();
 
     obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
-        NULL, sysprop, mid, javastring_new_char(property));
+        NULL, sysprop, mid, javastring_new_from_ascii(property));
     if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
 
     ch = javastring_tochar(obj);
@@ -3615,7 +3716,7 @@ GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
 {
     jmethodID mid;
@@ -3647,7 +3748,7 @@ SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
     if (!mid) throw_main_exception_exit();
 
     _Jv_JNINativeInterface.CallObjectMethod(
-        NULL, sysprop, mid, javastring_new_char(property),javastring_new_char(value));
+        NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
     
     return JVMTI_ERROR_NONE;
 }
@@ -3658,7 +3759,7 @@ SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
 {
     if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -3674,7 +3775,7 @@ GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
        CHECK_PHASE_START
@@ -3694,7 +3795,7 @@ GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
 {
        CHECK_PHASE_START
@@ -3713,7 +3814,7 @@ GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
        CHECK_PHASE_START
@@ -3732,7 +3833,7 @@ GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
 {
        CHECK_PHASE_START
@@ -3749,7 +3850,7 @@ GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 {
     if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -3768,7 +3869,7 @@ GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetTime (jvmtiEnv * env, jlong * nanos_ptr)
 {
     /* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
@@ -3793,9 +3894,8 @@ GetTime (jvmtiEnv * env, jlong * nanos_ptr)
 
 *******************************************************************************/
 
-jvmtiError
-GetPotentialCapabilities (jvmtiEnv * env,
-                         jvmtiCapabilities * capabilities_ptr)
+static jvmtiError
+GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
 {
     CHECK_PHASE_START
     CHECK_PHASE(JVMTI_PHASE_ONLOAD)
@@ -3810,11 +3910,13 @@ GetPotentialCapabilities (jvmtiEnv * env,
 }
 
 
-#define CHECK_ADD_CAPABILITY(env,CAN)      \
-        if ((capabilities_ptr->CAN == 1) && \
-           (JVMTI_Capabilities.CAN == 0))   \
-           return JVMTI_ERROR_NOT_AVAILABLE; \
-        env->capabilities.CAN = 1;
+#define CHECK_ADD_CAPABILITY(env,CAN)          \
+        if (capabilities_ptr->CAN == 1) {      \
+           if (JVMTI_Capabilities.CAN == 0)    \
+             return JVMTI_ERROR_NOT_AVAILABLE; \
+           else                                \
+             env->capabilities.CAN = 1;        \
+        }                                     
 
 /* AddCapabilities ************************************************************
 
@@ -3823,7 +3925,7 @@ GetPotentialCapabilities (jvmtiEnv * env,
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
 {
     environment* cacao_env;
@@ -3887,7 +3989,7 @@ AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 RelinquishCapabilities (jvmtiEnv * env,
                        const jvmtiCapabilities * capabilities_ptr)
 {
@@ -3940,13 +4042,13 @@ RelinquishCapabilities (jvmtiEnv * env,
     return JVMTI_ERROR_NONE;
 }
 
-/* *****************************************************************************
+/* GetAvailableProcessors *****************************************************
 
-   
+   Get number of processors available to the virtual machine.
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
 {
        CHECK_PHASE_START
@@ -3969,7 +4071,7 @@ GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
 {
     if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
@@ -3986,7 +4088,7 @@ GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
 {
     if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
@@ -4003,7 +4105,7 @@ SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
 {
     char* tmp_bcp;
@@ -4032,7 +4134,7 @@ AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
 {
     switch (flag) {
@@ -4061,7 +4163,7 @@ SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
 
 *******************************************************************************/
 
-jvmtiError
+static jvmtiError
 GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
 {
     CHECK_PHASE_START
@@ -4092,7 +4194,7 @@ static jvmtiCapabilities JVMTI_Capabilities = {
   1,                           /* can_get_bytecodes */
   0,                           /* can_get_synthetic_attribute */
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
   1,                           /* can_get_owned_monitor_info */
   1,                           /* can_get_current_contended_monitor */
 #else
@@ -4103,35 +4205,25 @@ static jvmtiCapabilities JVMTI_Capabilities = {
   0,                           /* can_get_monitor_info */
   0,                           /* can_pop_frame */
   0,                           /* can_redefine_classes */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-  /* current implementation does not work if called from another process */
-  0,                           /* can_signal_thread */
-#else
   0,                           /* can_signal_thread */
-#endif
   1,                           /* can_get_source_file_name */
   1,                           /* can_get_line_numbers */
   0,                           /* can_get_source_debug_extension */
   0,                           /* can_access_local_variables */
   0,                           /* can_maintain_original_method_order */
   0,                           /* can_generate_single_step_events */
-  0,                           /* can_generate_exception_events */
+  1,                           /* can_generate_exception_events */
   0,                           /* can_generate_frame_pop_events */
-  0,                           /* can_generate_breakpoint_events */
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-  /* current implementation does not work if called from another process */
-  0,                           /* can_suspend */
-#else
-  0,                           /* can_suspend */
-#endif
+  1,                           /* can_generate_breakpoint_events */
+  1,                           /* can_suspend */
   0,                           /* can_redefine_any_class */
   0,                           /* can_get_current_thread_cpu_time */
   0,                           /* can_get_thread_cpu_time */
-  0,                           /* can_generate_method_entry_events */
+  1,                           /* can_generate_method_entry_events */
   0,                           /* can_generate_method_exit_events */
   0,                           /* can_generate_all_class_hook_events */
   0,                           /* can_generate_compiled_method_load_events */
-  0,                           /* can_generate_monitor_events */
+  1,                           /* can_generate_monitor_events */
   0,                           /* can_generate_vm_object_alloc_events */
   0,                           /* can_generate_native_method_bind_events */
   0,                           /* can_generate_garbage_collection_events */
@@ -4295,11 +4387,16 @@ static struct jvmtiEnv_struct JVMTI_EnvTable = {
     &GetObjectSize
 };
 
+/* jvmti_set_phase ************************************************************
 
-void set_jvmti_phase(jvmtiPhase p) {
+  sets a new jvmti phase a fires an apropriate event.
+
+*******************************************************************************/
+
+void jvmti_set_phase(jvmtiPhase p) {
        genericEventData d;
 
-       fprintf (stderr,"set JVMTI pid %d phase %d\n",getpid(),p);
+       fprintf (stderr,"set JVMTI phase %d\n",p);
        fflush(stderr);
 
     switch (p) {
@@ -4312,13 +4409,13 @@ void set_jvmti_phase(jvmtiPhase p) {
     case JVMTI_PHASE_START: 
                phase = p;
                d.ev = JVMTI_EVENT_VM_START;
-               /* this event is sent during start or live phase */
-               log_text("debugger process - set brk in setthreadobj");
-               setsysbrkpt(SETTHREADOBJECTBRK,(void*)&setthreadobject);
         break;
     case JVMTI_PHASE_LIVE: 
                phase = p; 
                d.ev = JVMTI_EVENT_VM_INIT;
+               jvmti_fireEvent(&d);
+               /* thread start event for main thread */
+               d.ev = JVMTI_EVENT_THREAD_START;
                break;
     case JVMTI_PHASE_DEAD:
                phase = p;
@@ -4329,10 +4426,17 @@ void set_jvmti_phase(jvmtiPhase p) {
                exit(1);
     }
 
-       fireEvent(&d);
+       jvmti_fireEvent(&d);
 }
 
-jvmtiEnv* new_jvmtienv() {
+
+/* jvmti_new_environment ******************************************************
+
+  creates a new JVMTI environment
+
+*******************************************************************************/
+
+jvmtiEnv* jvmti_new_environment() {
     environment* env;
 
        if (envs == NULL) {
@@ -4340,80 +4444,110 @@ jvmtiEnv* new_jvmtienv() {
                env = envs;
        } else {
                env = envs;
-               if (env != NULL) 
-                       while (env->next!=NULL) {
-                               env=env->next;
-                       }
-                       env = heap_allocate(sizeof(environment),true,NULL);
+               while (env->next != NULL) env = env->next;
+               env->next = heap_allocate(sizeof(environment),true,NULL);
+               env = env->next;
        }
+
        env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
     memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
        memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
                   sizeof(jvmtiEventModeLL));
     /* To possess a capability, the agent must add the capability.*/
-    memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
+    memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
     RelinquishCapabilities(&(env->env),&(env->capabilities));
     env->EnvironmentLocalStorage = NULL;
        env->tls = NULL;
+       
+       /* initialize cacao debugging facilities */
+       jvmti_cacao_debug_init();
 
        return (jvmtiEnv*)env;
 }
 
-void agentload(char* opt_arg) {
-       lt_dlhandle  handle;
-       lt_ptr       onload;
-       char *libname, *arg;
+/* jvmti_agentload ************************************************************
+
+  loads the indicated shared library containing the jvmti agent and calls the
+  Agent_OnLoad function.
+
+*******************************************************************************/
+
+void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle  *handle, char **libname) {
+       lt_ptr onload;
+       char *arg;
        int i=0,len;
        jint retval;
-       classinfo* ci;
-       
+
        len = strlen(opt_arg);
        
-       while ((opt_arg[i]!='=')&&(i<len)) i++;
-       
-       libname=MNEW(char,i);
-       strncpy(libname,opt_arg,i-1);
-       libname[i-1]='\0';
+       /* separate arguments */
 
-       arg=MNEW(char, len-i);
-       strcpy(arg,&opt_arg[i+1]);
+       while ((opt_arg[i] != '=') && (i < len))
+               i++;
 
-       /* try to open the library */
+       opt_arg[i] = '\0';
+
+       if (i < len)
+               arg = &opt_arg[i + 1];
+       else
+               arg = "";
 
-       if (!(handle = lt_dlopen(libname)))
-               return;
+       if (agentbypath) {
+               /* -agentpath */
 
+               *libname = GCMNEW(char, i);
+
+               strcpy(*libname, opt_arg);
+       }
+       else {
+               /* -agentlib */
+
+               len = strlen("lib") + i + strlen(".so") + strlen("0");
+
+               *libname = GCMNEW(char, len);
+
+               strcpy(*libname, "lib");
+               strcat(*libname, opt_arg);
+               strcat(*libname, ".so");
+       }
+
+       /* try to open the library */
+       lt_dlinit();
+       if (!(*handle = lt_dlopen(*libname))) {
+               fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
+       }
+               
        /* resolve Agent_OnLoad function */
-       onload = lt_dlsym(handle, "Agent_OnLoad");
-       if (onload == NULL) {
-               fprintf(stderr, "unable to load Agent_OnLoad function in %s\n", libname);
-               exit(1);
+       if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
+               fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
+               vm_shutdown(1);
        }
 
        /* resolve Agent_UnLoad function */
-       unload = lt_dlsym(handle, "Agent_Unload");
-
-       /* add library to native library hashtable */
-       ci = load_class_from_sysloader(utf_new_char("java.lang.Object"));
-       native_hashtable_library_add(utf_new_char(libname), ci->classloader, handle);
+       unload = lt_dlsym(*handle, "Agent_Unload");
 
        retval = 
                ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
-                onload) ((JavaVM*) &_Jv_JNIInvokeInterface, arg, NULL);
-       
-       MFREE(libname,char,i);
-       MFREE(arg,char,len-i);
-       
+                onload) ((JavaVM *) _Jv_jvm, arg, NULL);
+
        if (retval != 0) exit (retval);
 }
 
-void agentunload() {
+/* jvmti_agentunload **********************************************************
+
+  calls the Agent_UnLoad function in the jvmti agent if present.
+
+*******************************************************************************/
+
+void jvmti_agentunload() {
        if (unload != NULL) {
                ((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload) 
                        ((JavaVM*) &_Jv_JNIInvokeInterface);
        }
 }
 
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where