Merged with tip.
[cacao.git] / src / vm / builtin.c
index 77f3ff323af8c6404dc60045f2595b190bedba92..377bad8830fd3370390200d55b26348f91e13fd7 100644 (file)
@@ -1,9 +1,7 @@
 /* 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.
 
@@ -28,8 +26,6 @@
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 8295 2007-08-11 17:57:24Z michi $
-
 */
 
 
 
 #include "native/jni.h"
 #include "native/llni.h"
-#include "native/include/java_lang_String.h"
-#include "native/include/java_lang_Throwable.h"
 
 #include "threads/lock-common.h"
+#include "threads/thread.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/primitive.h"
+#include "vm/primitive.hpp"
 #include "vm/stringlocal.h"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/trace.h"
 
 #include "vmcore/class.h"
 #include "vmcore/linker.h"
@@ -84,9 +81,6 @@
 #include <vmlog_cacao.h>
 #endif
 
-#if defined(ENABLE_DEBUG_FILTER)
-#      include "vm/jit/show.h"
-#endif
 
 /* include builtin tables *****************************************************/
 
 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
@@ -106,12 +105,13 @@ CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
 static bool builtintable_init(void)
 {
        descriptor_pool    *descpool;
-       s4                  dumpsize;
        builtintable_entry *bte;
+       methodinfo         *m;
+       int32_t             dumpmarker;
 
        /* mark start of dump memory area */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        /* create a new descriptor pool */
 
@@ -128,14 +128,13 @@ static bool builtintable_init(void)
        /* 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 */
 
-                       dump_release(dumpsize);
+                       DRELEASE;
 
                        return false;
                }
@@ -145,7 +144,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
@@ -156,7 +155,7 @@ static bool builtintable_init(void)
                bte->descriptor = utf_new_char(bte->cdescriptor);
 
                if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
-                       dump_release(dumpsize);
+                       DRELEASE;
                        return false;
                }
        }
@@ -178,6 +177,13 @@ static bool builtintable_init(void)
                                                                                                        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);
+               }
        }
 
        for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
@@ -186,6 +192,10 @@ static bool builtintable_init(void)
                                                                                                        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++) {
@@ -194,11 +204,18 @@ static bool builtintable_init(void)
                                                                                                        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 */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        return true;
 }
@@ -249,6 +266,8 @@ static void builtintable_sort_automatic(void)
 
 bool builtin_init(void)
 {
+       TRACESUBSYSTEMINITIALIZATION("builtin_init");
+
        /* initialize the builtin tables */
 
        if (!builtintable_init())
@@ -311,7 +330,8 @@ builtintable_entry *builtintable_get_automatic(s4 opcode)
                if (middle->opcode < opcode) {
                        first = middle + 1;
                        entries -= half + 1;
-               } else
+               }
+               else
                        entries = half;
        }
 
@@ -356,14 +376,15 @@ bool builtintable_replace_function(void *iptr_)
 
        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 */
 
-                       iptr->opc   = bte->opcode;
+                       iptr->opc           = bte->opcode;
                        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;
@@ -377,9 +398,9 @@ bool builtintable_replace_function(void *iptr_)
 #endif /* defined(ENABLE_JIT) */
 
 
-/*****************************************************************************
-                                                               TYPE CHECKS
-*****************************************************************************/
+/*============================================================================*/
+/* INTERNAL BUILTIN FUNCTIONS                                                 */
+/*============================================================================*/
 
 /* builtin_instanceof **********************************************************
 
@@ -387,34 +408,47 @@ bool builtintable_replace_function(void *iptr_)
    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_handle_t *o, classinfo *class)
+bool builtin_instanceof(java_handle_t *o, classinfo *c)
 {
+       classinfo *oc;
+
        if (o == NULL)
                return 0;
 
-       return class_isanysubclass(o->vftbl->class, class);
+       LLNI_class_get(o, oc);
+
+       return class_isanysubclass(oc, c);
 }
 
 
 
 /* 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_handle_t *o, classinfo *class)
+bool builtin_checkcast(java_handle_t *o, classinfo *c)
 {
+       classinfo *oc;
+
        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;
@@ -423,15 +457,15 @@ s4 builtin_checkcast(java_handle_t *o, classinfo *class)
 
 /* 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;
@@ -445,6 +479,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {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)*/
 
