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