* Removed all Id tags.
[cacao.git] / src / vm / builtin.c
index 57918bdcaada8b461545d8ef80213210775ef5d2..544ae21781d730c93435beaa0001b140407fcf63 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/builtin.c - functions for unsupported operations
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-            Andreas Krall
-            Mark Probst
-
-   Changes: Christian Thalinger
-            Edwin Steiner
-
    Contains C functions for JavaVM Instructions that cannot be
    translated to machine language directly. Consequently, the
    generated machine code for these instructions contains function
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 4690 2006-03-27 11:37:46Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
-#include <math.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 
 #include "vm/types.h"
 
 #include "md-abi.h"
 
 #include "fdlibm/fdlibm.h"
+#if defined(__CYGWIN__) && defined(Bias)
+# undef Bias
+#endif
 
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
 #include "mm/memory.h"
-#include "native/native.h"
-#include "native/include/java_lang_Cloneable.h"
-#include "native/include/java_lang_Object.h"          /* required by VMObject */
-#include "native/include/java_lang_VMObject.h"
-
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-#  include "threads/green/locks.h"
-# endif
+
+#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"
+#if defined(ENABLE_THREADS)
+#include "threads/native/threads.h"
+#else
+#include "threads/none/threads.h"
 #endif
 
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
+
+#include "vm/array.h"
 #include "vm/builtin.h"
-#include "vm/class.h"
+#include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
+#include "vm/primitive.h"
 #include "vm/stringlocal.h"
+
 #include "vm/jit/asmpart.h"
-#include "vm/jit/patcher.h"
 
+#include "vmcore/class.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/rt-timing.h"
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+#      include "vm/jit/show.h"
+#endif
 
 /* include builtin tables *****************************************************/
 
 #include "vm/builtintable.inc"
 
 
+CYCLES_STATS_DECLARE(builtin_new         ,100,5)
+CYCLES_STATS_DECLARE(builtin_overhead    , 80,1)
+
 /* builtintable_init ***********************************************************
 
    Parse the descriptors of builtin functions and create the parsed
 
 static bool builtintable_init(void)
 {
-       descriptor_pool *descpool;
-       s4               dumpsize;
-       utf             *descriptor;
-       s4               entries_internal;
-       s4               entries_automatic;
-       s4               i;
+       descriptor_pool    *descpool;
+       s4                  dumpsize;
+       builtintable_entry *bte;
 
        /* mark start of dump memory area */
 
@@ -123,23 +129,14 @@ static bool builtintable_init(void)
        if (!descriptor_pool_add_class(descpool, utf_java_lang_Class))
                return false;
 
-       /* calculate table entries statically */
-
-       entries_internal =
-               sizeof(builtintable_internal) / sizeof(builtintable_entry);
-
-       entries_automatic =
-               sizeof(builtintable_automatic) / sizeof(builtintable_entry)
-               - 1; /* last filler entry (comment see builtintable.inc) */
-
        /* first add all descriptors to the pool */
 
-       for (i = 0; i < entries_internal; i++) {
+       for (bte = builtintable_internal; bte->fp != NULL; bte++) {
                /* create a utf8 string from descriptor */
 
-               descriptor = utf_new_char(builtintable_internal[i].descriptor);
+               bte->descriptor = utf_new_char(bte->cdescriptor);
 
-               if (!descriptor_pool_add(descpool, descriptor, NULL)) {
+               if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                        /* release dump area */
 
                        dump_release(dumpsize);
@@ -148,16 +145,22 @@ static bool builtintable_init(void)
                }
        }
 
-       for (i = 0; i < entries_automatic; i++) {
-               /* create a utf8 string from descriptor */
+       for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
+               bte->descriptor = utf_new_char(bte->cdescriptor);
 
-               descriptor = utf_new_char(builtintable_automatic[i].descriptor);
+               if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
+                       dump_release(dumpsize);
+                       return false;
+               }
+       }
 
