* src/threads/thread.hpp (thread_set_object, thread_get_object): Removed.
[cacao.git] / src / native / vm / openjdk / jvm.cpp
index 1b9780fafffc3cd6a3cb4437f3bc324408ad16e6..0d365146f0e398fb44aa2bdfa738b5a9b414d024 100644 (file)
@@ -1,7 +1,8 @@
 /* src/native/vm/openjdk/jvm.cpp - HotSpot VM interface functions
 
-   Copyright (C) 2007, 2008
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2009 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -37,8 +38,6 @@
 #include <sys/ioctl.h>
 #endif
 
-#include <sys/socket.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 
 // Include our JNI header before the JVM headers, because the JVM
 #include INCLUDE_JVM_MD_H
 #include INCLUDE_JVM_H
 
-#include "mm/memory.h"
+#include "fdlibm/fdlibm.h"
+
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 #include "native/native.hpp"
 
 #include "native/vm/reflection.hpp"
 
-#include "native/vm/openjdk/hpi.h"
+#include "native/vm/openjdk/hpi.hpp"
 #include "native/vm/openjdk/management.hpp"
 
 #include "threads/lock.hpp"
 #include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/list.hpp"
 
 #include "vm/array.hpp"
 #endif
 
 #include "vm/jit/builtin.hpp"
-#include "vm/classcache.h"
+#include "vm/classcache.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/initialize.h"
+#include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/options.h"
 #include "vm/os.hpp"
 #include "vm/package.hpp"
 #include "vm/primitive.hpp"
 #include "vm/properties.hpp"
-#include "vm/resolve.h"
-#include "vm/signallocal.h"
+#include "vm/resolve.hpp"
+#include "vm/signallocal.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
         }                                                                              \
     } while (0)
 
-# define PRINTJVMWARNINGS(x)
-/*     do { \ */
-/*         if (opt_PrintJVMWarnings) { \ */
-/*             log_println x; \ */
-/*         } \ */
-/*     } while (0) */
+# define PRINTJVMWARNINGS(x)                                   \
+    do {                                                                               \
+        if (opt_PrintWarnings) {                               \
+            log_println x;                                             \
+        }                                                                              \
+    } while (0)
 
 #else
 
@@ -406,9 +408,9 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
                return 0;
        }
 
-       java_handle_bytearray_t* ba = jlt.get_backtrace();
+       ByteArray ba(jlt.get_backtrace());
 
-       if (ba == NULL)
+       if (ba.is_null())
                return 0;
 
        // We need a critical section here as the stacktrace structure is
@@ -416,7 +418,7 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 
        LLNI_CRITICAL_START;
 
-       stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
+       stacktrace_t* st = (stacktrace_t *) ba.get_raw_data_ptr();
 
        int32_t depth = st->length;
 
