diff --git a/vm/oo/Array.c b/vm/oo/Array.c
new file mode 100644
index 0000000..19a0f96
--- /dev/null
+++ b/vm/oo/Array.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * Array objects.
+ */
+#include "Dalvik.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+
+#if WITH_HPROF && WITH_HPROF_STACK
+#include "hprof/Hprof.h"
+#endif
+
+static ClassObject* createArrayClass(const char* descriptor, Object* loader);
+static ClassObject* createPrimitiveClass(int idx);
+
+static const char gPrimLetter[] = PRIM_TYPE_TO_LETTER;
+
+/*
+ * Allocate space for a new array object.  This is the lowest-level array
+ * allocation function.
+ *
+ * Pass in the array class and the width of each element.
+ *
+ * On failure, returns NULL with an exception raised.
+ */
+ArrayObject* dvmAllocArray(ClassObject* arrayClass, size_t length,
+    size_t elemWidth, int allocFlags)
+{
+    ArrayObject* newArray;
+    size_t size;
+
+    assert(arrayClass->descriptor[0] == '[');
+
+    if (length > 0x0fffffff) {
+        /* too large and (length * elemWidth) will overflow 32 bits */
+        LOGE("Rejecting allocation of %u-element array\n", length);
+        dvmThrowBadAllocException("array size too large");
+        return NULL;
+    }
+
+    size = offsetof(ArrayObject, contents);
+    size += length * elemWidth;
+
+    /* Note that we assume that the Array class does not
+     * override finalize().
+     */
+    newArray = dvmMalloc(size, allocFlags);
+    if (newArray != NULL) {
+        DVM_OBJECT_INIT(&newArray->obj, arrayClass);
+        newArray->length = length;
+        LOGVV("AllocArray: %s [%d] (%d)\n",
+            arrayClass->descriptor, (int) length, (int) size);
+#if WITH_HPROF && WITH_HPROF_STACK
+        hprofFillInStackTrace(&newArray->obj);
+#endif
+        dvmTrackAllocation(arrayClass, size);
+    }
+    /* the caller must call dvmReleaseTrackedAlloc */
+    return newArray;
+}
+
+/*
+ * Create a new array, given an array class.  The class may represent an
+ * array of references or primitives.
+ */
+ArrayObject* dvmAllocArrayByClass(ClassObject* arrayClass,
+    size_t length, int allocFlags)
+{
+    const char* descriptor = arrayClass->descriptor;
+
+    assert(descriptor[0] == '[');       /* must be array class */
+    if (descriptor[1] != '[' && descriptor[1] != 'L') {
+        /* primitive array */
+        assert(descriptor[2] == '\0');
+        return dvmAllocPrimitiveArray(descriptor[1], length, allocFlags);
+    } else {
+        return dvmAllocArray(arrayClass, length, kObjectArrayRefWidth,
+            allocFlags);
+    }
+}
+
+/*
+ * Find the array class for "elemClassObj", which could itself be an
+ * array class.
+ */
+ClassObject* dvmFindArrayClassForElement(ClassObject* elemClassObj)
+{
+    ClassObject* arrayClass;
+
+    assert(elemClassObj != NULL);
+
+    if (elemClassObj->arrayClass != NULL) {
+        arrayClass = elemClassObj->arrayClass;
+        LOGVV("using cached '%s' class for '%s'\n",
+            arrayClass->descriptor, elemClassObj->descriptor);
+    } else {
+        /* Simply prepend "[" to the descriptor. */
+        int nameLen = strlen(elemClassObj->descriptor);
+        char className[nameLen + 2];
+
+        className[0] = '[';
+        memcpy(className+1, elemClassObj->descriptor, nameLen+1);
+        arrayClass = dvmFindArrayClass(className, elemClassObj->classLoader);
+        if (arrayClass != NULL)
+            elemClassObj->arrayClass = arrayClass;
+    }
+
+    return arrayClass;
+}
+
+/*
+ * Create a new array that holds references to members of the specified class.
+ *
+ * "elemClassObj" is the element type, and may itself be an array class.  It
+ * may not be a primitive class.
+ *
+ * "allocFlags" determines whether the new object will be added to the
+ * "tracked alloc" table.
+ *
+ * This is less efficient than dvmAllocArray(), but occasionally convenient.
+ */
+ArrayObject* dvmAllocObjectArray(ClassObject* elemClassObj, size_t length,
+    int allocFlags)
+{
+    ClassObject* arrayClass;
+    ArrayObject* newArray = NULL;
+
+    LOGVV("dvmAllocObjectArray: '%s' len=%d\n",
+        elemClassObj->descriptor, (int)length);
+
+    arrayClass = dvmFindArrayClassForElement(elemClassObj);
+    if (arrayClass != NULL) {
+        newArray = dvmAllocArray(arrayClass, length, kObjectArrayRefWidth,
+            allocFlags);
+    }
+
+    /* the caller must call dvmReleaseTrackedAlloc */
+    return newArray;
+}
+
+/*
+ * Create a new array that holds primitive types.
+ *
+ * "type" is the primitive type letter, e.g. 'I' for int or 'J' for long.
+ * If the array class doesn't exist, it will be created.
+ */
+ArrayObject* dvmAllocPrimitiveArray(char type, size_t length, int allocFlags)
+{
+    ArrayObject* newArray;
+    ClassObject** pTypeClass;
+    int width;
+
+    switch (type) {
+    case 'I':
+        pTypeClass = &gDvm.classArrayInt;
+        width = 4;
+        break;
+    case 'C':
+        pTypeClass = &gDvm.classArrayChar;
+        width = 2;
+        break;
+    case 'B':
+        pTypeClass = &gDvm.classArrayByte;
+        width = 1;
+        break;
+    case 'Z':
+        pTypeClass = &gDvm.classArrayBoolean;
+        width = 1; /* special-case this? */
+        break;
+    case 'F':
+        pTypeClass = &gDvm.classArrayFloat;
+        width = 4;
+        break;
+    case 'D':
+        pTypeClass = &gDvm.classArrayDouble;
+        width = 8;
+        break;
+    case 'S':
+        pTypeClass = &gDvm.classArrayShort;
+        width = 2;
+        break;
+    case 'J':
+        pTypeClass = &gDvm.classArrayLong;
+        width = 8;
+        break;
+    default:
+        LOGE("Unknown type '%c'\n", type);
+        assert(false);
+        return NULL;
+    }
+
+    if (*pTypeClass == NULL) {
+        char typeClassName[3] = "[x";
+
+        typeClassName[1] = type;
+
+        *pTypeClass = dvmFindArrayClass(typeClassName, NULL);
+        if (*pTypeClass == NULL) {
+            LOGE("ERROR: failed to generate array class for '%s'\n",
+                typeClassName);
+            return NULL;
+        }
+    }
+
+    newArray = dvmAllocArray(*pTypeClass, length, width, allocFlags);
+
+    /* the caller must dvmReleaseTrackedAlloc if allocFlags==ALLOC_DEFAULT */
+    return newArray;
+}
+
+/*
+ * Recursively create an array with multiple dimensions.  Elements may be
+ * Objects or primitive types.
+ *
+ * The dimension we're creating is in dimensions[0], so when we recurse
+ * we advance the pointer.
+ */
+ArrayObject* dvmAllocMultiArray(ClassObject* arrayClass, int curDim, 
+    const int* dimensions)
+{
+    ArrayObject* newArray;
+    const char* elemName = arrayClass->descriptor + 1; // Advance past one '['.
+
+    LOGVV("dvmAllocMultiArray: class='%s' curDim=%d *dimensions=%d\n",
+        arrayClass->descriptor, curDim, *dimensions);
+
+    if (curDim == 0) {
+        if (*elemName == 'L' || *elemName == '[') {
+            LOGVV("  end: array class (obj) is '%s'\n",
+                arrayClass->descriptor);
+            newArray = dvmAllocArray(arrayClass, *dimensions,
+                        kObjectArrayRefWidth, ALLOC_DEFAULT);
+        } else {
+            LOGVV("  end: array class (prim) is '%s'\n",
+                arrayClass->descriptor);
+            newArray = dvmAllocPrimitiveArray(
+                    gPrimLetter[arrayClass->elementClass->primitiveType],
+                    *dimensions, ALLOC_DEFAULT);
+        }
+    } else {
+        ClassObject* subArrayClass;
+        Object** contents;
+        int i;
+
+        /* if we have X[][], find X[] */
+        subArrayClass = dvmFindArrayClass(elemName, arrayClass->classLoader);
+        if (subArrayClass == NULL) {
+            /* not enough '['s on the initial class? */
+            assert(dvmCheckException(dvmThreadSelf()));
+            return NULL;
+        }
+        assert(dvmIsArrayClass(subArrayClass));
+
+        /* allocate the array that holds the sub-arrays */
+        newArray = dvmAllocArray(arrayClass, *dimensions, kObjectArrayRefWidth,
+                        ALLOC_DEFAULT);
+        if (newArray == NULL) {
+            assert(dvmCheckException(dvmThreadSelf()));
+            return NULL;
+        }
+
+        /*
+         * Create a new sub-array in every element of the array.
+         */
+        contents = (Object**) newArray->contents;
+        for (i = 0; i < *dimensions; i++) {
+            ArrayObject* newSubArray;
+
+            newSubArray = dvmAllocMultiArray(subArrayClass, curDim-1,
+                            dimensions+1);
+            if (newSubArray == NULL) {
+                dvmReleaseTrackedAlloc((Object*) newArray, NULL);
+                assert(dvmCheckException(dvmThreadSelf()));
+                return NULL;
+            }
+
+            *contents++ = (Object*) newSubArray;
+            dvmReleaseTrackedAlloc((Object*) newSubArray, NULL);
+        }
+    }
+
+    /* caller must call dvmReleaseTrackedAlloc */
+    return newArray;
+}
+
+
+/*
+ * Find an array class, by name (e.g. "[I").
+ *
+ * If the array class doesn't exist, we generate it.
+ *
+ * If the element class doesn't exist, we return NULL (no exception raised).
+ */
+ClassObject* dvmFindArrayClass(const char* descriptor, Object* loader)
+{
+    ClassObject* clazz;
+
+    assert(descriptor[0] == '[');
+    //LOGV("dvmFindArrayClass: '%s' %p\n", descriptor, loader);
+
+    clazz = dvmLookupClass(descriptor, loader, false);
+    if (clazz == NULL) {
+        LOGV("Array class '%s' %p not found; creating\n", descriptor, loader);
+        clazz = createArrayClass(descriptor, loader);
+        if (clazz != NULL)
+            dvmAddInitiatingLoader(clazz, loader);
+    }
+
+    return clazz;
+}
+
+/*
+ * Create an array class (i.e. the class object for the array, not the
+ * array itself).  "descriptor" looks like "[C" or "[Ljava/lang/String;".
+ *
+ * If "descriptor" refers to an array of primitives, look up the
+ * primitive type's internally-generated class object.
+ *
+ * "loader" is the class loader of the class that's referring to us.  It's
+ * used to ensure that we're looking for the element type in the right
+ * context.  It does NOT become the class loader for the array class; that
+ * always comes from the base element class.
+ *
+ * Returns NULL with an exception raised on failure.
+ */
+static ClassObject* createArrayClass(const char* descriptor, Object* loader)
+{
+    ClassObject* newClass = NULL;
+    ClassObject* elementClass = NULL;
+    int arrayDim;
+    u4 extraFlags;
+
+    assert(descriptor[0] == '[');
+    assert(gDvm.classJavaLangClass != NULL);
+    assert(gDvm.classJavaLangObject != NULL);
+
+    /*
+     * Identify the underlying element class and the array dimension depth.
+     */
+    extraFlags = CLASS_ISARRAY;
+    if (descriptor[1] == '[') {
+        /* array of arrays; keep descriptor and grab stuff from parent */
+        ClassObject* outer;
+
+        outer = dvmFindClassNoInit(&descriptor[1], loader);
+        if (outer != NULL) {
+            /* want the base class, not "outer", in our elementClass */
+            elementClass = outer->elementClass;
+            arrayDim = outer->arrayDim + 1;
+            extraFlags |= CLASS_ISOBJECTARRAY;
+        } else {
+            assert(elementClass == NULL);     /* make sure we fail */
+        }
+    } else {
+        arrayDim = 1;
+        if (descriptor[1] == 'L') {
+            /* array of objects; strip off "[" and look up descriptor. */
+            const char* subDescriptor = &descriptor[1];
+            LOGVV("searching for element class '%s'\n", subDescriptor);
+            elementClass = dvmFindClassNoInit(subDescriptor, loader);
+            extraFlags |= CLASS_ISOBJECTARRAY;
+        } else {
+            /* array of a primitive type */
+            elementClass = dvmFindPrimitiveClass(descriptor[1]);
+        }
+    }
+
+    if (elementClass == NULL) {
+        /* failed */
+        assert(dvmCheckException(dvmThreadSelf()));
+        dvmFreeClassInnards(newClass);
+        dvmReleaseTrackedAlloc((Object*) newClass, NULL);
+        return NULL;
+    }
+
+    /*
+     * See if it's already loaded.  Array classes are always associated
+     * with the class loader of their underlying element type -- an array
+     * of Strings goes with the loader for java/lang/String -- so we need
+     * to look for it there.  (The caller should have checked for the
+     * existence of the class before calling here, but they did so with
+     * *their* class loader, not the element class' loader.)
+     *
+     * If we find it, the caller adds "loader" to the class' initiating
+     * loader list, which should prevent us from going through this again.
+     *
+     * This call is unnecessary if "loader" and "elementClass->classLoader"
+     * are the same, because our caller (dvmFindArrayClass) just did the
+     * lookup.  (Even if we get this wrong we still have correct behavior,
+     * because we effectively do this lookup again when we add the new
+     * class to the hash table -- necessary because of possible races with
+     * other threads.)
+     */
+    if (loader != elementClass->classLoader) {
+        LOGVV("--- checking for '%s' in %p vs. elem %p\n",
+            descriptor, loader, elementClass->classLoader);
+        newClass = dvmLookupClass(descriptor, elementClass->classLoader, false);
+        if (newClass != NULL) {
+            LOGV("--- we already have %s in %p, don't need in %p\n",
+                descriptor, elementClass->classLoader, loader);
+            return newClass;
+        }
+    }
+
+
+    /*
+     * Fill out the fields in the ClassObject.
+     *
+     * It is possible to execute some methods against arrays, because all
+     * arrays are instances of Object, so we need to set up a vtable.  We
+     * can just point at the one in Object.
+     *
+     * Array classes are simple enough that we don't need to do a full
+     * link step.
+     */
+    newClass = (ClassObject*) dvmMalloc(sizeof(*newClass), ALLOC_DEFAULT);
+    if (newClass == NULL)
+        return NULL;
+    DVM_OBJECT_INIT(&newClass->obj, gDvm.unlinkedJavaLangClass);
+    dvmSetClassSerialNumber(newClass);
+    newClass->descriptorAlloc = strdup(descriptor);
+    newClass->descriptor = newClass->descriptorAlloc;
+    newClass->super = gDvm.classJavaLangObject;
+    newClass->vtableCount = gDvm.classJavaLangObject->vtableCount;
+    newClass->vtable = gDvm.classJavaLangObject->vtable;
+    newClass->primitiveType = PRIM_NOT;
+    newClass->elementClass = elementClass;
+    newClass->classLoader = elementClass->classLoader;
+    newClass->arrayDim = arrayDim;
+    newClass->status = CLASS_INITIALIZED;
+#if WITH_HPROF && WITH_HPROF_STACK
+    hprofFillInStackTrace(newClass);
+#endif
+
+    /* don't need to set newClass->objectSize */
+
+    /*
+     * All arrays have java/lang/Cloneable and java/io/Serializable as
+     * interfaces.  We need to set that up here, so that stuff like
+     * "instanceof" works right.
+     *
+     * Note: The GC could run during the call to dvmFindSystemClassNoInit(),
+     * so we need to make sure the class object is GC-valid while we're in
+     * there.  Do this by clearing the interface list so the GC will just
+     * think that the entries are null.
+     *
+     * TODO?
+     * We may want to cache these two classes to avoid the lookup, though
+     * it's not vital -- we only do it when creating an array class, not
+     * every time we create an array.  Better yet, create a single, global
+     * copy of "interfaces" and "iftable" somewhere near the start and
+     * just point to those (and remember not to free them for arrays).
+     */
+    newClass->interfaceCount = 2;
+    newClass->interfaces = (ClassObject**)dvmLinearAlloc(newClass->classLoader,
+                                sizeof(ClassObject*) * 2);
+    memset(newClass->interfaces, 0, sizeof(ClassObject*) * 2);
+    newClass->interfaces[0] =
+        dvmFindSystemClassNoInit("Ljava/lang/Cloneable;");
+    newClass->interfaces[1] =
+        dvmFindSystemClassNoInit("Ljava/io/Serializable;");
+    dvmLinearReadOnly(newClass->classLoader, newClass->interfaces);
+    if (newClass->interfaces[0] == NULL || newClass->interfaces[1] == NULL) {
+        LOGE("Unable to create array class '%s': missing interfaces\n",
+            descriptor);
+        dvmFreeClassInnards(newClass);
+        dvmThrowException("Ljava/lang/InternalError;", "missing array ifaces");
+        dvmReleaseTrackedAlloc((Object*) newClass, NULL);
+        return NULL;
+    }
+    /*
+     * We assume that Cloneable/Serializable don't have superinterfaces --
+     * normally we'd have to crawl up and explicitly list all of the
+     * supers as well.  These interfaces don't have any methods, so we
+     * don't have to worry about the ifviPool either.
+     */
+    newClass->iftableCount = 2;
+    newClass->iftable = (InterfaceEntry*) dvmLinearAlloc(newClass->classLoader,
+                                sizeof(InterfaceEntry) * 2);
+    memset(newClass->iftable, 0, sizeof(InterfaceEntry) * 2);
+    newClass->iftable[0].clazz = newClass->interfaces[0];
+    newClass->iftable[1].clazz = newClass->interfaces[1];
+    dvmLinearReadOnly(newClass->classLoader, newClass->iftable);
+
+    /*
+     * Inherit access flags from the element.  Arrays can't be used as a
+     * superclass or interface, so we want to add "final" and remove
+     * "interface".
+     *
+     * Don't inherit any non-standard flags (e.g., CLASS_FINALIZABLE)
+     * from elementClass.  We assume that the array class does not
+     * override finalize().
+     */
+    newClass->accessFlags = ((newClass->elementClass->accessFlags &
+                             ~ACC_INTERFACE) | ACC_FINAL) & JAVA_FLAGS_MASK;
+
+    /* Set the flags we determined above.
+     * This must happen after accessFlags is set.
+     */
+    SET_CLASS_FLAG(newClass, extraFlags);
+
+    if (!dvmAddClassToHash(newClass)) {
+        /*
+         * Another thread must have loaded the class after we
+         * started but before we finished.  Discard what we've
+         * done and leave some hints for the GC.
+         */
+        LOGI("WOW: somebody generated %s simultaneously\n",
+            newClass->descriptor);
+
+        /* Clean up the class before letting the
+         * GC get its hands on it.
+         */
+        assert(newClass->obj.clazz == gDvm.unlinkedJavaLangClass);
+        dvmFreeClassInnards(newClass);
+
+        /* Let the GC free the class.
+         */
+        dvmReleaseTrackedAlloc((Object*) newClass, NULL);
+
+        /* Grab the winning class.
+         */
+        newClass = dvmLookupClass(descriptor, elementClass->classLoader, false);
+        assert(newClass != NULL);
+        return newClass;
+    }
+
+    /* make it available to the GC */
+    newClass->obj.clazz = gDvm.classJavaLangClass;
+    dvmReleaseTrackedAlloc((Object*) newClass, NULL);
+
+    LOGV("Created array class '%s' %p (access=0x%04x.%04x)\n",
+        descriptor, newClass->classLoader,
+        newClass->accessFlags >> 16,
+        newClass->accessFlags & JAVA_FLAGS_MASK);
+
+    return newClass;
+}
+
+/*
+ * Get a class we generated for the primitive types.
+ *
+ * These correspond to e.g. Integer.TYPE, and are used as the element
+ * class in arrays of primitives.
+ *
+ * "type" should be 'I', 'J', 'Z', etc.
+ *
+ * Returns NULL if the type doesn't correspond to a known primitive type.
+ */
+ClassObject* dvmFindPrimitiveClass(char type)
+{
+    int idx;
+
+    switch (type) {
+    case 'Z':
+        idx = PRIM_BOOLEAN;
+        break;
+    case 'C':
+        idx = PRIM_CHAR;
+        break;
+    case 'F':
+        idx = PRIM_FLOAT;
+        break;
+    case 'D':
+        idx = PRIM_DOUBLE;
+        break;
+    case 'B':
+        idx = PRIM_BYTE;
+        break;
+    case 'S':
+        idx = PRIM_SHORT;
+        break;
+    case 'I':
+        idx = PRIM_INT;
+        break;
+    case 'J':
+        idx = PRIM_LONG;
+        break;
+    case 'V':
+        idx = PRIM_VOID;
+        break;
+    default:
+        LOGW("Unknown primitive type '%c'\n", type);
+        return NULL;
+    }
+
+    /*
+     * Create the primitive class if it hasn't already been, and add it
+     * to the table.
+     */
+    if (gDvm.primitiveClass[idx] == NULL) {
+        ClassObject* primClass = createPrimitiveClass(idx);
+        dvmReleaseTrackedAlloc((Object*) primClass, NULL);
+
+        if (!ATOMIC_CMP_SWAP((int*) &gDvm.primitiveClass[idx],
+            0, (int) primClass))
+        {
+            /*
+             * Looks like somebody beat us to it.  Free up the one we
+             * just created and use the other one.
+             */
+            dvmFreeClassInnards(primClass);
+        }
+    }
+
+    return gDvm.primitiveClass[idx];
+}
+
+/*
+ * Synthesize a primitive class.
+ *
+ * The spec for java.lang.Class.isPrimitive describes the names to
+ * be used for these classes.
+ *
+ * Just creates the class and returns it (does not add it to the class list).
+ */
+static ClassObject* createPrimitiveClass(int idx)
+{
+    ClassObject* newClass;
+    static const char* kClassDescriptors[PRIM_MAX] = {
+        "Z", "C", "F", "D", "B", "S", "I", "J", "V"
+    };
+
+    assert(gDvm.classJavaLangClass != NULL);
+    assert(idx >= 0 && idx < PRIM_MAX);
+
+    /*
+     * Fill out a few fields in the ClassObject.
+     *
+     * Note that primitive classes do not sub-class java/lang/Object.  This
+     * matters for "instanceof" checks.  Also, we assume that the primitive
+     * class does not override finalize().
+     */
+    newClass = (ClassObject*) dvmMalloc(sizeof(*newClass), ALLOC_DEFAULT);
+    if (newClass == NULL)
+        return NULL;
+    DVM_OBJECT_INIT(&newClass->obj, gDvm.classJavaLangClass);
+    dvmSetClassSerialNumber(newClass);
+    newClass->accessFlags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
+    newClass->primitiveType = idx;
+    newClass->descriptorAlloc = NULL;
+    newClass->descriptor = kClassDescriptors[idx];
+    //newClass->super = gDvm.classJavaLangObject;
+    newClass->status = CLASS_INITIALIZED;
+#if WITH_HPROF && WITH_HPROF_STACK
+    hprofFillInStackTrace(newClass);
+#endif
+
+    /* don't need to set newClass->objectSize */
+
+    LOGVV("Created primitive class '%s'\n", kClassDescriptors[idx]);
+
+    return newClass;
+}
+
+/*
+ * Copy the entire contents of one array of objects to another.  If the copy
+ * is impossible because of a type clash, we fail and return "false".
+ */
+bool dvmCopyObjectArray(ArrayObject* dstArray, const ArrayObject* srcArray,
+    ClassObject* dstElemClass)
+{
+    Object** src = (Object**)srcArray->contents;
+    Object** dst = (Object**)dstArray->contents;
+    u4 count = dstArray->length;
+
+    assert(srcArray->length == dstArray->length);
+    assert(dstArray->obj.clazz->elementClass == dstElemClass ||
+        (dstArray->obj.clazz->elementClass == dstElemClass->elementClass &&
+         dstArray->obj.clazz->arrayDim == dstElemClass->arrayDim+1));
+
+    while (count--) {
+        if (!dvmInstanceof((*src)->clazz, dstElemClass)) {
+            LOGW("dvmCopyObjectArray: can't store %s in %s\n",
+                (*src)->clazz->descriptor, dstElemClass->descriptor);
+            return false;
+        }
+        *dst++ = *src++;
+    }
+
+    return true;
+}
+
+/*
+ * Add all primitive classes to the root set of objects.
+TODO: do these belong to the root class loader?
+ */
+void dvmGcScanPrimitiveClasses()
+{
+    int i;
+
+    for (i = 0; i < PRIM_MAX; i++) {
+        dvmMarkObject((Object *)gDvm.primitiveClass[i]);    // may be NULL
+    }
+}
+