-               if (!descriptor_pool_add(descpool, descriptor, NULL)) {
-                       /* release dump area */
+       for (bte = builtintable_function; bte->fp != NULL; bte++) {
+               bte->classname  = utf_new_char(bte->cclassname);
+               bte->name       = utf_new_char(bte->cname);
+               bte->descriptor = utf_new_char(bte->cdescriptor);
 
+               if (!descriptor_pool_add(descpool, bte->descriptor, NULL)) {
                        dump_release(dumpsize);
-
                        return false;
                }
        }
@@ -170,30 +173,31 @@ static bool builtintable_init(void)
 
        descriptor_pool_alloc_parsed_descriptors(descpool);
 
-       /* now parse all descriptors */
-
-       for (i = 0; i < entries_internal; i++) {
-               /* create a utf8 string from descriptor */
-
-               descriptor = utf_new_char(builtintable_internal[i].descriptor);
+       /* Now parse all descriptors.  NOTE: builtin-functions are treated
+          like static methods (no `this' pointer). */
 
-               /* parse the descriptor, builtin is always static (no `this' pointer) */
-
-               builtintable_internal[i].md =
-                       descriptor_pool_parse_method_descriptor(descpool, descriptor,
-                                                                                                       ACC_STATIC, NULL);
+       for (bte = builtintable_internal; bte->fp != NULL; bte++) {
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
        }
 
-       for (i = 0; i < entries_automatic; i++) {
-               /* create a utf8 string from descriptor */
-
-               descriptor = utf_new_char(builtintable_automatic[i].descriptor);
-
-               /* parse the descriptor, builtin is always static (no `this' pointer) */
+       for (bte = builtintable_automatic; bte->fp != NULL; bte++) {
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
+       }
 
-               builtintable_automatic[i].md =
-                       descriptor_pool_parse_method_descriptor(descpool, descriptor,
-                                                                                                       ACC_STATIC, NULL);
+       for (bte = builtintable_function; bte->fp != NULL; bte++) {
+               bte->md =
+                       descriptor_pool_parse_method_descriptor(descpool,
+                                                                                                       bte->descriptor,
+                                                                                                       ACC_STATIC | ACC_METHOD_BUILTIN,
+                                                                                                       NULL);
        }
 
        /* release dump area */
@@ -243,7 +247,7 @@ static void builtintable_sort_automatic(void)
 
 /* builtin_init ****************************************************************
 
-   XXX
+   Initialize the global table of builtin functions.
 
 *******************************************************************************/
 
@@ -271,11 +275,11 @@ bool builtin_init(void)
 
 builtintable_entry *builtintable_get_internal(functionptr fp)
 {
-       s4 i;
+       builtintable_entry *bte;
 
-       for (i = 0; builtintable_internal[i].fp != NULL; i++) {
-               if (builtintable_internal[i].fp == fp)
-                       return &builtintable_internal[i];
+       for (bte = builtintable_internal; bte->fp != NULL; bte++) {
+               if (bte->fp == fp)
+                       return bte;
        }
 
        return NULL;
@@ -319,100 +323,102 @@ builtintable_entry *builtintable_get_automatic(s4 opcode)
 }
 
 
-/*****************************************************************************
-                                                               TYPE CHECKS
-*****************************************************************************/
-
+/* builtintable_replace_function ***********************************************
 
+   XXX
 
-/*************** internal function: builtin_isanysubclass *********************
+*******************************************************************************/
 
-       Checks a subclass relation between two classes. Implemented interfaces
-       are interpreted as super classes.
-       Return value:  1 ... sub is subclass of super
-                                  0 ... otherwise
-                                       
-*****************************************************************************/                                 
-s4 builtin_isanysubclass(classinfo *sub, classinfo *super)
+#if defined(ENABLE_JIT)
+bool builtintable_replace_function(void *iptr_)
 {
-       s4 res;
-       castinfo classvalues;
+       constant_FMIref    *mr;
+       builtintable_entry *bte;
+       instruction        *iptr;
 
-       if (sub == super)
-               return 1;
+       iptr = (instruction *) iptr_; /* twisti will kill me ;) */
 
-       if (super->flags & ACC_INTERFACE) {
-               res = (sub->vftbl->interfacetablelength > super->index) &&
-                       (sub->vftbl->interfacetable[-super->index] != NULL);
+       /* get name and descriptor of the function */
 
-       } else {
-               ASM_GETCLASSVALUES_ATOMIC(super->vftbl, sub->vftbl, &classvalues);
+       switch (iptr->opc) {
+       case ICMD_INVOKESTATIC:
+               /* The instruction MUST be resolved, otherwise we run into
+                  lazy loading troubles.  Anyway, we should/can only replace
+                  very VM-close functions. */
 
-               res = (u4) (classvalues.sub_baseval - classvalues.super_baseval) <=
-                       (u4) classvalues.super_diffval;
-       }
+               if (INSTRUCTION_IS_UNRESOLVED(iptr))
+                       return false;
 
-       return res;
-}
+               mr = iptr->sx.s23.s3.fmiref;
+               break;  
 
+       default:
+               return false;
+       }
 
-s4 builtin_isanysubclass_vftbl(vftbl_t *sub, vftbl_t *super)
-{
-       s4 res;
-       s4 base;
-       castinfo classvalues;
+       /* search the function table */
 
-       if (sub == super)
-               return 1;
+       for (bte = builtintable_function; bte->fp != NULL; bte++) {
+               if ((METHODREF_CLASSNAME(mr) == bte->classname) &&
+                       (mr->name             == bte->name) &&
+                       (mr->descriptor       == bte->descriptor)) {
 
-       ASM_GETCLASSVALUES_ATOMIC(super, sub, &classvalues);
+                       /* set the values in the instruction */
 
-       if ((base = classvalues.super_baseval) <= 0) {
-               /* super is an interface */
-               res = (sub->interfacetablelength > -base) &&
-                       (sub->interfacetable[base] != NULL);
-       } else {
-           res = (u4) (classvalues.sub_baseval - classvalues.super_baseval)
-                       <= (u4) classvalues.super_diffval;
+                       iptr->opc   = bte->opcode;
+                       iptr->sx.s23.s3.bte = bte;
+                       if (bte->checkexception)
+                               iptr->flags.bits |= INS_FLAG_CHECK;
+                       else
+                               iptr->flags.bits &= ~INS_FLAG_CHECK;
+
+                       return true;
+               }
        }
 
-       return res;
+       return false;
 }
+#endif /* defined(ENABLE_JIT) */
+
+
+/*****************************************************************************
+                                                               TYPE CHECKS
+*****************************************************************************/
 
+/* builtin_instanceof **********************************************************
 
-/****************** function: builtin_instanceof *****************************
+   Checks if an object is an instance of some given class (or subclass
+   of that class). If class is an interface, checks if the interface
+   is implemented.
 
-       Checks if an object is an instance of some given class (or subclass of
-       that class). If class is an interface, checks if the interface is
-       implemented.
-       Return value:  1 ... obj is an instance of class or implements the interface
-                                  0 ... otherwise or if obj == NULL
+   Return value: 1 ... o is an instance of class or implements the interface
+                 0 ... otherwise or if o == NULL
                         
-*****************************************************************************/
+*******************************************************************************/
 
-s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
+s4 builtin_instanceof(java_handle_t *o, classinfo *class)
 {
-       if (!obj)
+       if (o == NULL)
                return 0;
 
-       return builtin_isanysubclass(obj->vftbl->class, class);
+       return class_isanysubclass(o->vftbl->class, class);
 }
 
 
 
-/**************** function: builtin_checkcast *******************************
+/* builtin_checkcast ***********************************************************
 
-       The same as builtin_instanceof except that 1 is returned when
-       obj == NULL
+   The same as builtin_instanceof except that 1 is returned when o ==
+   NULL.
                          
-****************************************************************************/
+*******************************************************************************/
 
-s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
+s4 builtin_checkcast(java_handle_t *o, classinfo *class)
 {
-       if (obj == NULL)
+       if (o == NULL)
                return 1;
 
-       if (builtin_isanysubclass(obj->vftbl->class, class))
+       if (class_isanysubclass(o->vftbl->class, class))
                return 1;
 
        return 0;
@@ -450,8 +456,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
                        (target->elementvftbl->baseval == 1))
                        return 1;
 
-               return builtin_isanysubclass_vftbl(desc->elementvftbl,
-                                                                                  target->elementvftbl);
+               return class_isanysubclass(desc->elementvftbl->class,
+                                                                  target->elementvftbl->class);
        }
 
        if (desc->dimension < target->dimension)
@@ -459,8 +465,8 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
 
        /* {desc has higher dimension than target} */
 
-       return builtin_isanysubclass_vftbl(pseudo_class_Arraystub->vftbl,
-                                                                          target->elementvftbl);
+       return class_isanysubclass(pseudo_class_Arraystub,
+                                                          target->elementvftbl->class);
 }
 
 
@@ -477,37 +483,43 @@ static s4 builtin_descriptorscompatible(arraydescriptor *desc,
        
 *******************************************************************************/
 
-s4 builtin_arraycheckcast(java_objectheader *o, classinfo *targetclass)
+s4 builtin_arraycheckcast(java_handle_t *o, classinfo *targetclass)
 {
        arraydescriptor *desc;
 
-       if (!o)
+       if (o == NULL)
                return 1;
 
-       if ((desc = o->vftbl->arraydesc) == NULL)
+       desc = o->vftbl->arraydesc;
+
+       if (desc == NULL)
                return 0;
  
        return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc);
 }
 
 
-s4 builtin_arrayinstanceof(java_objectheader *o, classinfo *targetclass)
+s4 builtin_arrayinstanceof(java_handle_t *o, classinfo *targetclass)
 {
-       if (!o)
+       if (o == NULL)
                return 0;
 
        return builtin_arraycheckcast(o, targetclass);
 }
 
 
-/************************** exception functions *******************************
+/* builtin_throw_exception *****************************************************
 
-******************************************************************************/
+   Sets the exceptionptr with the thrown exception and prints some
+   debugging information.  Called from asm_vm_call_method.
 
-#if !defined(NDEBUG)
-java_objectheader *builtin_throw_exception(java_objectheader *xptr)
+*******************************************************************************/
+
+void *builtin_throw_exception(java_handle_t *xptr)
 {
+#if !defined(NDEBUG)
     java_lang_Throwable *t;
+       java_lang_String    *s;
        char                *logtext;
        s4                   logtextlen;
        s4                   dumpsize;
@@ -515,18 +527,27 @@ java_objectheader *builtin_throw_exception(java_objectheader *xptr)
        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_strlen(xptr->vftbl->class->name) +
-                               strlen(": ") +
-                               javastring_strlen(t->detailMessage);
-
-               } else
+                               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)");
+               }
 
                /* allocate memory */
 
@@ -537,16 +558,15 @@ java_objectheader *builtin_throw_exception(java_objectheader *xptr)
                strcpy(logtext, "Builtin exception thrown: ");
 
                if (t) {
-                       utf_sprint_classname(logtext + strlen(logtext),
-                                                                xptr->vftbl->class->name);
+                       utf_cat_classname(logtext, xptr->vftbl->class->name);
 
-                       if (t->detailMessage) {
+                       if (s) {
                                char *buf;
 
-                               buf = javastring_tochar((java_objectheader *) t->detailMessage);
+                               buf = javastring_tochar((java_handle_t *) s);
                                strcat(logtext, ": ");
                                strcat(logtext, buf);
-                               MFREE(buf, char, strlen(buf));
+                               MFREE(buf, char, strlen(buf) + 1);
                        }
 
                } else {
@@ -559,12 +579,17 @@ java_objectheader *builtin_throw_exception(java_objectheader *xptr)
 
                dump_release(dumpsize);
        }
+#endif /* !defined(NDEBUG) */
 
-       *exceptionptr = xptr;
+       /* actually set the exception */
 
-       return xptr;
+       exceptions_set_exception(xptr);
+
+       /* Return a NULL pointer.  This is required for vm_call_method to
+          check for an exception.  This is for convenience. */
+
+       return NULL;
 }
-#endif /* !defined(NDEBUG) */
 
 
 /* builtin_canstore ************************************************************
@@ -572,20 +597,21 @@ java_objectheader *builtin_throw_exception(java_objectheader *xptr)
    Checks, if an object can be stored in an array.
 
    Return value: 1 ... possible
-                 0 ... otherwise
+                 0 ... otherwise (throws an ArrayStoreException)
 
 *******************************************************************************/
 
-s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
+s4 builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 {
        arraydescriptor *desc;
        arraydescriptor *valuedesc;
        vftbl_t         *componentvftbl;
        vftbl_t         *valuevftbl;
-       s4               base;
-       castinfo         classvalues;
+       int32_t          baseval;
+       uint32_t         diffval;
+       int              result;
 
-       if (!o)
+       if (o == NULL)
                return 1;
 
        /* The following is guaranteed (by verifier checks):
@@ -598,54 +624,69 @@ s4 builtin_canstore(java_objectarray *oa, java_objectheader *o)
        desc           = oa->header.objheader.vftbl->arraydesc;
        componentvftbl = desc->componentvftbl;
        valuevftbl     = o->vftbl;
+       valuedesc      = valuevftbl->arraydesc;
 
        if ((desc->dimension - 1) == 0) {
-               s4 res;
-
                /* {oa is a one-dimensional array} */
                /* {oa is an array of references} */
                
                if (valuevftbl == componentvftbl)
                        return 1;
 
-               ASM_GETCLASSVALUES_ATOMIC(componentvftbl, valuevftbl, &classvalues);
+               LOCK_MONITOR_ENTER(linker_classrenumber_lock);
 
-               if ((base = classvalues.super_baseval) <= 0)
+               baseval = componentvftbl->baseval;
+
+               if (baseval <= 0) {
                        /* an array of interface references */
-                       return (valuevftbl->interfacetablelength > -base &&
-                                       valuevftbl->interfacetable[base] != NULL);
-               
-               res = ((unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
-                          <= (unsigned) classvalues.super_diffval);
 
-               return res;
-       }
+                       result = ((valuevftbl->interfacetablelength > -baseval) &&
+                                         (valuevftbl->interfacetable[baseval] != NULL));
+               }
+               else {
+                       diffval = valuevftbl->baseval - componentvftbl->baseval;
+                       result  = diffval <= (uint32_t) componentvftbl->diffval;
+               }
 
-       /* {oa has dimension > 1} */
-       /* {componentvftbl->arraydesc != NULL} */
+               LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+       }
+       else if (valuedesc == NULL) {
+               /* {oa has dimension > 1} */
+               /* {componentvftbl->arraydesc != NULL} */
 
-       /* check if o is an array */
+               /* check if o is an array */
 
-       if ((valuedesc = valuevftbl->arraydesc) == NULL)
                return 0;
+       }
+       else {
+               /* {o is an array} */
+
+               result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
+       }
+
+       /* if not possible, throw an exception */
 
-       /* {o is an array} */
+       if (result == 0)
+               exceptions_throw_arraystoreexception();
 
-       return builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
+       /* return result */
+
+       return result;
 }
 
 
 /* This is an optimized version where a is guaranteed to be one-dimensional */