@@ -433,66 +435,13 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
        TRACEJVMCALLS(("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index));
 
        java_lang_Throwable jlt(throwable);
-       java_handle_bytearray_t* ba = jlt.get_backtrace();
+       ByteArray ba(jlt.get_backtrace());
 
-       // We need a critical section here as the stacktrace structure is
+       // XXX We need a critical section here as the stacktrace structure is
        // mapped onto a Java byte-array.
-       LLNI_CRITICAL_START;
-
-       stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
-
-       if ((index < 0) || (index >= st->length)) {
-               /* XXX This should be an IndexOutOfBoundsException (check this
-                  again). */
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       // Get the stacktrace entry.
-       stacktrace_entry_t* ste = &(st->entries[index]);
-
-       // Get the codeinfo, methodinfo and classinfo.
-       codeinfo*   code = ste->code;
-       methodinfo* m    = code->m;
-       classinfo*  c    = m->clazz;
-
-       // Get filename.
-       java_handle_t* filename;
-
-       if (!(m->flags & ACC_NATIVE)) {
-               if (c->sourcefile != NULL)
-                       filename = javastring_new(c->sourcefile);
-               else
-                       filename = NULL;
-       }
-       else
-               filename = NULL;
-
-       // Get line number.
-       int32_t linenumber;
-
-       if (m->flags & ACC_NATIVE) {
-               linenumber = -2;
-       }
-       else {
-               // FIXME linenumbertable->find could change the methodinfo
-               // pointer when hitting an inlined method.
-               linenumber = code->linenumbertable->find(&m, ste->pc);
-               linenumber = (linenumber == 0) ? -1 : linenumber;
-       }
-
-       LLNI_CRITICAL_END;
-
-       // Get declaring class name.
-       java_handle_t* declaringclass = class_get_classname(c);
-
-       // Allocate a new StackTraceElement object.
-       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
-
-       if (jlste.is_null())
-               return NULL;
+       stacktrace_t* st = (stacktrace_t *) ba.get_raw_data_ptr();
 
-       return (jobject) jlste.get_handle();
+       return stacktrace_get_StackTraceElement(st, index);
 }
 
 
@@ -645,21 +594,23 @@ void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
 
 /* JVM_GetLastErrorString */
 
-jint JVM_GetLastErrorString(char *buf, int len)
+jint JVM_GetLastErrorString(charbuf, int len)
 {
        TRACEJVMCALLS(("JVM_GetLastErrorString(buf=%p, len=%d", buf, len));
 
-       return hpi_system->GetLastErrorString(buf, len);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_system().GetLastErrorString(buf, len);
 }
 
 
 /* JVM_NativePath */
 
-char *JVM_NativePath(char *path)
+char *JVM_NativePath(charpath)
 {
        TRACEJVMCALLS(("JVM_NativePath(path=%s)", path));
 
-       return hpi_file->NativePath(path);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().NativePath(path);
 }
 
 
@@ -702,6 +653,25 @@ void JVM_ResolveClass(JNIEnv* env, jclass cls)
 }
 
 
+/* JVM_FindClassFromBootLoader */
+
+jclass JVM_FindClassFromBootLoader(JNIEnv* env, const char* name)
+{
+       classinfo     *c;
+       utf           *u;
+
+       TRACEJVMCALLS(("JVM_FindClassFromBootLoader(name=%s)", name));
+
+       u  = utf_new_char(name);
+       c = load_class_from_classloader(u, NULL);
+
+       if (c == NULL)
+               return NULL;
+
+       return (jclass) LLNI_classinfo_wrap(c);
+}
+
+
 /* JVM_FindClassFromClassLoader */
 
 jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)
