Merged with tip.
[cacao.git] / src / vm / builtin.c
index fdbec98fc19fc5c3d84bb5ab770542b11a9fd621..377bad8830fd3370390200d55b26348f91e13fd7 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/builtin.c - functions for unsupported operations
 
 /* src/vm/builtin.c - functions for unsupported operations
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 
    This file is part of CACAO.
 
@@ -28,8 +26,6 @@
    calls instead of machine instructions, using the C calling
    convention.
 
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 7986 2007-05-30 20:45:43Z twisti $
-
 */
 
 
 */
 
 
 #include "mm/memory.h"
 
 #include "native/jni.h"
 #include "mm/memory.h"
 
 #include "native/jni.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
+#include "native/llni.h"
 
 #include "threads/lock-common.h"
 
 #include "threads/lock-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
 
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
 
+#include "vm/array.h"
 #include "vm/builtin.h"
 #include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
 #include "vm/builtin.h"
 #include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
+#include "vm/primitive.hpp"
 #include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
 #include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/patcher.h"
+#include "vm/jit/trace.h"
 
 #include "vmcore/class.h"
 
 #include "vmcore/class.h"
+#include "vmcore/linker.h"
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
 #include "vmcore/rt-timing.h"
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
 #include "vmcore/rt-timing.h"
@@ -82,9 +81,6 @@
 #include <vmlog_cacao.h>
 #endif
 
 #include <vmlog_cacao.h>
 #endif
 
-#if defined(ENABLE_DEBUG_FILTER)
-#      include "vm/jit/show.h"
-#endif
 
 /* include builtin tables *****************************************************/
 
 
 /* include builtin tables *****************************************************/
 
 CYCLES_STATS_DECLARE(builtin_new         ,100,5)
 CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
 
 CYCLES_STATS_DECLARE(builtin_new         ,100,5)
 CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
 
+
+/*============================================================================*/
+/* BUILTIN TABLE MANAGEMENT FUNCTIONS                                         */
+/*============================================================================*/
+
 /* builtintable_init ***********************************************************
 
    Parse the descriptors of builtin functions and create the parsed
 /* builtintable_init ***********************************************************
 
    Parse the descriptors of builtin functions and create the parsed
@@ -104,12 +105,13 @@ CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
 static bool builtintable_init(void)
 {
        descriptor_pool    *descpool;
 static bool builtintable_init(void)
 {
        descriptor_pool    *descpool;
-       s4                  dumpsize;
        builtintable_entry *bte;
        builtintable_entry *bte;
+       methodinfo         *m;
+       int32_t             dumpmarker;
 
        /* mark start of dump memory area */
 
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* create a new descriptor pool */
 
 
        /* create a new descriptor pool */
 
@@ -126,14 +128,13 @@ static bool builtintable_init(void)
        /* first add all descriptors to the pool */
 
        for (bte = builtintable_internal; bte->fp != NULL; bte++) {
        /* first add all descriptors to the pool */
 
        for (bte = builtintable_internal; bte->fp != NULL; bte++) {
-               /* create a utf8 string from descriptor */
-
+               bte->name       = utf_new_char(bte->cname);
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                        /* release dump area */
 
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                        /* release dump area */
 
-                       dump_release(dumpsize);
+                       DRELEASE;
 
                        return false;
                }
 
                        return false;
                }
@@ -143,7 +144,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
                        return false;
                }
        }
@@ -154,7 +155,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
                        return false;
                }
        }
@@ -167,31 +168,54 @@ static bool builtintable_init(void)
 
        descriptor_pool_alloc_parsed_descriptors(descpool);
 
 
        descriptor_pool_alloc_parsed_descriptors(descpool);
 
-       /* now parse all descriptors */
+       /* Now parse all descriptors.  NOTE: builtin-functions are treated
+          like static methods (no `this' pointer). */
 
        for (bte = builtintable_internal; bte->fp != NULL; bte++) {
 
        for (bte = builtintable_internal; bte->fp != NULL; bte++) {
-               /* parse the descriptor, builtin is always static (no `this' pointer) */
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
+
+               /* generate a builtin stub if we need one */
 
 
-               bte->md = descriptor_pool_parse_method_descriptor(descpool,
-                                                                                                                 bte->descriptor,
-                                                                                                                 ACC_STATIC, NULL);
+               if (bte->flags & BUILTINTABLE_FLAG_STUB) {
+                       m = method_new_builtin(bte);
+                       codegen_generate_stub_builtin(m, bte);
+               }
        }
 
        for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
        }
 
        for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
-               bte->md = descriptor_pool_parse_method_descriptor(descpool,
-                                                                                                                 bte->descriptor,
-                                                                                                                 ACC_STATIC, NULL);
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
+
+               /* no stubs should be needed for this table */
+
+               assert(!bte->flags & BUILTINTABLE_FLAG_STUB);
        }
 
        for (bte = builtintable_function; bte->fp != NULL; bte++) {
        }
 
        for (bte = builtintable_function; bte->fp != NULL; bte++) {
-               bte->md = descriptor_pool_parse_method_descriptor(descpool,
-                                                                                                                 bte->descriptor,
-                                                                                                                 ACC_STATIC, NULL);
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
+
+               /* generate a builtin stub if we need one */
+
+               if (bte->flags & BUILTINTABLE_FLAG_STUB) {
+                       m = method_new_builtin(bte);
+                       codegen_generate_stub_builtin(m, bte);
+               }
        }
 
        /* release dump area */
 
        }
 
        /* release dump area */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return true;
 }
 
        return true;
 }
@@ -242,6 +266,8 @@ static void builtintable_sort_automatic(void)
 
 bool builtin_init(void)
 {
 
 bool builtin_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("builtin_init");
+
        /* initialize the builtin tables */
 
        if (!builtintable_init())
        /* initialize the builtin tables */
 
        if (!builtintable_init())
@@ -304,7 +330,8 @@ builtintable_entry *builtintable_get_automatic(s4 opcode)
                if (middle->opcode < opcode) {
                        first = middle + 1;
                        entries -= half + 1;
                if (middle->opcode < opcode) {
                        first = middle + 1;
                        entries -= half + 1;
-               } else
+               }
+               else
                        entries = half;
        }
 
                        entries = half;
        }
 
