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