| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 1 | // Copyright 2011 Google Inc. All Rights Reserved. | 
 | 2 |  | 
 | 3 | #ifndef ART_SRC_OBJECT_H_ | 
 | 4 | #define ART_SRC_OBJECT_H_ | 
 | 5 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 6 | #include "src/dex_file.h" | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 7 | #include "src/globals.h" | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 8 | #include "src/macros.h" | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 9 | #include "src/stringpiece.h" | 
 | 10 | #include "src/monitor.h" | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 11 |  | 
 | 12 | namespace art { | 
 | 13 |  | 
 | 14 | class Array; | 
 | 15 | class Class; | 
 | 16 | class DexFile; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 17 | class InstanceField; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 18 | class InterfaceEntry; | 
 | 19 | class Monitor; | 
 | 20 | class Method; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 21 | class Object; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 22 | class StaticField; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 23 |  | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 24 | union JValue { | 
 | 25 |   uint8_t z; | 
 | 26 |   int8_t b; | 
 | 27 |   uint16_t c; | 
 | 28 |   int16_t s; | 
 | 29 |   int32_t i; | 
 | 30 |   int64_t j; | 
 | 31 |   float f; | 
 | 32 |   double d; | 
 | 33 |   Object* l; | 
 | 34 | }; | 
 | 35 |  | 
 | 36 | static const uint32_t kAccPublic = 0x0001; // class, field, method, ic | 
 | 37 | static const uint32_t kAccPrivate = 0x0002; // field, method, ic | 
 | 38 | static const uint32_t kAccProtected = 0x0004; // field, method, ic | 
 | 39 | static const uint32_t kAccStatic = 0x0008; // field, method, ic | 
 | 40 | static const uint32_t kAccFinal = 0x0010; // class, field, method, ic | 
 | 41 | static const uint32_t kAccSynchronized = 0x0020; // method (only allowed on natives) | 
 | 42 | static const uint32_t kAccSuper = 0x0020; // class (not used in Dalvik) | 
 | 43 | static const uint32_t kAccVolatile = 0x0040; // field | 
 | 44 | static const uint32_t kAccBridge = 0x0040; // method (1.5) | 
 | 45 | static const uint32_t kAccTransient = 0x0080; // field | 
 | 46 | static const uint32_t kAccVarargs = 0x0080; // method (1.5) | 
 | 47 | static const uint32_t kAccNative = 0x0100; // method | 
 | 48 | static const uint32_t kAccInterface = 0x0200; // class, ic | 
 | 49 | static const uint32_t kAccAbstract = 0x0400; // class, method, ic | 
 | 50 | static const uint32_t kAccStrict = 0x0800; // method | 
 | 51 | static const uint32_t kAccSynthetic = 0x1000; // field, method, ic | 
 | 52 | static const uint32_t kAccAnnotation = 0x2000; // class, ic (1.5) | 
 | 53 | static const uint32_t kAccEnum = 0x4000; // class, field, ic (1.5) | 
 | 54 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 55 | static const uint32_t kAccMiranda = 0x8000;  // method | 
 | 56 |  | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 57 | static const uint32_t kAccConstructor = 0x00010000; // method (Dalvik only) | 
 | 58 | static const uint32_t kAccDeclaredSynchronized = 0x00020000; // method (Dalvik only) | 
 | 59 |  | 
 | 60 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 61 | /* | 
 | 62 |  * Definitions for packing refOffsets in ClassObject. | 
 | 63 |  */ | 
 | 64 | /* | 
 | 65 |  * A magic value for refOffsets. Ignore the bits and walk the super | 
 | 66 |  * chain when this is the value. | 
 | 67 |  * [This is an unlikely "natural" value, since it would be 30 non-ref instance | 
 | 68 |  * fields followed by 2 ref instance fields.] | 
 | 69 |  */ | 
 | 70 | #define CLASS_WALK_SUPER ((unsigned int)(3)) | 
 | 71 | #define CLASS_SMALLEST_OFFSET (sizeof(struct Object)) | 
 | 72 | #define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8) | 
 | 73 | #define CLASS_OFFSET_ALIGNMENT 4 | 
 | 74 | #define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1)) | 
 | 75 | /* | 
 | 76 |  * Given an offset, return the bit number which would encode that offset. | 
 | 77 |  * Local use only. | 
 | 78 |  */ | 
 | 79 | #define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \ | 
 | 80 |     (((unsigned int)(byteOffset) - CLASS_SMALLEST_OFFSET) / \ | 
 | 81 |      CLASS_OFFSET_ALIGNMENT) | 
 | 82 | /* | 
 | 83 |  * Is the given offset too large to be encoded? | 
 | 84 |  */ | 
 | 85 | #define CLASS_CAN_ENCODE_OFFSET(byteOffset) \ | 
 | 86 |     (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD) | 
 | 87 | /* | 
 | 88 |  * Return a single bit, encoding the offset. | 
 | 89 |  * Undefined if the offset is too large, as defined above. | 
 | 90 |  */ | 
 | 91 | #define CLASS_BIT_FROM_OFFSET(byteOffset) \ | 
 | 92 |     (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset)) | 
 | 93 | /* | 
 | 94 |  * Return an offset, given a bit number as returned from CLZ. | 
 | 95 |  */ | 
 | 96 | #define CLASS_OFFSET_FROM_CLZ(rshift) \ | 
 | 97 |     (((int)(rshift) * CLASS_OFFSET_ALIGNMENT) + CLASS_SMALLEST_OFFSET) | 
 | 98 |  | 
 | 99 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 100 | class Object { | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 101 |  public: | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 102 |   Class* GetClass() const { | 
 | 103 |     return klass_; | 
 | 104 |   } | 
 | 105 |  | 
 | 106 |   void MonitorEnter() { | 
 | 107 |     monitor_->Enter(); | 
 | 108 |   } | 
 | 109 |  | 
 | 110 |   void MonitorExit() { | 
 | 111 |     monitor_->Exit(); | 
 | 112 |   } | 
 | 113 |  | 
 | 114 |   void Notify() { | 
 | 115 |     monitor_->Notify(); | 
 | 116 |   } | 
 | 117 |  | 
 | 118 |   void NotifyAll() { | 
 | 119 |     monitor_->NotifyAll(); | 
 | 120 |   } | 
 | 121 |  | 
 | 122 |   void Wait() { | 
 | 123 |     monitor_->Wait(); | 
 | 124 |   } | 
 | 125 |  | 
 | 126 |   void Wait(int64_t timeout) { | 
 | 127 |     monitor_->Wait(timeout); | 
 | 128 |   } | 
 | 129 |  | 
 | 130 |   void Wait(int64_t timeout, int32_t nanos) { | 
 | 131 |     monitor_->Wait(timeout, nanos); | 
 | 132 |   } | 
 | 133 |  | 
 | 134 |   void SetObjectAt(size_t offset, Object* new_value) { | 
 | 135 |     byte* raw_addr = reinterpret_cast<byte*>(this) + offset; | 
 | 136 |     *reinterpret_cast<Object**>(raw_addr) = new_value; | 
 | 137 |     // TODO: write barrier | 
 | 138 |   } | 
 | 139 |  | 
 | 140 |  public: | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 141 |   Class* klass_; | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 142 |   Monitor* monitor_; | 
 | 143 |  | 
 | 144 |  private: | 
 | 145 |   DISALLOW_COPY_AND_ASSIGN(Object); | 
 | 146 | }; | 
 | 147 |  | 
 | 148 | class ObjectLock { | 
 | 149 |  public: | 
 | 150 |   ObjectLock(Object* object) : obj_(object) { | 
 | 151 |     CHECK(object != NULL); | 
 | 152 |     obj_->MonitorEnter(); | 
 | 153 |   } | 
 | 154 |  | 
 | 155 |   ~ObjectLock() { | 
 | 156 |     obj_->MonitorExit(); | 
 | 157 |   } | 
 | 158 |  | 
 | 159 |   void Wait(int64_t millis = 0) { | 
 | 160 |     return obj_->Wait(millis); | 
 | 161 |   } | 
 | 162 |  | 
 | 163 |   void Notify() { | 
 | 164 |     obj_->Notify(); | 
 | 165 |   } | 
 | 166 |  | 
 | 167 |   void NotifyAll() { | 
 | 168 |     obj_->NotifyAll(); | 
 | 169 |   } | 
 | 170 |  | 
 | 171 |  private: | 
 | 172 |   Object* obj_; | 
 | 173 |   DISALLOW_COPY_AND_ASSIGN(ObjectLock); | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 174 | }; | 
 | 175 |  | 
 | 176 | class Field { | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 177 |  public: | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 178 |   Class* GetClass() const { | 
 | 179 |     return klass_; | 
 | 180 |   } | 
 | 181 |  | 
 | 182 |   const char* GetName() const { | 
 | 183 |     return name_; | 
 | 184 |   } | 
 | 185 |  | 
 | 186 |   char GetType() const {  // TODO: return type | 
 | 187 |     return signature_[0]; | 
 | 188 |   } | 
 | 189 |  | 
 | 190 |  public:  // TODO: private | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 191 |   // The class in which this field is declared. | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 192 |   Class* klass_; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 193 |  | 
 | 194 |   const char* name_; | 
 | 195 |  | 
 | 196 |   // e.g. "I", "[C", "Landroid/os/Debug;" | 
 | 197 |   const char* signature_; | 
 | 198 |  | 
 | 199 |   uint32_t access_flags_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 200 | }; | 
 | 201 |  | 
 | 202 | // Instance fields. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 203 | class InstanceField : public Field { | 
 | 204 |  public: | 
 | 205 |   uint32_t GetOffset() const { | 
 | 206 |     return offset_; | 
 | 207 |   } | 
 | 208 |  | 
 | 209 |   void SetOffset(size_t num_bytes) { | 
 | 210 |     offset_ = num_bytes; | 
 | 211 |   } | 
 | 212 |  | 
 | 213 |   // TODO: stl::swap | 
 | 214 |   void Swap(InstanceField* that) { | 
 | 215 |     InstanceField tmp; | 
 | 216 |     memcpy(&tmp, this, sizeof(InstanceField)); | 
 | 217 |     memcpy(this, that, sizeof(InstanceField)); | 
 | 218 |     memcpy(that, &tmp, sizeof(InstanceField)); | 
 | 219 |   } | 
 | 220 |  | 
 | 221 |  private: | 
 | 222 |   size_t offset_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 223 | }; | 
 | 224 |  | 
 | 225 | // Static fields. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 226 | class StaticField : public Field { | 
 | 227 |  private: | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 228 |   JValue value_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 229 | }; | 
 | 230 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 231 | class Method { | 
 | 232 |  public: | 
 | 233 |   // Returns the method name. | 
 | 234 |   // TODO: example | 
 | 235 |   const StringPiece& GetName() const { | 
 | 236 |     return name_; | 
 | 237 |   } | 
 | 238 |  | 
 | 239 |   Class* GetClass() const { | 
 | 240 |     return klass_; | 
 | 241 |   } | 
 | 242 |  | 
 | 243 |   // const char* GetReturnTypeDescriptor() const { | 
 | 244 |   //   return dex_file_->GetRaw()->dexStringByTypeIdx(proto_id_.return_type_id_); | 
 | 245 |   // } | 
 | 246 |  | 
 | 247 |   // Returns true if the method is declared public. | 
 | 248 |   bool IsPublic() const { | 
 | 249 |     return (access_flags_ & kAccPublic) != 0; | 
 | 250 |   } | 
 | 251 |  | 
 | 252 |   // Returns true if the method is declared private. | 
 | 253 |   bool IsPrivate() const { | 
 | 254 |     return (access_flags_ & kAccPrivate) != 0; | 
 | 255 |   } | 
 | 256 |  | 
 | 257 |   // Returns true if the method is declared static. | 
 | 258 |   bool IsStatic() const { | 
 | 259 |     return (access_flags_ & kAccStatic) != 0; | 
 | 260 |   } | 
 | 261 |  | 
 | 262 |   // Returns true if the method is declared synchronized. | 
 | 263 |   bool IsSynchronized() const { | 
 | 264 |     uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized; | 
 | 265 |     return (access_flags_ & synchonized) != 0; | 
 | 266 |   } | 
 | 267 |  | 
 | 268 |   // Returns true if the method is declared final. | 
 | 269 |   bool IsFinal() const { | 
 | 270 |     return (access_flags_ & kAccFinal) != 0; | 
 | 271 |   } | 
 | 272 |  | 
 | 273 |   // Returns true if the method is declared native. | 
 | 274 |   bool IsNative() const { | 
 | 275 |     return (access_flags_ & kAccNative) != 0; | 
 | 276 |   } | 
 | 277 |  | 
 | 278 |   // Returns true if the method is declared abstract. | 
 | 279 |   bool IsAbstract() const { | 
 | 280 |     return (access_flags_ & kAccAbstract) != 0; | 
 | 281 |   } | 
 | 282 |  | 
 | 283 |   bool IsSynthetic() const { | 
 | 284 |     return (access_flags_ & kAccSynthetic) != 0; | 
 | 285 |   } | 
 | 286 |  | 
 | 287 |   // Number of argument registers required by the prototype. | 
 | 288 |   uint32_t NumArgRegisters(); | 
 | 289 |  | 
 | 290 |   bool HasSameNameAndPrototype(const Method* that) const { | 
 | 291 |     return HasSameName(that) && HasSamePrototype(that); | 
 | 292 |   } | 
 | 293 |  | 
 | 294 |   bool HasSameName(const Method* that) const { | 
 | 295 |     return this->GetName() == that->GetName(); | 
 | 296 |   } | 
 | 297 |  | 
 | 298 |   bool HasSamePrototype(const Method* that) const { | 
 | 299 |     return HasSameReturnType(that) && HasSameArgumentTypes(that); | 
 | 300 |   } | 
 | 301 |  | 
 | 302 |   bool HasSameReturnType(const Method* that) const; | 
 | 303 |  | 
 | 304 |   bool HasSameArgumentTypes(const Method* that) const; | 
 | 305 |  | 
 | 306 |  public:  // TODO: private | 
 | 307 |   // the class we are a part of | 
 | 308 |   Class* klass_; | 
 | 309 |  | 
 | 310 |   // access flags; low 16 bits are defined by spec (could be uint16_t?) | 
 | 311 |   uint32_t access_flags_; | 
 | 312 |  | 
 | 313 |   // For concrete virtual methods, this is the offset of the method | 
 | 314 |   // in "vtable". | 
 | 315 |   // | 
 | 316 |   // For abstract methods in an interface class, this is the offset | 
 | 317 |   // of the method in "iftable[n]->methodIndexArray". | 
 | 318 |   uint16_t method_index_; | 
 | 319 |  | 
 | 320 |   // Method bounds; not needed for an abstract method. | 
 | 321 |   // | 
 | 322 |   // For a native method, we compute the size of the argument list, and | 
 | 323 |   // set "insSize" and "registerSize" equal to it. | 
 | 324 |   uint16_t num_registers_;  // ins + locals | 
 | 325 |   uint16_t num_outs_; | 
 | 326 |   uint16_t num_ins_; | 
 | 327 |  | 
 | 328 |   // method name, e.g. "<init>" or "eatLunch" | 
 | 329 |   StringPiece name_; | 
 | 330 |  | 
 | 331 |   // A pointer to the DEX file this class was loaded from or NULL for | 
 | 332 |   // proxy objects. | 
 | 333 |   DexFile* dex_file_; | 
 | 334 |  | 
 | 335 |   // Method prototype descriptor string (return and argument types). | 
 | 336 |   uint32_t proto_idx_; | 
 | 337 |  | 
 | 338 |   // The short-form method descriptor string. | 
 | 339 |   StringPiece shorty_; | 
 | 340 |  | 
 | 341 |   // A pointer to the memory-mapped DEX code. | 
 | 342 |   const uint16_t* insns_; | 
 | 343 | }; | 
 | 344 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 345 | // Class objects. | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 346 | class Class : public Object { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 347 |  public: | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 348 |   enum Status { | 