@@ -349,14 +376,15 @@ bool builtintable_replace_function(void *iptr_)
 
        for (bte = builtintable_function; bte->fp != NULL; bte++) {
                if ((METHODREF_CLASSNAME(mr) == bte->classname) &&
 
        for (bte = builtintable_function; bte->fp != NULL; bte++) {
                if ((METHODREF_CLASSNAME(mr) == bte->classname) &&
-                       (mr->name             == bte->name) &&
-                       (mr->descriptor       == bte->descriptor)) {
+                       (mr->name                == bte->name) &&
+                       (mr->descriptor          == bte->descriptor)) {
 
                        /* set the values in the instruction */
 
 
                        /* set the values in the instruction */
 
-                       iptr->opc   = bte->opcode;
+                       iptr->opc           = bte->opcode;
                        iptr->sx.s23.s3.bte = bte;
                        iptr->sx.s23.s3.bte = bte;
-                       if (bte->checkexception)
+
+                       if (bte->flags & BUILTINTABLE_FLAG_EXCEPTION)
                                iptr->flags.bits |= INS_FLAG_CHECK;
                        else
                                iptr->flags.bits &= ~INS_FLAG_CHECK;
                                iptr->flags.bits |= INS_FLAG_CHECK;
                        else
                                iptr->flags.bits &= ~INS_FLAG_CHECK;
@@ -370,9 +398,9 @@ bool builtintable_replace_function(void *iptr_)
 #endif /* defined(ENABLE_JIT) */
 
 
 #endif /* defined(ENABLE_JIT) */
 
 
-/*****************************************************************************
-                                                               TYPE CHECKS
-*****************************************************************************/
+/*============================================================================*/
+/* INTERNAL BUILTIN FUNCTIONS                                                 */
+/*============================================================================*/
 
 /* builtin_instanceof **********************************************************
 
 
 /* builtin_instanceof **********************************************************
 
@@ -380,34 +408,47 @@ bool builtintable_replace_function(void *iptr_)
    of that class). If class is an interface, checks if the interface
    is implemented.
 
    of that class). If class is an interface, checks if the interface
    is implemented.
 
-   Return value: 1 ... o is an instance of class or implements the interface
-                 0 ... otherwise or if o == NULL
-                        
+   RETURN VALUE:
+     1......o is an instance of class or implements the interface
+     0......otherwise or if o == NULL
+
+   NOTE: This builtin can be called from NATIVE code only.
+
 *******************************************************************************/
 
 *******************************************************************************/
 
-s4 builtin_instanceof(java_objectheader *o, classinfo *class)
+bool builtin_instanceof(java_handle_t *o, classinfo *c)
 {
 {
+       classinfo *oc;
+
        if (o == NULL)
                return 0;
 
        if (o == NULL)
                return 0;
 
-       return class_isanysubclass(o->vftbl->class, class);
+       LLNI_class_get(o, oc);
+
+       return class_isanysubclass(oc, c);
 }
 
 
 
 /* builtin_checkcast ***********************************************************
 
 }
 
 
 
 /* builtin_checkcast ***********************************************************
 
-   The same as builtin_instanceof except that 1 is returned when o ==
-   NULL.
-                         
+   The same as builtin_instanceof but with the exception
+   that 1 is returned when (o == NULL).
+
+   NOTE: This builtin can be called from NATIVE code only.
+
 *******************************************************************************/
 
 *******************************************************************************/
 
-s4 builtin_checkcast(java_objectheader *o, classinfo *class)
+bool builtin_checkcast(java_handle_t *o, classinfo *c)
 {
 {
+       classinfo *oc;
+
        if (o == NULL)
                return 1;
 
        if (o == NULL)
                return 1;
 
-       if (class_isanysubclass(o->vftbl->class, class))
+       LLNI_class_get(o, oc);
+
+       if (class_isanysubclass(oc, c))
                return 1;
 
        return 0;
                return 1;
 
        return 0;
@@ -416,15 +457,15 @@ s4 builtin_checkcast(java_objectheader *o, classinfo *class)
 
 /* builtin_descriptorscompatible ***********************************************
 
 
 /* builtin_descriptorscompatible ***********************************************
 
-   Checks if two array type descriptors are assignment compatible
+   Checks if two array type descriptors are assignment compatible.
 
 
-   Return value: 1 ... target = desc is possible
-                 0 ... otherwise
+   RETURN VALUE:
+      1......target = desc is possible
+      0......otherwise
                        
 *******************************************************************************/
 
                        
 *******************************************************************************/
 
-static s4 builtin_descriptorscompatible(arraydescriptor *desc,
-                                                                               arraydescriptor *target)
+static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
 {
        if (desc == target)
                return 1;
 {
        if (desc == target)
                return 1;
@@ -438,6 +479,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {both arrays are arrays of references} */
 
        if (desc->dimension == target->dimension) {
        /* {both arrays are arrays of references} */
 
        if (desc->dimension == target->dimension) {
+               if (!desc->elementvftbl)
+                       return 0;
                /* an array which contains elements of interface types is
            allowed to be casted to Object (JOWENN)*/
 
                /* an array which contains elements of interface types is
            allowed to be casted to Object (JOWENN)*/
 
@@ -445,8 +488,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
                        (target->elementvftbl->baseval == 1))
                        return 1;
 
                        (target->elementvftbl->baseval == 1))
                        return 1;
 
-               return class_isanysubclass(desc->elementvftbl->class,
-                                                                  target->elementvftbl->class);
+               return class_isanysubclass(desc->elementvftbl->clazz,
+                                                                  target->elementvftbl->clazz);
        }
 
        if (desc->dimension < target->dimension)
        }
 
        if (desc->dimension < target->dimension)
@@ -455,7 +498,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {desc has higher dimension than target} */
 
        return class_isanysubclass(pseudo_class_Arraystub,
        /* {desc has higher dimension than target} */
 
        return class_isanysubclass(pseudo_class_Arraystub,
-                                                          target->elementvftbl->class);
+                                                          target->elementvftbl->clazz);
 }
 
 
 }
 
 
@@ -469,10 +512,12 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
    arrays of arrays (which in turn can again be arrays of arrays), the
    types at the lowest level have to satisfy the corresponding sub
    class relation.
    arrays of arrays (which in turn can again be arrays of arrays), the
    types at the lowest level have to satisfy the corresponding sub
    class relation.
-       
+
+   NOTE: This is a FAST builtin and can be called from JIT code only.
+
 *******************************************************************************/
 
 *******************************************************************************/
 
-s4 builtin_arraycheckcast(java_objectheader *o, classinfo *targetclass)
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 {
        arraydescriptor *desc;
 
 {
        arraydescriptor *desc;
 
@@ -488,86 +533,63 @@ s4 builtin_arraycheckcast(java_objectheader *o, classinfo *targetclass)
 }
 
 
 }
 
 
-s4 builtin_arrayinstanceof(java_objectheader *o, classinfo *targetclass)
+/* builtin_fast_arrayinstanceof ************************************************
+
+   NOTE: This is a FAST builtin and can be called from JIT code only.
+
+*******************************************************************************/
+
+bool builtin_fast_arrayinstanceof(java_object_t *o, classinfo *targetclass)
 {
        if (o == NULL)
                return 0;
 
 {
        if (o == NULL)
                return 0;
 
-       return builtin_arraycheckcast(o, targetclass);
+       return builtin_fast_arraycheckcast(o, targetclass);
 }
 
 
 }
 
 
-/* builtin_throw_exception *****************************************************
+/* builtin_arrayinstanceof *****************************************************
 
 
-   Sets the exceptionptr with the thrown exception and prints some
-   debugging information.  Called from asm_vm_call_method.
+   NOTE: This builtin can be called from NATIVE code only.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-void *builtin_throw_exception(java_objectheader *xptr)
+bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
 {
 {
-#if !defined(NDEBUG)
-    java_lang_Throwable *t;
-       char                *logtext;
-       s4                   logtextlen;
-       s4                   dumpsize;
-
-       if (opt_verbose) {
-               t = (java_lang_Throwable *) xptr;
-
-               /* calculate message length */
-
-               logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
-
-               if (t) {
-                       logtextlen +=
-                               utf_bytes(xptr->vftbl->class->name);
-                       if (t->detailMessage) {
-                               logtextlen += strlen(": ") +
-                                       u2_utflength(t->detailMessage->value->data 
-                                                                       + t->detailMessage->offset,
-                                                        t->detailMessage->count);
-                       }
-               } 
-               else {
-                       logtextlen += strlen("(nil)");
-               }
-
-               /* allocate memory */
+       bool result;
 
 
-               dumpsize = dump_size();
+       LLNI_CRITICAL_START;
 
 
-               logtext = DMNEW(char, logtextlen);
+       result = builtin_fast_arrayinstanceof(LLNI_UNWRAP(h), targetclass);
 
 
-               strcpy(logtext, "Builtin exception thrown: ");
+       LLNI_CRITICAL_END;
 
 
-               if (t) {
-                       utf_cat_classname(logtext, xptr->vftbl->class->name);
+       return result;
+}
 
 
-                       if (t->detailMessage) {
-                               char *buf;
 
 
-                               buf = javastring_tochar((java_objectheader *) t->detailMessage);
-                               strcat(logtext, ": ");
-                               strcat(logtext, buf);
-                               MFREE(buf, char, strlen(buf) + 1);
-                       }
+/* builtin_throw_exception *****************************************************
 
 
-               } else {
-                       strcat(logtext, "(nil)");
-               }
+   Sets the exception pointer with the thrown exception and prints some
+   debugging information.
+   
+   NOTE: This is a FAST builtin and can be called from JIT code,
+   or from asm_vm_call_method.
 
 
-               log_text(logtext);
+*******************************************************************************/
 
 
-               /* release memory */
+void *builtin_throw_exception(java_object_t *xptr)
+{
+#if !defined(NDEBUG)
+       /* print exception trace */
 
 
-               dump_release(dumpsize);
-       }
+       if (opt_TraceExceptions)
+               trace_exception_builtin(xptr);
 #endif /* !defined(NDEBUG) */
 
        /* actually set the exception */
 
 #endif /* !defined(NDEBUG) */
 
        /* actually set the exception */
 
-       exceptions_set_exception(xptr);
+       exceptions_set_exception(LLNI_QUICKWRAP(xptr));
 
        /* Return a NULL pointer.  This is required for vm_call_method to
           check for an exception.  This is for convenience. */
 
        /* Return a NULL pointer.  This is required for vm_call_method to
           check for an exception.  This is for convenience. */
@@ -576,24 +598,84 @@ void *builtin_throw_exception(java_objectheader *xptr)
 }
 
 
 }
 
 
+/* builtin_retrieve_exception **************************************************
+
+   Gets and clears the exception pointer of the current thread.
+
+   RETURN VALUE:
+      the exception object, or NULL if no exception was thrown.
+
+   NOTE: This is a FAST builtin and can be called from JIT code,
+   or from the signal handlers.
+
+*******************************************************************************/
+
+java_object_t *builtin_retrieve_exception(void)
+{
+       java_handle_t *h;
+       java_object_t *o;
+
+       /* actually get and clear the exception */
+
+       h = exceptions_get_and_clear_exception();
+       o = LLNI_UNWRAP(h);
+
+       return o;
+}
+
+
 /* builtin_canstore ************************************************************
 
    Checks, if an object can be stored in an array.
 
 /* builtin_canstore ************************************************************
 
    Checks, if an object can be stored in an array.
 
-   Return value: 1 ... possible
-                 0 ... otherwise (throws an ArrayStoreException)
+   RETURN VALUE:
+      1......possible
+      0......otherwise (throws an ArrayStoreException)
+
+   NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
+bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
+{
+       bool result;
+
+       LLNI_CRITICAL_START;
+
+       result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
+
+       LLNI_CRITICAL_END;
+
+       /* if not possible, throw an exception */
+
+       if (result == 0)
+               exceptions_throw_arraystoreexception();
+
+       return result;
+}
+
+
+/* builtin_fast_canstore *******************************************************
+
+   Checks, if an object can be stored in an array.
+
+   RETURN VALUE:
+      1......possible
+      0......otherwise (no exception thrown!)
+
+   NOTE: This is a FAST builtin and can be called from JIT code only.
+
+*******************************************************************************/
+
+bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
        arraydescriptor *valuedesc;
        vftbl_t         *componentvftbl;
        vftbl_t         *valuevftbl;
 {
        arraydescriptor *desc;
        arraydescriptor *valuedesc;
        vftbl_t         *componentvftbl;
        vftbl_t         *valuevftbl;
-       s4               base;
-       castinfo         classvalues;
-       s4               result;
+       int32_t          baseval;
+       uint32_t         diffval;
+       bool             result;
 
        if (o == NULL)
                return 1;
 
        if (o == NULL)
                return 1;
@@ -604,7 +686,7 @@ s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
         *     *) oa->...vftbl->arraydesc->componentvftbl != NULL
         *     *) o->vftbl is not an interface vftbl
         */
         *     *) oa->...vftbl->arraydesc->componentvftbl != NULL
         *     *) o->vftbl is not an interface vftbl
         */
