* src/vm/global.h: Made 'lockword' member of java_object_t a plain
[cacao.git] / src / vm / jit / builtin.cpp
index 1b9ccb99c0eb23d4fc18d6df2d62d6d88b848c41..146e64dffdb87a8fbbc3820076088d0d08cb02ab 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/builtin.cpp - functions for unsupported operations
 
 /* src/vm/jit/builtin.cpp - functions for unsupported operations
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008
+   Copyright (C) 1996-2005, 2006, 2007, 2008, 2010
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
@@ -48,7 +48,7 @@
 #endif
 
 #include "mm/gc.hpp"
 #endif
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 
 #include "native/llni.h"
 
@@ -56,7 +56,7 @@
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/util.h"
 
 #include "vm/array.hpp"
 #include "toolbox/util.h"
 
 #include "vm/array.hpp"
@@ -67,7 +67,7 @@
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/initialize.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/initialize.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
@@ -75,6 +75,7 @@
 #include "vm/string.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/string.hpp"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/emit-common.hpp"
 #include "vm/jit/stubs.hpp"
 #include "vm/jit/trace.hpp"
 
 #include "vm/jit/stubs.hpp"
 #include "vm/jit/trace.hpp"
 
@@ -441,53 +442,6 @@ bool builtin_checkcast(java_handle_t *o, classinfo *c)
 }
 
 
 }
 
 
-/* builtin_descriptorscompatible ***********************************************
-
-   Checks if two array type descriptors are assignment compatible.
-
-   RETURN VALUE:
-      1......target = desc is possible
-      0......otherwise
-                       
-*******************************************************************************/
-
-static bool builtin_descriptorscompatible(arraydescriptor *desc, arraydescriptor *target)
-{
-       if (desc == target)
-               return 1;
-
-       if (desc->arraytype != target->arraytype)
-               return 0;
-
-       if (desc->arraytype != ARRAYTYPE_OBJECT)
-               return 1;
-       
-       /* {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)*/
-
-               if ((desc->elementvftbl->baseval < 0) &&
-                       (target->elementvftbl->baseval == 1))
-                       return 1;
-
-               return class_isanysubclass(desc->elementvftbl->clazz,
-                                                                  target->elementvftbl->clazz);
-       }
-
-       if (desc->dimension < target->dimension)
-               return 0;
-
-       /* {desc has higher dimension than target} */
-
-       return class_isanysubclass(pseudo_class_Arraystub,
-                                                          target->elementvftbl->clazz);
-}
-
-
 /* builtin_arraycheckcast ******************************************************
 
    Checks if an object is really a subtype of the requested array
 /* builtin_arraycheckcast ******************************************************
 
    Checks if an object is really a subtype of the requested array
@@ -515,7 +469,7 @@ bool builtin_fast_arraycheckcast(java_object_t *o, classinfo *targetclass)
        if (desc == NULL)
                return 0;
  
        if (desc == NULL)
                return 0;
  
-       return builtin_descriptorscompatible(desc, targetclass->vftbl->arraydesc);
+       return class_is_arraycompatible(desc, targetclass->vftbl->arraydesc);
 }
 
 
 }
 
 
@@ -628,7 +582,7 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
        LLNI_CRITICAL_START;
 
 
        LLNI_CRITICAL_START;
 
-       result = builtin_fast_canstore(LLNI_DIRECT(oa), LLNI_UNWRAP(o));
+       result = builtin_fast_canstore((java_objectarray_t*) LLNI_DIRECT(oa), LLNI_UNWRAP(o));
 
        LLNI_CRITICAL_END;
 
 
        LLNI_CRITICAL_END;
 
@@ -640,6 +594,28 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
        return result;
 }
 
        return result;
 }
 
+#if USES_NEW_SUBTYPE
+/* fast_subtype_check **********************************************************
+
+   Checks if s is a subtype of t, using both the restricted subtype relation
+   and the overflow array (see Cliff Click and John Rose: Fast subtype checking
+   in the Hotspot JVM.)
+
+   RETURN VALUE:
+      1......s is a subtype of t.
+      0......otherwise
+
+*******************************************************************************/
+
+bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
+{
+   if (s->subtype_display[t->subtype_depth] == t)
+       return true;
+   if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
+       return false;
+   return s->subtype_depth >= t->subtype_depth && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t;
+}
+#endif
 
 /* builtin_fast_canstore *******************************************************
 
 
 /* builtin_fast_canstore *******************************************************
 
@@ -653,15 +629,6 @@ bool builtin_canstore(java_handle_objectarray_t *oa, java_handle_t *o)
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-bool fast_subtype_check(struct _vftbl *s, struct _vftbl *t)
-{
-       if (s->subtype_display[t->subtype_depth] == t)
-               return true;
-       if (t->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]))
-               return false;
-       return s->subtype_depth >= t->subtype_depth && s->subtype_overflow[t->subtype_depth - DISPLAY_SIZE] == t;
-}
-
 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
 bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
 {
        arraydescriptor *desc;
@@ -669,7 +636,6 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
        vftbl_t         *componentvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        vftbl_t         *componentvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
-       uint32_t         diffval;
        bool             result;
 
        if (o == NULL)
        bool             result;
 
        if (o == NULL)
@@ -694,6 +660,8 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
                if (valuevftbl == componentvftbl)
                        return 1;
 
                if (valuevftbl == componentvftbl)
                        return 1;
 
+               LOCK_CLASSRENUMBER_LOCK;
+
                baseval = componentvftbl->baseval;
 
                if (baseval <= 0) {
                baseval = componentvftbl->baseval;
 
                if (baseval <= 0) {
@@ -703,8 +671,15 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
                                          (valuevftbl->interfacetable[baseval] != NULL));
                }
                else {
                                          (valuevftbl->interfacetable[baseval] != NULL));
                }
                else {
+#if USES_NEW_SUBTYPE
                        result = fast_subtype_check(valuevftbl, componentvftbl);
                        result = fast_subtype_check(valuevftbl, componentvftbl);
+#else
+                       uint32_t diffval = valuevftbl->baseval - componentvftbl->baseval;
+                       result = diffval <= (uint32_t) componentvftbl->diffval;
+#endif
                }
                }
+
+               UNLOCK_CLASSRENUMBER_LOCK;
        }
        else if (valuedesc == NULL) {
                /* {oa has dimension > 1} */
        }
        else if (valuedesc == NULL) {
                /* {oa has dimension > 1} */
@@ -717,7 +692,7 @@ bool builtin_fast_canstore(java_objectarray_t *oa, java_object_t *o)
        else {
                /* {o is an array} */
 
        else {
                /* {o is an array} */
 
-               result = builtin_descriptorscompatible(valuedesc, componentvftbl->arraydesc);
+               result = class_is_arraycompatible(valuedesc, componentvftbl->arraydesc);
        }
 
        /* return result */
        }
 
        /* return result */
@@ -733,7 +708,6 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
        vftbl_t         *elementvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
        vftbl_t         *elementvftbl;
        vftbl_t         *valuevftbl;
        int32_t          baseval;
-       uint32_t         diffval;
        bool             result;
        
        if (o == NULL)
        bool             result;
        
        if (o == NULL)
@@ -756,6 +730,8 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
        if (valuevftbl == elementvftbl)
                return 1;
 
+       LOCK_CLASSRENUMBER_LOCK;
+
        baseval = elementvftbl->baseval;
 
        if (baseval <= 0) {
        baseval = elementvftbl->baseval;
 
        if (baseval <= 0) {
@@ -764,9 +740,16 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
                                  (valuevftbl->interfacetable[baseval] != NULL));
        }
        else {
                                  (valuevftbl->interfacetable[baseval] != NULL));
        }
        else {
+#if USES_NEW_SUBTYPE
                result = fast_subtype_check(valuevftbl, elementvftbl);
                result = fast_subtype_check(valuevftbl, elementvftbl);
+#else
+               uint32_t diffval = valuevftbl->baseval - elementvftbl->baseval;
+               result = diffval <= (uint32_t) elementvftbl->diffval;
+#endif
        }
 
        }
 