@@ -452,8 +488,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
                        (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)
@@ -462,7 +498,7 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        /* {desc has higher dimension than target} */
 
        return class_isanysubclass(pseudo_class_Arraystub,
-                                                          target->elementvftbl->class);
+                                                          target->elementvftbl->clazz);
 }
 
 
@@ -476,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.
-       
+
+   NOTE: This is a FAST builtin and can be called from JIT code only.
+
 *******************************************************************************/
 
-s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass)
+bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
 {
        arraydescriptor *desc;
 
@@ -495,91 +533,63 @@ s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass)
 }
 
 
-s4 builtin_arrayinstanceof(java_handle_t *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;
 
-       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_handle_t *xptr)
+bool builtin_arrayinstanceof(java_handle_t *h, classinfo *targetclass)
 {
-#if !defined(NDEBUG)
-    java_lang_Throwable *t;
-       java_lang_String    *s;
-       char                *logtext;
-       s4                   logtextlen;
-       s4                   dumpsize;
-
-       if (opt_verbose) {
-               t = (java_lang_Throwable *) xptr;
-
-               /* get detail message */
-               if (t)
-                       LLNI_field_get_ref(t, detailMessage, s);
-
-               /* calculate message length */
-
-               logtextlen = strlen("Builtin exception thrown: ") + strlen("0");
-
-               if (t) {
-                       logtextlen +=
-                               utf_bytes(xptr->vftbl->class->name);
-                       if (s) {
-                               logtextlen += strlen(": ") +
-                                       u2_utflength(LLNI_field_direct(s, value)->data 
-                                                                       + LLNI_field_direct(s, offset),
-                                                        LLNI_field_direct(s,count));
-                       }
-               } 
-               else {
-                       logtextlen += strlen("(nil)");
-               }
+       bool result;
 
-               /* allocate memory */
+       LLNI_CRITICAL_START;
 
-               dumpsize = dump_size();
+       result = builtin_fast_arrayinstanceof(LLNI_UNWRAP(h), targetclass);
 
-               logtext = DMNEW(char, logtextlen);
+       LLNI_CRITICAL_END;
 
-               strcpy(logtext, "Builtin exception thrown: ");
-
-               if (t) {
-                       utf_cat_classname(logtext, xptr->vftbl->class->name);
+       return result;
+}
 
-                       if (s) {
-                               char *buf;
 
-                               buf = javastring_tochar((java_handle_t *) s);
-                               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 */
 
-       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. */
@@ -588,16 +598,76 @@ void *builtin_throw_exception(java_handle_t *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.
 
-   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_handle_t *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;
@@ -605,7 +675,7 @@ s4 builtin_canstore(java_objectarray *oa, java_handle_t *o)
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
 
        if (o == NULL)
                return 1;
@@ -616,7 +686,7 @@ s4 builtin_canstore(java_objectarray *oa, java_handle_t *o)
         *     *) oa->...vftbl->arraydesc->componentvftbl != NULL
         *     *) o->vftbl is not an interface vftbl
         */
-       
+
        desc           = oa->header.objheader.vftbl->arraydesc;
        componentvftbl = desc->componentvftbl;
        valuevftbl     = o->vftbl;
@@ -660,11 +730,6 @@ s4 builtin_canstore(java_objectarray *oa, java_handle_t *o)
                result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
        }
 
-       /* if not possible, throw an exception */
-
-       if (result == 0)
-               exceptions_throw_arraystoreexception();
-
        /* return result */
 
        return result;
@@ -672,14 +737,14 @@ s4 builtin_canstore(java_objectarray *oa, java_handle_t *o)
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_canstore_onedim (java_objectarray *a, java_handle_t *o)
+bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
 {
        arraydescriptor *desc;
        vftbl_t         *elementvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        uint32_t         diffval;
-       int              result;
+       bool             result;
        
        if (o == NULL)
                return 1;
@@ -723,12 +788,12 @@ s4 builtin_canstore_onedim (java_objectarray *a, java_handle_t *o)
 
 /* 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_handle_t *o)
+bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
        vftbl_t  *elementvftbl;
        vftbl_t  *valuevftbl;
        uint32_t  diffval;
-       int       result;
+       bool      result;
        
        if (o == NULL)
                return 1;
@@ -765,14 +830,16 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_handle_t *o)
 
    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_handle_t *builtin_new(classinfo *c)
 {
-       java_object_t *o;
+       java_handle_t *o;
 #if defined(ENABLE_RT_TIMING)
        struct timespec time_start, time_end;
 #endif
@@ -810,16 +877,22 @@ java_handle_t *builtin_new(classinfo *c)
                        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;
 
-       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)
-       lock_init_object_lock(o);
+       lock_init_object_lock(LLNI_DIRECT(o));
 #endif
 
        CYCLES_STATS_GET(cycles_end);
@@ -831,258 +904,339 @@ java_handle_t *builtin_new(classinfo *c)
        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_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
+#endif
 
        RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
 
-       desc          = arrayclass->vftbl->arraydesc;
-       dataoffset    = desc->dataoffset;
-       componentsize = desc->componentsize;
+       /* is the class loaded */
 
-       if (size < 0) {
-               exceptions_throw_negativearraysizeexception();
+       assert(c->state & CLASS_LOADED);
+
+       /* check if we can instantiate this class */
+
+       if (c->flags & ACC_ABSTRACT) {
+               exceptions_throw_instantiationerror(c);
                return NULL;
        }
 
-       actualsize = dataoffset + size * componentsize;
+       /* is the class linked */
 
-       /* check for overflow */
+       if (!(c->state & CLASS_LINKED))
+               if (!link_class(c))
+                       return NULL;
 
-       if (((u4) actualsize) < ((u4) size)) {
-               exceptions_throw_outofmemoryerror();
-               return NULL;
+       if (!(c->state & CLASS_INITIALIZED)) {
+#if !defined(NDEBUG)
+               if (initverbose)
+                       log_message_class("Initialize class (from builtin_new): ", c);
+#endif
+
+               if (!initialize_class(c))
+                       return NULL;
        }
 
-       a = heap_allocate(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
+       /*
+       o = tlh_alloc(&(THREADOBJECT->tlh), c->instancesize);
+       */
+       o = NULL;
 
-       if (a == NULL)
+       if (o == NULL) {
+               o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                          c->finalizer, true);
+       }
+
+       if (!o)
                return NULL;
 
-       a->objheader.vftbl = arrayclass->vftbl;
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
 
-#if defined(ENABLE_THREADS)
-       lock_init_object_lock(&a->objheader);
+       o = LLNI_WRAP((java_object_t *) o);
 #endif
 
-       a->size = size;
+       LLNI_vftbl_direct(o) = c->vftbl;
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(o));
+#endif
 
+       CYCLES_STATS_GET(cycles_end);
        RT_TIMING_GET_TIME(time_end);
-       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
-       return a;
+/*
+       CYCLES_STATS_COUNT(builtin_new,cycles_end - cycles_start);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_OBJECT);
+*/
+
+       return o;
+#endif
 }
 
+/* builtin_java_new ************************************************************
 
-/* builtin_anewarray ***********************************************************
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
-   Creates an array of references to the given class type on the heap.
+*******************************************************************************/
+
+java_handle_t *builtin_java_new(java_handle_t *clazz)
+{
+       return builtin_new(LLNI_classinfo_unwrap(clazz));
+}
+
+
+/* builtin_fast_new ************************************************************
+
+   Creates a new instance of class c 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_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
+java_object_t *builtin_fast_new(classinfo *c)
 {
-       classinfo *arrayclass;
-       
-       /* is class loaded */
+       java_object_t *o;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+#if defined(ENABLE_CYCLES_STATS)
+       u8 cycles_start, cycles_end;
+#endif
 
-       assert(componentclass->state & CLASS_LOADED);
+       RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
 
-       /* is class linked */
+       /* is the class loaded */
 
-       if (!(componentclass->state & CLASS_LINKED))
-               if (!link_class(componentclass))
-                       return NULL;
+       assert(c->state & CLASS_LOADED);
 
-       arrayclass = class_array_of(componentclass, true);
+       /* check if we can instantiate this class */
 
-       if (!arrayclass)
+       if (c->flags & ACC_ABSTRACT)
                return NULL;
 
-       return (java_objectarray *) builtin_newarray(size, arrayclass);
-}
+       /* is the class linked */
 
+       if (!(c->state & CLASS_LINKED))
+               return NULL;
 
-/* builtin_newarray_boolean ****************************************************
+       if (!(c->state & CLASS_INITIALIZED))
+               return NULL;
 
-   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
+       o = heap_alloc(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                  c->finalizer, false);
 
-*******************************************************************************/
+       if (!o)
+               return NULL;
 
-java_booleanarray *builtin_newarray_boolean(s4 size)
-{
-       return (java_booleanarray *)
-               builtin_newarray(size,
-                                                primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass);
+       o->vftbl = c->vftbl;
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(o);
+#endif
+
+       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);
+
+       return o;
 }
 
 
