• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
dvmIsClassInitialized(const ClassObject * clazz)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 /* during DEX optimizing, add an extra DEX to the bootstrap class path */
153 INLINE void dvmSetBootPathExtraDex(DvmDex* pDvmDex);
154 
155 /*
156  * Debugging.
157  */
158 void dvmDumpClass(const ClassObject* clazz, int flags);
159 void dvmDumpAllClasses(int flags);
160 void dvmDumpLoaderStats(const char* msg);
161 int  dvmGetNumLoadedClasses();
162 
163 #ifdef PROFILE_FIELD_ACCESS
164 void dvmDumpFieldAccessCounts(void);
165 #endif
166 
167 /* flags for dvmDumpClass / dvmDumpAllClasses */
168 #define kDumpClassFullDetail    1
169 #define kDumpClassClassLoader   (1 << 1)
170 #define kDumpClassInitialized   (1 << 2)
171 
172 
173 /*
174  * Store a copy of the method prototype descriptor string
175  * for the given method into the given DexStringCache, returning the
176  * stored string for convenience.
177  */
dvmCopyDescriptorStringFromMethod(const Method * method,DexStringCache * pCache)178 INLINE char* dvmCopyDescriptorStringFromMethod(const Method* method,
179         DexStringCache *pCache)
180 {
181     const char* result =
182         dexProtoGetMethodDescriptor(&method->prototype, pCache);
183     return dexStringCacheEnsureCopy(pCache, result);
184 }
185 
186 /*
187  * Compute the number of argument words (u4 units) required by the
188  * given method's prototype. For example, if the method descriptor is
189  * "(IJ)D", this would return 3 (one for the int, two for the long;
190  * return value isn't relevant).
191  */
dvmComputeMethodArgsSize(const Method * method)192 INLINE int dvmComputeMethodArgsSize(const Method* method)
193 {
194     return dexProtoComputeArgsSize(&method->prototype);
195 }
196 
197 /*
198  * Compare the two method prototypes. The two prototypes are compared
199  * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
200  */
dvmCompareMethodProtos(const Method * method1,const Method * method2)201 INLINE int dvmCompareMethodProtos(const Method* method1,
202         const Method* method2)
203 {
204     return dexProtoCompare(&method1->prototype, &method2->prototype);
205 }
206 
207 /*
208  * Compare the two method prototypes, considering only the parameters
209  * (i.e. ignoring the return types). The two prototypes are compared
210  * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
211  */
dvmCompareMethodParameterProtos(const Method * method1,const Method * method2)212 INLINE int dvmCompareMethodParameterProtos(const Method* method1,
213         const Method* method2)
214 {
215     return dexProtoCompareParameters(&method1->prototype, &method2->prototype);
216 }
217 
218 /*
219  * Compare the two method names and prototypes, a la strcmp(). The
220  * name is considered the "major" order and the prototype the "minor"
221  * order. The prototypes are compared as if by dexProtoGetMethodDescriptor().
222  */
223 int dvmCompareMethodNamesAndProtos(const Method* method1,
224         const Method* method2);
225 
226 /*
227  * Compare the two method names and prototypes, a la strcmp(), ignoring
228  * the return type. The name is considered the "major" order and the
229  * prototype the "minor" order. The prototypes are compared as if by
230  * dexProtoGetMethodDescriptor().
231  */
232 int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
233         const Method* method2);
234 
235 /*
236  * Compare a method descriptor string with the prototype of a method,
237  * as if by converting the descriptor to a DexProto and comparing it
238  * with dexProtoCompare().
239  */
dvmCompareDescriptorAndMethodProto(const char * descriptor,const Method * method)240 INLINE int dvmCompareDescriptorAndMethodProto(const char* descriptor,
241     const Method* method)
242 {
243     // Sense is reversed.
244     return -dexProtoCompareToDescriptor(&method->prototype, descriptor);
245 }
246 
247 /*
248  * Compare a (name, prototype) pair with the (name, prototype) of
249  * a method, a la strcmp(). The name is considered the "major" order and
250  * the prototype the "minor" order. The descriptor and prototype are
251  * compared as if by dvmCompareDescriptorAndMethodProto().
252  */
253 int dvmCompareNameProtoAndMethod(const char* name,
254     const DexProto* proto, const Method* method);
255 
256 /*
257  * Compare a (name, method descriptor) pair with the (name, prototype) of
258  * a method, a la strcmp(). The name is considered the "major" order and
259  * the prototype the "minor" order. The descriptor and prototype are
260  * compared as if by dvmCompareDescriptorAndMethodProto().
261  */
262 int dvmCompareNameDescriptorAndMethod(const char* name,
263     const char* descriptor, const Method* method);
264 
265 #endif /*_DALVIK_OO_CLASS*/
266