+       UNLOCK_CLASSRENUMBER_LOCK;
+
        return result;
 }
 
        return result;
 }
 
@@ -775,10 +758,9 @@ bool builtin_fast_canstore_onedim(java_objectarray_t *a, java_object_t *o)
  * one-dimensional array of a class type */
 bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
  * one-dimensional array of a class type */
 bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
 {
-       vftbl_t  *elementvftbl;
-       vftbl_t  *valuevftbl;
-       uint32_t  diffval;
-       bool      result;
+       vftbl_t *elementvftbl;
+       vftbl_t *valuevftbl;
+       bool     result;
        
        if (o == NULL)
                return 1;
        
        if (o == NULL)
                return 1;
@@ -800,7 +782,16 @@ bool builtin_fast_canstore_onedim_class(java_objectarray_t *a, java_object_t *o)
        if (valuevftbl == elementvftbl)
                return 1;
 
        if (valuevftbl == elementvftbl)
                return 1;
 
+       LOCK_CLASSRENUMBER_LOCK;
+
+#if USES_NEW_SUBTYPE
        result = fast_subtype_check(valuevftbl, elementvftbl);
        result = fast_subtype_check(valuevftbl, elementvftbl);
+#else
+       uint32_t diffval = valuevftbl->baseval - elementvftbl->baseval;
+       result = diffval <= (uint32_t) elementvftbl->diffval;
+#endif
+
+       UNLOCK_CLASSRENUMBER_LOCK;
 
        return result;
 }
 
        return result;
 }