-/* builtin_newarray_byte *******************************************************
+/* builtin_newarray ************************************************************
 
-   Creates an array of 8 bit Integers on the heap.
+   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
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is available
+
+   NOTE: This builtin can be called from NATIVE code only.
 
 *******************************************************************************/
 
-java_bytearray *builtin_newarray_byte(s4 size)
+java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
 {
-       return (java_bytearray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].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
 
+       RT_TIMING_GET_TIME(time_start);
 
-/* builtin_newarray_char *******************************************************
+       desc          = arrayclass->vftbl->arraydesc;
+       dataoffset    = desc->dataoffset;
+       componentsize = desc->componentsize;
 
-   Creates an array of characters on the heap.
+       if (size < 0) {
+               exceptions_throw_negativearraysizeexception();
+               return NULL;
+       }
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+       actualsize = dataoffset + size * componentsize;
 
-*******************************************************************************/
+       /* check for overflow */
 
-java_chararray *builtin_newarray_char(s4 size)
-{
-       return (java_chararray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass);
-}
+       if (((u4) actualsize) < ((u4) size)) {
+               exceptions_throw_outofmemoryerror();
+               return NULL;
+       }
 
+       a = heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
-/* builtin_newarray_short ******************************************************
+       if (a == NULL)
+               return NULL;
 
-   Creates an array of 16 bit Integers on the heap.
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+       a = LLNI_WRAP((java_object_t *) a);
+#endif
 
-*******************************************************************************/
+       LLNI_vftbl_direct(a) = arrayclass->vftbl;
 
-java_shortarray *builtin_newarray_short(s4 size)
-{
-       return (java_shortarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass);
-}
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(LLNI_DIRECT(a));
+#endif
+
+       LLNI_array_size(a) = size;
+
+       RT_TIMING_GET_TIME(time_end);
+       RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
+       return a;
+}
 
