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