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