-       
+
        desc           = oa->header.objheader.vftbl->arraydesc;
        componentvftbl = desc->componentvftbl;
        valuevftbl     = o->vftbl;
        desc           = oa->header.objheader.vftbl->arraydesc;
        componentvftbl = desc->componentvftbl;
        valuevftbl     = o->vftbl;
@@ -617,20 +699,22 @@ s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
                if (valuevftbl == componentvftbl)
                        return 1;
 
                if (valuevftbl == componentvftbl)
                        return 1;
 
-               ASM_GETCLASSVALUES_ATOMIC(componentvftbl, valuevftbl, &classvalues);
+               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
 
 
-               base = classvalues.super_baseval;
+               baseval = componentvftbl->baseval;
 
 
-               if (base <= 0) {
+               if (baseval <= 0) {
                        /* an array of interface references */
 
                        /* an array of interface references */
 
-                       result = ((valuevftbl->interfacetablelength > -base) &&
-                                       (valuevftbl->interfacetable[base] != NULL));
+                       result = ((valuevftbl->interfacetablelength > -baseval) &&
+                                         (valuevftbl->interfacetable[baseval] != NULL));
                }
                else {
                }
                else {
-                       result = ((unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
-                                  <= (unsigned) classvalues.super_diffval);
+                       diffval = valuevftbl->baseval - componentvftbl->baseval;
+                       result  = diffval <= (uint32_t) componentvftbl->diffval;
                }
                }
+
+               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
        }
        else if (valuedesc == NULL) {
                /* {oa has dimension > 1} */
        }
        else if (valuedesc == NULL) {
                /* {oa has dimension > 1} */
@@ -646,11 +730,6 @@ s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
                result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
        }
 
                result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
        }
 
-       /* if not possible, throw an exception */
-
-       if (result == 0)
-               exceptions_throw_arraystoreexception();
-
        /* return result */
 
        return result;
        /* return result */
 
        return result;
@@ -658,16 +737,17 @@ s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
+bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 {
        arraydescriptor *desc;
 {
        arraydescriptor *desc;
-       vftbl_t *elementvftbl;
-       vftbl_t *valuevftbl;
-       s4 res;
-       int base;
-       castinfo classvalues;
+       vftbl_t         *elementvftbl;
+       vftbl_t         *valuevftbl;
+       int32_t          baseval;
+       uint32_t         diffval;
+       bool             result;
        
        
-       if (!o) return 1;
+       if (o == NULL)
+               return 1;
 
        /* The following is guaranteed (by verifier checks):
         *
 
        /* The following is guaranteed (by verifier checks):
         *
@@ -686,30 +766,37 @@ s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
        if (valuevftbl == elementvftbl)
                return 1;
 
-       ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues);
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+
+       baseval = elementvftbl->baseval;
 
 
-       if ((base = classvalues.super_baseval) <= 0)
+       if (baseval <= 0) {
                /* an array of interface references */
                /* an array of interface references */
-               return (valuevftbl->interfacetablelength > -base &&
-                               valuevftbl->interfacetable[base] != NULL);
+               result = ((valuevftbl->interfacetablelength > -baseval) &&
+                                 (valuevftbl->interfacetable[baseval] != NULL));
+       }
+       else {
+               diffval = valuevftbl->baseval - elementvftbl->baseval;
+               result  = diffval <= (uint32_t) elementvftbl->diffval;
+       }
 
 
-       res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
-               <= (unsigned) classvalues.super_diffval;
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
 
 
-       return res;
+       return result;
 }
 
 
 /* This is an optimized version where a is guaranteed to be a
  * one-dimensional array of a class type */
 }
 
 
 /* This is an optimized version where a is guaranteed to be a
  * one-dimensional array of a class type */
-s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
+bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
 {
-       vftbl_t *elementvftbl;
-       vftbl_t *valuevftbl;
-       s4 res;
-       castinfo classvalues;
+       vftbl_t  *elementvftbl;
+       vftbl_t  *valuevftbl;
+       uint32_t  diffval;
+       bool      result;
        
        
-       if (!o) return 1;
+       if (o == NULL)
+               return 1;
 
        /* The following is guaranteed (by verifier checks):
         *
 
        /* The following is guaranteed (by verifier checks):
         *
@@ -728,12 +815,14 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
        if (valuevftbl == elementvftbl)
                return 1;
 
-       ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues);
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
+
+       diffval = valuevftbl->baseval - elementvftbl->baseval;
+       result  = diffval <= (uint32_t) elementvftbl->diffval;
 
 
-       res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
-               <= (unsigned) classvalues.super_diffval;
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
 
 
-       return res;
+       return result;
 }
 
 
 }
 
 
@@ -741,14 +830,16 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
 
    Creates a new instance of class c on the heap.
 
 
    Creates a new instance of class c on the heap.
 
-   Return value: pointer to the object or NULL if no memory is
-   available
-                       
+   RETURN VALUE:
+      pointer to the object, or NULL if no memory is available
+
+   NOTE: This builtin can be called from NATIVE code only.
+
 *******************************************************************************/
 
 *******************************************************************************/
 
-java_objectheader *builtin_new(classinfo *c)
+java_handle_t *builtin_new(classinfo *c)
 {
 {
-       java_objectheader *o;
+       java_handle_t *o;
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
@@ -786,16 +877,22 @@ java_objectheader *builtin_new(classinfo *c)
                        return NULL;
        }
 
                        return NULL;
        }
 
-       o = heap_allocate(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
-                                         c->finalizer);
+       o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                  c->finalizer, true);
 
        if (!o)
                return NULL;
 
 
        if (!o)
                return NULL;
 
-       o->vftbl = c->vftbl;
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
+
+       o = LLNI_WRAP((java_object_t *) o);
+#endif
+
+       LLNI_vftbl_direct(o) = c->vftbl;
 
 #if defined(ENABLE_THREADS)
 
 #if defined(ENABLE_THREADS)
-       lock_init_object_lock(o);
+       lock_init_object_lock(LLNI_DIRECT(o));
 #endif
 
        CYCLES_STATS_GET(cycles_end);
 #endif
 
        CYCLES_STATS_GET(cycles_end);
@@ -807,916 +904,465 @@ java_objectheader *builtin_new(classinfo *c)
        return o;
 }
 
        return o;
 }
 
