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