aboutsummaryrefslogtreecommitdiff
path: root/vm/oo/Class.h
blob: ca76f662300742b9c29047bfca6ce3be5ff7130c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Class loader.
 */
#ifndef DALVIK_OO_CLASS_H_
#define DALVIK_OO_CLASS_H_

#include "libdex/DexClass.h"

/*
 * The classpath and bootclasspath differ in that only the latter is
 * consulted when looking for classes needed by the VM.  When searching
 * for an arbitrary class definition, we start with the bootclasspath,
 * look for optional packages (a/k/a standard extensions), and then try
 * the classpath.
 *
 * In Dalvik, a class can be found in one of two ways:
 *  - in a .dex file
 *  - in a .dex file named specifically "classes.dex", which is held
 *    inside a jar file
 *
 * These two may be freely intermixed in a classpath specification.
 * Ordering is significant.
 */
enum ClassPathEntryKind {
    kCpeUnknown = 0,
    kCpeJar,
    kCpeDex,
    kCpeLastEntry       /* used as sentinel at end of array */
};

struct ClassPathEntry {
    ClassPathEntryKind kind;
    char*   fileName;
    void*   ptr;            /* JarFile* or DexFile* */
};

bool dvmClassStartup(void);
void dvmClassShutdown(void);
bool dvmPrepBootClassPath(bool isNormalStart);

/*
 * Boot class path accessors, for class loader getResources().
 */
int dvmGetBootPathSize(void);
StringObject* dvmGetBootPathResource(const char* name, int idx);
void dvmDumpBootClassPath(void);

/*
 * Determine whether "path" is a member of "cpe".
 */
bool dvmClassPathContains(const ClassPathEntry* cpe, const char* path);

/*
 * Set clazz->serialNumber to the next available value.
 */
void dvmSetClassSerialNumber(ClassObject* clazz);

/*
 * Find the class object representing the primitive type with the
 * given descriptor. This returns NULL if the given type character
 * is invalid.
 */
ClassObject* dvmFindPrimitiveClass(char type);

/*
 * Find the class with the given descriptor.  Load it if it hasn't already
 * been.
 *
 * "loader" is the initiating class loader.
 */
ClassObject* dvmFindClass(const char* descriptor, Object* loader);
ClassObject* dvmFindClassNoInit(const char* descriptor, Object* loader);

/*
 * Like dvmFindClass, but only for system classes.
 */
ClassObject* dvmFindSystemClass(const char* descriptor);
ClassObject* dvmFindSystemClassNoInit(const char* descriptor);

/*
 * Find a loaded class by descriptor. Returns the first one found.
 * Because there can be more than one if class loaders are involved,
 * this is not an especially good API. (Currently only used by the
 * debugger and "checking" JNI.)
 *
 * "descriptor" should have the form "Ljava/lang/Class;" or
 * "[Ljava/lang/Class;", i.e. a descriptor and not an internal-form
 * class name.
 */
ClassObject* dvmFindLoadedClass(const char* descriptor);

/*
 * Load the named class (by descriptor) from the specified DEX file.
 * Used by class loaders to instantiate a class object from a
 * VM-managed DEX.
 */
ClassObject* dvmDefineClass(DvmDex* pDvmDex, const char* descriptor,
    Object* classLoader);

/*
 * Link a loaded class.  Normally done as part of one of the "find class"
 * variations, this is only called explicitly for synthetic class
 * generation (e.g. reflect.Proxy).
 */
bool dvmLinkClass(ClassObject* clazz);

/*
 * Determine if a class has been initialized.
 */
INLINE bool dvmIsClassInitialized(const ClassObject* clazz) {
    return (clazz->status == CLASS_INITIALIZED);
}
bool dvmIsClassInitializing(const ClassObject* clazz);

/*
 * Initialize a class.
 */
extern "C" bool dvmInitClass(ClassObject* clazz);

/*
 * Retrieve the system class loader.
 */
Object* dvmGetSystemClassLoader(void);

/*
 * Utility functions.
 */
ClassObject* dvmLookupClass(const char* descriptor, Object* loader,
    bool unprepOkay);
void dvmFreeClassInnards(ClassObject* clazz);
bool dvmAddClassToHash(ClassObject* clazz);
void dvmAddInitiatingLoader(ClassObject* clazz, Object* loader);
bool dvmLoaderInInitiatingList(const ClassObject* clazz, const Object* loader);

/*
 * Update method's "nativeFunc" and "insns".  If "insns" is NULL, the
 * current method->insns value is not changed.
 */
void dvmSetNativeFunc(Method* method, DalvikBridgeFunc func, const u2* insns);

/*
 * Set the method's "registerMap" field.
 */