| Carl Shapiro | 894d0fa | 2011-06-30 14:48:49 -0700 | [diff] [blame] | 349 |     kStatusError = -1, | 
 | 350 |     kStatusNotReady = 0, | 
 | 351 |     kStatusIdx = 1,  // loaded, DEX idx in super or ifaces | 
 | 352 |     kStatusLoaded = 2,  // DEX idx values resolved | 
 | 353 |     kStatusResolved = 3,  // part of linking | 
 | 354 |     kStatusVerifying = 4,  // in the process of being verified | 
 | 355 |     kStatusVerified = 5,  // logically part of linking; done pre-init | 
 | 356 |     kStatusInitializing = 6,  // class init in progress | 
 | 357 |     kStatusInitialized = 7,  // ready to go | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 358 |   }; | 
 | 359 |  | 
 | 360 |   enum PrimitiveType { | 
 | 361 |     kPrimNot = -1 | 
 | 362 |   }; | 
 | 363 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 364 |   Class* GetSuperClass() const { | 
 | 365 |     return super_class_; | 
 | 366 |   } | 
 | 367 |  | 
 | 368 |   uint32_t GetSuperClassIdx() const { | 
 | 369 |     return super_class_idx_; | 
 | 370 |   } | 
 | 371 |  | 
 | 372 |   bool HasSuperClass() const { | 
 | 373 |     return super_class_ != NULL; | 
 | 374 |   } | 
 | 375 |  | 
 | 376 |   Object* GetClassLoader() const { | 
 | 377 |     return class_loader_; | 
 | 378 |   } | 
 | 379 |  | 
 | 380 |   DexFile* GetDexFile() const { | 
 | 381 |     return dex_file_; | 
 | 382 |   } | 
 | 383 |  | 
 | 384 |   Class* GetComponentType() const { | 
 | 385 |     return component_type_; | 
 | 386 |   } | 
 | 387 |  | 
 | 388 |   const StringPiece& GetDescriptor() const { | 
 | 389 |     return descriptor_; | 
 | 390 |   } | 
 | 391 |  | 
 | 392 |   Status GetStatus() const { | 
 | 393 |     return status_; | 
 | 394 |   } | 
 | 395 |  | 
 | 396 |   void SetStatus(Status new_status) { | 
 | 397 |     // TODO: validate transition | 
 | 398 |     status_ = new_status; | 
 | 399 |   } | 
 | 400 |  | 
 | 401 |   bool IsErroneous() const { | 
 | 402 |     return GetStatus() == kStatusError; | 
 | 403 |   } | 
 | 404 |  | 
 | 405 |   bool IsVerified() const { | 
 | 406 |     return GetStatus() >= kStatusVerified; | 
 | 407 |   } | 
 | 408 |  | 
 | 409 |   bool IsLinked() const { | 
 | 410 |     return GetStatus() >= kStatusResolved; | 
 | 411 |   } | 
 | 412 |  | 
