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); 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". If "insns" is NULL, the 143 * current method->insns value is not changed. 144 */ 145 void dvmSetNativeFunc(Method* method, DalvikBridgeFunc func, 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 /* 277 * Returns the size of the given class object in bytes. 278 */ 279 size_t dvmClassObjectSize(const ClassObject *clazz); 280 281 #endif /*_DALVIK_OO_CLASS*/ 282