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