-s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
+s4 builtin_canstore_onedim (java_handle_objectarray_t *a, java_handle_t *o)
 {
        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;
+       int              result;
        
-       if (!o) return 1;
+       if (o == NULL)
+               return 1;
 
        /* The following is guaranteed (by verifier checks):
         *
@@ -664,30 +705,37 @@ s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
        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 */
-               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 */
-s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
+s4 builtin_canstore_onedim_class(java_handle_objectarray_t *a, java_handle_t *o)
 {
-       vftbl_t *elementvftbl;
-       vftbl_t *valuevftbl;
-       s4 res;
-       castinfo classvalues;
+       vftbl_t  *elementvftbl;
+       vftbl_t  *valuevftbl;
+       uint32_t  diffval;
+       int       result;
        
-       if (!o) return 1;
+       if (o == NULL)
+               return 1;
 
        /* The following is guaranteed (by verifier checks):
         *
@@ -706,12 +754,14 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
-       ASM_GETCLASSVALUES_ATOMIC(elementvftbl, valuevftbl, &classvalues);
+       LOCK_MONITOR_ENTER(linker_classrenumber_lock);
 
-       res = (unsigned) (classvalues.sub_baseval - classvalues.super_baseval)
-               <= (unsigned) classvalues.super_diffval;
+       diffval = valuevftbl->baseval - elementvftbl->baseval;
+       result  = diffval <= (uint32_t) elementvftbl->diffval;
 
-       return res;
+       LOCK_MONITOR_EXIT(linker_classrenumber_lock);
+
+       return result;
 }
 
 
@@ -724,9 +774,18 @@ s4 builtin_canstore_onedim_class(java_objectarray *a, java_objectheader *o)
                        
 *******************************************************************************/
 
-java_objectheader *builtin_new(classinfo *c)
+java_handle_t *builtin_new(classinfo *c)
 {
-       java_objectheader *o;
+       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
+
+       RT_TIMING_GET_TIME(time_start);
+       CYCLES_STATS_GET(cycles_start);
 
        /* is the class loaded */
 
@@ -735,9 +794,7 @@ java_objectheader *builtin_new(classinfo *c)
        /* check if we can instantiate this class */
 
        if (c->flags & ACC_ABSTRACT) {
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_InstantiationError,
-                                                                        c->name);
+               exceptions_throw_instantiationerror(c);
                return NULL;
        }
 
@@ -757,17 +814,24 @@ java_objectheader *builtin_new(classinfo *c)
                        return NULL;
        }
 
-       o = heap_allocate(c->instancesize, true, c->finalizer);
+       o = heap_allocate(c->instancesize, c->flags & ACC_CLASS_HAS_POINTERS,
+                                         c->finalizer);
 
        if (!o)
                return NULL;
 
        o->vftbl = c->vftbl;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initObjectLock(o);
+#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;
 }
 
@@ -781,13 +845,18 @@ java_objectheader *builtin_new(classinfo *c)
 
 *******************************************************************************/
 