-/* builtin_newarray_int ********************************************************
 
-   Creates an array of 32 bit Integers on the heap.
+/* builtin_java_newarray *******************************************************
 
-   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_intarray *builtin_newarray_int(s4 size)
+java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
 {
-       return (java_intarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass);
+       return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
 }
 
 
-/* builtin_newarray_long *******************************************************
+/* builtin_anewarray ***********************************************************
+
+   Creates an array of references to the given class type on the heap.
 
-   Creates an array of 64 bit Integers on the heap.
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is
+      available
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+   NOTE: This builtin can be called from NATIVE code only.
 
 *******************************************************************************/
 
-java_longarray *builtin_newarray_long(s4 size)
+java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
 {
-       return (java_longarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass);
-}
+       classinfo *arrayclass;
+       
+       /* is class loaded */
 
+       assert(componentclass->state & CLASS_LOADED);
 
-/* builtin_newarray_float ******************************************************
+       /* is class linked */
 
-   Creates an array of 32 bit IEEE floats on the heap.
+       if (!(componentclass->state & CLASS_LINKED))
+               if (!link_class(componentclass))
+                       return NULL;
 
-   Return value: pointer to the array or NULL if no memory is
-   available
+       arrayclass = class_array_of(componentclass, true);
 
-*******************************************************************************/
+       if (!arrayclass)
+               return NULL;
 
