Class.h revision 375fb116bcb817b37509ab579dbd55cdbb765cbf
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 */
37enum ClassPathEntryKind {
38    kCpeUnknown = 0,
39    kCpeJar,
40    kCpeDex,
41    kCpeLastEntry       /* used as sentinel at end of array */
42};
43
44struct ClassPathEntry {
45    ClassPathEntryKind kind;
46    char*   fileName;
47    void*   ptr;            /* JarFile* or DexFile* */
48};
49
50bool dvmClassStartup(void);
51void dvmClassShutdown(void);
52bool dvmPrepBootClassPath(bool isNormalStart);
53
54/*
55 * Boot class path accessors, for class loader getResources().
56 */
57int dvmGetBootPathSize(void);
58StringObject* dvmGetBootPathResource(const char* name, int idx);
59void dvmDumpBootClassPath(void);
60
61/*
62 * Determine whether "path" is a member of "cpe".
63 */
64bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path);
65
66/*
67 * Set clazz->serialNumber to the next available value.
68 */
69void 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 */
76ClassObject* 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 */
84ClassObject* dvmFindClass(const char* descriptor, Object* loader);
85ClassObject* dvmFindClassNoInit(const char* descriptor, Object* loader);
86
87/*
88 * Like dvmFindClass, but only for system classes.
89 */
90ClassObject* dvmFindSystemClass(const char* descriptor);
91ClassObject* 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 */
103ClassObject* 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 */
110ClassObject* 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 */
118bool dvmLinkClass(ClassObject* clazz);
119
120/*
121 * Determine if a class has been initialized.
122 */
123INLINE bool dvmIsClassInitialized(const ClassObject* clazz) {
124    return (clazz->status == CLASS_INITIALIZED);
125}
126bool dvmIsClassInitializing(const ClassObject* clazz);
127
128/*
129 * Initialize a class.
130 */
131extern "C" bool dvmInitClass(ClassObject* clazz);
132
133/*
134 * Retrieve the system class loader.
135 */
136Object* dvmGetSystemClassLoader(void);
137
138/*
139 * Utility functions.
140 */
141ClassObject* dvmLookupClass(const char* descriptor, Object* loader,
142    bool unprepOkay);
143void dvmFreeClassInnards(ClassObject* clazz);
144bool dvmAddClassToHash(ClassObject* clazz);
145void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader);
146bool 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 */
152void dvmSetNativeFunc(Method* method, DalvikBridgeFunc func, const u2* insns);
153
154/*
155 * Set the method's "registerMap" field.
156 */
157void 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 */
165void dvmMakeCodeReadWrite(Method* meth);
166void dvmMakeCodeReadOnly(Method* meth);
167
168/*
169 * During DEX optimizing, add an extra DEX to the bootstrap class path.
170 */
171void dvmSetBootPathExtraDex(DvmDex* pDvmDex);
172
173/*
174 * Debugging.
175 */
176void dvmDumpClass(const ClassObject* clazz, int flags);
177void dvmDumpAllClasses(int flags);
178void dvmDumpLoaderStats(const char* msg);
179int  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 */
192INLINE 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 */
206INLINE 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 */
215INLINE 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 */
226INLINE 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 */
237int 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 */
246int 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 */
254INLINE 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 */
267int 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 */
276int 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 */
282size_t dvmClassObjectSize(const ClassObject *clazz);
283
284#endif  // DALVIK_OO_CLASS_H_
285