-java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass)
+java_handle_t *builtin_newarray(s4 size, classinfo *arrayclass)
 {
-       arraydescriptor  *desc;
-       s4                dataoffset;
-       s4                componentsize;
-       s4                actualsize;
-       java_arrayheader *a;
+       arraydescriptor *desc;
+       s4               dataoffset;
+       s4               componentsize;
+       s4               actualsize;
+       java_array_t    *a;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
 
        desc          = arrayclass->vftbl->arraydesc;
        dataoffset    = desc->dataoffset;
@@ -800,23 +869,28 @@ java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass)
 
        actualsize = dataoffset + size * componentsize;
 
-       if (((u4) actualsize) < ((u4) size)) { /* overflow */
-               *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
+       /* check for overflow */
+
+       if (((u4) actualsize) < ((u4) size)) {
+               exceptions_throw_outofmemoryerror();
                return NULL;
        }
 
        a = heap_allocate(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL);
 
-       if (!a)
+       if (a == NULL)
                return NULL;
 
        a->objheader.vftbl = arrayclass->vftbl;
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       initObjectLock(&a->objheader);
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(&a->objheader);
 #endif
 
-       a->size = size;
+       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;
 }
@@ -831,7 +905,7 @@ java_arrayheader *builtin_newarray(s4 size, classinfo *arrayclass)
 
 *******************************************************************************/
 
-java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
+java_handle_objectarray_t *builtin_anewarray(s4 size, classinfo *componentclass)
 {
        classinfo *arrayclass;
        
@@ -850,7 +924,7 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
        if (!arrayclass)
                return NULL;
 
-       return (java_objectarray *) builtin_newarray(size, arrayclass);
+       return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
 }
 
 
@@ -864,9 +938,9 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *componentclass)
 
 *******************************************************************************/
 
-java_booleanarray *builtin_newarray_boolean(s4 size)
+java_handle_booleanarray_t *builtin_newarray_boolean(s4 size)
 {
-       return (java_booleanarray *)
+       return (java_handle_booleanarray_t *)
                builtin_newarray(size,
                                                 primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass);
 }
@@ -881,9 +955,9 @@ java_booleanarray *builtin_newarray_boolean(s4 size)
 
 *******************************************************************************/
 
-java_bytearray *builtin_newarray_byte(s4 size)
+java_handle_bytearray_t *builtin_newarray_byte(s4 size)
 {
-       return (java_bytearray *)
+       return (java_handle_bytearray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_BYTE].arrayclass);
 }
 
@@ -897,9 +971,9 @@ java_bytearray *builtin_newarray_byte(s4 size)
 
 *******************************************************************************/
 
-java_chararray *builtin_newarray_char(s4 size)
+java_handle_chararray_t *builtin_newarray_char(s4 size)
 {
-       return (java_chararray *)
+       return (java_handle_chararray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_CHAR].arrayclass);
 }
 
@@ -913,9 +987,9 @@ java_chararray *builtin_newarray_char(s4 size)
 
 *******************************************************************************/
 
-java_shortarray *builtin_newarray_short(s4 size)
+java_handle_shortarray_t *builtin_newarray_short(s4 size)
 {
-       return (java_shortarray *)
+       return (java_handle_shortarray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_SHORT].arrayclass);
 }
 
@@ -929,9 +1003,9 @@ java_shortarray *builtin_newarray_short(s4 size)
 
 *******************************************************************************/
 
-java_intarray *builtin_newarray_int(s4 size)
+java_handle_intarray_t *builtin_newarray_int(s4 size)
 {
-       return (java_intarray *)
+       return (java_handle_intarray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_INT].arrayclass);
 }
 
@@ -945,9 +1019,9 @@ java_intarray *builtin_newarray_int(s4 size)
 
 *******************************************************************************/
 
-java_longarray *builtin_newarray_long(s4 size)
+java_handle_longarray_t *builtin_newarray_long(s4 size)
 {
-       return (java_longarray *)
+       return (java_handle_longarray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_LONG].arrayclass);
 }
 
@@ -961,9 +1035,9 @@ java_longarray *builtin_newarray_long(s4 size)
 
 *******************************************************************************/
 
-java_floatarray *builtin_newarray_float(s4 size)
+java_handle_floatarray_t *builtin_newarray_float(s4 size)
 {
-       return (java_floatarray *)
+       return (java_handle_floatarray_t *)
                builtin_newarray(size, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass);
 }
 
@@ -977,9 +1051,9 @@ java_floatarray *builtin_newarray_float(s4 size)
 
 *******************************************************************************/
 
-java_doublearray *builtin_newarray_double(s4 size)
+java_handle_doublearray_t *builtin_newarray_double(s4 size)
 {
-       return (java_doublearray *)
+       return (java_handle_doublearray_t *)
                builtin_newarray(size,
                                                 primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass);
 }
@@ -991,28 +1065,28 @@ java_doublearray *builtin_newarray_double(s4 size)
    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
+       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
 
 ******************************************************************************/
 
-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;
@@ -1031,7 +1105,7 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
        /* 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 */
 
@@ -1043,7 +1117,7 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
                if (!ea)
                        return NULL;
                
-               ((java_objectarray *) a)->data[i] = (java_objectheader *) ea;
+               ((java_handle_objectarray_t *) a)->data[i] = (java_object_t *) ea;
        }
 
        return a;
@@ -1057,8 +1131,8 @@ static java_arrayheader *builtin_multianewarray_intern(int n,
 
 ******************************************************************************/
 
-java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
-                                                                                long *dims)
+java_handle_objectarray_t *builtin_multianewarray(int n, classinfo *arrayclass,
+                                                                                                 long *dims)
 {
        s4 i;
        s4 size;
@@ -1097,27 +1171,38 @@ java_arrayheader *builtin_multianewarray(int n, classinfo *arrayclass,
 static s4 methodindent = 0;
 static u4 callcount = 0;
 
-java_objectheader *builtin_trace_exception(java_objectheader *xptr,
-                                                                                  methodinfo *m,
-                                                                                  void *pos,
-                                                                                  s4 indent)
+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)
+#if defined(__S390__)
+               TRACEJAVACALLINDENT--;
+#else
                methodindent--;
+#endif
 
        /* calculate message length */
 
        if (xptr) {
                logtextlen =
-                       strlen("Exception ") +
-                       utf_strlen(xptr->vftbl->class->name);
-
-       } else {
+                       strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
+       } 
+       else {
                logtextlen = strlen("Some Throwable");
        }
 
@@ -1125,10 +1210,10 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
 
        if (m) {
                logtextlen +=
-                       utf_strlen(m->class->name) +
+                       utf_bytes(m->class->name) +
                        strlen(".") +
-                       utf_strlen(m->name) +
-                       utf_strlen(m->descriptor) +
+                       utf_bytes(m->name) +
+                       utf_bytes(m->descriptor) +
                        strlen("(NOSYNC,NATIVE");
 
 #if SIZEOF_VOID_P == 8
@@ -1141,12 +1226,14 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
                if (m->class->sourcefile == NULL)
                        logtextlen += strlen("<NO CLASSFILE INFORMATION>");
                else
-                       logtextlen += utf_strlen(m->class->sourcefile);
+                       logtextlen += utf_bytes(m->class->sourcefile);
 
                logtextlen += strlen(":65536)");
 
-       } else
+       } 
+       else {
                logtextlen += strlen("call_java_method");
+       }
 
        logtextlen += strlen("0");
 