+#if defined(ENABLE_ESCAPE_REASON)
+java_handle_t *builtin_escape_reason_new(classinfo *c) {
+       print_escape_reasons();
+       return builtin_java_new(c);
+}
+#endif
 
 
-/* builtin_newarray ************************************************************
-
-   Creates an array with the given vftbl on the heap. This function
-   takes as class argument an array class.
-
-   Return value: pointer to the array or NULL if no memory is available
-
-*******************************************************************************/
-
-java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass)
+#if defined(ENABLE_TLH)
+java_handle_t *builtin_tlh_new(classinfo *c)
 {
 {
-       arraydescriptor  *desc;
-       s4                dataoffset;
-       s4                componentsize;
-       s4                actualsize;
-       java_arrayheader *a;
+       java_handle_t *o;
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
+#if defined(ENABLE_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
+#endif
 
        RT_TIMING_GET_TIME(time_start);
 
        RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
 
 
-       desc          = arrayclass->vftbl->arraydesc;
-       dataoffset    = desc->dataoffset;
-       componentsize = desc->componentsize;
-
-       if (size < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       /* is the class loaded */
 
 
-       actualsize = dataoffset + size * componentsize;
+       assert(c->state & CLASS_LOADED);
 
 
-       /* check for overflow */
+       /* check if we can instantiate this class */
 
 
-       if (((u4) actualsize) < ((u4) size)) {
-               exceptions_throw_outofmemoryerror();
+       if (c->flags & ACC_ABSTRACT) {
+               exceptions_throw_instantiationerror(c);
                return NULL;
        }
 
                return NULL;
        }
 
-       a = heap_allocate(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
-
-       if (a == NULL)
-               return NULL;
+       /* is the class linked */
 
 
-       a->objheader.vftbl = arrayclass->vftbl;
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
 
 
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&a->objheader);
+       if (!(c->state & CLASS_INITIALIZED)) {
+#if !defined(NDEBUG)
+               if (initverbose)
+                       log_message_class("Initialize class (from builtin_new): ", c);
 #endif
 
 #endif
 
-       a->size = size;
-
-       RT_TIMING_GET_TIME(time_end);
-       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
-
-       return a;
-}
-
-
-/* builtin_anewarray ***********************************************************
-
-   Creates an array of references to the given class type on the heap.
-
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-*******************************************************************************/
-
-java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
-{
-       classinfo *arrayclass;
-       
-       /* is class loaded */
-
-       assert(componentclass->state & CLASS_LOADED);
-
-       /* is class linked */
-
-       if (!(componentclass->state & CLASS_LINKED))
-               if (!link_class(componentclass))
+               if (!initialize_class(c))
                        return NULL;
                        return NULL;
+       }
 
 
-       arrayclass = class_array_of(componentclass, true);
-
-       if (!arrayclass)
-               return NULL;
-
-       return (java_objectarray *) builtin_newarray(size, arrayclass);
-}
-
-
-/* builtin_newarray_boolean ****************************************************
-
-   Creates an array of bytes on the heap. The array is designated as
-   an array of booleans (important for casts)
-       
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-*******************************************************************************/
-
-java_booleanarray *builtin_newarray_boolean(s4 size)
-{
-       return (java_booleanarray *)
-               builtin_newarray(size,
-                                                primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass);
-}
-
-
-/* builtin_newarray_byte *******************************************************
-
-   Creates an array of 8 bit Integers on the heap.
-
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-*******************************************************************************/
-
-java_bytearray *builtin_newarray_byte(s4 size)
-{
-       return (java_bytearray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayclass);
-}
-
-
-/* builtin_newarray_char *******************************************************
-
-   Creates an array of characters on the heap.
-
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-*******************************************************************************/
-
-java_chararray *builtin_newarray_char(s4 size)
-{
-       return (java_chararray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass);
-}
-
-
-/* builtin_newarray_short ******************************************************
-
-   Creates an array of 16 bit Integers on the heap.
+       /*
+       o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
+       */
+       o = NULL;
 
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+       if (o == NULL) {
+               o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                          c->finalizer, true);
+       }
 
 
-*******************************************************************************/
+       if (!o)
+               return NULL;
 
 
-java_shortarray *builtin_newarray_short(s4 size)
-{
-       return (java_shortarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass);
-}
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
 
 
+       o = LLNI_WRAP((java_object_t *) o);
+#endif
 
 
-/* builtin_newarray_int ********************************************************
+       LLNI_vftbl_direct(o) = c->vftbl;
 
 
-   Creates an array of 32 bit Integers on the heap.
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(o));
+#endif
 
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+       CYCLES_STATS_GET(cycles_end);
+       RT_TIMING_GET_TIME(time_end);
 
 
-*******************************************************************************/
+/*
+       CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
+*/
 
 
-java_intarray *builtin_newarray_int(s4 size)
-{
-       return (java_intarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass);
+       return o;
+#endif
 }
 
 }
 