-java_floatarray *builtin_newarray_float(s4 size)
-{
-       return (java_floatarray *)
-               builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass);
+       return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
 }
 
 
-/* builtin_newarray_double *****************************************************
+/* builtin_newarray_type ****************************************************
 
-   Creates an array of 64 bit IEEE floats on the heap.
+   Creates an array of [type]s on the heap.
+       
+   RETURN VALUE:
+      pointer to the array or NULL if no memory is available
 
-   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 & NATIVE code.
 
 *******************************************************************************/
 
-java_doublearray *builtin_newarray_double(s4 size)
-{
-       return (java_doublearray *)
-               builtin_newarray(size,
-                                                primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass);
+#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); \
 }
 
+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)
+
 
 /* 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
-       arrayclass....the array class
-       dims..........array containing the size of each dimension to create
+   ARGUMENTS:
+      n.............number of dimensions to create
+      arrayclass....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
+   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)
+static java_handle_t *builtin_multianewarray_intern(int n,
+                                                                                                       classinfo *arrayclass,
+                                                                                                       long *dims)
 {
-       s4                size;
-       java_arrayheader *a;
-       classinfo        *componentclass;
-       s4                i;
+       s4             size;
+       java_handle_t *a;
+       classinfo     *componentclass;
+       s4             i;
 
        /* create this dimension */
 
        size = (s4) dims[0];
-       a = builtin_newarray(size, arrayclass);
+       a = builtin_newarray(size, arrayclass);
 
        if (!a)
                return NULL;
@@ -1094,14 +1248,14 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
 
        /* get the class of the components to create */
 
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->class;
+       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
        /* The verifier guarantees that the dimension count is in the range. */
 
        /* create the component arrays */
 
        for (i = 0; i < size; i++) {
-               java_arrayheader *ea =
+               java_handle_t *ea =
 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
                        /* we save an s4 to a s8 slot, 8-byte aligned */
 
@@ -1112,8 +1266,8 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
 
                if (!ea)
                        return NULL;
-               
-               ((java_objectarray *) a)->data[i] = (java_object_t *) ea;
+
+               array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
        }
 
        return a;
@@ -1125,13 +1279,17 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
    Wrapper for builtin_multianewarray_intern which checks all
    dimensions before we start allocating.
 
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
+
 ******************************************************************************/
 
-java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
-                                                                                long *dims)
+java_handle_objectarray_t *builtin_multianewarray(int n,
+                                                                                                 java_handle_t *arrayclazz,
+                                                                                                 long *dims)
 {
-       s4 i;
-       s4 size;
+       classinfo *c;
+       s4         i;
+       s4         size;
 
        /* check all dimensions before doing anything */
 
@@ -1149,294 +1307,24 @@ java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
                }
        }
 