@@ -1158,7 +1245,7 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
 
        if (xptr) {
                strcpy(logtext, "Exception ");
-               utf_strcat_classname(logtext, xptr->vftbl->class->name);
+               utf_cat_classname(logtext, xptr->vftbl->class->name);
 
        } else {
                strcpy(logtext, "Some Throwable");
@@ -1167,10 +1254,10 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
        strcat(logtext, " thrown in ");
 
        if (m) {
-               utf_strcat_classname(logtext, m->class->name);
+               utf_cat_classname(logtext, m->class->name);
                strcat(logtext, ".");
-               utf_strcat(logtext, m->name);
-               utf_strcat(logtext, m->descriptor);
+               utf_cat(logtext, m->name);
+               utf_cat(logtext, m->descriptor);
 
                if (m->flags & ACC_SYNCHRONIZED)
                        strcat(logtext, "(SYNC");
@@ -1211,7 +1298,7 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
                        if (m->class->sourcefile == NULL)
                                strcat(logtext, "<NO CLASSFILE INFORMATION>");
                        else
-                               utf_strcat(logtext, m->class->sourcefile);
+                               utf_cat(logtext, m->class->sourcefile);
 
                        sprintf(logtext + strlen(logtext), ":%d)", 0);
                }
@@ -1230,26 +1317,146 @@ java_objectheader *builtin_trace_exception(java_objectheader *xptr,
 #endif /* !defined(NDEBUG) */
 
 
-/* builtin_trace_args **********************************************************
+/* builtin_print_argument ******************************************************
 
-   XXX
+   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.
 
 *******************************************************************************/
 
 #if !defined(NDEBUG)
 
 #ifdef TRACE_ARGS_NUM
-void builtin_trace_args(s8 a0, s8 a1,
-#if TRACE_ARGS_NUM >= 4
-                                               s8 a2, s8 a3,
-#endif /* TRACE_ARGS_NUM >= 4 */
-#if TRACE_ARGS_NUM >= 6
-                                               s8 a4, s8 a5,
-#endif /* TRACE_ARGS_NUM >= 6 */
-#if TRACE_ARGS_NUM == 8
-                                               s8 a6, s8 a7,
-#endif /* TRACE_ARGS_NUM == 8 */
-                                               methodinfo *m)
+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;
@@ -1258,6 +1465,15 @@ void builtin_trace_args(s8 a0, s8 a1,
        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 */
@@ -1267,15 +1483,34 @@ void builtin_trace_args(s8 a0, s8 a1,
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                methodindent +
                strlen("called: ") +
-               utf_strlen(m->class->name) +
+               utf_bytes(m->class->name) +
                strlen(".") +
-               utf_strlen(m->name) +
-               utf_strlen(m->descriptor) +
-               strlen(" SYNCHRONIZED") + strlen("(") + 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("0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, 0x123456789abcdef0, ...(255)");
+       logtextlen +=
+               strlen("(") +
+               strlen("-9223372036854775808 (0x123456789abcdef0), ") * TRACE_ARGS_NUM +
+               strlen("...(255)") +
+               strlen(")");
 
        /* allocate memory */
 
@@ -1295,10 +1530,10 @@ void builtin_trace_args(s8 a0, s8 a1,
 
        strcpy(logtext + pos, "called: ");
 
-       utf_strcat_classname(logtext, m->class->name);
+       utf_cat_classname(logtext, m->class->name);
        strcat(logtext, ".");
-       utf_strcat(logtext, m->name);
-       utf_strcat(logtext, m->descriptor);
+       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");
@@ -1314,209 +1549,111 @@ void builtin_trace_args(s8 a0, s8 a1,
 
        strcat(logtext, "(");
 
-       /* xxxprintf ?Bug? an PowerPc Linux (rlwinm.inso)                */
-       /* Only Arguments in integer Registers are passed correctly here */
-       /* long longs spilled on Stack have an wrong offset of +4        */
-       /* So preliminary Bugfix: Only pass 3 params at once to sprintf  */
-       /* for SIZEOG_VOID_P == 4 && TRACE_ARGS_NUM == 8                 */
-       switch (md->paramcount) {
-       case 0:
-               break;
+       if (md->paramcount >= 1) {
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[0], a0);
+       }
 
-#if SIZEOF_VOID_P == 4
-       case 1:
-               sprintf(logtext + strlen(logtext),
-                               "0x%llx",
-                               a0);
-               break;
+       if (md->paramcount >= 2) {
+               strcat(logtext, ", ");
 
-       case 2:
-               sprintf(logtext + strlen(logtext),
-                               "0x%llx, 0x%llx",
-                               a0, a1);
-               break;
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[1], a1);
+       }
 
 #if TRACE_ARGS_NUM >= 4
-       case 3:
-               sprintf(logtext + strlen(logtext),
-                               "0x%llx, 0x%llx, 0x%llx",
-                               a0, a1, a2);
-               break;
+       if (md->paramcount >= 3) {
+               strcat(logtext, ", ");
 
-       case 4:
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext), ", 0x%llx", a3);
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[2], a2);
+       }
 
-               break;
-#endif /* TRACE_ARGS_NUM >= 4 */
+       if (md->paramcount >= 4) {
+               strcat(logtext, ", ");
+
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[3], a3);
+       }
+#endif
 
 #if TRACE_ARGS_NUM >= 6
-       case 5:
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx", a3, a4);
-               break;
+       if (md->paramcount >= 5) {
+               strcat(logtext, ", ");
 
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[4], a4);
+       }
 
-       case 6:
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx"
-                               , a3, a4, a5);
-               break;
-#endif /* TRACE_ARGS_NUM >= 6 */
+       if (md->paramcount >= 6) {
+               strcat(logtext, ", ");
+
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[5], a5);
+       }
+#endif
 
 #if TRACE_ARGS_NUM == 8
-       case 7:
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx"
-                               , a3, a4, a5);
-               sprintf(logtext + strlen(logtext), ", 0x%llx", a6);
-               break;
+       if (md->paramcount >= 7) {
+               strcat(logtext, ", ");
 
-       case 8:
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, 0x%llx"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx, 0x%llx"
-                               , a3, a4, a5);
-               sprintf(logtext + strlen(logtext), ", 0x%llx, 0x%llx", a6, a7);
-               break;
-#endif /* TRACE_ARGS_NUM == 8 */
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[6], a6);
+       }
 
-       default:
-#if TRACE_ARGS_NUM == 2
-               sprintf(logtext + strlen(logtext), "0x%llx, 0x%llx, ...(%d)", a0, a1, md->paramcount - 2);
-
-#elif TRACE_ARGS_NUM == 4
-               sprintf(logtext + strlen(logtext),
-                               "0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)",
-                               a0, a1, a2, a3, md->paramcount - 4);
-
-#elif TRACE_ARGS_NUM == 6
-               sprintf(logtext + strlen(logtext),
-                               "0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx, ...(%d)",
-                               a0, a1, a2, a3, a4, a5, md->paramcount - 6);
-
-#elif TRACE_ARGS_NUM == 8
-               sprintf(logtext + strlen(logtext),"0x%llx, 0x%llx, 0x%llx,"
-                               , a0, a1, a2);
-               sprintf(logtext + strlen(logtext)," 0x%llx, 0x%llx, 0x%llx,"
-                               , a3, a4, a5);
-               sprintf(logtext + strlen(logtext)," 0x%llx, 0x%llx, ...(%d)"
-                               , a6, a7, md->paramcount - 8);
+       if (md->paramcount >= 8) {
+               strcat(logtext, ", ");
+
+               logtext = builtin_print_argument(logtext, &logtextlen,
+                                                                                &md->paramtypes[7], a7);
+       }
 #endif