@@ -825,7 +795,7 @@ jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
 
        oa = class_get_interfaces(c);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -875,14 +845,11 @@ jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
 
 void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
 {
-       classinfo                 *c;
-       java_handle_objectarray_t *hoa;
-
        TRACEJVMCALLS(("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers));
 
-       c = LLNI_classinfo_unwrap(cls);
+       classinfo* c = LLNI_classinfo_unwrap(cls);
 
-       hoa = (java_handle_objectarray_t *) signers;
+       ObjectArray oa(signers);
 
     /* This call is ignored for primitive types and arrays.  Signers
           are only set once, ClassLoader.java, and thus shouldn't be
@@ -892,7 +859,8 @@ void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
        if (class_is_primitive(c) || class_is_array(c))
                return;
 
-       LLNI_classinfo_field_set(c, signers, hoa);
+       // XXX: Fix this!
+       LLNI_classinfo_field_set(c, signers, (java_objectarray_t*) oa.get_handle());
 }
 
 
@@ -1078,7 +1046,7 @@ jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
 
        oa = class_get_declaredclasses(c, false);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1227,7 +1195,7 @@ jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean pu
 
        oa = class_get_declaredfields(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1241,7 +1209,7 @@ jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean p
 
        java_handle_objectarray_t* oa = class_get_declaredmethods(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1258,7 +1226,7 @@ jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jbool
 
        oa = class_get_declaredconstructors(c, publicOnly);
 
-       return (jobjectArray) oa;
+       return oa;
 }
 
 
@@ -1671,47 +1639,43 @@ jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
 
 jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 {
-       java_handle_objectarray_t             *classes;
-       java_handle_objectarray_t             *packages;
-       java_booleanarray_t                   *classEnabled;
-       java_booleanarray_t                   *packageEnabled;
 #if defined(ENABLE_ASSERTION)
-       java_handle_t                         *js;
-       s4                                     i, j;
+       java_handle_tjs;
+       s4             i, j;
 #endif
 
        TRACEJVMCALLS(("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused));
 
 #if defined(ENABLE_ASSERTION)
-       classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
+       ObjectArray classes(assertion_class_count, class_java_lang_Object);
 #else
-       classes = builtin_anewarray(0, class_java_lang_Object);
+       ObjectArray classes(0, class_java_lang_Object);
 #endif
-       if (classes == NULL)
+       if (classes.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
-       packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
+       ObjectArray packages(assertion_package_count, class_java_lang_Object);
 #else
-       packages = builtin_anewarray(0, class_java_lang_Object);
+       ObjectArray packages(0, class_java_lang_Object);
 #endif
-       if (packages == NULL)
+       if (packages.is_null())
                return NULL;
        
 #if defined(ENABLE_ASSERTION)
-       classEnabled = builtin_newarray_boolean(assertion_class_count);
+       BooleanArray classEnabled(assertion_class_count);
 #else
-       classEnabled = builtin_newarray_boolean(0);
+       BooleanArray classEnabled(0);
 #endif
-       if (classEnabled == NULL)
+       if (classEnabled.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
-       packageEnabled = builtin_newarray_boolean(assertion_package_count);
+       BooleanArray packageEnabled(assertion_package_count);
 #else
-       packageEnabled = builtin_newarray_boolean(0);
+       BooleanArray packageEnabled(0);
 #endif
-       if (packageEnabled == NULL)
+       if (packageEnabled.is_null())
                return NULL;
 
 #if defined(ENABLE_ASSERTION)
@@ -1730,13 +1694,13 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
                        }
 
                        if (item->package == false) {
-                               classes->data[i] = js;
-                               classEnabled->data[i] = (jboolean) item->enabled;
+                               classes.set_element(i, js);
+                               classEnabled.set_element(i, (jboolean) item->enabled);
                                i += 1;
                        }
                        else {
-                               packages->data[j] = js;
-                               packageEnabled->data[j] = (jboolean) item->enabled;
+                               packages.set_element(j, js);
+                               packageEnabled.set_element(j, (jboolean) item->enabled);
                                j += 1;
                        }
                }
@@ -1745,7 +1709,11 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 
        /* set instance fields */
 
-       java_lang_AssertionStatusDirectives jlasd(classes, classEnabled, packages, packageEnabled);
+       java_lang_AssertionStatusDirectives jlasd(
+                       classes.get_handle(),
+                       classEnabled.get_handle(),
+                       packages.get_handle(),
+                       packageEnabled.get_handle());
 
        return (jobject) jlasd.get_handle();
 }
@@ -2050,13 +2018,14 @@ jboolean JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
  */
 #define JVM_EEXIST       -100
 
-jint JVM_Open(const char *fname, jint flags, jint mode)
+jint JVM_Open(const charfname, jint flags, jint mode)
 {
        int result;
 
        TRACEJVMCALLS(("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode));
 
-       result = hpi_file->Open(fname, flags, mode);
+       HPI& hpi = VM::get_current()->get_hpi();
+       result = hpi.get_file().Open(fname, flags, mode);
 
        if (result >= 0) {
                return result;
@@ -2078,37 +2047,41 @@ jint JVM_Close(jint fd)
 {
        TRACEJVMCALLS(("JVM_Close(fd=%d)", fd));
 
-       return hpi_file->Close(fd);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().Close(fd);
 }
 
 
 /* JVM_Read */
 
-jint JVM_Read(jint fd, char *buf, jint nbytes)
+jint JVM_Read(jint fd, charbuf, jint nbytes)
 {
        TRACEJVMCALLS(("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes));
 
-       return (jint) hpi_file->Read(fd, buf, nbytes);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return (jint) hpi.get_file().Read(fd, buf, nbytes);
 }
 
 
 /* JVM_Write */
 
-jint JVM_Write(jint fd, char *buf, jint nbytes)
+jint JVM_Write(jint fd, charbuf, jint nbytes)
 {
        TRACEJVMCALLS(("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes));
 
-       return (jint) hpi_file->Write(fd, buf, nbytes);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return (jint) hpi.get_file().Write(fd, buf, nbytes);
 }
 
 
 /* JVM_Available */
 
-jint JVM_Available(jint fd, jlong *pbytes)
+jint JVM_Available(jint fd, jlongpbytes)
 {
        TRACEJVMCALLS(("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes));
 
-       return hpi_file->Available(fd, pbytes);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().Available(fd, pbytes);
 }
 
 
@@ -2118,7 +2091,8 @@ jlong JVM_Lseek(jint fd, jlong offset, jint whence)
 {
        TRACEJVMCALLS(("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence));
 
-       return hpi_file->Seek(fd, (off_t) offset, whence);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().Seek(fd, (off_t) offset, whence);
 }
 
 
@@ -2128,7 +2102,8 @@ jint JVM_SetLength(jint fd, jlong length)
 {
        TRACEJVMCALLS(("JVM_SetLength(fd=%d, length=%ld)", length));
 
-       return hpi_file->SetLength(fd, length);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().SetLength(fd, length);
 }
 
 
@@ -2138,7 +2113,8 @@ jint JVM_Sync(jint fd)
 {
        TRACEJVMCALLS(("JVM_Sync(fd=%d)", fd));
 
-       return hpi_file->Sync(fd);
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.get_file().Sync(fd);
 }
 
 
@@ -2173,8 +2149,7 @@ jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
-       /* The threadobject is null when a thread is created in Java. The
-          priority is set later during startup. */
+       /* The threadobject is null when a thread is created in Java. */
 
        if (t == NULL)
                return 0;
@@ -2189,7 +2164,23 @@ jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
 
 void JVM_SuspendThread(JNIEnv* env, jobject jthread)
 {
-       log_println("JVM_SuspendThread: Deprecated.  Not implemented.");
+       java_handle_t *h;
+       threadobject  *t;
+
+       TRACEJVMCALLS(("JVM_SuspendThread(env=%p, jthread=%p)", env, jthread));
+
+       if (opt_PrintWarnings)
+               log_println("JVM_SuspendThread: Deprecated, do not use!");
+
+       h = (java_handle_t *) jthread;
+       t = thread_get_thread(h);
+
+       /* The threadobject is null when a thread is created in Java. */
+
+       if (t == NULL)
+               return;
+
+       threads_suspend_thread(t, SUSPEND_REASON_JAVA);
 }
 
 
@@ -2197,7 +2188,23 @@ void JVM_SuspendThread(JNIEnv* env, jobject jthread)
 
 void JVM_ResumeThread(JNIEnv* env, jobject jthread)
 {
-       log_println("JVM_ResumeThread: Deprecated.  Not implemented.");
+       java_handle_t *h;
+       threadobject  *t;
+
+       TRACEJVMCALLS(("JVM_ResumeThread(env=%p, jthread=%p)", env, jthread));
+
+       if (opt_PrintWarnings)
+               log_println("JVM_ResumeThread: Deprecated, do not use!");
+
+       h = (java_handle_t *) jthread;
+       t = thread_get_thread(h);
+
+       /* The threadobject is null when a thread is created in Java. */
+
+       if (t == NULL)
+               return;
+
+       threads_resume_thread(t, SUSPEND_REASON_JAVA);
 }
 
 
@@ -2279,6 +2286,8 @@ void JVM_Interrupt(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
        if (t == NULL)
                return;
 
@@ -2299,6 +2308,11 @@ jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrup
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
+       if (t == NULL)
+               return JNI_FALSE;
+
        interrupted = thread_is_interrupted(t);
 
        if (interrupted && clear_interrupted)
@@ -2352,12 +2366,10 @@ jclass JVM_CurrentLoadedClass(JNIEnv *env)
 
 jobject JVM_CurrentClassLoader(JNIEnv *env)
 {
-    /* XXX if a method in a class in a trusted loader is in a
-          doPrivileged, return NULL */
+       TRACEJVMCALLS(("JVM_CurrentClassLoader(env=%p)", env));
+       PRINTJVMWARNINGS(("JVM_CurrentClassLoader is deprecated, do not use it."));
 
-       log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
-
-       return NULL;
+       return stacktrace_first_nonsystem_classloader();
 }
 
 
@@ -2367,7 +2379,7 @@ jobjectArray JVM_GetClassContext(JNIEnv *env)
 {
        TRACEJVMCALLS(("JVM_GetClassContext(env=%p)", env));
 
-       return (jobjectArray) stacktrace_getClassContext();
+       return stacktrace_getClassContext();
 }
 
 
@@ -2449,13 +2461,9 @@ jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint le
 
 jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 {
-       classloader_t *cl;
-
        TRACEJVMCALLS(("JVM_LatestUserDefinedLoader(env=%p)", env));
 
-       cl = stacktrace_first_nonnull_classloader();
-
-       return (jobject) cl;
+       return stacktrace_first_nonnull_classloader();
 }
 
 
@@ -2473,13 +2481,21 @@ jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring c
 
 jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 {
-       java_handle_t *a;
-
        TRACEJVMCALLS(("JVM_GetArrayLength(arr=%p)", arr));
 
-       a = (java_handle_t *) arr;
+       if (arr == NULL) {
+               exceptions_throw_nullpointerexception();
+               return -1;
+       }
+
+       Array a(arr);
+
+       // Check for exception in constructor.
+       if (a.is_null()) {
+               return -1;
+       }
 
-       return array_length_get(a);
+       return a.get_length();
 }
 
 
@@ -2487,21 +2503,16 @@ jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 
 jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
 {
-       java_handle_t *a;
-       java_handle_t *o;
-
        TRACEJVMCALLS(("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index));
 
-       a = (java_handle_t *) arr;
+       Array a(arr);
 
 /*     if (!class_is_array(a->objheader.vftbl->class)) { */
 /*             exceptions_throw_illegalargumentexception(); */
 /*             return NULL; */
 /*     } */
 
-       o = array_element_get(a, index);
-
-       return (jobject) o;
+       return a.get_boxed_element(index);
 }
 
 
@@ -2523,15 +2534,11 @@ jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint w
 
 void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)
 {
-       java_handle_t *a;
-       java_handle_t *value;
-
        TRACEJVMCALLS(("JVM_SetArrayElement(env=%p, arr=%p, index=%d, val=%p)", env, arr, index, val));
 
-       a     = (java_handle_t *) arr;
-       value = (java_handle_t *) val;
+       Array a(arr);
 
-       array_element_set(a, index, value);
+       a.set_boxed_element(index, val);
 }
 
 
@@ -2547,11 +2554,6 @@ void JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v
 
 jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 {
-       classinfo                 *c;
-       classinfo                 *pc;
-       java_handle_t             *a;
-       java_handle_objectarray_t *oa;
-
        TRACEJVMCALLS(("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length));
 
        if (eltClass == NULL) {
@@ -2559,14 +2561,14 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
                return NULL;
        }
 
-       /* NegativeArraySizeException is checked in builtin_newarray. */
+       /* NegativeArraySizeException is checked by array constructor. */
 
-       c = LLNI_classinfo_unwrap(eltClass);
+       classinfo* c = LLNI_classinfo_unwrap(eltClass);
 
        /* Create primitive or object array. */
 
        if (class_is_primitive(c)) {
-               pc = Primitive::get_arrayclass_by_name(c->name);
+               classinfo* pc = Primitive::get_arrayclass_by_name(c->name);
 
                /* void arrays are not allowed. */
 
@@ -2575,14 +2577,14 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
                        return NULL;
                }
 
-               a = builtin_newarray(length, pc);
+               Array a(length, pc);
 
-               return (jobject) a;
+               return (jobject) a.get_handle();
        }
        else {
-               oa = builtin_anewarray(length, c);
+               ObjectArray oa(length, c);
 
-               return (jobject) oa;
+               return (jobject) oa.get_handle();
        }
 }
 
@@ -2592,7 +2594,6 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 {
        classinfo                 *c;
-       java_handle_intarray_t    *ia;
        int32_t                    length;
        long                      *dims;
        int32_t                    value;
@@ -2611,17 +2612,17 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
        c = LLNI_classinfo_unwrap(eltClass);
 
-       ia = (java_handle_intarray_t *) dim;
-
-       length = array_length_get((java_handle_t *) ia);
+       IntArray ia(dim);
 
        /* We check here for exceptions thrown in array_length_get,
           otherwise these exceptions get overwritten by the following
           IllegalArgumentException. */
 
-       if (length < 0)
+       if (ia.is_null())
                return NULL;
 
+       length = ia.get_length();
+
        if ((length <= 0) || (length > /* MAX_DIM */ 255)) {
                exceptions_throw_illegalargumentexception();
                return NULL;
@@ -2632,20 +2633,32 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
        dims = MNEW(long, length);
 
        for (i = 0; i < length; i++) {
-               value = LLNI_array_direct(ia, i);
+               value = ia.get_element(i);
                dims[i] = (long) value;
        }
 
        /* Create an array-class if necessary. */
 
-       if (class_is_primitive(c))
+       if (class_is_primitive(c)) {
                ac = Primitive::get_arrayclass_by_name(c->name);
+
+               // Arrays of void are not allowed.
+               if (ac == NULL) {
+                       exceptions_throw_illegalargumentexception();
+                       return NULL;
+               }
+
+               if (length > 1)
+                       ac = class_multiarray_of((length - 1), ac, true);
+       }
        else
-               ac = class_array_of(c, true);
+               ac = class_multiarray_of(length, c, true);
 
        if (ac == NULL)
                return NULL;
 
+       /* Allocate a new array on the heap. */
+
        a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
 
        return (jobject) a;
@@ -2658,7 +2671,8 @@ jint JVM_InitializeSocketLibrary()
 {
        TRACEJVMCALLS(("JVM_InitializeSocketLibrary()"));
 
-       return hpi_initialize_socket_library();
+       HPI& hpi = VM::get_current()->get_hpi();
+       return hpi.initialize_socket_library();
 }
 
 
@@ -2706,9 +2720,13 @@ jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 
 jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 {
-       log_println("JVM_Send: IMPLEMENT ME!");
+       TRACEJVMCALLSENTER(("JVM_Send(fd=%d, buf=%p, nBytes=%d, flags=%d", fd, buf, nBytes, flags));
 
-       return 0;
+       int result = os::send(fd, buf, nBytes, flags);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -2886,17 +2904,15 @@ struct protoent *JVM_GetProtoByName(char* name)
 
 /* JVM_LoadLibrary */
 
-void *JVM_LoadLibrary(const char *name)
+void* JVM_LoadLibrary(const char* name)
 {
-       utf*  u;
-       void* handle;
-
        TRACEJVMCALLSENTER(("JVM_LoadLibrary(name=%s)", name));
 
-       u = utf_new_char(name);
-
-       handle = native_library_open(u);
+       utf* u = utf_new_char(name);
 
+       NativeLibrary nl(u);
+       void* handle = nl.open();
+       
        TRACEJVMCALLSEXIT(("->%p", handle));
 
        return handle;
@@ -2909,19 +2925,21 @@ void JVM_UnloadLibrary(void* handle)
 {
        TRACEJVMCALLS(("JVM_UnloadLibrary(handle=%p)", handle));
 
-       native_library_close(handle);
+       NativeLibrary nl(handle);
+       nl.close();
 }
 
 
 /* JVM_FindLibraryEntry */
 
-void *JVM_FindLibraryEntry(void *handle, const char *name)
+void *JVM_FindLibraryEntry(void* handle, const char* name)
 {
        void* symbol;
 
        TRACEJVMCALLSENTER(("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name));
 
-       symbol = hpi_library->FindLibraryEntry(handle, name);
+       HPI& hpi = VM::get_current()->get_hpi();
+       symbol = hpi.get_library().FindLibraryEntry(handle, name);
 
        TRACEJVMCALLSEXIT(("->%p", symbol));
 
@@ -2931,11 +2949,17 @@ void *JVM_FindLibraryEntry(void *handle, const char *name)
 
 /* JVM_IsNaN */
 
-jboolean JVM_IsNaN(jdouble a)
+jboolean JVM_IsNaN(jdouble d)
 {
-       log_println("JVM_IsNaN: IMPLEMENT ME!");
+       bool result;
 
-       return 0;
+       TRACEJVMCALLSENTER(("JVM_IsNaN(d=%f)", d));
+
+       result = isnan(d);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -3210,9 +3234,31 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
-       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+       // Get a list of all active threads.
+       List<threadobject*> active_threads;
+       ThreadList::get_active_java_threads(active_threads);
 
-       return NULL;
+       // Allocate array to hold the java.lang.Thread objects.
+       int32_t length = active_threads.size();
+       ObjectArray oa(length, class_java_lang_Thread);
+
+       if (oa.is_null())
+               return NULL;
+
+       // Iterate over all threads (which were active just a second ago).
+       int32_t index = 0;
+       for (List<threadobject*>::iterator it = active_threads.begin(); it != active_threads.end(); it++) {
+               threadobject* t = *it;
+
+               java_handle_t* h = LLNI_WRAP(t->object);
+               assert(h != NULL);
+
+               oa.set_element(index, h);
+
+               index++;
+       }
+
+       return oa.get_handle();
 }
 
 
@@ -3220,9 +3266,57 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
-       log_println("JVM_DumpThreads: IMPLEMENT ME!");
+       int32_t i;
 
-       return NULL;
+       TRACEJVMCALLS(("JVM_DumpThreads((env=%p, threadClass=%p, threads=%p)", env, threadClass, threads));
+
+       if (threads == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       ObjectArray oa(threads);
+
+       // Get length of the threads array.
+       int32_t length = oa.get_length();
+
+       if (length <= 0) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Allocate array to hold stacktraces.
+       classinfo* arrayclass = class_array_of(class_java_lang_StackTraceElement, true);
+       ObjectArray oaresult(length, arrayclass);
+
+       if (oaresult.is_null()) {
+               return NULL;
+       }
+
+       // Iterate over all passed thread objects.
+       for (i = 0; i < length; i++) {
+               java_handle_t* thread = oa.get_element(i);
+
+               // Get thread for the given thread object.
+               threadobject* t = thread_get_thread(thread);
+
+               // The threadobject is null when a thread is created in Java.
+               if (t == NULL)
+                       continue;
+
+               // Get stacktrace for given thread.
+               stacktrace_t* st = stacktrace_get_of_thread(t);
+
+               // Convert stacktrace into array of StackTraceElements.
+               java_handle_objectarray_t* oaste = stacktrace_get_StackTraceElements(st);
+
+               if (oaste == NULL)
+                       return NULL;
+
+               oaresult.set_element(i, oaste);
+       }
+
+       return oaresult.get_handle();
 }
 
 
@@ -3250,32 +3344,28 @@ jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 
 jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 {
-       classinfo                 *c;
-       methodinfo                *m;
-       java_handle_objectarray_t *oa;
-
        TRACEJVMCALLS(("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass));
 
-       c = LLNI_classinfo_unwrap(ofClass);
+       classinfo* c = LLNI_classinfo_unwrap(ofClass);
 
        if ((c == NULL) || class_is_primitive(c))
                return NULL;
 
-       m = class_get_enclosingmethod_raw(c);
+       methodinfo* m = class_get_enclosingmethod_raw(c);
 
        if (m == NULL)
                return NULL;
 
-       oa = builtin_anewarray(3, class_java_lang_Object);
+       ObjectArray oa(3, class_java_lang_Object);
 
-       if (oa == NULL)
+       if (oa.is_null())
                return NULL;
 
-       array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
-       array_objectarray_element_set(oa, 1, javastring_new(m->name));
-       array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
+       oa.set_element(0, (java_handle_t *) LLNI_classinfo_wrap(m->clazz));
+       oa.set_element(1, javastring_new(m->name));
+       oa.set_element(2, javastring_new(m->descriptor));
 
-       return (jobjectArray) oa;
+       return oa.get_handle();
 }
 
 
@@ -3283,8 +3373,6 @@ jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 
 jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 {
-       java_handle_intarray_t *ia;
-
        TRACEJVMCALLS(("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
                                  env, javaThreadState));
 
@@ -3297,71 +3385,79 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 
        switch (javaThreadState) {
     case THREAD_STATE_NEW:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_NEW);
-               break; 
+                       ia.set_element(0, THREAD_STATE_NEW);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_RUNNABLE:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_RUNNABLE);
-               break; 
+                       ia.set_element(0, THREAD_STATE_RUNNABLE);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_BLOCKED:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_BLOCKED);
-               break; 
+                       ia.set_element(0, THREAD_STATE_BLOCKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_WAITING:
-               ia = builtin_newarray_int(2);
+               {
+                       IntArray ia(2);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 1, PARKED); */
-               break; 
+                       ia.set_element(0, THREAD_STATE_WAITING);
+                       ia.set_element(1, THREAD_STATE_PARKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_TIMED_WAITING:
-               ia = builtin_newarray_int(3);
+               {
+                       IntArray ia(2);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               /* XXX Not sure about that one. */
-/*             array_intarray_element_set(ia, 0, SLEEPING); */
-               array_intarray_element_set(ia, 0, THREAD_STATE_TIMED_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 2, PARKED); */
-               break; 
+                       /* XXX Not sure about that one. */
+/*                     ia.set_element(0, SLEEPING); */
+                       ia.set_element(0, THREAD_STATE_TIMED_WAITING);
+                       ia.set_element(1, THREAD_STATE_TIMED_PARKED);
+                       return ia.get_handle();
+               }
 
     case THREAD_STATE_TERMINATED:
-               ia = builtin_newarray_int(1);
+               {
+                       IntArray ia(1);
 
-               if (ia == NULL)
-                       return NULL;
+                       if (ia.is_null())
+                               return NULL;
 
-               array_intarray_element_set(ia, 0, THREAD_STATE_TERMINATED);
-               break; 
+                       ia.set_element(0, THREAD_STATE_TERMINATED);
+                       return ia.get_handle();
+               }
 
     default:
                /* Unknown state - probably incompatible JDK version */
                return NULL;
        }
-
-       return (jintArray) ia;
 }
 
 
@@ -3369,14 +3465,12 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 
 jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values)
 {
-       java_handle_intarray_t    *ia;
-       java_handle_objectarray_t *oa;
-       java_object_t             *s;
+       java_object_t* s;
 
        TRACEJVMCALLS(("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
                                  env, javaThreadState, values));
 
-       ia = (java_handle_intarray_t *) values;
+       IntArray ia(values);
 
        /* If new thread states are added in future JDK and VM versions,
           this should check if the JDK version is compatible with thread
@@ -3392,103 +3486,122 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
 
        switch (javaThreadState) {
     case THREAD_STATE_NEW:
-               assert(ia->header.size == 1 && ia->data[0] == THREAD_STATE_NEW);
+               {
+                       assert(ia.get_length() == 1 && ia.get_element(0) == THREAD_STATE_NEW);
 
-               oa = builtin_anewarray(1, class_java_lang_String);
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("NEW"));
+                       s = javastring_new(utf_new_char("NEW"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_RUNNABLE:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("RUNNABLE"));
+                       s = javastring_new(utf_new_char("RUNNABLE"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_BLOCKED:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("BLOCKED"));
+                       s = javastring_new(utf_new_char("BLOCKED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_WAITING:
-               oa = builtin_anewarray(2, class_java_lang_String);
+               {
+                       ObjectArray oa(2, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("WAITING.PARKED")); */
+                       s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
+
+                       oa.set_element(0, s);
 
-               array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 1, s); */
-               break; 
+                       s = javastring_new(utf_new_char("WAITING.PARKED"));
+
+                       if (s == NULL)
+                               return NULL;
+
+                       oa.set_element(1, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_TIMED_WAITING:
-               oa = builtin_anewarray(3, class_java_lang_String);
+               {
+                       ObjectArray oa(2, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-/*             s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
-               s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("TIMED_WAITING.PARKED")); */
+/*                     s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
+                       s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
+
+                       oa.set_element(0, s);
 
-/*             array_objectarray_element_set(oa, 0, s); */
-               array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 2, s); */
-               break; 
+                       s = javastring_new(utf_new_char("TIMED_WAITING.PARKED"));
+
+                       if (s == NULL)
+                               return NULL;
+
+                       oa.set_element(1, s);
+                       return oa.get_handle();
+               }
 
     case THREAD_STATE_TERMINATED:
-               oa = builtin_anewarray(1, class_java_lang_String);
+               {
+                       ObjectArray oa(1, class_java_lang_String);
 
-               if (oa == NULL)
-                       return NULL;
+                       if (oa.is_null())
+                               return NULL;
 
-               s = javastring_new(utf_new_char("TERMINATED"));
+                       s = javastring_new(utf_new_char("TERMINATED"));
 
-               if (s == NULL)
-                       return NULL;
+                       if (s == NULL)
+                               return NULL;
 
-               array_objectarray_element_set(oa, 0, s);
-               break; 
+                       oa.set_element(0, s);
+                       return oa.get_handle();
+               }
 
        default:
                /* Unknown state - probably incompatible JDK version */
                return NULL;
        }
-
-       return (jobjectArray) oa;
 }
 
 
@@ -3496,7 +3609,15 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
 
 void JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)
 {
-       log_println("JVM_GetVersionInfo: IMPLEMENT ME!");
+       TRACEJVMCALLS(("JVM_GetVersionInfo(env=%p, info=%p, info_size=%zd)", env, info, info_size));
+
+       memset(info, 0, info_size);
+
+       info->jvm_version = ((VERSION_MAJOR & 0xff) << 24) | ((VERSION_MINOR & 0xff) << 16) | (VERSION_MICRO & 0xff);
+       info->update_version = 0;
+       info->special_update_version = 0;
+       info->is_attach_supported = 0;
+       info->is_kernel_jvm = 0;
 }