+/* builtin_java_new ************************************************************
 
 
-/* builtin_newarray_long *******************************************************
-
-   Creates an array of 64 bit Integers on the heap.
-
-   Return value: pointer to the array or NULL if no memory is
-   available
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-java_longarray *builtin_newarray_long(s4 size)
+java_handle_t *builtin_java_new(java_handle_t *clazz)
 {
 {
-       return (java_longarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass);
+       return builtin_new(LLNI_classinfo_unwrap(clazz));
 }
 
 
 }
 
 
-/* builtin_newarray_float ******************************************************
-
-   Creates an array of 32 bit IEEE floats on the heap.
-
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-*******************************************************************************/
-
-java_floatarray *builtin_newarray_float(s4 size)
-{
-       return (java_floatarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass);
-}
-
+/* builtin_fast_new ************************************************************
 
 
-/* builtin_newarray_double *****************************************************
+   Creates a new instance of class c on the heap.
 
 
-   Creates an array of 64 bit IEEE floats on the heap.
+   RETURN VALUE:
+      pointer to the object, or NULL if no fast return
+      is possible for any reason.
 
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+   NOTE: This is a FAST builtin and can be called from JIT code only.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-java_doublearray *builtin_newarray_double(s4 size)
+java_object_t *builtin_fast_new(classinfo *c)
 {
 {
-       return (java_doublearray *)
-               builtin_newarray(size,
-                                                primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass);
-}
-
-
-/* builtin_multianewarray_intern ***********************************************
-
-   Creates a multi-dimensional array on the heap. The dimensions are
-   passed in an array of longs.
-
-   Arguments:
-       n............number of dimensions to create
-       arrayvftbl...vftbl of the array class
-       dims.........array containing the size of each dimension to create
-
-   Return value: pointer to the array or NULL if no memory is
-   available
-
-******************************************************************************/
-
-static java_arrayheader *builtin_multianewarray_intern(int n,
-                                                                                                          classinfo *arrayclass,
-                                                                                                          long *dims)
-{
-       s4                size;
-       java_arrayheader *a;
-       classinfo        *componentclass;
-       s4                i;
-
-       /* create this dimension */
-
-       size = (s4) dims[0];
-       a = builtin_newarray(size, arrayclass);
-
-       if (!a)
-               return NULL;
-
-       /* if this is the last dimension return */
-
-       if (!--n)
-               return a;
-
-       /* get the class of the components to create */
-
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class;
-
-       /* The verifier guarantees that the dimension count is in the range. */
-
-       /* create the component arrays */
-
-       for (i = 0; i < size; i++) {
-               java_arrayheader *ea =
-#if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
-                       /* we save an s4 to a s8 slot, 8-byte aligned */
-
-                       builtin_multianewarray_intern(n, componentclass, dims + 2);
-#else
-                       builtin_multianewarray_intern(n, componentclass, dims + 1);
-#endif
-
-               if (!ea)
-                       return NULL;
-               
-               ((java_objectarray *) a)->data[i] = (java_objectheader *) ea;
-       }
-
-       return a;
-}
-
-
-/* builtin_multianewarray ******************************************************
-
-   Wrapper for builtin_multianewarray_intern which checks all
-   dimensions before we start allocating.
-
-******************************************************************************/
-
-java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
-                                                                                long *dims)
-{
-       s4 i;
-       s4 size;
-
-       /* check all dimensions before doing anything */
-
-       for (i = 0; i < n; i++) {
-#if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
-               /* we save an s4 to a s8 slot, 8-byte aligned */
-               size = (s4) dims[i * 2];
-#else
-               size = (s4) dims[i];
-#endif
-
-               if (size < 0) {
-                       exceptions_throw_negativearraysizeexception();
-                       return NULL;
-               }
-       }
-
-       /* now call the real function */
-
-       return builtin_multianewarray_intern(n, arrayclass, dims);
-}
-
-
-/*****************************************************************************
-                                         METHOD LOGGING
-
-       Various functions for printing a message at method entry or exit (for
-       debugging)
-       
-*****************************************************************************/
-
-#if !defined(NDEBUG)
-static s4 methodindent = 0;
-static u4 callcount = 0;
-
-java_objectheader *builtin_trace_exception(java_objectheader *xptr,
-                                                                                  methodinfo *m,
-                                                                                  void *pos,
-                                                                                  s4 indent)
-{
-       char *logtext;
-       s4    logtextlen;
-       s4    dumpsize;
-       codeinfo *code;
-
-#if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_exit(m)) return xptr;
-#endif
-
-#if defined(ENABLE_VMLOG)
-       return xptr;
-#endif
-
-       if (opt_verbosecall && indent)
-               methodindent--;
-
-       /* calculate message length */
-
-       if (xptr) {
-               logtextlen =
-                       strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
-       } 
-       else {
-               logtextlen = strlen("Some Throwable");
-       }
-
-       logtextlen += strlen(" thrown in ");
-
-       if (m) {
-               logtextlen +=
-                       utf_bytes(m->class->name) +
-                       strlen(".") +
-                       utf_bytes(m->name) +
-                       utf_bytes(m->descriptor) +
-                       strlen("(NOSYNC,NATIVE");
-
-#if SIZEOF_VOID_P == 8
-               logtextlen +=
-                       strlen(")(0x123456789abcdef0) at position 0x123456789abcdef0 (");
-#else
-               logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
-#endif
-
-               if (m->class->sourcefile == NULL)
-                       logtextlen += strlen("<NO CLASSFILE INFORMATION>");
-               else
-                       logtextlen += utf_bytes(m->class->sourcefile);
-
-               logtextlen += strlen(":65536)");
-
-       } 
-       else {
-               logtextlen += strlen("call_java_method");
-       }
-
-       logtextlen += strlen("0");
-
-       /* allocate memory */
-
-       dumpsize = dump_size();
-
-       logtext = DMNEW(char, logtextlen);
-
-       if (xptr) {
-               strcpy(logtext, "Exception ");
-               utf_cat_classname(logtext, xptr->vftbl->class->name);
-
-       } else {
-               strcpy(logtext, "Some Throwable");
-       }
-
-       strcat(logtext, " thrown in ");
-
-       if (m) {
-               utf_cat_classname(logtext, m->class->name);
-               strcat(logtext, ".");
-               utf_cat(logtext, m->name);
-               utf_cat(logtext, m->descriptor);
-
-               if (m->flags & ACC_SYNCHRONIZED)
-                       strcat(logtext, "(SYNC");
-               else
-                       strcat(logtext, "(NOSYNC");
-
-               if (m->flags & ACC_NATIVE) {
-                       strcat(logtext, ",NATIVE");
-
-                       code = m->code;
-
-#if SIZEOF_VOID_P == 8
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%016lx) at position 0x%016lx",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#else
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%08x) at position 0x%08x",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
+       java_object_t *o;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
 #endif
 #endif
-
-               } else {
-
-                       /* XXX preliminary: This should get the actual codeinfo */
-                       /* in which the exception happened.                     */
-                       code = m->code;
-                       
-#if SIZEOF_VOID_P == 8
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%016lx) at position 0x%016lx (",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
-#else
-                       sprintf(logtext + strlen(logtext),
-                                       ")(0x%08x) at position 0x%08x (",
-                                       (ptrint) code->entrypoint, (ptrint) pos);
+#if defined(ENABLE_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
 #endif
 
 #endif
 
-                       if (m->class->sourcefile == NULL)
-                               strcat(logtext, "<NO CLASSFILE INFORMATION>");
-                       else
-                               utf_cat(logtext, m->class->sourcefile);
-
-                       sprintf(logtext + strlen(logtext), ":%d)", 0);
-               }
-
-       } else
-               strcat(logtext, "call_java_method");
-
-       log_text(logtext);
-
-       /* release memory */
-
-       dump_release(dumpsize);
-
-       return xptr;
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* builtin_print_argument ******************************************************
-
-   Prints arguments and return values for the call trace.
+       RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
 
 
-*******************************************************************************/
+       /* is the class loaded */
 
 
-#if !defined(NDEBUG)
-static char *builtin_print_argument(char *logtext, s4 *logtextlen,
-                                                                       typedesc *paramtype, s8 value)
-{
-       imm_union          imu;
-       java_objectheader *o;
-       classinfo         *c;
-       utf               *u;
-       u4                 len;
-
-       switch (paramtype->type) {
-       case TYPE_INT:
-               imu.i = (s4) value;
-               sprintf(logtext + strlen(logtext), "%d (0x%08x)", imu.i, imu.i);
-               break;
-
-       case TYPE_LNG:
-               imu.l = value;
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "%lld (0x%016llx)", imu.l, imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "%ld (0x%016lx)", imu.l, imu.l);
-#endif
-               break;
+       assert(c->state & CLASS_LOADED);
 
 
-       case TYPE_FLT:
-               imu.i = (s4) value;
-               sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i);
-               break;
+       /* check if we can instantiate this class */
 
 
-       case TYPE_DBL:
-               imu.l = value;
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "%g (0x%016llx)", imu.d, imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "%g (0x%016lx)", imu.d, imu.l);
-#endif
-               break;
+       if (c->flags & ACC_ABSTRACT)
+               return NULL;
 
 
-       case TYPE_ADR:
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "0x%08x", (ptrint) value);
-#else
-               sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) value);
-#endif
+       /* is the class linked */
 
 
-               /* cast to java.lang.Object */
+       if (!(c->state & CLASS_LINKED))
+               return NULL;
 
 
-               o = (java_objectheader *) (ptrint) value;
+       if (!(c->state & CLASS_INITIALIZED))
+               return NULL;
 
 
-               /* check return argument for java.lang.Class or java.lang.String */
+       o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                  c->finalizer, false);
 
 
-               if (o != NULL) {
-                       if (o->vftbl->class == class_java_lang_String) {
-                               /* get java.lang.String object and the length of the
-                                  string */
+       if (!o)
+               return NULL;
 
 
-                               u = javastring_toutf(o, false);
+       o->vftbl = c->vftbl;
 
 
-                               len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")");
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(o);
+#endif
 
 
-                               /* realloc memory for string length */
+       CYCLES_STATS_GET(cycles_end);
+       RT_TIMING_GET_TIME(time_end);
 
 
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
+       CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
 
 
-                               /* convert to utf8 string and strcat it to the logtext */
+       return o;
+}
 
 
-                               strcat(logtext, " (String = \"");
-                               utf_cat(logtext, u);
-                               strcat(logtext, "\")");
-                       }
-                       else {
-                               if (o->vftbl->class == class_java_lang_Class) {
-                                       /* if the object returned is a java.lang.Class
-                                          cast it to classinfo structure and get the name
-                                          of the class */
 
 
-                                       c = (classinfo *) o;
+/* builtin_newarray ************************************************************
+
+   Creates an array with the given vftbl on the heap. This function
+   takes as class argument an array class.
 
 
-                                       u = c->name;
-                               }
-                               else {
-                                       /* if the object returned is not a java.lang.String or
-                                          a java.lang.Class just print the name of the class */
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is available
 
 
-                                       u = o->vftbl->class->name;
-                               }
+   NOTE: This builtin can be called from NATIVE code only.
 
 
-                               len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
+*******************************************************************************/
 
 
-                               /* realloc memory for string length */
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
+{
+       arraydescriptor *desc;
+       s4               dataoffset;
+       s4               componentsize;
+       s4               actualsize;
+       java_handle_t   *a;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
 
 
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
+       RT_TIMING_GET_TIME(time_start);
 
 
-                               /* strcat to the logtext */
+       desc          = arrayclass->vftbl->arraydesc;
+       dataoffset    = desc->dataoffset;
+       componentsize = desc->componentsize;
 
 
-                               strcat(logtext, " (Class = \"");
-                               utf_cat_classname(logtext, u);
-                               strcat(logtext, "\")");
-                       }
-               }
+       if (size < 0) {
+               exceptions_throw_negativearraysizeexception();
+               return NULL;
        }
 
        }
 
-       return logtext;
-}
-#endif /* !defined(NDEBUG) */
+       actualsize = dataoffset + size * componentsize;
 
 
-/* builtin_verbosecall_enter ***************************************************
+       /* check for overflow */
 
 
-   Print method call with arguments for -verbose:call.
+       if (((u4) actualsize) < ((u4) size)) {
+               exceptions_throw_outofmemoryerror();
+               return NULL;
+       }
 
 
-*******************************************************************************/
+       a = heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
 
