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