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  * Class loader.
     18  */
     19 #ifndef DALVIK_OO_CLASS_H_
     20 #define DALVIK_OO_CLASS_H_
     21 
     22 /*
     23  * The classpath and bootclasspath differ in that only the latter is
     24  * consulted when looking for classes needed by the VM.  When searching
     25  * for an arbitrary class definition, we start with the bootclasspath,
     26  * look for optional packages (a/k/a standard extensions), and then try
     27  * the classpath.
     28  *
     29  * In Dalvik, a class can be found in one of two ways:
     30  *  - in a .dex file
     31  *  - in a .dex file named specifically "classes.dex", which is held
     32  *    inside a jar file
     33  *
     34  * These two may be freely intermixed in a classpath specification.
     35  * Ordering is significant.
     36  */
     37 enum ClassPathEntryKind {
     38     kCpeUnknown = 0,
     39     kCpeJar,
     40     kCpeDex,
     41     kCpeLastEntry       /* used as sentinel at end of array */
     42 };
     43 
     44 struct ClassPathEntry {
     45     ClassPathEntryKind kind;
     46     char*   fileName;
     47     void*   ptr;            /* JarFile* or DexFile* */
     48 };
     49 
     50 bool dvmClassStartup(void);
     51 void dvmClassShutdown(void);
     52 bool dvmPrepBootClassPath(bool isNormalStart);
     53 
     54 /*
     55  * Boot class path accessors, for class loader getResources().
     56  */
     57 int dvmGetBootPathSize(void);
     58 StringObject* dvmGetBootPathResource(const char* name, int idx);
     59 void dvmDumpBootClassPath(void);
     60 
     61 /*
     62  * Determine whether "path" is a member of "cpe".
     63  */
     64 bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path);
     65 
     66 /*
     67  * Set clazz->serialNumber to the next available value.
     68  */
     69 void dvmSetClassSerialNumber(ClassObject* clazz);
     70 
     71 /*
     72  * Find the class object representing the primitive type with the
     73  * given descriptor. This returns NULL if the given type character
     74  * is invalid.
     75  */
     76 ClassObject* dvmFindPrimitiveClass(char type);
     77 
     78 /*
     79  * Find the class with the given descriptor.  Load it if it hasn't already
     80  * been.
     81  *
     82  * "loader" is the initiating class loader.
     83  */
     84 ClassObject* dvmFindClass(const char* descriptor, Object* loader);
     85 ClassObject* dvmFindClassNoInit(const char* descriptor, Object* loader);
     86 
     87 /*
     88  * Like dvmFindClass, but only for system classes.
     89  */
     90 ClassObject* dvmFindSystemClass(const char* descriptor);
     91 ClassObject* dvmFindSystemClassNoInit(const char* descriptor);
     92 
     93 /*
     94  * Find a loaded class by descriptor. Returns the first one found.
     95  * Because there can be more than one if class loaders are involved,
     96  * this is not an especially good API. (Currently only used by the
     97  * debugger and "checking" JNI.)
     98  *
     99  * "descriptor" should have the form "Ljava/lang/Class;" or
    100  * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form
    101  * class name.
    102  */
    103 ClassObject* dvmFindLoadedClass(const char* descriptor);
    104 
    105 /*
    106  * Load the named class (by descriptor) from the specified DEX file.
    107  * Used by class loaders to instantiate a class object from a
    108  * VM-managed DEX.
    109  */
    110 ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor,
    111     Object* classLoader);
    112 
    113 /*
    114  * Link a loaded class.  Normally done as part of one of the "find class"
    115  * variations, this is only called explicitly for synthetic class
    116  * generation (e.g. reflect.Proxy).
    117  */
    118 bool dvmLinkClass(ClassObject* clazz);
    119 
    120 /*
    121  * Determine if a class has been initialized.
    122  */
    123 INLINE bool dvmIsClassInitialized(const ClassObject* clazz) {
    124     return (clazz->status == CLASS_INITIALIZED);
    125 }
    126 bool dvmIsClassInitializing(const ClassObject* clazz);
    127 
    128 /*
    129  * Initialize a class.
    130  */
    131 extern "C" bool dvmInitClass(ClassObject* clazz);
    132 
    133 /*
    134  * Retrieve the system class loader.
    135  */
    136 Object* dvmGetSystemClassLoader(void);
    137 
    138 /*
    139  * Utility functions.
    140  */
    141 ClassObject* dvmLookupClass(const char* descriptor, Object* loader,
    142     bool unprepOkay);
    143 void dvmFreeClassInnards(ClassObject* clazz);
    144 bool dvmAddClassToHash(ClassObject* clazz);
    145 void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader);
    146 bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader);
    147 
    148 /*
    149  * Update method's "nativeFunc" and "insns".  If "insns" is NULL, the
    150  * current method->insns value is not changed.
    151  */
    152 void dvmSetNativeFunc(Method* method, DalvikBridgeFunc func, const u2* insns);
    153 
    154 /*
    155  * Set the method's "registerMap" field.
    156  */
    157 void dvmSetRegisterMap(Method* method, const RegisterMap* pMap);
    158 
    159 /*
    160  * Make a method's DexCode (which includes the bytecode) read-write or
    161  * read-only.  The conversion to read-write may involve making a new copy
    162  * of the DexCode, and in normal operation the read-only state is not
    163  * actually enforced.
    164  */
    165 void dvmMakeCodeReadWrite(Method* meth);
    166 void dvmMakeCodeReadOnly(Method* meth);
    167 
    168 /*
    169  * During DEX optimizing, add an extra DEX to the bootstrap class path.
    170  */
    171 void dvmSetBootPathExtraDex(DvmDex* pDvmDex);
    172 
    173 /*
    174  * Debugging.
    175  */
    176 void dvmDumpClass(const ClassObject* clazz, int flags);
    177 void dvmDumpAllClasses(int flags);
    178 void dvmDumpLoaderStats(const char* msg);
    179 int  dvmGetNumLoadedClasses();
    180 
    181 /* flags for dvmDumpClass / dvmDumpAllClasses */
    182 #define kDumpClassFullDetail    1
    183 #define kDumpClassClassLoader   (1 << 1)
    184 #define kDumpClassInitialized   (1 << 2)
    185 
    186 
    187 /*
    188  * Store a copy of the method prototype descriptor string
    189  * for the given method into the given DexStringCache, returning the
    190  * stored string for convenience.
    191  */
    192 INLINE char* dvmCopyDescriptorStringFromMethod(const Method* method,
    193         DexStringCache *pCache)
    194 {
    195     const char* result =
    196         dexProtoGetMethodDescriptor(&method->prototype, pCache);
    197     return dexStringCacheEnsureCopy(pCache, result);
    198 }
    199 
    200 /*
    201  * Compute the number of argument words (u4 units) required by the
    202  * given method's prototype. For example, if the method descriptor is
    203  * "(IJ)D", this would return 3 (one for the int, two for the long;
    204  * return value isn't relevant).
    205  */
    206 INLINE int dvmComputeMethodArgsSize(const Method* method)
    207 {
    208     return dexProtoComputeArgsSize(&method->prototype);
    209 }
    210 
    211 /*
    212  * Compare the two method prototypes. The two prototypes are compared
    213  * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
    214  */
    215 INLINE int dvmCompareMethodProtos(const Method* method1,
    216         const Method* method2)
    217 {
    218     return dexProtoCompare(&method1->prototype, &method2->prototype);
    219 }
    220 
    221 /*
    222  * Compare the two method prototypes, considering only the parameters
    223  * (i.e. ignoring the return types). The two prototypes are compared
    224  * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
    225  */
    226 INLINE int dvmCompareMethodParameterProtos(const Method* method1,
    227         const Method* method2)
    228 {
    229     return dexProtoCompareParameters(&method1->prototype, &method2->prototype);
    230 }
    231 
    232 /*
    233  * Compare the two method names and prototypes, a la strcmp(). The
    234  * name is considered the "major" order and the prototype the "minor"
    235  * order. The prototypes are compared as if by dexProtoGetMethodDescriptor().
    236  */
    237 int dvmCompareMethodNamesAndProtos(const Method* method1,
    238         const Method* method2);
    239 
    240 /*
    241  * Compare the two method names and prototypes, a la strcmp(), ignoring
    242  * the return type. The name is considered the "major" order and the
    243  * prototype the "minor" order. The prototypes are compared as if by
    244  * dexProtoGetMethodDescriptor().
    245  */
    246 int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
    247         const Method* method2);
    248 
    249 /*
    250  * Compare a method descriptor string with the prototype of a method,
    251  * as if by converting the descriptor to a DexProto and comparing it
    252  * with dexProtoCompare().
    253  */
    254 INLINE int dvmCompareDescriptorAndMethodProto(const char* descriptor,
    255     const Method* method)
    256 {
    257     // Sense is reversed.
    258     return -dexProtoCompareToDescriptor(&method->prototype, descriptor);
    259 }
    260 
    261 /*
    262  * Compare a (name, prototype) pair with the (name, prototype) of
    263  * a method, a la strcmp(). The name is considered the "major" order and
    264  * the prototype the "minor" order. The descriptor and prototype are
    265  * compared as if by dvmCompareDescriptorAndMethodProto().
    266  */
    267 int dvmCompareNameProtoAndMethod(const char* name,
    268     const DexProto* proto, const Method* method);
    269 
    270 /*
    271  * Compare a (name, method descriptor) pair with the (name, prototype) of
    272  * a method, a la strcmp(). The name is considered the "major" order and
    273  * the prototype the "minor" order. The descriptor and prototype are
    274  * compared as if by dvmCompareDescriptorAndMethodProto().
    275  */
    276 int dvmCompareNameDescriptorAndMethod(const char* name,
    277     const char* descriptor, const Method* method);
    278 
    279 /*
    280  * Returns the size of the given class object in bytes.
    281  */
    282 size_t dvmClassObjectSize(const ClassObject *clazz);
    283 
    284 #endif  // DALVIK_OO_CLASS_H_
    285