-#if !defined(NDEBUG)
+       if (a == NULL)
+               return NULL;
 
 
-#ifdef TRACE_ARGS_NUM
-void builtin_verbosecall_enter(s8 a0, s8 a1,
-# if TRACE_ARGS_NUM >= 4
-                                                          s8 a2, s8 a3,
-# endif
-# if TRACE_ARGS_NUM >= 6
-                                                          s8 a4, s8 a5,
-# endif
-# if TRACE_ARGS_NUM == 8
-                                                          s8 a6, s8 a7,
-# endif
-                                                          methodinfo *m)
-{
-       methoddesc *md;
-       char       *logtext;
-       s4          logtextlen;
-       s4          dumpsize;
-       s4          i;
-       s4          pos;
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
 
 
-#if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_enter(m)) return;
+       a = LLNI_WRAP((java_object_t *) a);
 #endif
 
 #endif
 
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_enter_method(m);
-       return;
-#endif
+       LLNI_vftbl_direct(a) = arrayclass->vftbl;
 
 
-       md = m->parseddesc;
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(a));
+#endif
 
 
-       /* calculate message length */
+       LLNI_array_size(a) = size;
 
 
-       logtextlen =
-               strlen("4294967295 ") +
-               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
-               methodindent +
-               strlen("called: ") +
-               utf_bytes(m->class->name) +
-               strlen(".") +
-               utf_bytes(m->name) +
-               utf_bytes(m->descriptor);
+       RT_TIMING_GET_TIME(time_end);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
 
-       /* Actually it's not possible to have all flags printed, but:
-          safety first! */
+       return a;
+}
 
 
-       logtextlen +=
-               strlen(" PUBLIC") +
-               strlen(" PRIVATE") +
-               strlen(" PROTECTED") +
-               strlen(" STATIC") +
-               strlen(" FINAL") +
-               strlen(" SYNCHRONIZED") +
-               strlen(" VOLATILE") +
-               strlen(" TRANSIENT") +
-               strlen(" NATIVE") +
-               strlen(" INTERFACE") +
-               strlen(" ABSTRACT");
 
 
-       /* add maximal argument length */
+/* builtin_java_newarray *******************************************************
 
 
-       logtextlen +=
-               strlen("(") +
-               strlen("-9223372036854775808 (0x123456789abcdef0), ") * TRACE_ARGS_NUM +
-               strlen("...(255)") +
-               strlen(")");
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
 
-       /* allocate memory */
+*******************************************************************************/
 
 
-       dumpsize = dump_size();
+java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
+{
+       return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
+}
 
 
-       logtext = DMNEW(char, logtextlen);
 
 
-       callcount++;
+/* builtin_anewarray ***********************************************************
 
 
-       sprintf(logtext, "%10d ", callcount);
-       sprintf(logtext + strlen(logtext), "-%d-", methodindent);
+   Creates an array of references to the given class type on the heap.
 
 
-       pos = strlen(logtext);
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is
+      available
 
 
-       for (i = 0; i < methodindent; i++)
-               logtext[pos++] = '\t';
+   NOTE: This builtin can be called from NATIVE code only.
 
 
-       strcpy(logtext + pos, "called: ");
+*******************************************************************************/
 
 
-       utf_cat_classname(logtext, m->class->name);
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
+{
+       classinfo *arrayclass;
+       
+       /* is class loaded */
 
 
-       if (m->flags & ACC_PUBLIC)       strcat(logtext, " PUBLIC");
-       if (m->flags & ACC_PRIVATE)      strcat(logtext, " PRIVATE");
-       if (m->flags & ACC_PROTECTED)    strcat(logtext, " PROTECTED");
-       if (m->flags & ACC_STATIC)       strcat(logtext, " STATIC");
-       if (m->flags & ACC_FINAL)        strcat(logtext, " FINAL");
-       if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED");
-       if (m->flags & ACC_VOLATILE)     strcat(logtext, " VOLATILE");
-       if (m->flags & ACC_TRANSIENT)    strcat(logtext, " TRANSIENT");
-       if (m->flags & ACC_NATIVE)       strcat(logtext, " NATIVE");
-       if (m->flags & ACC_INTERFACE)    strcat(logtext, " INTERFACE");
-       if (m->flags & ACC_ABSTRACT)     strcat(logtext, " ABSTRACT");
+       assert(componentclass->state & CLASS_LOADED);
 
 
-       strcat(logtext, "(");
+       /* is class linked */
 
 
-       if (md->paramcount >= 1) {
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[0], a0);
-       }
+       if (!(componentclass->state & CLASS_LINKED))
+               if (!link_class(componentclass))
+                       return NULL;
 
 
-       if (md->paramcount >= 2) {
-               strcat(logtext, ", ");
+       arrayclass = class_array_of(componentclass, true);
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[1], a1);
-       }
+       if (!arrayclass)
+               return NULL;
 
 
-#if TRACE_ARGS_NUM >= 4
-       if (md->paramcount >= 3) {
-               strcat(logtext, ", ");
+       return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
+}
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[2], a2);
-       }
 
 
-       if (md->paramcount >= 4) {
-               strcat(logtext, ", ");
+/* builtin_newarray_type ****************************************************
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[3], a3);
-       }
-#endif
+   Creates an array of [type]s on the heap.
+       
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is available
 
 
-#if TRACE_ARGS_NUM >= 6
-       if (md->paramcount >= 5) {
-               strcat(logtext, ", ");
+   NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[4], a4);
-       }
+*******************************************************************************/
 
 
-       if (md->paramcount >= 6) {
-               strcat(logtext, ", ");
+#define BUILTIN_NEWARRAY_TYPE(type, arraytype)                             \
+java_handle_##type##array_t *builtin_newarray_##type(int32_t size)              \
+{                                                                          \
+       return (java_handle_##type##array_t *)                                 \
+               builtin_newarray(size, primitivetype_table[arraytype].arrayclass); \
+}
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[5], a5);
-       }
-#endif
+BUILTIN_NEWARRAY_TYPE(boolean, ARRAYTYPE_BOOLEAN)
+BUILTIN_NEWARRAY_TYPE(byte,    ARRAYTYPE_BYTE)
+BUILTIN_NEWARRAY_TYPE(char,    ARRAYTYPE_CHAR)
+BUILTIN_NEWARRAY_TYPE(short,   ARRAYTYPE_SHORT)
+BUILTIN_NEWARRAY_TYPE(int,     ARRAYTYPE_INT)
+BUILTIN_NEWARRAY_TYPE(long,    ARRAYTYPE_LONG)
+BUILTIN_NEWARRAY_TYPE(float,   ARRAYTYPE_FLOAT)
+BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
 
 
-#if TRACE_ARGS_NUM == 8
-       if (md->paramcount >= 7) {
-               strcat(logtext, ", ");
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[6], a6);
-       }
+/* builtin_multianewarray_intern ***********************************************
 
 
-       if (md->paramcount >= 8) {
-               strcat(logtext, ", ");
+   Creates a multi-dimensional array on the heap. The dimensions are
+   passed in an array of longs.
 
 
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[7], a7);
-       }
-#endif
+   ARGUMENTS:
+      n.............number of dimensions to create
+      arrayclass....the array class
+      dims..........array containing the size of each dimension to create
 
 
-       if (md->paramcount > 8) {
-               sprintf(logtext + strlen(logtext), ", ...(%d)",
-                               md->paramcount - TRACE_ARGS_NUM);
-       }
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is available
 
 
-       strcat(logtext, ")");
+******************************************************************************/
 
 
-       log_text(logtext);
+static java_handle_t *builtin_multianewarray_intern(int n,
+                                                                                                       classinfo *arrayclass,
+                                                                                                       long *dims)
+{
+       s4             size;
+       java_handle_t *a;
+       classinfo     *componentclass;
+       s4             i;
 
 
-       /* release memory */
+       /* create this dimension */
 
 
-       dump_release(dumpsize);
+       size = (s4) dims[0];
+       a = builtin_newarray(size, arrayclass);
 
 
-       methodindent++;
+       if (!a)
+               return NULL;
 
 
-}
-#endif
-#endif /* !defined(NDEBUG) */
+       /* if this is the last dimension return */
 
 
+       if (!--n)
+               return a;
 
 
-/* builtin_verbosecall_exit ****************************************************
+       /* get the class of the components to create */
 
 
-   Print method exit for -verbose:call.
+       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
 