@@ -872,7 +863,7 @@ java_handle_t *builtin_new(classinfo *c)
        LLNI_vftbl_direct(o) = c->vftbl;
 
 #if defined(ENABLE_THREADS)
        LLNI_vftbl_direct(o) = c->vftbl;
 
 #if defined(ENABLE_THREADS)
-       LLNI_DIRECT(o)->lockword.init();
+       Lockword(LLNI_DIRECT(o)->lockword).init();
 #endif
 
        CYCLES_STATS_GET(cycles_end);
 #endif
 
        CYCLES_STATS_GET(cycles_end);
@@ -954,7 +945,7 @@ java_handle_t *builtin_tlh_new(classinfo *c)
        LLNI_vftbl_direct(o) = c->vftbl;
 
 # if defined(ENABLE_THREADS)
        LLNI_vftbl_direct(o) = c->vftbl;
 
 # if defined(ENABLE_THREADS)
-       LLNI_DIRECT(o)->lockword.init();
+       Lockword(LLNI_DIRECT(o)->lockword).init();
 # endif
 
        CYCLES_STATS_GET(cycles_end);
 # endif
 
        CYCLES_STATS_GET(cycles_end);
@@ -1033,7 +1024,7 @@ java_object_t *builtin_fast_new(classinfo *c)
        o->vftbl = c->vftbl;
 
 #if defined(ENABLE_THREADS)
        o->vftbl = c->vftbl;
 
 #if defined(ENABLE_THREADS)
-       LLNI_DIRECT(o)->lockword.init();
+       Lockword(LLNI_DIRECT(o)->lockword).init();
 #endif
 
        CYCLES_STATS_GET(cycles_end);
 #endif
 
        CYCLES_STATS_GET(cycles_end);
@@ -1046,7 +1037,7 @@ java_object_t *builtin_fast_new(classinfo *c)
 }
 
 
 }
 
 
-/* builtin_newarray ************************************************************
+/* builtin_java_newarray *******************************************************
 
    Creates an array with the given vftbl on the heap. This function
    takes as class argument an array class.
 
    Creates an array with the given vftbl on the heap. This function
    takes as class argument an array class.
@@ -1054,111 +1045,27 @@ java_object_t *builtin_fast_new(classinfo *c)
    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.
+   NOTE: This is a SLOW builtin and can be called from JIT code only.
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-java_handle_t *builtin_newarray(int32_t size, classinfo *arrayclass)
+java_handle_array_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
 {
 {
-       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);
 
 #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;
-       componentsize = desc->componentsize;
+       classinfo* arrayclass = LLNI_classinfo_unwrap(arrayclazz);
 
 
-       if (size < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       actualsize = dataoffset + size * componentsize;
-
-       /* check for overflow */
-
-       if (((u4) actualsize) < ((u4) size)) {
-               exceptions_throw_outofmemoryerror();
-               return NULL;
-       }
-
-       a = (java_handle_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
-
-       if (a == NULL)
-               return NULL;
-
-#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
-       /* XXX this is only a dirty hack to make Boehm work with handles */
-
-       a = LLNI_WRAP((java_object_t *) a);
-#endif
-
-       LLNI_vftbl_direct(a) = arrayclass->vftbl;
-
-#if defined(ENABLE_THREADS)
-       LLNI_DIRECT(a)->lockword.init();
-#endif
-
-       LLNI_array_size(a) = size;
+       // Allocate a new array with given size and class on the heap
+       Array a(size, arrayclass);
 
        RT_TIMING_GET_TIME(time_end);
        RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
 
        RT_TIMING_GET_TIME(time_end);
        RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_NEW_ARRAY);
 
