blob: b32d5b92e0bc109775952d250a17a6e4018d2b98 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 */
Andy McFaddenb51ea112009-05-08 16:50:17 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Declaration of the fundamental Object type and refinements thereof, plus
19 * some functions for manipulating them.
20 */
21#ifndef _DALVIK_OO_OBJECT
22#define _DALVIK_OO_OBJECT
23
Andy McFadden861b3382010-03-05 15:58:31 -080024#include <Atomic.h>
25
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080026#include <stddef.h>
27
28/* fwd decl */
29struct DataObject;
Barry Hayes2c987472009-04-06 10:03:48 -070030struct InitiatingLoaderList;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080031struct ClassObject;
32struct StringObject;
33struct ArrayObject;
34struct Method;
35struct ExceptionEntry;
36struct LineNumEntry;
37struct StaticField;
38struct InstField;
39struct Field;
40struct RegisterMap;
41typedef struct DataObject DataObject;
Barry Hayes2c987472009-04-06 10:03:48 -070042typedef struct InitiatingLoaderList InitiatingLoaderList;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080043typedef struct ClassObject ClassObject;
44typedef struct StringObject StringObject;
45typedef struct ArrayObject ArrayObject;
46typedef struct Method Method;
47typedef struct ExceptionEntry ExceptionEntry;
48typedef struct LineNumEntry LineNumEntry;
49typedef struct StaticField StaticField;
50typedef struct InstField InstField;
51typedef struct Field Field;
52typedef struct RegisterMap RegisterMap;
53
54/*
55 * Native function pointer type.
56 *
57 * "args[0]" holds the "this" pointer for virtual methods.
58 *
59 * The "Bridge" form is a super-set of the "Native" form; in many places
60 * they are used interchangeably. Currently, all functions have all
61 * arguments passed in, but some functions only care about the first two.
62 * Passing extra arguments to a C function is (mostly) harmless.
63 */
64typedef void (*DalvikBridgeFunc)(const u4* args, JValue* pResult,
65 const Method* method, struct Thread* self);
66typedef void (*DalvikNativeFunc)(const u4* args, JValue* pResult);
67
68
69/* vm-internal access flags and related definitions */
70typedef enum AccessFlags {
71 ACC_MIRANDA = 0x8000, // method (internal to VM)
72 JAVA_FLAGS_MASK = 0xffff, // bits set from Java sources (low 16)
73} AccessFlags;
74
75/* Use the top 16 bits of the access flags field for
76 * other class flags. Code should use the *CLASS_FLAG*()
77 * macros to set/get these flags.
78 */
79typedef enum ClassFlags {
80 CLASS_ISFINALIZABLE = (1<<31), // class/ancestor overrides finalize()
81 CLASS_ISARRAY = (1<<30), // class is a "[*"
82 CLASS_ISOBJECTARRAY = (1<<29), // class is a "[L*" or "[[*"
Carl Shapiro3475f9c2011-03-21 13:35:24 -070083
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080084 CLASS_ISREFERENCE = (1<<28), // class is a soft/weak/phantom ref
85 // only ISREFERENCE is set --> soft
86 CLASS_ISWEAKREFERENCE = (1<<27), // class is a weak reference
Carl Shapiro3475f9c2011-03-21 13:35:24 -070087 CLASS_ISFINALIZERREFERENCE = (1<<26), // class is a phantom reference
88 CLASS_ISPHANTOMREFERENCE = (1<<25), // class is a phantom reference
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080089
Carl Shapiro3475f9c2011-03-21 13:35:24 -070090 CLASS_MULTIPLE_DEFS = (1<<24), // DEX verifier: defs in multiple DEXs
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080091
92 /* unlike the others, these can be present in the optimized DEX file */
93 CLASS_ISOPTIMIZED = (1<<17), // class may contain opt instrs
94 CLASS_ISPREVERIFIED = (1<<16), // class has been pre-verified
95} ClassFlags;
96
97/* bits we can reasonably expect to see set in a DEX access flags field */
98#define EXPECTED_FILE_FLAGS \
99 (ACC_CLASS_MASK | CLASS_ISPREVERIFIED | CLASS_ISOPTIMIZED)
100
Andy McFaddenb51ea112009-05-08 16:50:17 -0700101/*
102 * Get/set class flags.
103 */
104#define SET_CLASS_FLAG(clazz, flag) \
105 do { (clazz)->accessFlags |= (flag); } while (0)
106
107#define CLEAR_CLASS_FLAG(clazz, flag) \
108 do { (clazz)->accessFlags &= ~(flag); } while (0)
109
110#define IS_CLASS_FLAG_SET(clazz, flag) \
111 (((clazz)->accessFlags & (flag)) != 0)
112
113#define GET_CLASS_FLAG_GROUP(clazz, flags) \
114 ((u4)((clazz)->accessFlags & (flags)))
115
116/*
117 * Use the top 16 bits of the access flags field for other method flags.
118 * Code should use the *METHOD_FLAG*() macros to set/get these flags.
119 */
120typedef enum MethodFlags {
121 METHOD_ISWRITABLE = (1<<31), // the method's code is writable
122} MethodFlags;
123
124/*
125 * Get/set method flags.
126 */
127#define SET_METHOD_FLAG(method, flag) \
128 do { (method)->accessFlags |= (flag); } while (0)
129
130#define CLEAR_METHOD_FLAG(method, flag) \
131 do { (method)->accessFlags &= ~(flag); } while (0)
132
133#define IS_METHOD_FLAG_SET(method, flag) \
134 (((method)->accessFlags & (flag)) != 0)
135
136#define GET_METHOD_FLAG_GROUP(method, flags) \
137 ((u4)((method)->accessFlags & (flags)))
138
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800139/* current state of the class, increasing as we progress */
140typedef enum ClassStatus {
141 CLASS_ERROR = -1,
142
143 CLASS_NOTREADY = 0,
Barry Hayesc49db852010-05-14 13:43:34 -0700144 CLASS_IDX = 1, /* loaded, DEX idx in super or ifaces */
145 CLASS_LOADED = 2, /* DEX idx values resolved */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800146 CLASS_RESOLVED = 3, /* part of linking */
147 CLASS_VERIFYING = 4, /* in the process of being verified */
148 CLASS_VERIFIED = 5, /* logically part of linking; done pre-init */
149 CLASS_INITIALIZING = 6, /* class init in progress */
150 CLASS_INITIALIZED = 7, /* ready to go */
151} ClassStatus;
152
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800153/*
Barry Hayeseac47ed2009-06-22 11:45:20 -0700154 * Definitions for packing refOffsets in ClassObject.
155 */
156/*
157 * A magic value for refOffsets. Ignore the bits and walk the super
158 * chain when this is the value.
159 * [This is an unlikely "natural" value, since it would be 30 non-ref instance
160 * fields followed by 2 ref instance fields.]
161 */
162#define CLASS_WALK_SUPER ((unsigned int)(3))
163#define CLASS_SMALLEST_OFFSET (sizeof(struct Object))
164#define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8)
165#define CLASS_OFFSET_ALIGNMENT 4
166#define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1))
167/*
Barry Hayes6daaac12009-07-08 10:01:56 -0700168 * Given an offset, return the bit number which would encode that offset.
169 * Local use only.
170 */
171#define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \
172 (((unsigned int)(byteOffset) - CLASS_SMALLEST_OFFSET) / \
173 CLASS_OFFSET_ALIGNMENT)
174/*
175 * Is the given offset too large to be encoded?
176 */
177#define CLASS_CAN_ENCODE_OFFSET(byteOffset) \
178 (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD)
179/*
180 * Return a single bit, encoding the offset.
181 * Undefined if the offset is too large, as defined above.
Barry Hayeseac47ed2009-06-22 11:45:20 -0700182 */
183#define CLASS_BIT_FROM_OFFSET(byteOffset) \
Barry Hayes6daaac12009-07-08 10:01:56 -0700184 (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset))
Barry Hayeseac47ed2009-06-22 11:45:20 -0700185/*
186 * Return an offset, given a bit number as returned from CLZ.
187 */
188#define CLASS_OFFSET_FROM_CLZ(rshift) \
189 (((int)(rshift) * CLASS_OFFSET_ALIGNMENT) + CLASS_SMALLEST_OFFSET)
190
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800191
192/*
193 * Used for iftable in ClassObject.
194 */
195typedef struct InterfaceEntry {
196 /* pointer to interface class */
197 ClassObject* clazz;
198
199 /*
200 * Index into array of vtable offsets. This points into the ifviPool,
201 * which holds the vtables for all interfaces declared by this class.
202 */
203 int* methodIndexArray;
204} InterfaceEntry;
205
206
207
208/*
209 * There are three types of objects:
210 * Class objects - an instance of java.lang.Class
211 * Array objects - an object created with a "new array" instruction
212 * Data objects - an object that is neither of the above
213 *
214 * We also define String objects. At present they're equivalent to
215 * DataObject, but that may change. (Either way, they make some of the
216 * code more obvious.)
217 *
218 * All objects have an Object header followed by type-specific data.
219 */
220typedef struct Object {
221 /* ptr to class object */
222 ClassObject* clazz;
223
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800224 /*
225 * A word containing either a "thin" lock or a "fat" monitor. See
226 * the comments in Sync.c for a description of its layout.
227 */
228 u4 lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800229} Object;
230
231/*
232 * Properly initialize an Object.
233 * void DVM_OBJECT_INIT(Object *obj, ClassObject *clazz_)
234 */
Barry Hayes364f9d92010-06-11 16:12:47 -0700235#define DVM_OBJECT_INIT(obj, clazz_) \
236 do { \
237 dvmSetFieldObject((Object *)obj, offsetof(Object, clazz), \
238 (Object *)clazz_); \
239 DVM_LOCK_INIT(&(obj)->lock); \
240 } while (0)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800241
242/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800243 * Data objects have an Object header followed by their instance data.
244 */
245struct DataObject {
246 Object obj; /* MUST be first item */
247
248 /* variable #of u4 slots; u8 uses 2 slots */
249 u4 instanceData[1];
250};
251
252/*
253 * Strings are used frequently enough that we may want to give them their
254 * own unique type.
255 *
256 * Using a dedicated type object to access the instance data provides a
257 * performance advantage but makes the java/lang/String.java implementation
258 * fragile.
259 *
260 * Currently this is just equal to DataObject, and we pull the fields out
261 * like we do for any other object.
262 */
263struct StringObject {
264 Object obj; /* MUST be first item */
265
266 /* variable #of u4 slots; u8 uses 2 slots */
267 u4 instanceData[1];
268};
269
270
271/*
272 * Array objects have these additional fields.
273 *
274 * We don't currently store the size of each element. Usually it's implied
275 * by the instruction. If necessary, the width can be derived from
Elliott Hughesbeea0b72009-11-13 11:20:15 -0800276 * the first char of obj->clazz->descriptor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800277 */
278struct ArrayObject {
279 Object obj; /* MUST be first item */
280
281 /* number of elements; immutable after init */
282 u4 length;
283
284 /*
285 * Array contents; actual size is (length * sizeof(type)). This is
286 * declared as u8 so that the compiler inserts any necessary padding
287 * (e.g. for EABI); the actual allocation may be smaller than 8 bytes.
288 */
289 u8 contents[1];
290};
291
292/*
Barry Hayes2c987472009-04-06 10:03:48 -0700293 * For classes created early and thus probably in the zygote, the
294 * InitiatingLoaderList is kept in gDvm. Later classes use the structure in
295 * Object Class. This helps keep zygote pages shared.
296 */
297struct InitiatingLoaderList {
298 /* a list of initiating loader Objects; grown and initialized on demand */
299 Object** initiatingLoaders;
300 /* count of loaders in the above list */
301 int initiatingLoaderCount;
302};
303
304/*
Barry Hayes03aa70a2010-03-01 15:49:41 -0800305 * Generic field header. We pass this around when we want a generic Field
306 * pointer (e.g. for reflection stuff). Testing the accessFlags for
307 * ACC_STATIC allows a proper up-cast.
308 */
309struct Field {
310 ClassObject* clazz; /* class in which the field is declared */
311 const char* name;
312 const char* signature; /* e.g. "I", "[C", "Landroid/os/Debug;" */
313 u4 accessFlags;
314#ifdef PROFILE_FIELD_ACCESS
315 u4 gets;
316 u4 puts;
317#endif
318};
319
320/*
321 * Static field.
322 */
323struct StaticField {
324 Field field; /* MUST be first item */
325 JValue value; /* initially set from DEX for primitives */
326};
327
328/*
329 * Instance field.
330 */
331struct InstField {
332 Field field; /* MUST be first item */
333
334 /*
335 * This field indicates the byte offset from the beginning of the
336 * (Object *) to the actual instance data; e.g., byteOffset==0 is
337 * the same as the object pointer (bug!), and byteOffset==4 is 4
338 * bytes farther.
339 */
340 int byteOffset;
341};
342
343/*
Andy McFaddenb51ea112009-05-08 16:50:17 -0700344 * This defines the amount of space we leave for field slots in the
345 * java.lang.Class definition. If we alter the class to have more than
346 * this many fields, the VM will abort at startup.
347 */
348#define CLASS_FIELD_SLOTS 4
349
350/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800351 * Class objects have many additional fields. This is used for both
352 * classes and interfaces, including synthesized classes (arrays and
353 * primitive types).
354 *
355 * Class objects are unusual in that they have some fields allocated with
356 * the system malloc (or LinearAlloc), rather than on the GC heap. This is
357 * handy during initialization, but does require special handling when
358 * discarding java.lang.Class objects.
359 *
360 * The separation of methods (direct vs. virtual) and fields (class vs.
361 * instance) used in Dalvik works out pretty well. The only time it's
362 * annoying is when enumerating or searching for things with reflection.
363 */
364struct ClassObject {
365 Object obj; /* MUST be first item */
366
367 /* leave space for instance data; we could access fields directly if we
368 freeze the definition of java/lang/Class */
369 u4 instanceData[CLASS_FIELD_SLOTS];
370
371 /* UTF-8 descriptor for the class; from constant pool, or on heap
372 if generated ("[C") */
373 const char* descriptor;
374 char* descriptorAlloc;
375
376 /* access flags; low 16 bits are defined by VM spec */
377 u4 accessFlags;
378
379 /* VM-unique class serial number, nonzero, set very early */
380 u4 serialNumber;
381
382 /* DexFile from which we came; needed to resolve constant pool entries */
383 /* (will be NULL for VM-generated, e.g. arrays and primitive classes) */
384 DvmDex* pDvmDex;
385
386 /* state of class initialization */
387 ClassStatus status;
388
389 /* if class verify fails, we must return same error on subsequent tries */
390 ClassObject* verifyErrorClass;
391
392 /* threadId, used to check for recursive <clinit> invocation */
393 u4 initThreadId;
394
395 /*
396 * Total object size; used when allocating storage on gc heap. (For
397 * interfaces and abstract classes this will be zero.)
398 */
399 size_t objectSize;
400
401 /* arrays only: class object for base element, for instanceof/checkcast
402 (for String[][][], this will be String) */
403 ClassObject* elementClass;
404
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800405 /* arrays only: number of dimensions, e.g. int[][] is 2 */
406 int arrayDim;
407
408 /* primitive type index, or PRIM_NOT (-1); set for generated prim classes */
409 PrimitiveType primitiveType;
410
411 /* superclass, or NULL if this is java.lang.Object */
412 ClassObject* super;
413
414 /* defining class loader, or NULL for the "bootstrap" system loader */
415 Object* classLoader;
416
417 /* initiating class loader list */
Barry Hayes2c987472009-04-06 10:03:48 -0700418 /* NOTE: for classes with low serialNumber, these are unused, and the
419 values are kept in a table in gDvm. */
420 InitiatingLoaderList initiatingLoaderList;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800421
422 /* array of interfaces this class implements directly */
423 int interfaceCount;
424 ClassObject** interfaces;
425
426 /* static, private, and <init> methods */
427 int directMethodCount;
428 Method* directMethods;
429
430 /* virtual methods defined in this class; invoked through vtable */
431 int virtualMethodCount;
432 Method* virtualMethods;
433
434 /*
435 * Virtual method table (vtable), for use by "invoke-virtual". The
436 * vtable from the superclass is copied in, and virtual methods from
437 * our class either replace those from the super or are appended.
438 */
439 int vtableCount;
440 Method** vtable;
441
442 /*
443 * Interface table (iftable), one entry per interface supported by
444 * this class. That means one entry for each interface we support
445 * directly, indirectly via superclass, or indirectly via
446 * superinterface. This will be null if neither we nor our superclass
447 * implement any interfaces.
448 *
449 * Why we need this: given "class Foo implements Face", declare
450 * "Face faceObj = new Foo()". Invoke faceObj.blah(), where "blah" is
451 * part of the Face interface. We can't easily use a single vtable.
452 *
453 * For every interface a concrete class implements, we create a list of
454 * virtualMethod indices for the methods in the interface.
455 */
456 int iftableCount;
457 InterfaceEntry* iftable;
458
459 /*
460 * The interface vtable indices for iftable get stored here. By placing
461 * them all in a single pool for each class that implements interfaces,
462 * we decrease the number of allocations.
463 */
464 int ifviPoolCount;
465 int* ifviPool;
466
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800467 /* instance fields
468 *
469 * These describe the layout of the contents of a DataObject-compatible
470 * Object. Note that only the fields directly defined by this class
471 * are listed in ifields; fields defined by a superclass are listed
472 * in the superclass's ClassObject.ifields.
473 *
474 * All instance fields that refer to objects are guaranteed to be
475 * at the beginning of the field list. ifieldRefCount specifies
476 * the number of reference fields.
477 */
478 int ifieldCount;
479 int ifieldRefCount; // number of fields that are object refs
480 InstField* ifields;
481
Barry Hayeseac47ed2009-06-22 11:45:20 -0700482 /* bitmap of offsets of ifields */
483 u4 refOffsets;
484
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800485 /* source file name, if known */
486 const char* sourceFile;
Barry Hayes03aa70a2010-03-01 15:49:41 -0800487
488 /* static fields */
489 int sfieldCount;
490 StaticField sfields[]; /* MUST be last item */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800491};
492
493/*
494 * A method. We create one of these for every method in every class
495 * we load, so try to keep the size to a minimum.
496 *
497 * Much of this comes from and could be accessed in the data held in shared
498 * memory. We hold it all together here for speed. Everything but the
499 * pointers could be held in a shared table generated by the optimizer;
500 * if we're willing to convert them to offsets and take the performance
501 * hit (e.g. "meth->insns" becomes "baseAddr + meth->insnsOffset") we
502 * could move everything but "nativeFunc".
503 */
504struct Method {
505 /* the class we are a part of */
506 ClassObject* clazz;
507
508 /* access flags; low 16 bits are defined by spec (could be u2?) */
509 u4 accessFlags;
510
511 /*
512 * For concrete virtual methods, this is the offset of the method
513 * in "vtable".
514 *
515 * For abstract methods in an interface class, this is the offset
516 * of the method in "iftable[n]->methodIndexArray".
517 */
518 u2 methodIndex;
519
520 /*
521 * Method bounds; not needed for an abstract method.
522 *
523 * For a native method, we compute the size of the argument list, and
524 * set "insSize" and "registerSize" equal to it.
525 */
526 u2 registersSize; /* ins + locals */
527 u2 outsSize;
528 u2 insSize;
529
530 /* method name, e.g. "<init>" or "eatLunch" */
531 const char* name;
532
533 /*
534 * Method prototype descriptor string (return and argument types).
535 *
536 * TODO: This currently must specify the DexFile as well as the proto_ids
537 * index, because generated Proxy classes don't have a DexFile. We can
538 * remove the DexFile* and reduce the size of this struct if we generate
539 * a DEX for proxies.
540 */
541 DexProto prototype;
542
543 /* short-form method descriptor string */
544 const char* shorty;
545
546 /*
547 * The remaining items are not used for abstract or native methods.
548 * (JNI is currently hijacking "insns" as a function pointer, set
549 * after the first call. For internal-native this stays null.)
550 */
551
552 /* the actual code */
553 const u2* insns; /* instructions, in memory-mapped .dex */
554
555 /* cached JNI argument and return-type hints */
556 int jniArgInfo;
557
558 /*
559 * Native method ptr; could be actual function or a JNI bridge. We
560 * don't currently discriminate between DalvikBridgeFunc and
561 * DalvikNativeFunc; the former takes an argument superset (i.e. two
562 * extra args) which will be ignored. If necessary we can use
563 * insns==NULL to detect JNI bridge vs. internal native.
564 */
565 DalvikBridgeFunc nativeFunc;
566
567 /*
568 * Register map data, if available. This will point into the DEX file
569 * if the data was computed during pre-verification, or into the
570 * linear alloc area if not.
571 */
572 const RegisterMap* registerMap;
573
Andy McFadden0d615c32010-08-18 12:19:51 -0700574 /* set if method was called during method profiling */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800575 bool inProfile;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800576};
577
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800578
579/*
580 * Find a method within a class. The superclass is not searched.
581 */
582Method* dvmFindDirectMethodByDescriptor(const ClassObject* clazz,
583 const char* methodName, const char* signature);
584Method* dvmFindVirtualMethodByDescriptor(const ClassObject* clazz,
585 const char* methodName, const char* signature);
586Method* dvmFindVirtualMethodByName(const ClassObject* clazz,
587 const char* methodName);
588Method* dvmFindDirectMethod(const ClassObject* clazz, const char* methodName,
589 const DexProto* proto);
590Method* dvmFindVirtualMethod(const ClassObject* clazz, const char* methodName,
591 const DexProto* proto);
592
593
594/*
595 * Find a method within a class hierarchy.
596 */
597Method* dvmFindDirectMethodHierByDescriptor(const ClassObject* clazz,
598 const char* methodName, const char* descriptor);
599Method* dvmFindVirtualMethodHierByDescriptor(const ClassObject* clazz,
600 const char* methodName, const char* signature);
601Method* dvmFindDirectMethodHier(const ClassObject* clazz,
602 const char* methodName, const DexProto* proto);
603Method* dvmFindVirtualMethodHier(const ClassObject* clazz,
604 const char* methodName, const DexProto* proto);
Andy McFadden1d9206d2009-07-15 14:34:49 -0700605Method* dvmFindMethodHier(const ClassObject* clazz, const char* methodName,
606 const DexProto* proto);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800607
608/*
Andy McFaddenfc8044d2011-01-06 17:04:05 -0800609 * Find a method in an interface hierarchy.
610 */
611Method* dvmFindInterfaceMethodHierByDescriptor(const ClassObject* iface,
612 const char* methodName, const char* descriptor);
613Method* dvmFindInterfaceMethodHier(const ClassObject* iface,
614 const char* methodName, const DexProto* proto);
615
616/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800617 * Find the implementation of "meth" in "clazz".
618 *
619 * Returns NULL and throws an exception if not found.
620 */
621const Method* dvmGetVirtualizedMethod(const ClassObject* clazz,
622 const Method* meth);
623
624/*
625 * Get the source file associated with a method.
626 */
627const char* dvmGetMethodSourceFile(const Method* meth);
628
629/*
630 * Find a field within a class. The superclass is not searched.
631 */
632InstField* dvmFindInstanceField(const ClassObject* clazz,
633 const char* fieldName, const char* signature);
634StaticField* dvmFindStaticField(const ClassObject* clazz,
635 const char* fieldName, const char* signature);
636
637/*
638 * Find a field in a class/interface hierarchy.
639 */
640InstField* dvmFindInstanceFieldHier(const ClassObject* clazz,
641 const char* fieldName, const char* signature);
642StaticField* dvmFindStaticFieldHier(const ClassObject* clazz,
643 const char* fieldName, const char* signature);
Andy McFadden1d9206d2009-07-15 14:34:49 -0700644Field* dvmFindFieldHier(const ClassObject* clazz, const char* fieldName,
645 const char* signature);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800646
647/*
648 * Find a field and return the byte offset from the object pointer. Only
649 * searches the specified class, not the superclass.
650 *
651 * Returns -1 on failure.
652 */
653INLINE int dvmFindFieldOffset(const ClassObject* clazz,
654 const char* fieldName, const char* signature)
655{
656 InstField* pField = dvmFindInstanceField(clazz, fieldName, signature);
657 if (pField == NULL)
658 return -1;
659 else
660 return pField->byteOffset;
661}
662
663/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800664 * Helpers.
665 */
666INLINE bool dvmIsPublicMethod(const Method* method) {
667 return (method->accessFlags & ACC_PUBLIC) != 0;
668}
669INLINE bool dvmIsPrivateMethod(const Method* method) {
670 return (method->accessFlags & ACC_PRIVATE) != 0;
671}
672INLINE bool dvmIsStaticMethod(const Method* method) {
673 return (method->accessFlags & ACC_STATIC) != 0;
674}
675INLINE bool dvmIsSynchronizedMethod(const Method* method) {
676 return (method->accessFlags & ACC_SYNCHRONIZED) != 0;
677}
678INLINE bool dvmIsDeclaredSynchronizedMethod(const Method* method) {
679 return (method->accessFlags & ACC_DECLARED_SYNCHRONIZED) != 0;
680}
681INLINE bool dvmIsFinalMethod(const Method* method) {
682 return (method->accessFlags & ACC_FINAL) != 0;
683}
684INLINE bool dvmIsNativeMethod(const Method* method) {
685 return (method->accessFlags & ACC_NATIVE) != 0;
686}
687INLINE bool dvmIsAbstractMethod(const Method* method) {
688 return (method->accessFlags & ACC_ABSTRACT) != 0;
689}
Jesse Wilson3c6f4c02011-02-22 20:20:36 -0800690INLINE bool dvmIsSyntheticMethod(const Method* method) {
691 return (method->accessFlags & ACC_SYNTHETIC) != 0;
692}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800693INLINE bool dvmIsMirandaMethod(const Method* method) {
694 return (method->accessFlags & ACC_MIRANDA) != 0;
695}
696INLINE bool dvmIsConstructorMethod(const Method* method) {
697 return *method->name == '<';
698}
699/* Dalvik puts private, static, and constructors into non-virtual table */
700INLINE bool dvmIsDirectMethod(const Method* method) {
701 return dvmIsPrivateMethod(method) ||
702 dvmIsStaticMethod(method) ||
703 dvmIsConstructorMethod(method);
704}
705/* Get whether the given method has associated bytecode. This is the
706 * case for methods which are neither native nor abstract. */
707INLINE bool dvmIsBytecodeMethod(const Method* method) {
708 return (method->accessFlags & (ACC_NATIVE | ACC_ABSTRACT)) == 0;
709}
710
711INLINE bool dvmIsProtectedField(const Field* field) {
712 return (field->accessFlags & ACC_PROTECTED) != 0;
713}
714INLINE bool dvmIsStaticField(const Field* field) {
715 return (field->accessFlags & ACC_STATIC) != 0;
716}
717INLINE bool dvmIsFinalField(const Field* field) {
718 return (field->accessFlags & ACC_FINAL) != 0;
719}
Andy McFadden861b3382010-03-05 15:58:31 -0800720INLINE bool dvmIsVolatileField(const Field* field) {
721 return (field->accessFlags & ACC_VOLATILE) != 0;
722}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800723
724INLINE bool dvmIsInterfaceClass(const ClassObject* clazz) {
725 return (clazz->accessFlags & ACC_INTERFACE) != 0;
726}
727INLINE bool dvmIsPublicClass(const ClassObject* clazz) {
728 return (clazz->accessFlags & ACC_PUBLIC) != 0;
729}
730INLINE bool dvmIsFinalClass(const ClassObject* clazz) {
731 return (clazz->accessFlags & ACC_FINAL) != 0;
732}
733INLINE bool dvmIsAbstractClass(const ClassObject* clazz) {
734 return (clazz->accessFlags & ACC_ABSTRACT) != 0;
735}
Carl Shapirode750892010-06-08 16:37:12 -0700736INLINE bool dvmIsAnnotationClass(const ClassObject* clazz) {
737 return (clazz->accessFlags & ACC_ANNOTATION) != 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800738}
739INLINE bool dvmIsPrimitiveClass(const ClassObject* clazz) {
740 return clazz->primitiveType != PRIM_NOT;
741}
742
743/* linked, here meaning prepared and resolved */
744INLINE bool dvmIsClassLinked(const ClassObject* clazz) {
745 return clazz->status >= CLASS_RESOLVED;
746}
747/* has class been verified? */
748INLINE bool dvmIsClassVerified(const ClassObject* clazz) {
749 return clazz->status >= CLASS_VERIFIED;
750}
751
752/*
753 * Get the associated code struct for a method. This returns NULL
754 * for non-bytecode methods.
755 */
756INLINE const DexCode* dvmGetMethodCode(const Method* meth) {
757 if (dvmIsBytecodeMethod(meth)) {
758 /*
759 * The insns field for a bytecode method actually points at
760 * &(DexCode.insns), so we can subtract back to get at the
761 * DexCode in front.
762 */
763 return (const DexCode*)
764 (((const u1*) meth->insns) - offsetof(DexCode, insns));
765 } else {
766 return NULL;
767 }
768}
769
770/*
771 * Get the size of the insns associated with a method. This returns 0
772 * for non-bytecode methods.
773 */
774INLINE u4 dvmGetMethodInsnsSize(const Method* meth) {
775 const DexCode* pCode = dvmGetMethodCode(meth);
776 return (pCode == NULL) ? 0 : pCode->insnsSize;
777}
778
779/* debugging */
780void dvmDumpObject(const Object* obj);
781
782#endif /*_DALVIK_OO_OBJECT*/