-*******************************************************************************/
+       /* The verifier guarantees that the dimension count is in the range. */
 
 
-#if !defined(NDEBUG)
-void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m)
-{
-       methoddesc *md;
-       char       *logtext;
-       s4          logtextlen;
-       s4          dumpsize;
-       s4          i;
-       s4          pos;
-       imm_union   val;
+       /* create the component arrays */
 
 
-#if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_exit(m)) return;
-#endif
+       for (i = 0; i < size; i++) {
+               java_handle_t *ea =
+#if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
+                       /* we save an s4 to a s8 slot, 8-byte aligned */
 
 
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_leave_method(m);
-       return;
+                       builtin_multianewarray_intern(n, componentclass, dims + 2);
+#else
+                       builtin_multianewarray_intern(n, componentclass, dims + 1);
 #endif
 
 #endif
 
-       md = m->parseddesc;
-
-       /* calculate message length */
-
-       logtextlen =
-               strlen("4294967295 ") +
-               strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
-               methodindent +
-               strlen("finished: ") +
-               utf_bytes(m->class->name) +
-               strlen(".") +
-               utf_bytes(m->name) +
-               utf_bytes(m->descriptor) +
-               strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
-
-       /* add maximal argument length */
+               if (!ea)
+                       return NULL;
 
 
-       logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)");
+               array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
+       }
 
 
-       /* allocate memory */
+       return a;
+}
 
 
-       dumpsize = dump_size();
 
 
-       logtext = DMNEW(char, logtextlen);
+/* builtin_multianewarray ******************************************************
 
 
-       /* outdent the log message */
+   Wrapper for builtin_multianewarray_intern which checks all
+   dimensions before we start allocating.
 
 
-       if (methodindent)
-               methodindent--;
-       else
-               log_text("WARNING: unmatched methodindent--");
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
 
-       /* generate the message */
+******************************************************************************/
 
 
-       sprintf(logtext, "           ");
-       sprintf(logtext + strlen(logtext), "-%d-", methodindent);
+java_handle_objectarray_t *builtin_multianewarray(int n,
+                                                                                                 java_handle_t *arrayclazz,
+                                                                                                 long *dims)
+{
+       classinfo *c;
+       s4         i;
+       s4         size;
 
 
-       pos = strlen(logtext);
+       /* check all dimensions before doing anything */
 
 
-       for (i = 0; i < methodindent; i++)
-               logtext[pos++] = '\t';
+       for (i = 0; i < n; i++) {
+#if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
+               /* we save an s4 to a s8 slot, 8-byte aligned */
+               size = (s4) dims[i * 2];
+#else
+               size = (s4) dims[i];
+#endif
 
 
-       strcpy(logtext + pos, "finished: ");
-       utf_cat_classname(logtext, m->class->name);
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
+               if (size < 0) {
+                       exceptions_throw_negativearraysizeexception();
+                       return NULL;
+               }
+       }
 
 
-       if (!IS_VOID_TYPE(md->returntype.type)) {
-               strcat(logtext, "->");
+       c = LLNI_classinfo_unwrap(arrayclazz);
 
 
-               switch (md->returntype.type) {
-               case TYPE_INT:
-               case TYPE_LNG:
-               case TYPE_ADR:
-                       val.l = l;
-                       break;
+       /* now call the real function */
 
 
-               case TYPE_FLT:
-                       val.f = f;
-                       break;
+       return (java_handle_objectarray_t *)
+               builtin_multianewarray_intern(n, c, dims);
+}
 
 
-               case TYPE_DBL:
-                       val.d = d;
-                       break;
-               }
 
 
-               logtext =
-                       builtin_print_argument(logtext, &logtextlen, &md->returntype, val.l);
-       }
+/* builtin_verbosecall_enter ***************************************************
 
 
-       log_text(logtext);
+   Print method call with arguments for -verbose:call.
 
 
-       /* release memory */
+   XXX: Remove mew once all archs use the new tracer!
 
 
-       dump_release(dumpsize);
+*******************************************************************************/
 
 
+#if !defined(NDEBUG)
+#ifdef TRACE_ARGS_NUM
+void builtin_verbosecall_enter(s8 a0, s8 a1,
+# if TRACE_ARGS_NUM >= 4
+                                                          s8 a2, s8 a3,
+# endif
+# if TRACE_ARGS_NUM >= 6
+                                                          s8 a4, s8 a5,
+# endif
+# if TRACE_ARGS_NUM == 8
+                                                          s8 a6, s8 a7,
+# endif
+                                                          methodinfo *m)
+{
+       log_text("builtin_verbosecall_enter: Do not call me anymore!");
 }
 }
+#endif
 #endif /* !defined(NDEBUG) */
 
 
 #endif /* !defined(NDEBUG) */
 
 
-#if defined(ENABLE_CYCLES_STATS)
-void builtin_print_cycles_stats(FILE *file)
-{
-       fprintf(file,"builtin cylce count statistics:\n");
+/* builtin_verbosecall_exit ****************************************************
 
 
-       CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file);
-       CYCLES_STATS_PRINT(builtin_new         ,file);
+   Print method exit for -verbose:call.
 
 
-       fprintf(file,"\n");
-}
-#endif /* defined(ENABLE_CYCLES_STATS) */
+   XXX: Remove mew once all archs use the new tracer!
 
 
+*******************************************************************************/
 
 
-/*****************************************************************************
-                         MISCELLANEOUS HELPER FUNCTIONS
-*****************************************************************************/
+#if !defined(NDEBUG)
+void builtin_verbosecall_exit(s8 l, double d, float f, methodinfo *m)
+{
+       log_text("builtin_verbosecall_exit: Do not call me anymore!");
+}
+#endif /* !defined(NDEBUG) */
 
 
 
 
+/*============================================================================*/
+/* MISCELLANEOUS MATHEMATICAL HELPER FUNCTIONS                                */
+/*============================================================================*/
 
 /*********** Functions for integer divisions *****************************
  
 
 /*********** Functions for integer divisions *****************************
  
@@ -2431,7 +2077,7 @@ s4 builtin_f2i(float a)
 #endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
 
 
 #endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
 
 
-#if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L)
+#if !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) || defined(DISABLE_GC)
 s8 builtin_f2l(float a)
 {
        s8 l;
 s8 builtin_f2l(float a)
 {
        s8 l;
@@ -2481,7 +2127,7 @@ s4 builtin_d2i(double a)
 #endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
 
 
 #endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC) */
 
 
-#if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L)
+#if !(SUPPORT_DOUBLE && SUPPORT_LONG && SUPPORT_D2L) || defined(DISABLE_GC)
 s8 builtin_d2l(double a)
 {
        double d;
 s8 builtin_d2l(double a)
 {
        double d;
@@ -2529,42 +2175,54 @@ float builtin_d2f(double a)
 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
 
 
 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
 
 
+/*============================================================================*/
+/* AUTOMATICALLY REPLACED FUNCTIONS                                           */
+/*============================================================================*/
+
 /* builtin_arraycopy ***********************************************************
 
    Builtin for java.lang.System.arraycopy.
 
 /* builtin_arraycopy ***********************************************************
 
    Builtin for java.lang.System.arraycopy.
 
-   ATTENTION: This builtin function returns a boolean value to signal
-   the ICMD_BUILTIN if there was an exception.
+   NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
-                                          java_arrayheader *dest, s4 destStart, s4 len)
+void builtin_arraycopy(java_handle_t *src, s4 srcStart,
+                                          java_handle_t *dest, s4 destStart, s4 len)
 {
        arraydescriptor *sdesc;
        arraydescriptor *ddesc;
        s4               i;
 
 {
        arraydescriptor *sdesc;
        arraydescriptor *ddesc;
        s4               i;
 
-       if ((src == NULL) || (dest == NULL)) { 
+       if ((src == NULL) || (dest == NULL)) {
                exceptions_throw_nullpointerexception();
                exceptions_throw_nullpointerexception();
-               return false;
+               return;
        }
 
        }
 
-       sdesc = src->objheader.vftbl->arraydesc;
-       ddesc = dest->objheader.vftbl->arraydesc;
+       sdesc = LLNI_vftbl_direct(src)->arraydesc;
+       ddesc = LLNI_vftbl_direct(dest)->arraydesc;
 
        if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
                exceptions_throw_arraystoreexception();
 
        if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
                exceptions_throw_arraystoreexception();
-               return false;
+               return;
        }
 
        }
 
-       /* we try to throw exception with the same message as SUN does */
+       // Check if offsets and length are positive.
+       if ((srcStart < 0) || (destStart < 0) || (len < 0)) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return;
+       }
 
 
-       if ((len < 0) || (srcStart < 0) || (destStart < 0) ||
-               (srcStart  + len < 0) || (srcStart  + len > src->size) ||
-               (destStart + len < 0) || (destStart + len > dest->size)) {
+       // Check if ranges are valid.
+       if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) LLNI_array_size(src)) ||
+               (((uint32_t) destStart + (uint32_t) len) > (uint32_t) LLNI_array_size(dest))) {
                exceptions_throw_arrayindexoutofboundsexception();
                exceptions_throw_arrayindexoutofboundsexception();
-               return false;
+               return;
+       }
+
+       // Special case.
+       if (len == 0) {
+               return;
        }
 
        if (sdesc->componentvftbl == ddesc->componentvftbl) {
        }
 
        if (sdesc->componentvftbl == ddesc->componentvftbl) {
@@ -2573,24 +2231,30 @@ bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
                s4 dataoffset = sdesc->dataoffset;
                s4 componentsize = sdesc->componentsize;
 
                s4 dataoffset = sdesc->dataoffset;
                s4 componentsize = sdesc->componentsize;
 
-               memmove(((u1 *) dest) + dataoffset + componentsize * destStart,
-                               ((u1 *) src)  + dataoffset + componentsize * srcStart,
-                               (size_t) len * componentsize);
+               LLNI_CRITICAL_START;
+
+               MMOVE(((u1 *) LLNI_DIRECT(dest)) + dataoffset + componentsize * destStart,
+                         ((u1 *) LLNI_DIRECT(src))  + dataoffset + componentsize * srcStart,
+                         u1, (size_t) len * componentsize);
+
+               LLNI_CRITICAL_END;
        }
        else {
                /* We copy references of different type */
 
        }
        else {
                /* We copy references of different type */
 
-               java_objectarray *oas = (java_objectarray *) src;
-               java_objectarray *oad = (java_objectarray *) dest;
-                
+               java_handle_objectarray_t *oas = (java_handle_objectarray_t *) src;
+               java_handle_objectarray_t *oad = (java_handle_objectarray_t *) dest;
                if (destStart <= srcStart) {
                        for (i = 0; i < len; i++) {
                if (destStart <= srcStart) {
                        for (i = 0; i < len; i++) {
-                               java_objectheader *o = oas->data[srcStart + i];
+                               java_handle_t *o;
+
+                               o = array_objectarray_element_get(oas, srcStart + i);
 
                                if (!builtin_canstore(oad, o))
 
                                if (!builtin_canstore(oad, o))
-                                       return false;
+                                       return;
 
 
-                               oad->data[destStart + i] = o;
+                               array_objectarray_element_set(oad, destStart + i, o);
                        }
                }
                else {
                        }
                }
                else {
@@ -2601,39 +2265,53 @@ bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
-                               java_objectheader *o = oas->data[srcStart + i];
+                               java_handle_t *o;
+
+                               o = array_objectarray_element_get(oas, srcStart + i);
 
                                if (!builtin_canstore(oad, o))
 
                                if (!builtin_canstore(oad, o))
-                                       return false;
+                                       return;
 
 
-                               oad->data[destStart + i] = o;
+                               array_objectarray_element_set(oad, destStart + i, o);
                        }
                }
        }
                        }
                }
        }
