2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Declaration of the fundamental Object type and refinements thereof, plus
19 * some functions for manipulating them.
21 #ifndef DALVIK_OO_OBJECT_H_
22 #define DALVIK_OO_OBJECT_H_
29 struct InitiatingLoaderList;
34 struct ExceptionEntry;
42 * Native function pointer type.
44 * "args[0]" holds the "this" pointer for virtual methods.
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.
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);
56 /* vm-internal access flags and related definitions */
58 ACC_MIRANDA = 0x8000, // method (internal to VM)
59 JAVA_FLAGS_MASK = 0xffff, // bits set from Java sources (low 16)
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.
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
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
78 CLASS_MULTIPLE_DEFS = (1<<23), // DEX verifier: defs in multiple DEXs
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
85 /* bits we can reasonably expect to see set in a DEX access flags field */
86 #define EXPECTED_FILE_FLAGS \
87 (ACC_CLASS_MASK | CLASS_ISPREVERIFIED | CLASS_ISOPTIMIZED)
90 * Get/set class flags.
92 #define SET_CLASS_FLAG(clazz, flag) \
93 do { (clazz)->accessFlags |= (flag); } while (0)
95 #define CLEAR_CLASS_FLAG(clazz, flag) \
96 do { (clazz)->accessFlags &= ~(flag); } while (0)
98 #define IS_CLASS_FLAG_SET(clazz, flag) \
99 (((clazz)->accessFlags & (flag)) != 0)
101 #define GET_CLASS_FLAG_GROUP(clazz, flags) \
102 ((u4)((clazz)->accessFlags & (flags)))
105 * Use the top 16 bits of the access flags field for other method flags.
106 * Code should use the *METHOD_FLAG*() macros to set/get these flags.
109 METHOD_ISWRITABLE = (1<<31), // the method's code is writable
113 * Get/set method flags.
115 #define SET_METHOD_FLAG(method, flag) \
116 do { (method)->accessFlags |= (flag); } while (0)
118 #define CLEAR_METHOD_FLAG(method, flag) \
119 do { (method)->accessFlags &= ~(flag); } while (0)
121 #define IS_METHOD_FLAG_SET(method, flag) \
122 (((method)->accessFlags & (flag)) != 0)
124 #define GET_METHOD_FLAG_GROUP(method, flags) \
125 ((u4)((method)->accessFlags & (flags)))
127 /* current state of the class, increasing as we progress */
132 CLASS_IDX = 1, /* loaded, DEX idx in super or ifaces */
133 CLASS_LOADED = 2, /* DEX idx values resolved */
134 CLASS_RESOLVED = 3, /* part of linking */
135 CLASS_VERIFYING = 4, /* in the process of being verified */
136 CLASS_VERIFIED = 5, /* logically part of linking; done pre-init */
137 CLASS_INITIALIZING = 6, /* class init in progress */
138 CLASS_INITIALIZED = 7, /* ready to go */
142 * Definitions for packing refOffsets in ClassObject.
145 * A magic value for refOffsets. Ignore the bits and walk the super
146 * chain when this is the value.
147 * [This is an unlikely "natural" value, since it would be 30 non-ref instance
148 * fields followed by 2 ref instance fields.]
150 #define CLASS_WALK_SUPER ((unsigned int)(3))
151 #define CLASS_SMALLEST_OFFSET (sizeof(struct Object))
152 #define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8)
153 #define CLASS_OFFSET_ALIGNMENT 4
154 #define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1))
156 * Given an offset, return the bit number which would encode that offset.
159 #define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \
160 (((unsigned int)(byteOffset) - CLASS_SMALLEST_OFFSET) / \
161 CLASS_OFFSET_ALIGNMENT)
163 * Is the given offset too large to be encoded?
165 #define CLASS_CAN_ENCODE_OFFSET(byteOffset) \
166 (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD)
168 * Return a single bit, encoding the offset.
169 * Undefined if the offset is too large, as defined above.
171 #define CLASS_BIT_FROM_OFFSET(byteOffset) \
172 (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset))
174 * Return an offset, given a bit number as returned from CLZ.
176 #define CLASS_OFFSET_FROM_CLZ(rshift) \
177 (((int)(rshift) * CLASS_OFFSET_ALIGNMENT) + CLASS_SMALLEST_OFFSET)
181 * Used for iftable in ClassObject.
183 struct InterfaceEntry {
184 /* pointer to interface class */
188 * Index into array of vtable offsets. This points into the ifviPool,
189 * which holds the vtables for all interfaces declared by this class.
191 int* methodIndexArray;
197 * There are three types of objects:
198 * Class objects - an instance of java.lang.Class
199 * Array objects - an object created with a "new array" instruction
200 * Data objects - an object that is neither of the above
202 * We also define String objects. At present they're equivalent to
203 * DataObject, but that may change. (Either way, they make some of the
204 * code more obvious.)
206 * All objects have an Object header followed by type-specific data.
209 /* ptr to class object */
213 * A word containing either a "thin" lock or a "fat" monitor. See
214 * the comments in Sync.c for a description of its layout.
220 * Properly initialize an Object.
221 * void DVM_OBJECT_INIT(Object *obj, ClassObject *clazz_)
223 #define DVM_OBJECT_INIT(obj, clazz_) \
224 dvmSetFieldObject(obj, OFFSETOF_MEMBER(Object, clazz), clazz_)
227 * Data objects have an Object header followed by their instance data.
229 struct DataObject : Object {
230 /* variable #of u4 slots; u8 uses 2 slots */
235 * Strings are used frequently enough that we may want to give them their
238 * Using a dedicated type object to access the instance data provides a
239 * performance advantage but makes the java/lang/String.java implementation
242 * Currently this is just equal to DataObject, and we pull the fields out
243 * like we do for any other object.
245 struct StringObject : Object {
246 /* variable #of u4 slots; u8 uses 2 slots */
249 /** Returns this string's length in characters. */
253 * Returns this string's length in bytes when encoded as modified UTF-8.
254 * Does not include a terminating NUL byte.
256 int utfLength() const;
258 /** Returns this string's char[] as an ArrayObject. */
259 ArrayObject* array() const;
261 /** Returns this string's char[] as a u2*. */
262 const u2* chars() const;
267 * Array objects have these additional fields.
269 * We don't currently store the size of each element. Usually it's implied
270 * by the instruction. If necessary, the width can be derived from
271 * the first char of obj->clazz->descriptor.
273 struct ArrayObject : Object {
274 /* number of elements; immutable after init */
277 #ifdef MTERP_NO_UNALIGN_64
278 u4 dummy; /* padding to get 'contents' at offset 16 */
282 * Array contents; actual size is (length * sizeof(type)). This is
283 * declared as u8 so that the compiler inserts any necessary padding
284 * (e.g. for EABI); the actual allocation may be smaller than 8 bytes.
290 * For classes created early and thus probably in the zygote, the
291 * InitiatingLoaderList is kept in gDvm. Later classes use the structure in
292 * Object Class. This helps keep zygote pages shared.
294 struct InitiatingLoaderList {
295 /* a list of initiating loader Objects; grown and initialized on demand */
296 Object** initiatingLoaders;
297 /* count of loaders in the above list */
298 int initiatingLoaderCount;
302 * Generic field header. We pass this around when we want a generic Field
303 * pointer (e.g. for reflection stuff). Testing the accessFlags for
304 * ACC_STATIC allows a proper up-cast.
307 ClassObject* clazz; /* class in which the field is declared */
309 const char* signature; /* e.g. "I", "[C", "Landroid/os/Debug;" */
316 struct StaticField : Field {
317 JValue value; /* initially set from DEX for primitives */
323 struct InstField : Field {
325 * This field indicates the byte offset from the beginning of the
326 * (Object *) to the actual instance data; e.g., byteOffset==0 is
327 * the same as the object pointer (bug!), and byteOffset==4 is 4
334 * This defines the amount of space we leave for field slots in the
335 * java.lang.Class definition. If we alter the class to have more than
336 * this many fields, the VM will abort at startup.
338 #define CLASS_FIELD_SLOTS 4
341 * Class objects have many additional fields. This is used for both
342 * classes and interfaces, including synthesized classes (arrays and
345 * Class objects are unusual in that they have some fields allocated with
346 * the system malloc (or LinearAlloc), rather than on the GC heap. This is
347 * handy during initialization, but does require special handling when
348 * discarding java.lang.Class objects.
350 * The separation of methods (direct vs. virtual) and fields (class vs.
351 * instance) used in Dalvik works out pretty well. The only time it's
352 * annoying is when enumerating or searching for things with reflection.
354 struct ClassObject : Object {
355 /* leave space for instance data; we could access fields directly if we
356 freeze the definition of java/lang/Class */
357 u4 instanceData[CLASS_FIELD_SLOTS];
359 /* UTF-8 descriptor for the class; from constant pool, or on heap
360 if generated ("[C") */
361 const char* descriptor;
362 char* descriptorAlloc;
364 /* access flags; low 16 bits are defined by VM spec */
367 /* VM-unique class serial number, nonzero, set very early */
370 /* DexFile from which we came; needed to resolve constant pool entries */
371 /* (will be NULL for VM-generated, e.g. arrays and primitive classes) */
374 /* state of class initialization */
377 /* if class verify fails, we must return same error on subsequent tries */
378 ClassObject* verifyErrorClass;
380 /* threadId, used to check for recursive <clinit> invocation */
384 * Total object size; used when allocating storage on gc heap. (For
385 * interfaces and abstract classes this will be zero.)
389 /* arrays only: class object for base element, for instanceof/checkcast
390 (for String[][][], this will be String) */
391 ClassObject* elementClass;
393 /* arrays only: number of dimensions, e.g. int[][] is 2 */
396 /* primitive type index, or PRIM_NOT (-1); set for generated prim classes */
397 PrimitiveType primitiveType;
399 /* superclass, or NULL if this is java.lang.Object */
402 /* defining class loader, or NULL for the "bootstrap" system loader */
405 /* initiating class loader list */
406 /* NOTE: for classes with low serialNumber, these are unused, and the
407 values are kept in a table in gDvm. */
408 InitiatingLoaderList initiatingLoaderList;
410 /* array of interfaces this class implements directly */
412 ClassObject** interfaces;
414 /* static, private, and <init> methods */
415 int directMethodCount;
416 Method* directMethods;
418 /* virtual methods defined in this class; invoked through vtable */
419 int virtualMethodCount;
420 Method* virtualMethods;
423 * Virtual method table (vtable), for use by "invoke-virtual". The
424 * vtable from the superclass is copied in, and virtual methods from
425 * our class either replace those from the super or are appended.
431 * Interface table (iftable), one entry per interface supported by
432 * this class. That means one entry for each interface we support
433 * directly, indirectly via superclass, or indirectly via
434 * superinterface. This will be null if neither we nor our superclass
435 * implement any interfaces.
437 * Why we need this: given "class Foo implements Face", declare
438 * "Face faceObj = new Foo()". Invoke faceObj.blah(), where "blah" is
439 * part of the Face interface. We can't easily use a single vtable.
441 * For every interface a concrete class implements, we create a list of
442 * virtualMethod indices for the methods in the interface.
445 InterfaceEntry* iftable;
448 * The interface vtable indices for iftable get stored here. By placing
449 * them all in a single pool for each class that implements interfaces,
450 * we decrease the number of allocations.
457 * These describe the layout of the contents of a DataObject-compatible
458 * Object. Note that only the fields directly defined by this class
459 * are listed in ifields; fields defined by a superclass are listed
460 * in the superclass's ClassObject.ifields.
462 * All instance fields that refer to objects are guaranteed to be
463 * at the beginning of the field list. ifieldRefCount specifies
464 * the number of reference fields.
467 int ifieldRefCount; // number of fields that are object refs
470 /* bitmap of offsets of ifields */
473 /* source file name, if known */
474 const char* sourceFile;
478 StaticField sfields[0]; /* MUST be last item */
482 * A method. We create one of these for every method in every class
483 * we load, so try to keep the size to a minimum.
485 * Much of this comes from and could be accessed in the data held in shared
486 * memory. We hold it all together here for speed. Everything but the
487 * pointers could be held in a shared table generated by the optimizer;
488 * if we're willing to convert them to offsets and take the performance
489 * hit (e.g. "meth->insns" becomes "baseAddr + meth->insnsOffset") we
490 * could move everything but "nativeFunc".
493 /* the class we are a part of */
496 /* access flags; low 16 bits are defined by spec (could be u2?) */
500 * For concrete virtual methods, this is the offset of the method
503 * For abstract methods in an interface class, this is the offset
504 * of the method in "iftable[n]->methodIndexArray".
509 * Method bounds; not needed for an abstract method.
511 * For a native method, we compute the size of the argument list, and
512 * set "insSize" and "registerSize" equal to it.
514 u2 registersSize; /* ins + locals */
518 /* method name, e.g. "<init>" or "eatLunch" */
522 * Method prototype descriptor string (return and argument types).
524 * TODO: This currently must specify the DexFile as well as the proto_ids
525 * index, because generated Proxy classes don't have a DexFile. We can
526 * remove the DexFile* and reduce the size of this struct if we generate
531 /* short-form method descriptor string */
535 * The remaining items are not used for abstract or native methods.
536 * (JNI is currently hijacking "insns" as a function pointer, set
537 * after the first call. For internal-native this stays null.)
540 /* the actual code */
541 const u2* insns; /* instructions, in memory-mapped .dex */
543 /* JNI: cached argument and return-type hints */
547 * JNI: native method ptr; could be actual function or a JNI bridge. We
548 * don't currently discriminate between DalvikBridgeFunc and
549 * DalvikNativeFunc; the former takes an argument superset (i.e. two
550 * extra args) which will be ignored. If necessary we can use
551 * insns==NULL to detect JNI bridge vs. internal native.
553 DalvikBridgeFunc nativeFunc;
556 * JNI: true if this static non-synchronized native method (that has no
557 * reference arguments) needs a JNIEnv* and jclass/jobject. Libcore
563 * JNI: true if this method has no reference arguments. This lets the JNI
564 * bridge avoid scanning the shorty for direct pointers that need to be
565 * converted to local references.
567 * TODO: replace this with a list of indexes of the reference arguments.
572 * JNI: true if we should log entry and exit. This is the only way
573 * developers can log the local references that are passed into their code.
574 * Used for debugging JNI problems in third-party code.
579 * Register map data, if available. This will point into the DEX file
580 * if the data was computed during pre-verification, or into the
581 * linear alloc area if not.
583 const RegisterMap* registerMap;
585 /* set if method was called during method profiling */
594 * Find a method within a class. The superclass is not searched.
596 Method* dvmFindDirectMethodByDescriptor(const ClassObject* clazz,
597 const char* methodName, const char* signature);
598 Method* dvmFindVirtualMethodByDescriptor(const ClassObject* clazz,
599 const char* methodName, const char* signature);
600 Method* dvmFindVirtualMethodByName(const ClassObject* clazz,
601 const char* methodName);
602 Method* dvmFindDirectMethod(const ClassObject* clazz, const char* methodName,
603 const DexProto* proto);
604 Method* dvmFindVirtualMethod(const ClassObject* clazz, const char* methodName,
605 const DexProto* proto);
609 * Find a method within a class hierarchy.
611 Method* dvmFindDirectMethodHierByDescriptor(const ClassObject* clazz,
612 const char* methodName, const char* descriptor);
613 Method* dvmFindVirtualMethodHierByDescriptor(const ClassObject* clazz,
614 const char* methodName, const char* signature);
615 Method* dvmFindDirectMethodHier(const ClassObject* clazz,
616 const char* methodName, const DexProto* proto);
617 Method* dvmFindVirtualMethodHier(const ClassObject* clazz,
618 const char* methodName, const DexProto* proto);
619 Method* dvmFindMethodHier(const ClassObject* clazz, const char* methodName,
620 const DexProto* proto);
623 * Find a method in an interface hierarchy.
625 Method* dvmFindInterfaceMethodHierByDescriptor(const ClassObject* iface,
626 const char* methodName, const char* descriptor);
627 Method* dvmFindInterfaceMethodHier(const ClassObject* iface,
628 const char* methodName, const DexProto* proto);
631 * Find the implementation of "meth" in "clazz".
633 * Returns NULL and throws an exception if not found.
635 const Method* dvmGetVirtualizedMethod(const ClassObject* clazz,
639 * Get the source file associated with a method.
641 extern "C" const char* dvmGetMethodSourceFile(const Method* meth);
644 * Find a field within a class. The superclass is not searched.
646 InstField* dvmFindInstanceField(const ClassObject* clazz,
647 const char* fieldName, const char* signature);
648 StaticField* dvmFindStaticField(const ClassObject* clazz,
649 const char* fieldName, const char* signature);
652 * Find a field in a class/interface hierarchy.
654 InstField* dvmFindInstanceFieldHier(const ClassObject* clazz,
655 const char* fieldName, const char* signature);
656 StaticField* dvmFindStaticFieldHier(const ClassObject* clazz,
657 const char* fieldName, const char* signature);
658 Field* dvmFindFieldHier(const ClassObject* clazz, const char* fieldName,
659 const char* signature);
662 * Find a field and return the byte offset from the object pointer. Only
663 * searches the specified class, not the superclass.
665 * Returns -1 on failure.
667 INLINE int dvmFindFieldOffset(const ClassObject* clazz,
668 const char* fieldName, const char* signature)
670 InstField* pField = dvmFindInstanceField(clazz, fieldName, signature);
674 return pField->byteOffset;
680 INLINE bool dvmIsPublicMethod(const Method* method) {
681 return (method->accessFlags & ACC_PUBLIC) != 0;
683 INLINE bool dvmIsPrivateMethod(const Method* method) {
684 return (method->accessFlags & ACC_PRIVATE) != 0;
686 INLINE bool dvmIsStaticMethod(const Method* method) {
687 return (method->accessFlags & ACC_STATIC) != 0;
689 INLINE bool dvmIsSynchronizedMethod(const Method* method) {
690 return (method->accessFlags & ACC_SYNCHRONIZED) != 0;
692 INLINE bool dvmIsDeclaredSynchronizedMethod(const Method* method) {
693 return (method->accessFlags & ACC_DECLARED_SYNCHRONIZED) != 0;
695 INLINE bool dvmIsFinalMethod(const Method* method) {
696 return (method->accessFlags & ACC_FINAL) != 0;
698 INLINE bool dvmIsNativeMethod(const Method* method) {
699 return (method->accessFlags & ACC_NATIVE) != 0;
702 INLINE void dvmSetHoudiniMethod(Method* method, bool needHoudini) {
703 method->needHoudini = needHoudini;
705 INLINE bool dvmNeedHoudiniMethod(const Method* method) {
706 return (method->needHoudini);
709 INLINE bool dvmIsAbstractMethod(const Method* method) {
710 return (method->accessFlags & ACC_ABSTRACT) != 0;
712 INLINE bool dvmIsSyntheticMethod(const Method* method) {
713 return (method->accessFlags & ACC_SYNTHETIC) != 0;
715 INLINE bool dvmIsMirandaMethod(const Method* method) {
716 return (method->accessFlags & ACC_MIRANDA) != 0;
718 INLINE bool dvmIsConstructorMethod(const Method* method) {
719 return *method->name == '<';
721 /* Dalvik puts private, static, and constructors into non-virtual table */
722 INLINE bool dvmIsDirectMethod(const Method* method) {
723 return dvmIsPrivateMethod(method) ||
724 dvmIsStaticMethod(method) ||
725 dvmIsConstructorMethod(method);
727 /* Get whether the given method has associated bytecode. This is the
728 * case for methods which are neither native nor abstract. */
729 INLINE bool dvmIsBytecodeMethod(const Method* method) {
730 return (method->accessFlags & (ACC_NATIVE | ACC_ABSTRACT)) == 0;
733 INLINE bool dvmIsProtectedField(const Field* field) {
734 return (field->accessFlags & ACC_PROTECTED) != 0;
736 INLINE bool dvmIsStaticField(const Field* field) {
737 return (field->accessFlags & ACC_STATIC) != 0;
739 INLINE bool dvmIsFinalField(const Field* field) {
740 return (field->accessFlags & ACC_FINAL) != 0;
742 INLINE bool dvmIsVolatileField(const Field* field) {
743 return (field->accessFlags & ACC_VOLATILE) != 0;
746 INLINE bool dvmIsInterfaceClass(const ClassObject* clazz) {
747 return (clazz->accessFlags & ACC_INTERFACE) != 0;
749 INLINE bool dvmIsPublicClass(const ClassObject* clazz) {
750 return (clazz->accessFlags & ACC_PUBLIC) != 0;
752 INLINE bool dvmIsFinalClass(const ClassObject* clazz) {
753 return (clazz->accessFlags & ACC_FINAL) != 0;
755 INLINE bool dvmIsAbstractClass(const ClassObject* clazz) {
756 return (clazz->accessFlags & ACC_ABSTRACT) != 0;
758 INLINE bool dvmIsAnnotationClass(const ClassObject* clazz) {
759 return (clazz->accessFlags & ACC_ANNOTATION) != 0;
761 INLINE bool dvmIsPrimitiveClass(const ClassObject* clazz) {
762 return clazz->primitiveType != PRIM_NOT;
765 /* linked, here meaning prepared and resolved */
766 INLINE bool dvmIsClassLinked(const ClassObject* clazz) {
767 return clazz->status >= CLASS_RESOLVED;
769 /* has class been verified? */
770 INLINE bool dvmIsClassVerified(const ClassObject* clazz) {
771 return clazz->status >= CLASS_VERIFIED;
775 * Return whether the given object is an instance of Class.
777 INLINE bool dvmIsClassObject(const Object* obj) {
779 assert(obj->clazz != NULL);
780 return IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISCLASS);
784 * Return whether the given object is the class Class (that is, the
785 * unique class which is an instance of itself).
787 INLINE bool dvmIsTheClassClass(const ClassObject* clazz) {
788 assert(clazz != NULL);
789 return IS_CLASS_FLAG_SET(clazz, CLASS_ISCLASS);
793 * Get the associated code struct for a method. This returns NULL
794 * for non-bytecode methods.
796 INLINE const DexCode* dvmGetMethodCode(const Method* meth) {
797 if (dvmIsBytecodeMethod(meth)) {
799 * The insns field for a bytecode method actually points at
800 * &(DexCode.insns), so we can subtract back to get at the
803 return (const DexCode*)
804 (((const u1*) meth->insns) - offsetof(DexCode, insns));
811 * Get the size of the insns associated with a method. This returns 0
812 * for non-bytecode methods.
814 INLINE u4 dvmGetMethodInsnsSize(const Method* meth) {
815 const DexCode* pCode = dvmGetMethodCode(meth);
816 return (pCode == NULL) ? 0 : pCode->insnsSize;
820 void dvmDumpObject(const Object* obj);
822 #endif // DALVIK_OO_OBJECT_H_