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