void dvmSetRegisterMap(Method* method, const RegisterMap* pMap);

/*
 * Make a method's DexCode (which includes the bytecode) read-write or
 * read-only.  The conversion to read-write may involve making a new copy
 * of the DexCode, and in normal operation the read-only state is not
 * actually enforced.
 */
void dvmMakeCodeReadWrite(Method* meth);
void dvmMakeCodeReadOnly(Method* meth);

/*
 * During DEX optimizing, add an extra DEX to the bootstrap class path.
 */
void dvmSetBootPathExtraDex(DvmDex* pDvmDex);

/*
 * Debugging.
 */
void dvmDumpClass(const ClassObject* clazz, int flags);
void dvmDumpAllClasses(int flags);
void dvmDumpLoaderStats(const char* msg);
int  dvmGetNumLoadedClasses();

/* flags for dvmDumpClass / dvmDumpAllClasses */
#define kDumpClassFullDetail    1
#define kDumpClassClassLoader   (1 << 1)
#define kDumpClassInitialized   (1 << 2)


/*
 * Store a copy of the method prototype descriptor string
 * for the given method into the given DexStringCache, returning the
 * stored string for convenience.
 */
INLINE char* dvmCopyDescriptorStringFromMethod(const Method* method,
        DexStringCache *pCache)
{
    const char* result =
        dexProtoGetMethodDescriptor(&method->prototype, pCache);
    return dexStringCacheEnsureCopy(pCache, result);
}

/*
 * Compute the number of argument words (u4 units) required by the
 * given method's prototype. For example, if the method descriptor is
 * "(IJ)D", this would return 3 (one for the int, two for the long;
 * return value isn't relevant).
 */
INLINE int dvmComputeMethodArgsSize(const Method* method)
{
    return dexProtoComputeArgsSize(&method->prototype);
}

/*
 * Compare the two method prototypes. The two prototypes are compared
 * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
 */
INLINE int dvmCompareMethodProtos(const Method* method1,
        const Method* method2)
{
    return dexProtoCompare(&method1->prototype, &method2->prototype);
}

/*
 * Compare the two method prototypes, considering only the parameters
 * (i.e. ignoring the return types). The two prototypes are compared
 * as if by strcmp() on the result of dexProtoGetMethodDescriptor().
 */
INLINE int dvmCompareMethodParameterProtos(const Method* method1,
        const Method* method2)
{
    return dexProtoCompareParameters(&method1->prototype, &method2->prototype);
}

/*
 * Compare the two method names and prototypes, a la strcmp(). The
 * name is considered the "major" order and the prototype the "minor"
 * order. The prototypes are compared as if by dexProtoGetMethodDescriptor().
 */
int dvmCompareMethodNamesAndProtos(const Method* method1,
        const Method* method2);

/*
 * Compare the two method names and prototypes, a la strcmp(), ignoring
 * the return type. The name is considered the "major" order and the
 * prototype the "minor" order. The prototypes are compared as if by
 * dexProtoGetMethodDescriptor().
 */
int dvmCompareMethodNamesAndParameterProtos(const Method* method1,
        const Method* method2);

/*
 * Compare a method descriptor string with the prototype of a method,
 * as if by converting the descriptor to a DexProto and comparing it
 * with dexProtoCompare().
 */
INLINE int dvmCompareDescriptorAndMethodProto(const char* descriptor,
    const Method* method)
{
    // Sense is reversed.
    return -dexProtoCompareToDescriptor(&method->prototype, descriptor);
}

/*
 * Compare a (name, prototype) pair with the (name, prototype) of
 * a method, a la strcmp(). The name is considered the "major" order and
 * the prototype the "minor" order. The descriptor and prototype are
 * compared as if by dvmCompareDescriptorAndMethodProto().
 */
int dvmCompareNameProtoAndMethod(const char* name,
    const DexProto* proto, const Method* method);

/*
 * Compare a (name, method descriptor) pair with the (name, prototype) of
 * a method, a la strcmp(). The name is considered the "major" order and
 * the prototype the "minor" order. The descriptor and prototype are
 * compared as if by dvmCompareDescriptorAndMethodProto().
 */
int dvmCompareNameDescriptorAndMethod(const char* name,
    const char* descriptor, const Method* method);

/*
 * Returns the size of the given class object in bytes.
 */
size_t dvmClassObjectSize(const ClassObject *clazz);

typedef struct OptClassMap{
    const char* descriptor;
    void (*handleIfield) (ClassObject* newClass, Object* classLoader, const DexClassDataHeader* pHeader, const u1** pData);
} OptClassMap;

OptClassMap* getOptClassHandler(ClassObject*  newClass);

#endif  // DALVIK_OO_CLASS_H_