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