| Carl Shapiro | 894d0fa | 2011-06-30 14:48:49 -0700 | [diff] [blame] | 413 |   // Returns true if this class is in the same packages as that class. | 
 | 414 |   bool IsInSamePackage(const Class* that) const; | 
 | 415 |  | 
 | 416 |   static bool IsInSamePackage(const char* descriptor1, const char* descriptor2); | 
 | 417 |  | 
 | 418 |   // Returns true if this class represents an array class. | 
 | 419 |   bool IsArray() const { | 
 | 420 |     return descriptor_[0] == '[';  // TODO: avoid parsing the descriptor | 
 | 421 |   } | 
 | 422 |  | 
 | 423 |   // Returns true if the class is an interface. | 
 | 424 |   bool IsInterface() const { | 
 | 425 |     return (access_flags_ & kAccInterface) != 0; | 
 | 426 |   } | 
 | 427 |  | 
 | 428 |   // Returns true if the class is declared public. | 
 | 429 |   bool IsPublic() const { | 
 | 430 |     return (access_flags_ & kAccPublic) != 0; | 
 | 431 |   } | 
 | 432 |  | 
 | 433 |   // Returns true if the class is declared final. | 
 | 434 |   bool IsFinal() const { | 
 | 435 |     return (access_flags_ & kAccFinal) != 0; | 
 | 436 |   } | 
 | 437 |  | 
 | 438 |   // Returns true if the class is abstract. | 
 | 439 |   bool IsAbstract() const { | 
 | 440 |     return (access_flags_ & kAccAbstract) != 0; | 
 | 441 |   } | 
 | 442 |  | 
 | 443 |   // Returns true if the class is an annotation. | 
 | 444 |   bool IsAnnotation() const { | 
 | 445 |     return (access_flags_ & kAccAnnotation) != 0; | 
 | 446 |   } | 
 | 447 |  | 
 | 448 |   // Returns true if the class is a primitive type. | 
 | 449 |   bool IsPrimitive() const { | 
 | 450 |     return primitive_type_ != kPrimNot; | 
 | 451 |   } | 
 | 452 |  | 
 | 453 |   // Returns true if this class can access that class. | 
 | 454 |   bool CanAccess(const Class* that) const { | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 455 |     return that->IsPublic() || this->IsInSamePackage(that); | 
| Carl Shapiro | 894d0fa | 2011-06-30 14:48:49 -0700 | [diff] [blame] | 456 |   } | 
 | 457 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 458 |   // Returns the size in bytes of a class object instance with the | 
 | 459 |   // given number of static fields. | 
 | 460 |   static size_t Size(size_t num_sfields) { | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 461 |     return OFFSETOF_MEMBER(Class, sfields_) + sizeof(StaticField) * num_sfields; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 462 |   } | 
 | 463 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 464 |   // Returns the number of static, private, and constructor methods. | 
 | 465 |   size_t NumDirectMethods() const { | 
 | 466 |     return num_direct_methods_; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 467 |   } | 
 | 468 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 469 |   Method* GetDirectMethod(uint32_t i) const { | 
 | 470 |     return &direct_methods_[i]; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 471 |   } | 
 | 472 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 473 |   // Returns the number of non-inherited virtual methods. | 
 | 474 |   size_t NumVirtualMethods() const { | 
 | 475 |     return num_virtual_methods_; | 
 | 476 |   } | 
 | 477 |  | 
 | 478 |   Method* GetVirtualMethod(uint32_t i) const { | 
 | 479 |     return &virtual_methods_[i]; | 
 | 480 |   } | 
 | 481 |  | 
 | 482 |   size_t NumInstanceFields() const { | 
 | 483 |     return num_ifields_; | 
 | 484 |   } | 
 | 485 |  | 
 | 486 |   size_t NumReferenceInstanceFields() const { | 
 | 487 |     return num_reference_ifields_; | 
 | 488 |   } | 
 | 489 |  | 
 | 490 |   InstanceField* GetInstanceField(uint32_t i) {  // TODO: uint16_t | 
 | 491 |     return &ifields_[i]; | 
 | 492 |   } | 
 | 493 |  | 
 | 494 |   size_t NumStaticFields() const { | 
 | 495 |     return num_sfields_; | 
 | 496 |   } | 
 | 497 |  | 
 | 498 |   StaticField* GetStaticField(uint32_t i) {  // TODO: uint16_t | 
 | 499 |     return &sfields_[i]; | 
 | 500 |   } | 
 | 501 |  | 
 | 502 |   uint32_t GetReferenceOffsets() const { | 
 | 503 |     return reference_offsets_; | 
 | 504 |   } | 
 | 505 |  | 
 | 506 |   void SetReferenceOffsets(uint32_t new_reference_offsets) { | 
 | 507 |     reference_offsets_ = new_reference_offsets; | 
 | 508 |   } | 
 | 509 |  | 
 | 510 |   Method* FindDirectMethodLocally(const StringPiece& name, | 
 | 511 |                                   const StringPiece& descriptor) const; | 
 | 512 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 513 |  public: // TODO: private | 
 | 514 |   // leave space for instance data; we could access fields directly if | 
 | 515 |   // we freeze the definition of java/lang/Class | 