-       /* 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_handle_t *builtin_trace_exception(java_handle_t *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);
-#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);
-#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 */
+       c = LLNI_classinfo_unwrap(arrayclazz);
 
-       dump_release(dumpsize);
+       /* now call the real function */
 
-       return xptr;
+       return (java_handle_objectarray_t *)
+               builtin_multianewarray_intern(n, c, dims);
 }
-#endif /* !defined(NDEBUG) */
-
-
-/* builtin_print_argument ******************************************************
-
-   Prints arguments and return values for the call trace.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-static char *builtin_print_argument(char *logtext, s4 *logtextlen,
-                                                                       typedesc *paramtype, s8 value)
-{
-       imm_union          imu;
-       java_handle_t     *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;
-
-       case TYPE_FLT:
-#if defined(__S390__)
-               imu.l = value;
-               /* The below won't work on S390 */
-#else
-               imu.i = (s4) value;
-#endif
-               sprintf(logtext + strlen(logtext), "%g (0x%08x)", imu.f, imu.i);
-               break;
-
-       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;
-
-       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
-
-               /* cast to java.lang.Object */
-
-               o = (java_handle_t *) (ptrint) value;
-
-               /* check return argument for java.lang.Class or java.lang.String */
-
-               if (o != NULL) {
-                       if (o->vftbl->class == class_java_lang_String) {
-                               /* get java.lang.String object and the length of the
-                                  string */
-
-                               u = javastring_toutf(o, false);
-
-                               len = strlen(" (String = \"") + utf_bytes(u) + strlen("\")");
-
-                               /* realloc memory for string length */
-
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
 
-                               /* convert to utf8 string and strcat it to the logtext */
-
-                               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;
-
-                                       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 */
-
-                                       u = o->vftbl->class->name;
-                               }
-
-                               len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
-
-                               /* realloc memory for string length */
-
-                               logtext = DMREALLOC(logtext, char, *logtextlen, *logtextlen + len);
-                               *logtextlen += len;
-
-                               /* strcat to the logtext */
-
-                               strcat(logtext, " (Class = \"");
-                               utf_cat_classname(logtext, u);
-                               strcat(logtext, "\")");
-                       }
-               }
-       }
-
-       return logtext;
-}
-#endif /* !defined(NDEBUG) */
 
 /* builtin_verbosecall_enter ***************************************************
 
    Print method call with arguments for -verbose:call.
 
+   XXX: Remove mew once all archs use the new tracer!
+
 *******************************************************************************/
 
 #if !defined(NDEBUG)