-       return a;
-}
-
-
-/* builtin_java_newarray *******************************************************
-
-   NOTE: This is a SLOW builtin and can be called from JIT code only.
-
-*******************************************************************************/
-
-java_handle_t *builtin_java_newarray(int32_t size, java_handle_t *arrayclazz)
-{
-       return builtin_newarray(size, LLNI_classinfo_unwrap(arrayclazz));
-}
-
-
-/* builtin_anewarray ***********************************************************
-
-   Creates an array of references to the given class type on the heap.
-
-   RETURN VALUE:
-      pointer to the array or NULL if no memory is
-      available
-
-   NOTE: This builtin can be called from NATIVE code only.
-
-*******************************************************************************/
-
-java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentclass)
-{
-       classinfo *arrayclass;
-       
-       /* is class loaded */
-
-       assert(componentclass->state & CLASS_LOADED);
-
-       /* is class linked */
-
-       if (!(componentclass->state & CLASS_LINKED))
-               if (!link_class(componentclass))
-                       return NULL;
-
-       arrayclass = class_array_of(componentclass, true);
-
-       if (!arrayclass)
-               return NULL;
-
-       return (java_handle_objectarray_t *) builtin_newarray(size, arrayclass);
+       return a.get_handle();
 }
 
 
 }
 
 
@@ -1173,21 +1080,21 @@ java_handle_objectarray_t *builtin_anewarray(int32_t size, classinfo *componentc
 
 *******************************************************************************/
 
 
 *******************************************************************************/
 
-#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); \
+#define BUILTIN_NEWARRAY_TYPE(type, name)                          \
+java_handle_##type##array_t *builtin_newarray_##type(int32_t size) \
+{                                                                  \
+       name##Array a(size);                                           \
+       return a.get_handle();                                         \
 }
 
 }
 
-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_NEWARRAY_TYPE(boolean, Boolean)
+BUILTIN_NEWARRAY_TYPE(byte,    Byte)
+BUILTIN_NEWARRAY_TYPE(char,    Char)
+BUILTIN_NEWARRAY_TYPE(short,   Short)
+BUILTIN_NEWARRAY_TYPE(int,     Int)
+BUILTIN_NEWARRAY_TYPE(long,    Long)
+BUILTIN_NEWARRAY_TYPE(float,   Float)
+BUILTIN_NEWARRAY_TYPE(double,  Double)
 
 
 /* builtin_multianewarray_intern ***********************************************
 
 
 /* builtin_multianewarray_intern ***********************************************
@@ -1205,38 +1112,37 @@ BUILTIN_NEWARRAY_TYPE(double,  ARRAYTYPE_DOUBLE)
 
 ******************************************************************************/
 
 
 ******************************************************************************/
 
-static java_handle_t *builtin_multianewarray_intern(int n,
+static java_handle_array_t *builtin_multianewarray_intern(int n,
                                                                                                        classinfo *arrayclass,
                                                                                                        long *dims)
 {
                                                                                                        classinfo *arrayclass,
                                                                                                        long *dims)
 {
-       s4             size;
-       java_handle_t *a;
-       classinfo     *componentclass;
-       s4             i;
+       int32_t i;
 
        /* create this dimension */
 
 
        /* create this dimension */
 
-       size = (s4) dims[0];
-       a = builtin_newarray(size, arrayclass);
+       int32_t size = (int32_t) dims[0];
+       Array a(size, arrayclass);
 
 
-       if (!a)
+       if (a.is_null())
                return NULL;
 
        /* if this is the last dimension return */
 
        if (!--n)
                return NULL;
 
        /* if this is the last dimension return */
 
        if (!--n)
-               return a;
+               return a.get_handle();
 
        /* get the class of the components to create */
 
 
        /* get the class of the components to create */
 
-       componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
+       classinfo* componentclass = arrayclass->vftbl->arraydesc->componentvftbl->clazz;
 
        /* The verifier guarantees that the dimension count is in the range. */
 
        /* create the component arrays */
 
 
        /* The verifier guarantees that the dimension count is in the range. */
 
        /* create the component arrays */
 
+       ObjectArray oa(a.get_handle());
+
        for (i = 0; i < size; i++) {
        for (i = 0; i < size; i++) {
-               java_handle_t *ea =
+               java_handle_array_t *ea =
 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
                        /* we save an s4 to a s8 slot, 8-byte aligned */
 
 #if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
                        /* we save an s4 to a s8 slot, 8-byte aligned */
 
@@ -1248,10 +1154,10 @@ static java_handle_t *builtin_multianewarray_intern(int n,
                if (!ea)
                        return NULL;
 
                if (!ea)
                        return NULL;
 
-               array_objectarray_element_set((java_handle_objectarray_t *) a, i, ea);
+               oa.set_element(i, (java_handle_t*) ea);
        }
 
        }
 
-       return a;
+       return a.get_handle();
 }
 
 
 }
 
 
@@ -2096,6 +2002,9 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
                return;
        }
 
                return;
        }
 
