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