| Carl Shapiro | 894d0fa | 2011-06-30 14:48:49 -0700 | [diff] [blame] | 516 | #define CLASS_FIELD_SLOTS 4 | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 517 |   uint32_t instance_data_[CLASS_FIELD_SLOTS]; | 
 | 518 | #undef CLASS_FIELD_SLOTS | 
 | 519 |  | 
 | 520 |   // UTF-8 descriptor for the class from constant pool | 
 | 521 |   // ("Ljava/lang/Class;"), or on heap if generated ("[C") | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 522 |   StringPiece descriptor_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 523 |  | 
 | 524 |   // Proxy classes have their descriptor allocated on the native heap. | 
 | 525 |   // When this field is non-NULL it must be explicitly freed. | 
 | 526 |   char* descriptor_alloc_; | 
 | 527 |  | 
 | 528 |   // access flags; low 16 bits are defined by VM spec | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 529 |   uint32_t access_flags_;  // TODO: make an instance field? | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 530 |  | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 531 |   // DexFile from which we came; needed to resolve constant pool entries | 
 | 532 |   // (will be NULL for VM-generated, e.g. arrays and primitive classes) | 
 | 533 |   DexFile* dex_file_; | 
 | 534 |  | 
 | 535 |   // state of class initialization | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 536 |   Status status_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 537 |  | 
 | 538 |   // if class verify fails, we must return same error on subsequent tries | 
 | 539 |   Class* verify_error_class_; | 
 | 540 |  | 
 | 541 |   // threadId, used to check for recursive <clinit> invocation | 
 | 542 |   uint32_t clinit_thread_id_; | 
 | 543 |  | 
 | 544 |   // Total object size; used when allocating storage on gc heap.  (For | 
 | 545 |   // interfaces and abstract classes this will be zero.) | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 546 |   size_t object_size_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 547 |  | 
 | 548 |   // For array classes, the class object for base element, for | 
 | 549 |   // instanceof/checkcast (for String[][][], this will be String). | 
 | 550 |   // Otherwise, NULL. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 551 |   Class* component_type_;  // TODO: make an instance field | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 552 |  | 
 | 553 |   // For array classes, the number of array dimensions, e.g. int[][] | 
 | 554 |   // is 2.  Otherwise 0. | 
 | 555 |   int32_t array_rank_; | 
 | 556 |  | 
 | 557 |   // primitive type index, or PRIM_NOT (-1); set for generated prim classes | 
 | 558 |   PrimitiveType primitive_type_; | 
 | 559 |  | 
 | 560 |   // The superclass, or NULL if this is java.lang.Object or a | 
 | 561 |   // primitive type. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 562 |   Class* super_class_;  // TODO: make an instance field | 
 | 563 |   uint32_t super_class_idx_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 564 |  | 
 | 565 |   // defining class loader, or NULL for the "bootstrap" system loader | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 566 |   Object* class_loader_;  // TODO: make an instance field | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 567 |  | 
 | 568 |   // initiating class loader list | 
 | 569 |   // NOTE: for classes with low serialNumber, these are unused, and the | 
 | 570 |   // values are kept in a table in gDvm. | 
 | 571 |   //InitiatingLoaderList initiating_loader_list_; | 
 | 572 |  | 
 | 573 |   // array of interfaces this class implements directly | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 574 |   size_t interface_count_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 575 |   Class** interfaces_; | 
 | 576 |  | 
 | 577 |   // static, private, and <init> methods | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 578 |   size_t num_direct_methods_; | 
 | 579 |   Method* direct_methods_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 580 |  | 
 | 581 |   // virtual methods defined in this class; invoked through vtable | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 582 |   size_t num_virtual_methods_; | 
 | 583 |   Method* virtual_methods_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 584 |  | 
 | 585 |   // Virtual method table (vtable), for use by "invoke-virtual".  The | 
 | 586 |   // vtable from the superclass is copied in, and virtual methods from | 
 | 587 |   // our class either replace those from the super or are appended. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 588 |   size_t vtable_count_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 589 |   Method** vtable_; | 
 | 590 |  | 
 | 591 |   // Interface table (iftable), one entry per interface supported by | 
 | 592 |   // this class.  That means one entry for each interface we support | 
 | 593 |   // directly, indirectly via superclass, or indirectly via | 
 | 594 |   // superinterface.  This will be null if neither we nor our | 
 | 595 |   // superclass implement any interfaces. | 
 | 596 |   // | 
 | 597 |   // Why we need this: given "class Foo implements Face", declare | 
 | 598 |   // "Face faceObj = new Foo()".  Invoke faceObj.blah(), where "blah" | 
 | 599 |   // is part of the Face interface.  We can't easily use a single | 
 | 600 |   // vtable. | 
 | 601 |   // | 
 | 602 |   // For every interface a concrete class implements, we create a list | 
 | 603 |   // of virtualMethod indices for the methods in the interface. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 604 |   size_t iftable_count_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 605 |   InterfaceEntry* iftable_; | 
 | 606 |  | 
 | 607 |   // The interface vtable indices for iftable get stored here.  By | 
 | 608 |   // placing them all in a single pool for each class that implements | 
 | 609 |   // interfaces, we decrease the number of allocations. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 610 |   size_t ifvi_pool_count_; | 
 | 611 |   uint32_t* ifvi_pool_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 612 |  | 
 | 613 |   // instance fields | 
 | 614 |   // | 
 | 615 |   // These describe the layout of the contents of a | 
 | 616 |   // DataObject-compatible Object.  Note that only the fields directly | 
 | 617 |   // declared by this class are listed in ifields; fields declared by | 
 | 618 |   // a superclass are listed in the superclass's ClassObject.ifields. | 
 | 619 |   // | 
 | 620 |   // All instance fields that refer to objects are guaranteed to be at | 
 | 621 |   // the beginning of the field list.  ifieldRefCount specifies the | 
 | 622 |   // number of reference fields. | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 623 |   size_t num_ifields_; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 624 |  | 
 | 625 |   // number of fields that are object refs | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 626 |   size_t num_reference_ifields_; | 
 | 627 |   InstanceField* ifields_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 628 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 629 |   // Bitmap of offsets of ifields. | 
 | 630 |   uint32_t reference_offsets_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 631 |  | 
 | 632 |   // source file name, if known.  Otherwise, NULL. | 
 | 633 |   const char* source_file_; | 
 | 634 |  | 
 | 635 |   // Static fields | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 636 |   size_t num_sfields_; | 
 | 637 |   StaticField sfields_[];  // MUST be last item | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 638 | }; | 
 | 639 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 640 | class DataObject : public Object { | 
 | 641 |  public: | 
 | 642 |   uint32_t fields_[1]; | 
 | 643 | }; | 
 | 644 |  | 
 | 645 | class String : public Object { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 646 |  public: | 
 | 647 |   Array* array_; | 
 | 648 |  | 
 | 649 |   uint32_t hash_code_; | 
 | 650 |  | 
 | 651 |   uint32_t offset_; | 
 | 652 |  | 
 | 653 |   uint32_t count_; | 
 | 654 | }; | 
 | 655 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 656 | class Array : public Object { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 657 |  public: | 
 | 658 |   // The number of array elements. | 
 | 659 |   uint32_t length_; | 
 | 660 | }; | 
 | 661 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 662 | class InterfaceEntry { | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 663 |  public: | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 664 |   Class* GetClass() const { | 
 | 665 |     return klass_; | 
 | 666 |   }; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 667 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 668 |   void SetClass(Class* klass) { | 
 | 669 |     klass_ = klass; | 
 | 670 |   }; | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 671 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 672 |  private: | 
 | 673 |   // Points to the interface class. | 
| Carl Shapiro | 3ee755d | 2011-06-28 12:11:04 -0700 | [diff] [blame] | 674 |   Class* klass_; | 
 | 675 |  | 
| Carl Shapiro | 0e5d75d | 2011-07-06 18:28:37 -0700 | [diff] [blame^] | 676 |  public:  // TODO: private | 
 | 677 |   // Index into array of vtable offsets.  This points into the | 
 | 678 |   // ifviPool, which holds the vtables for all interfaces declared by | 
 | 679 |   // this class. | 
 | 680 |   uint32_t* method_index_array_; | 
| Carl Shapiro | 1fb8620 | 2011-06-27 17:43:13 -0700 | [diff] [blame] | 681 | }; | 
 | 682 |  | 
 | 683 | }  // namespace art | 
 | 684 |  | 
 | 685 | #endif  // ART_SRC_OBJECT_H_ |