+       Array sa(src);
+       Array da(dest);
+
        sdesc = LLNI_vftbl_direct(src)->arraydesc;
        ddesc = LLNI_vftbl_direct(dest)->arraydesc;
 
        sdesc = LLNI_vftbl_direct(src)->arraydesc;
        ddesc = LLNI_vftbl_direct(dest)->arraydesc;
 
@@ -2111,8 +2020,8 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
        }
 
        // Check if ranges are valid.
        }
 
        // 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))) {
+       if ((((uint32_t) srcStart  + (uint32_t) len) > (uint32_t) sa.get_length()) ||
+               (((uint32_t) destStart + (uint32_t) len) > (uint32_t) da.get_length())) {
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
                exceptions_throw_arrayindexoutofboundsexception();
                return;
        }
@@ -2139,19 +2048,17 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
        else {
                /* We copy references of different type */
 
        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;
+               ObjectArray oas((java_handle_objectarray_t*) src);
+               ObjectArray oad((java_handle_objectarray_t*) dest);
  
                if (destStart <= srcStart) {
                        for (i = 0; i < len; i++) {
  
                if (destStart <= srcStart) {
                        for (i = 0; i < len; i++) {
-                               java_handle_t *o;
+                               java_handle_t* o = oas.get_element(srcStart + i);
 
 
-                               o = array_objectarray_element_get(oas, srcStart + i);
-
-                               if (!builtin_canstore(oad, o))
+                               if (!builtin_canstore(oad.get_handle(), o))
                                        return;
 
                                        return;
 
-                               array_objectarray_element_set(oad, destStart + i, o);
+                               oad.set_element(destStart + i, o);
                        }
                }
                else {
                        }
                }
                else {
@@ -2162,14 +2069,12 @@ void builtin_arraycopy(java_handle_t *src, s4 srcStart,
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
                           index have been copied before the throw. */
 
                        for (i = len - 1; i >= 0; i--) {
-                               java_handle_t *o;
-
-                               o = array_objectarray_element_get(oas, srcStart + i);
+                               java_handle_t* o = oas.get_element(srcStart + i);
 
 
-                               if (!builtin_canstore(oad, o))
+                               if (!builtin_canstore(oad.get_handle(), o))
                                        return;
 
                                        return;
 
-                               array_objectarray_element_set(oad, destStart + i, o);
+                               oad.set_element(destStart + i, o);
                        }
                }
        }
                        }
                }
        }
@@ -2234,7 +2139,9 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
        /* we are cloning an array */
 
        if (ad != NULL) {
        /* we are cloning an array */
 
        if (ad != NULL) {
-               size = ad->dataoffset + ad->componentsize * LLNI_array_size(o);
+               Array a(o);
+
+               size = ad->dataoffset + ad->componentsize * a.get_length();
         
                co = (java_handle_t*) heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
         
                co = (java_handle_t*) heap_alloc(size, (ad->arraytype == ARRAYTYPE_OBJECT), NULL, true);
 
@@ -2256,7 +2163,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
 #endif
 
 #if defined(ENABLE_THREADS)
 #endif
 
 #if defined(ENABLE_THREADS)
-               LLNI_DIRECT(co)->lockword.init();
+               Lockword(LLNI_DIRECT(co)->lockword).init();
 #endif
 
                LLNI_CRITICAL_END;
 #endif
 
                LLNI_CRITICAL_END;
@@ -2291,7 +2198,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o)
 #endif
 
 #if defined(ENABLE_THREADS)
 #endif
 
 #if defined(ENABLE_THREADS)
-       LLNI_DIRECT(co)->lockword.init();
+       Lockword(LLNI_DIRECT(co)->lockword).init();
 #endif
 
        LLNI_CRITICAL_END;
 #endif
 
        LLNI_CRITICAL_END;