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