-               break;
 
-#else /* SIZEOF_VOID_P == 4 */
+       if (md->paramcount > 8) {
+               sprintf(logtext + strlen(logtext), ", ...(%d)",
+                               md->paramcount - TRACE_ARGS_NUM);
+       }
 
-       case 1:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx",
-                               a0);
-               break;
+       strcat(logtext, ")");
 
-       case 2:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx",
-                               a0, a1);
-               break;
+       log_text(logtext);
 
-       case 3:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx", a0, a1, a2);
-               break;
-
-       case 4:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx",
-                               a0, a1, a2, a3);
-               break;
-
-#if TRACE_ARGS_NUM >= 6
-       case 5:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
-                               a0, a1, a2, a3, a4);
-               break;
-
-       case 6:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
-                               a0, a1, a2, a3, a4, a5);
-               break;
-#endif /* TRACE_ARGS_NUM >= 6 */
-
-#if TRACE_ARGS_NUM == 8
-       case 7:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
-                               a0, a1, a2, a3, a4, a5, a6);
-               break;
-
-       case 8:
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",
-                               a0, a1, a2, a3, a4, a5, a6, a7);
-               break;
-#endif /* TRACE_ARGS_NUM == 8 */
-
-       default:
-#if TRACE_ARGS_NUM == 4
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
-                               a0, a1, a2, a3, md->paramcount - 4);
-
-#elif TRACE_ARGS_NUM == 6
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
-                               a0, a1, a2, a3, a4, a5, md->paramcount - 6);
-
-#elif TRACE_ARGS_NUM == 8
-               sprintf(logtext + strlen(logtext),
-                               "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, ...(%d)",
-                               a0, a1, a2, a3, a4, a5, a6, a7, md->paramcount - 8);
-#endif
-               break;
-#endif /* SIZEOF_VOID_P == 4 */
-       }
-
-       strcat(logtext, ")");
-
-       log_text(logtext);
-
-       /* release memory */
+       /* release memory */
 
        dump_release(dumpsize);
 
        methodindent++;
+
 }
 #endif
 #endif /* !defined(NDEBUG) */
 
 
-/* builtin_displaymethodstop ***************************************************
+/* builtin_verbosecall_exit ****************************************************
 
-   XXX
+   Print method exit for -verbose:call.
 
 *******************************************************************************/
 
 #if !defined(NDEBUG)
-void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
-{
-       methoddesc        *md;
-       char              *logtext;
-       s4                 logtextlen;
-       s4                 dumpsize;
-       s4                 i;
-       s4                 pos;
-       java_objectheader *o;
-       java_lang_String  *s;
-       classinfo         *c;
-       s4                 len;
-       utf               *u;
-       imm_union          imu;
+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;
 
@@ -1527,10 +1664,10 @@ void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                methodindent +
                strlen("finished: ") +
-               utf_strlen(m->class->name) +
+               utf_bytes(m->class->name) +
                strlen(".") +
-               utf_strlen(m->name) +
-               utf_strlen(m->descriptor) +
+               utf_bytes(m->name) +
+               utf_bytes(m->descriptor) +
                strlen(" SYNCHRONIZED") + strlen("(") + strlen(")");
 
        /* add maximal argument length */
@@ -1561,98 +1698,32 @@ void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
                logtext[pos++] = '\t';
 
        strcpy(logtext + pos, "finished: ");
-       utf_strcat_classname(logtext, m->class->name);
+       utf_cat_classname(logtext, m->class->name);
        strcat(logtext, ".");
-       utf_strcat(logtext, m->name);
-       utf_strcat(logtext, m->descriptor);
-
-       switch (md->returntype.type) {
-       case TYPE_INT:
-               sprintf(logtext + strlen(logtext), "->%d (0x%08x)", (s4) l, (s4) l);
-               break;
-
-       case TYPE_LNG:
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "->%lld (0x%016llx)", (s8) l, l);
-#else
-               sprintf(logtext + strlen(logtext), "->%ld (0x%016lx)", (s8) l, l);
-#endif
-               break;
-
-       case TYPE_ADR:
-               sprintf(logtext + strlen(logtext), "->%p", (void *) (ptrint) l);
-
-               /* check return argument for java.lang.Class or java.lang.String */
-
-               o = (java_objectheader *) (ptrint) l;
-
-               if (o != NULL) {
-                       if (o->vftbl->class == class_java_lang_String) {
-                               /* get java.lang.String object and the length of the
-                   string */
-
-                               s= (java_lang_String *) (ptrint) l;
-
-                               len = strlen(", String = \"") + javastring_strlen(s) +
-                                       strlen("\"");
-
-                               /* realloc memory for string length */
-
-                               DMREALLOC(logtext, char, logtextlen, logtextlen + len);
-
-                               /* convert to utf8 string and strcat it to the logtext */
-
-                               u = javastring_toutf(s, false);
-
-                               strcat(logtext, ", String = \"");
-                               utf_strcat(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 *) (ptrint) l;
-
-                                       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_strlen(u) + strlen("\"");
-
-                               /* realloc memory for string length */
-
-                               DMREALLOC(logtext, char, logtextlen, logtextlen + len);
-
-                               /* strcat to the logtext */
-
-                               strcat(logtext, ", Class = \"");
-                               utf_strcat(logtext, u);
-                               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;
                }
-               break;
 
-       case TYPE_FLT:
-               imu.f = f;
-               sprintf(logtext + strlen(logtext), "->%.8f (0x%08x)", f, imu.i);
-               break;
-
-       case TYPE_DBL:
-               imu.d = d;
-#if SIZEOF_VOID_P == 4
-               sprintf(logtext + strlen(logtext), "->%.16g (0x%016llx)", d, imu.l);
-#else
-               sprintf(logtext + strlen(logtext), "->%.16g (0x%016lx)", d, imu.l);
-#endif
-               break;
+               logtext =
+                       builtin_print_argument(logtext, &logtextlen, &md->returntype, val.l);
        }
 
        log_text(logtext);
@@ -1660,158 +1731,22 @@ void builtin_displaymethodstop(methodinfo *m, s8 l, double d, float f)
        /* release memory */
 
        dump_release(dumpsize);
-}
-#endif /* !defined(NDEBUG) */
-
-
-/****************************************************************************
-                        SYNCHRONIZATION FUNCTIONS
-*****************************************************************************/
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-/*
- * Lock the mutex of an object.
- */
-void internal_lock_mutex_for_object(java_objectheader *object)
-{
-       mutexHashEntry *entry;
-       int hashValue;
-
-       assert(object != 0);
-
-       hashValue = MUTEX_HASH_VALUE(object);
-       entry = &mutexHashTable[hashValue];
-
-       if (entry->object != 0) {
-               if (entry->mutex.count == 0 && entry->conditionCount == 0) {
-                       entry->object = 0;
-                       entry->mutex.holder = 0;
-                       entry->mutex.count = 0;
-                       entry->mutex.muxWaiters = 0;
-
-               } else {
-                       while (entry->next != 0 && entry->object != object)
-                               entry = entry->next;
-
-                       if (entry->object != object) {
-                               entry->next = firstFreeOverflowEntry;
-                               firstFreeOverflowEntry = firstFreeOverflowEntry->next;
-
-                               entry = entry->next;
-                               entry->object = 0;
-                               entry->next = 0;
-                               assert(entry->conditionCount == 0);
-                       }
-               }
-
-       } else {
-               entry->mutex.holder = 0;
-               entry->mutex.count = 0;
-               entry->mutex.muxWaiters = 0;
-       }
-
-       if (entry->object == 0)
-               entry->object = object;
-       
-       internal_lock_mutex(&entry->mutex);
-}
-#endif
-
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-/*
- * Unlocks the mutex of an object.
- */
-void internal_unlock_mutex_for_object (java_objectheader *object)
-{
-       int hashValue;
-       mutexHashEntry *entry;
-
-       hashValue = MUTEX_HASH_VALUE(object);
-       entry = &mutexHashTable[hashValue];
-
-       if (entry->object == object) {
-               internal_unlock_mutex(&entry->mutex);
-
-       } else {
-               while (entry->next != 0 && entry->next->object != object)
-                       entry = entry->next;
-
-               assert(entry->next != 0);
-
-               internal_unlock_mutex(&entry->next->mutex);
-
-               if (entry->next->mutex.count == 0 && entry->conditionCount == 0) {
-                       mutexHashEntry *unlinked = entry->next;
-
-                       entry->next = unlinked->next;
-                       unlinked->next = firstFreeOverflowEntry;
-                       firstFreeOverflowEntry = unlinked;
-               }
-       }
-}
-#endif
 