-
 #ifdef TRACE_ARGS_NUM
 void builtin_verbosecall_enter(s8 a0, s8 a1,
 # if TRACE_ARGS_NUM >= 4
@@ -1450,172 +1338,7 @@ void builtin_verbosecall_enter(s8 a0, s8 a1,
 # endif
                                                           methodinfo *m)
 {
-       methoddesc *md;
-       char       *logtext;
-       s4          logtextlen;
-       s4          dumpsize;
-       s4          i;
-       s4          pos;
-
-#if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_enter(m)) return;
-#endif
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_enter_method(m);
-       return;
-#endif
-
-       md = m->parseddesc;
-
-       /* calculate message length */
-
-       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);
-
-       /* Actually it's not possible to have all flags printed, but:
-          safety first! */
-
-       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 */
-
-       logtextlen +=
-               strlen("(") +
-               strlen("-9223372036854775808 (0x123456789abcdef0), ") * TRACE_ARGS_NUM +
-               strlen("...(255)") +
-               strlen(")");
-
-       /* allocate memory */
-
-       dumpsize = dump_size();
-
-       logtext = DMNEW(char, logtextlen);
-
-       callcount++;
-
-       sprintf(logtext, "%10d ", callcount);
-       sprintf(logtext + strlen(logtext), "-%d-", methodindent);
-
-       pos = strlen(logtext);
-
-       for (i = 0; i < methodindent; i++)
-               logtext[pos++] = '\t';
-
-       strcpy(logtext + pos, "called: ");
-
-       utf_cat_classname(logtext, m->class->name);
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
-
-       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");
-
-       strcat(logtext, "(");
-
-       if (md->paramcount >= 1) {
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[0], a0);
-       }
-
-       if (md->paramcount >= 2) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[1], a1);
-       }
-
-#if TRACE_ARGS_NUM >= 4
-       if (md->paramcount >= 3) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[2], a2);
-       }
-
-       if (md->paramcount >= 4) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[3], a3);
-       }
-#endif
-
-#if TRACE_ARGS_NUM >= 6
-       if (md->paramcount >= 5) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[4], a4);
-       }
-
-       if (md->paramcount >= 6) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[5], a5);
-       }
-#endif
-
-#if TRACE_ARGS_NUM == 8
-       if (md->paramcount >= 7) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[6], a6);
-       }
-
-       if (md->paramcount >= 8) {
-               strcat(logtext, ", ");
-
-               logtext = builtin_print_argument(logtext, &logtextlen,
-                                                                                &md->paramtypes[7], a7);
-       }
-#endif
-
-       if (md->paramcount > 8) {
-               sprintf(logtext + strlen(logtext), ", ...(%d)",
-                               md->paramcount - TRACE_ARGS_NUM);
-       }
-
-       strcat(logtext, ")");
-
-       log_text(logtext);
-
-       /* release memory */
-
-       dump_release(dumpsize);
-
-       methodindent++;
-
+       log_text("builtin_verbosecall_enter: Do not call me anymore!");
 }
 #endif
 #endif /* !defined(NDEBUG) */
@@ -1625,127 +1348,21 @@ void builtin_verbosecall_enter(s8 a0, s8 a1,
 
    Print method exit for -verbose:call.
 
+   XXX: Remove mew once all archs use the new tracer!
+
 *******************************************************************************/
 
 #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;
-
-#if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_exit(m)) return;
-#endif
-
-#if defined(ENABLE_VMLOG)
-       vmlog_cacao_leave_method(m);
-       return;
-#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 */
-
-       logtextlen += strlen("->0.4872328470301428 (0x0123456789abcdef)");
-
-       /* allocate memory */
-
-       dumpsize = dump_size();
-
-       logtext = DMNEW(char, logtextlen);
-
-       /* outdent the log message */
-
-       if (methodindent)
-               methodindent--;
-       else
-               log_text("WARNING: unmatched methodindent--");
-
-       /* generate the message */
-
-       sprintf(logtext, "           ");
-       sprintf(logtext + strlen(logtext), "-%d-", methodindent);
-
-       pos = strlen(logtext);
-
-       for (i = 0; i < methodindent; i++)
-               logtext[pos++] = '\t';
-
-       strcpy(logtext + pos, "finished: ");
-       utf_cat_classname(logtext, m->class->name);
-       strcat(logtext, ".");
-       utf_cat(logtext, m->name);
-       utf_cat(logtext, m->descriptor);
-
-       if (!IS_VOID_TYPE(md->returntype.type)) {
-               strcat(logtext, "->");
-
-               switch (md->returntype.type) {
-               case TYPE_INT:
-               case TYPE_LNG:
-               case TYPE_ADR:
-                       val.l = l;
-                       break;
-
-               case TYPE_FLT:
-                       val.f = f;
-                       break;
-
-               case TYPE_DBL:
-                       val.d = d;
-                       break;
-               }
-
-               logtext =
-                       builtin_print_argument(logtext, &logtextlen, &md->returntype, val.l);
-       }
-
-       log_text(logtext);
-
-       /* release memory */
-
-       dump_release(dumpsize);
-
+       log_text("builtin_verbosecall_exit: Do not call me anymore!");
 }
 #endif /* !defined(NDEBUG) */
 
 
