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