-
-#if defined(USE_THREADS)
-void builtin_monitorenter(java_objectheader *o)
-{
-#if !defined(NATIVE_THREADS)
-       int hashValue;
-
-       ++blockInts;
-
-       hashValue = MUTEX_HASH_VALUE(o);
-       if (mutexHashTable[hashValue].object == o 
-               && mutexHashTable[hashValue].mutex.holder == currentThread)
-               ++mutexHashTable[hashValue].mutex.count;
-       else
-               internal_lock_mutex_for_object(o);
-
-       --blockInts;
-#else
-       monitorEnter((threadobject *) THREADOBJECT, o);
-#endif
-}
-#endif
-
-
-#if defined(USE_THREADS)
-/*
- * Locks the class object - needed for static synchronized methods.
- */
-void builtin_staticmonitorenter(classinfo *c)
-{
-       builtin_monitorenter(&c->object.header);
 }
-#endif
+#endif /* !defined(NDEBUG) */
 
 
-#if defined(USE_THREADS)
-void builtin_monitorexit(java_objectheader *o)
+#if defined(ENABLE_CYCLES_STATS)
+void builtin_print_cycles_stats(FILE *file)
 {
-#if !defined(NATIVE_THREADS)
-       int hashValue;
+       fprintf(file,"builtin cylce count statistics:\n");
 
-       ++blockInts;
+       CYCLES_STATS_PRINT_OVERHEAD(builtin_overhead,file);
+       CYCLES_STATS_PRINT(builtin_new         ,file);
 
-       hashValue = MUTEX_HASH_VALUE(o);
-       if (mutexHashTable[hashValue].object == o) {
-               if (mutexHashTable[hashValue].mutex.count == 1
-                       && mutexHashTable[hashValue].mutex.muxWaiters != 0)
-                       internal_unlock_mutex_for_object(o);
-               else
-                       --mutexHashTable[hashValue].mutex.count;
-
-       } else
-               internal_unlock_mutex_for_object(o);
-
-       --blockInts;
-#else
-       monitorExit((threadobject *) THREADOBJECT, o);
-#endif
+       fprintf(file,"\n");
 }
-#endif
+#endif /* defined(ENABLE_CYCLES_STATS) */
 
 
 /*****************************************************************************
@@ -1827,7 +1762,7 @@ void builtin_monitorexit(java_objectheader *o)
 
 ******************************************************************************/
 
-#if !SUPPORT_DIVISION
+#if !SUPPORT_DIVISION || defined(DISABLE_GC)
 s4 builtin_idiv(s4 a, s4 b)
 {
        s4 c;
@@ -1845,7 +1780,7 @@ s4 builtin_irem(s4 a, s4 b)
 
        return c;
 }
-#endif /* !SUPPORT_DIVISION */
+#endif /* !SUPPORT_DIVISION || defined(DISABLE_GC) */
 
 
 /* functions for long arithmetics **********************************************
@@ -1913,7 +1848,7 @@ s8 builtin_lmul(s8 a, s8 b)
 #endif /* !(SUPPORT_LONG && SUPPORT_LONG_MUL) */
 
 
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
+#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) || defined (DISABLE_GC)
 s8 builtin_ldiv(s8 a, s8 b)
 {
        s8 c;
@@ -2193,17 +2128,26 @@ float builtin_fneg(float a)
 #endif /* !SUPPORT_FLOAT */
 
 
-#if !SUPPORT_FLOAT || defined(ENABLE_INTRP)
+#if !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP)
 s4 builtin_fcmpl(float a, float b)
 {
-       if (isnanf(a)) return -1;
-       if (isnanf(b)) return -1;
+       if (isnanf(a))
+               return -1;
+
+       if (isnanf(b))
+               return -1;
+
        if (!finitef(a) || !finitef(b)) {
                a = finitef(a) ? 0 : copysignf(1.0,     a);
                b = finitef(b) ? 0 : copysignf(1.0, b);
        }
-       if (a > b) return 1;
-       if (a == b) return 0;
+
+       if (a > b)
+               return 1;
+
+       if (a == b)
+               return 0;
+
        return -1;
 }
 
@@ -2220,7 +2164,7 @@ s4 builtin_fcmpg(float a, float b)
        if (a == b) return 0;
        return -1;
 }
-#endif /* !SUPPORT_FLOAT || defined(ENABLE_INTRP) */
+#endif /* !SUPPORT_FLOAT || !SUPPORT_FLOAT_CMP || defined(ENABLE_INTRP) */
 
 
 float builtin_frem(float a, float b)
@@ -2372,34 +2316,52 @@ double builtin_dneg(double a)
 #endif /* !SUPPORT_DOUBLE */
 
 
-#if !SUPPORT_DOUBLE || defined(ENABLE_INTRP)
+#if !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP)
 s4 builtin_dcmpl(double a, double b)
 {
-       if (isnan(a)) return -1;
-       if (isnan(b)) return -1;
+       if (isnan(a))
+               return -1;
+
+       if (isnan(b))
+               return -1;
+
        if (!finite(a) || !finite(b)) {
                a = finite(a) ? 0 : copysign(1.0, a);
                b = finite(b) ? 0 : copysign(1.0, b);
        }
-       if (a > b) return 1;
-       if (a == b) return 0;
+
+       if (a > b)
+               return 1;
+
+       if (a == b)
+               return 0;
+
        return -1;
 }
 
 
 s4 builtin_dcmpg(double a, double b)
 {
-       if (isnan(a)) return 1;
-       if (isnan(b)) return 1;
+       if (isnan(a))
+               return 1;
+
+       if (isnan(b))
+               return 1;
+
        if (!finite(a) || !finite(b)) {
                a = finite(a) ? 0 : copysign(1.0, a);
                b = finite(b) ? 0 : copysign(1.0, b);
        }
-       if (a > b) return 1;
-       if (a == b) return 0;
+
+       if (a > b)
+               return 1;
+
+       if (a == b)
+               return 0;
+
        return -1;
 }
-#endif /* !SUPPORT_DOUBLE || defined(ENABLE_INTRP) */
+#endif /* !SUPPORT_DOUBLE || !SUPPORT_DOUBLE_CMP || defined(ENABLE_INTRP) */
 
 
 double builtin_drem(double a, double b)