-#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) */
-
-
-/*****************************************************************************
-                         MISCELLANEOUS HELPER FUNCTIONS
-*****************************************************************************/
-
-
+/*============================================================================*/
+/* MISCELLANEOUS MATHEMATICAL HELPER FUNCTIONS                                */
+/*============================================================================*/
 
 /*********** Functions for integer divisions *****************************
  
@@ -2558,42 +2175,54 @@ float builtin_d2f(double a)
 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
 
 
+/*============================================================================*/
+/* AUTOMATICALLY REPLACED FUNCTIONS                                           */
+/*============================================================================*/
+
 /* 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;
 
-       if ((src == NULL) || (dest == NULL)) { 
+       if ((src == NULL) || (dest == NULL)) {
                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();
-               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();
-               return false;
+               return;
+       }
+
+       // Special case.
+       if (len == 0) {
+               return;
        }
 
        if (sdesc->componentvftbl == ddesc->componentvftbl) {
@@ -2602,24 +2231,30 @@ bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
                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 */
 
-               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++) {
-                               java_handle_t *o = oas->data[srcStart + i];
+                               java_handle_t *o;
+
+                               o = array_objectarray_element_get(oas, srcStart + i);
 
                                if (!builtin_canstore(oad, o))
-                                       return false;
+                                       return;
 
-                               oad->data[destStart + i] = o;
+                               array_objectarray_element_set(oad, destStart + i, o);
                        }
                }
                else {
@@ -2630,17 +2265,17 @@ bool builtin_arraycopy(java_arrayheader *src, s4 srcStart,
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
-                               java_handle_t *o = oas->data[srcStart + i];
+                               java_handle_t *o;
+
+                               o = array_objectarray_element_get(oas, srcStart + i);
 
                                if (!builtin_canstore(oad, o))
-                                       return false;
+                                       return;
 
-                               oad->data[destStart + i] = o;
+                               array_objectarray_element_set(oad, destStart + i, o);
                        }
                }
        }
-
-       return true;
 }
 
 
@@ -2684,42 +2319,51 @@ s8 builtin_currenttimemillis(void)
 
    Function for cloning objects or arrays.
 
+   NOTE: This is a SLOW builtin and can be called from JIT & NATIVE code.
+
 *******************************************************************************/
 
 java_handle_t *builtin_clone(void *env, java_handle_t *o)
 {
-       arraydescriptor   *ad;
-       java_arrayheader  *ah;
-       u4                 size;
-       classinfo         *c;
-       java_handle_t     *co;              /* cloned object header               */
+       arraydescriptor *ad;
+       u4               size;
+       classinfo       *c;
+       java_handle_t   *co;                /* cloned object header               */
 
        /* get the array descriptor */
 
-       ad = o->vftbl->arraydesc;
+       ad = LLNI_vftbl_direct(o)->arraydesc;
 
        /* 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;
 
-               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)
-               heap_init_objectheader(co, size);
+               heap_init_objectheader(LLNI_DIRECT(co), size);
 #endif
 
 #if defined(ENABLE_THREADS)
-               lock_init_object_lock(co);
+               lock_init_object_lock(LLNI_DIRECT(co));
 #endif
 
+               LLNI_CRITICAL_END;
+
                return co;
        }
     
@@ -2732,7 +2376,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
 
        /* get the class of the object */
 
-    c = o->vftbl->class;
+       LLNI_class_get(o, c);
 
        /* create new object */
 
@@ -2741,19 +2385,37 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
     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)
-       heap_init_objectheader(co, c->instancesize);
+       heap_init_objectheader(LLNI_DIRECT(co), c->instancesize);
 #endif
 
 #if defined(ENABLE_THREADS)
-       lock_init_object_lock(co);
+       lock_init_object_lock(LLNI_DIRECT(co));
 #endif
 
+       LLNI_CRITICAL_END;
+
     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>