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