@@ -2478,7 +2440,7 @@ double builtin_l2d(s8 a)
 #endif /* !(SUPPORT_LONG && SUPPORT_DOUBLE && SUPPORT_L2D) */
 
 
-#if !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP)
+#if !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
 s4 builtin_f2i(float a) 
 {
        s4 i;
@@ -2503,10 +2465,10 @@ s4 builtin_f2i(float a)
                return 2147483647;
                return (-2147483648); */
 }
-#endif /* !(SUPPORT_FLOAT && SUPPORT_F2I) || defined(ENABLE_INTRP) */
+#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;
@@ -2534,7 +2496,7 @@ s8 builtin_f2l(float a)
 #endif /* !(SUPPORT_FLOAT && SUPPORT_LONG && SUPPORT_F2L) */
 
 
-#if !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP)
+#if !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) || defined(DISABLE_GC)
 s4 builtin_d2i(double a) 
 { 
        double d;
@@ -2553,10 +2515,10 @@ s4 builtin_d2i(double a)
                return 2147483647;
        return (-2147483647-1);
 }
-#endif /* !(SUPPORT_DOUBLE && SUPPORT_D2I) || defined(ENABLE_INTRP) */
+#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;
@@ -2604,36 +2566,205 @@ float builtin_d2f(double a)
 #endif /* !(SUPPORT_FLOAT && SUPPORT_DOUBLE) */
 
 
-/* builtin_clone_array *********************************************************
+/* builtin_arraycopy ***********************************************************
 
-   Wrapper function for cloning arrays.
+   Builtin for java.lang.System.arraycopy.
+
+   ATTENTION: This builtin function returns a boolean value to signal
+   the ICMD_BUILTIN if there was an exception.
 
 *******************************************************************************/
 
-java_arrayheader *builtin_clone_array(void *env, java_arrayheader *o)
+bool builtin_arraycopy(java_handle_t *src, s4 srcStart,
+                                          java_handle_t *dest, s4 destStart, s4 len)
 {
-       java_arrayheader    *ah;
-       java_lang_Cloneable *c;
+       arraydescriptor *sdesc;
+       arraydescriptor *ddesc;
+       s4               i;
+
+       if ((src == NULL) || (dest == NULL)) { 
+               exceptions_throw_nullpointerexception();
+               return false;
+       }
+
+       sdesc = LLNI_vftbl_direct(src)->arraydesc;
+       ddesc = LLNI_vftbl_direct(dest)->arraydesc;
 
-       c = (java_lang_Cloneable *) o;
+       if (!sdesc || !ddesc || (sdesc->arraytype != ddesc->arraytype)) {
+               exceptions_throw_arraystoreexception();
+               return false;
+       }
 
-       ah = (java_arrayheader *) Java_java_lang_VMObject_clone(0, 0, c);
+       /* we try to throw exception with the same message as SUN does */
 
-       return ah;
+       if ((len < 0) || (srcStart < 0) || (destStart < 0) ||
+               (srcStart  + len < 0) || (srcStart  + len > LLNI_array_size(src)) ||
+               (destStart + len < 0) || (destStart + len > LLNI_array_size(dest))) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return false;
+       }
+
+       if (sdesc->componentvftbl == ddesc->componentvftbl) {
+               /* We copy primitive values or references of exactly the same type */
+
+               s4 dataoffset = sdesc->dataoffset;
+               s4 componentsize = sdesc->componentsize;
+
+               memmove(((u1 *) dest) + dataoffset + componentsize * destStart,
+                               ((u1 *) src)  + dataoffset + componentsize * srcStart,
+                               (size_t) len * componentsize);
+       }
+       else {
+               /* We copy references of different type */
+
+               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];
+
+                               if (!builtin_canstore(oad, o))
+                                       return false;
+
+                               oad->data[destStart + i] = o;
+                       }
+               }
+               else {
+                       /* XXX this does not completely obey the specification!
+                          If an exception is thrown only the elements above the
+                          current index have been copied. The specification
+                          requires that only the elements *below* the current
+                          index have been copied before the throw. */
+
+                       for (i = len - 1; i >= 0; i--) {
+                               java_handle_t *o = oas->data[srcStart + i];
+
+                               if (!builtin_canstore(oad, o))
+                                       return false;
+
+                               oad->data[destStart + i] = o;
+                       }
+               }
+       }
+
+       return true;
 }
 
 
-/* builtin_asm_get_exceptionptrptr *********************************************
+/* builtin_nanotime ************************************************************
 
-   this is a wrapper for calls from asmpart
+   Return the current time in nanoseconds.
 
 *******************************************************************************/
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-java_objectheader **builtin_asm_get_exceptionptrptr(void)
+s8 builtin_nanotime(void)
 {
-       return builtin_get_exceptionptrptr();
+       struct timeval tv;
+       s8             usecs;
+
+       if (gettimeofday(&tv, NULL) == -1)
+               vm_abort("gettimeofday failed: %s", strerror(errno));
+
+       usecs = (s8) tv.tv_sec * (1000 * 1000) + (s8) tv.tv_usec;
+
+       return usecs * 1000;
 }
+
+
+/* builtin_currenttimemillis ***************************************************
+
+   Return the current time in milliseconds.
+
+*******************************************************************************/
+
+s8 builtin_currenttimemillis(void)
+{
+       s8 msecs;
+
+       msecs = builtin_nanotime() / 1000 / 1000;
+
+       return msecs;
+}
+
+
+/* builtin_clone ***************************************************************
+
+   Function for cloning objects or arrays.
+
+*******************************************************************************/
+
+java_handle_t *builtin_clone(void *env, java_handle_t *o)
+{
+       arraydescriptor *ad;
+       java_handle_t   *ah;
+       u4               size;
+       classinfo       *c;
+       java_handle_t   *co;                /* cloned object header               */
+
+       /* get the array descriptor */
+
+       ad = o->vftbl->arraydesc;
+
+       /* we are cloning an array */
+
+       if (ad != NULL) {
+               ah = (java_handle_t *) o;
+
+               size = ad->dataoffset + ad->componentsize * LLNI_array_size(ah);
+        
+               co = heap_allocate(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL);
+
+               if (co == NULL)
+                       return NULL;
+
+               MCOPY(co, o, u1, size);
+
+#if defined(ENABLE_GC_CACAO)
+               heap_init_objectheader(co, size);
+#endif
+
+#if defined(ENABLE_THREADS)
+               lock_init_object_lock(co);
+#endif
+
+               return co;
+       }
+    
+    /* we are cloning a non-array */
+
+    if (!builtin_instanceof(o, class_java_lang_Cloneable)) {
+        exceptions_throw_clonenotsupportedexception();
+        return NULL;
+    }
+
+       /* get the class of the object */
+
+    c = o->vftbl->class;
+
+       /* create new object */
+
+    co = builtin_new(c);
+
+    if (co == NULL)
+        return NULL;
+
+    MCOPY(co, o, u1, c->instancesize);
+
+#if defined(ENABLE_GC_CACAO)
+       heap_init_objectheader(co, c->instancesize);
+#endif
+
+#if defined(ENABLE_THREADS)
+       lock_init_object_lock(co);
+#endif
+
+    return co;
+}
+
+#if defined(ENABLE_VMLOG)
+#define NDEBUG
+#include <vmlog_cacao.c>
 #endif