-
-       return true;
 }
 
 
 }
 
 
-/* builtin_currenttimemillis ***************************************************
+/* builtin_nanotime ************************************************************
 
 
-   Return the current time in milliseconds.
+   Return the current time in nanoseconds.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-s8 builtin_currenttimemillis(void)
+s8 builtin_nanotime(void)
 {
        struct timeval tv;
 {
        struct timeval tv;
-       s8             result;
+       s8             usecs;
 
        if (gettimeofday(&tv, NULL) == -1)
                vm_abort("gettimeofday failed: %s", strerror(errno));
 
 
        if (gettimeofday(&tv, NULL) == -1)
                vm_abort("gettimeofday failed: %s", strerror(errno));
 
-       result = (s8) tv.tv_sec;
-       result *= 1000;
-       result += (tv.tv_usec / 1000);
+       usecs = (s8) tv.tv_sec * (1000 * 1000) + (s8) tv.tv_usec;
 
 
-       return result;
+       return usecs * 1000;
+}
+
+
+/* builtin_currenttimemillis ***************************************************
+
+   Return the current time in milliseconds.
+
+*******************************************************************************/
+
+s8 builtin_currenttimemillis(void)
+{
+       s8 msecs;
+
+       msecs = builtin_nanotime() / 1000 / 1000;
+
+       return msecs;
 }
 
 
 }
 
 
@@ -2641,42 +2319,51 @@ s8 builtin_currenttimemillis(void)
 
    Function for cloning objects or arrays.
 
 
    Function for cloning objects or arrays.
 
+   NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
+
 *******************************************************************************/
 
 *******************************************************************************/
 
-java_objectheader *builtin_clone(void *env, java_objectheader *o)
+java_handle_t *builtin_clone(void *env, java_handle_t *o)
 {
 {
-       arraydescriptor   *ad;
-       java_arrayheader  *ah;
-       u4                 size;
-       classinfo         *c;
-       java_objectheader *co;              /* cloned object header               */
+       arraydescriptor *ad;
+       u4               size;
+       classinfo       *c;
+       java_handle_t   *co;                /* cloned object header               */
 
        /* get the array descriptor */
 
 
        /* get the array descriptor */
 
-       ad = o->vftbl->arraydesc;
+       ad = LLNI_vftbl_direct(o)->arraydesc;
 
        /* we are cloning an array */
 
        if (ad != NULL) {
 
        /* we are cloning an array */
 
        if (ad != NULL) {
-               ah = (java_arrayheader *) o;
-
-               size = ad->dataoffset + ad->componentsize * ah->size;
+               size = ad->dataoffset + ad->componentsize * LLNI_array_size(o);
         
         
-               co = heap_allocate(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL);
+               co = heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
                if (co == NULL)
                        return NULL;
 
 
                if (co == NULL)
                        return NULL;
 
-               MCOPY(co, o, u1, size);
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+               /* XXX this is only a dirty hack to make Boehm work with handles */
+
+               co = LLNI_WRAP((java_object_t *) co);
+#endif
+
+               LLNI_CRITICAL_START;
+
+               MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, size);
 
 #if defined(ENABLE_GC_CACAO)
 
 #if defined(ENABLE_GC_CACAO)
-               heap_init_objectheader(co, size);
+               heap_init_objectheader(LLNI_DIRECT(co), size);
 #endif
 
 #if defined(ENABLE_THREADS)
 #endif
 
 #if defined(ENABLE_THREADS)
-               lock_init_object_lock(co);
+               lock_init_object_lock(LLNI_DIRECT(co));
 #endif
 
 #endif
 
+               LLNI_CRITICAL_END;
+
                return co;
        }
     
                return co;
        }
     
@@ -2689,7 +2376,7 @@ java_objectheader *builtin_clone(void *env, java_objectheader *o)
 
        /* get the class of the object */
 
 
        /* get the class of the object */
 
-    c = o->vftbl->class;
+       LLNI_class_get(o, c);
 
        /* create new object */
 
 
        /* create new object */
 
@@ -2698,19 +2385,37 @@ java_objectheader *builtin_clone(void *env, java_objectheader *o)
     if (co == NULL)
         return NULL;
 
     if (co == NULL)
         return NULL;
 
-    MCOPY(co, o, u1, c->instancesize);
+       LLNI_CRITICAL_START;
+
+       MCOPY(LLNI_DIRECT(co), LLNI_DIRECT(o), u1, c->instancesize);
 
 #if defined(ENABLE_GC_CACAO)
 
 #if defined(ENABLE_GC_CACAO)
-       heap_init_objectheader(co, c->instancesize);
+       heap_init_objectheader(LLNI_DIRECT(co), c->instancesize);
 #endif
 
 #if defined(ENABLE_THREADS)
 #endif
 
 #if defined(ENABLE_THREADS)
-       lock_init_object_lock(co);
+       lock_init_object_lock(LLNI_DIRECT(co));
 #endif
 
 #endif
 
+       LLNI_CRITICAL_END;
+
     return co;
 }
 
     return co;
 }
 
+
+#if defined(ENABLE_CYCLES_STATS)
+void builtin_print_cycles_stats(FILE *file)
+{
+       fprintf(file,"builtin cylce count statistics:\n");
+
+       CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file);
+       CYCLES_STATS_PRINT(builtin_new         ,file);
+
+       fprintf(file,"\n");
+}
+#endif /* defined(ENABLE_CYCLES_STATS) */
+
+
 #if defined(ENABLE_VMLOG)
 #define NDEBUG
 #include <vmlog_cacao.c>
 #if defined(ENABLE_VMLOG)
 #define NDEBUG
 #include <vmlog_cacao.c>