Home | History | Annotate | Download | only in oo
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /*
     17  * Array handling.
     18  */
     19 #ifndef _DALVIK_OO_ARRAY
     20 #define _DALVIK_OO_ARRAY
     21 
     22 /* width of an object reference, for arrays of objects */
     23 #define kObjectArrayRefWidth    sizeof(Object*)
     24 
     25 /*
     26  * Find a matching array class.  If it doesn't exist, create it.
     27  *
     28  * "descriptor" looks like "[I".
     29  *
     30  * "loader" should be the defining class loader for the elements held
     31  * in the array.
     32  */
     33 ClassObject* dvmFindArrayClass(const char* descriptor, Object* loader);
     34 
     35 /*
     36  * Find the array class for the specified class.  If "elemClassObj" is the
     37  * class "Foo", this returns the class object for "[Foo".
     38  */
     39 ClassObject* dvmFindArrayClassForElement(ClassObject* elemClassObj);
     40 
     41 /*
     42  * Allocate space for a new array object.
     43  *
     44  * "allocFlags" determines whether the new object will be added to the
     45  * "tracked alloc" table.
     46  *
     47  * Returns NULL with an exception raised if allocation fails.
     48  */
     49 ArrayObject* dvmAllocArray(ClassObject* arrayClass, size_t length,
     50     size_t elemWidth, int allocFlags);
     51 
     52 /*
     53  * Create a new array, given an array class.  The class may represent an
     54  * array of references or primitives.
     55  *
     56  * Returns NULL with an exception raised if allocation fails.
     57  */
     58 ArrayObject* dvmAllocArrayByClass(ClassObject* arrayClass,
     59     size_t length, int allocFlags);
     60 
     61 /*
     62  * Create a new array that holds references to members of the specified class.
     63  *
     64  * "elemClassObj" is the element type, and may itself be an array class.  It
     65  * may not be a primitive class.
     66  *
     67  * "allocFlags" determines whether the new object will be added to the
     68  * "tracked alloc" table.
     69  *
     70  * This is less efficient than dvmAllocArray(), but occasionally convenient.
     71  *
     72  * Returns NULL with an exception raised if allocation fails.
     73  */
     74 ArrayObject* dvmAllocObjectArray(ClassObject* elemClassObj, size_t length,
     75     int allocFlags);
     76 
     77 /*
     78  * Allocate an array whose members are primitives (bools, ints, etc.).
     79  *
     80  * "type" should be 'I', 'J', 'Z', etc.
     81  *
     82  * The new object will be added to the "tracked alloc" table.
     83  *
     84  * Returns NULL with an exception raised if allocation fails.
     85  */
     86 ArrayObject* dvmAllocPrimitiveArray(char type, size_t length, int allocFlags);
     87 
     88 /*
     89  * Allocate an array with multiple dimensions.  Elements may be Objects or
     90  * primitive types.
     91  *
     92  * The base object will be added to the "tracked alloc" table.
     93  *
     94  * Returns NULL with an exception raised if allocation fails.
     95  */
     96 ArrayObject* dvmAllocMultiArray(ClassObject* arrayClass, int curDim,
     97     const int* dimensions);
     98 
     99 /*
    100  * Find the synthesized object for the primitive class, generating it
    101  * if this is the first reference.
    102  */
    103 ClassObject* dvmFindPrimitiveClass(char type);
    104 
    105 /*
    106  * Verify that the object is actually an array.
    107  *
    108  * Does not verify that the object is actually a non-NULL object.
    109  */
    110 INLINE bool dvmIsArray(const ArrayObject* arrayObj)
    111 {
    112     return ( ((Object*)arrayObj)->clazz->descriptor[0] == '[' );
    113 }
    114 
    115 /*
    116  * Verify that the array is an object array and not a primitive array.
    117  *
    118  * Does not verify that the object is actually a non-NULL object.
    119  */
    120 INLINE bool dvmIsObjectArrayClass(const ClassObject* clazz)
    121 {
    122     const char* descriptor = clazz->descriptor;
    123     return descriptor[0] == '[' && (descriptor[1] == 'L' ||
    124                                     descriptor[1] == '[');
    125 }
    126 
    127 /*
    128  * Verify that the array is an object array and not a primitive array.
    129  *
    130  * Does not verify that the object is actually a non-NULL object.
    131  */
    132 INLINE bool dvmIsObjectArray(const ArrayObject* arrayObj)
    133 {
    134     return dvmIsObjectArrayClass(arrayObj->obj.clazz);
    135 }
    136 
    137 /*
    138  * Verify that the class is an array class.
    139  *
    140  * TODO: there may be some performance advantage to setting a flag in
    141  * the accessFlags field instead of chasing into the name string.
    142  */
    143 INLINE bool dvmIsArrayClass(const ClassObject* clazz)
    144 {
    145     return (clazz->descriptor[0] == '[');
    146 }
    147 
    148 /*
    149  * Copy the entire contents of one array of objects to another.  If the copy
    150  * is impossible because of a type clash, we fail and return "false".
    151  *
    152  * "dstElemClass" is the type of element that "dstArray" holds.
    153  */
    154 bool dvmCopyObjectArray(ArrayObject* dstArray, const ArrayObject* srcArray,
    155     ClassObject* dstElemClass);
    156 
    157 /*
    158  * Copy the entire contents of an array of boxed primitives into an
    159  * array of primitives.  The boxed value must fit in the primitive (i.e.
    160  * narrowing conversions are not allowed).
    161  */
    162 bool dvmUnboxObjectArray(ArrayObject* dstArray, const ArrayObject* srcArray,
    163     ClassObject* dstElemClass);
    164 
    165 /*
    166  * Returns the size of the given array object in bytes.
    167  */
    168 size_t dvmArrayObjectSize(const ArrayObject *array);
    169 
    170 /*
    171  * Returns the width, in bytes, required by elements in instances of
    172  * the array class.
    173  */
    174 size_t dvmArrayClassElementWidth(const ClassObject* clazz);
    175 
    176 #endif /*_DALVIK_OO_ARRAY*/
    177