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