object-inl.h revision 2c4257be8191c5eefde744e8965fcefc80a0a97d
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_ 18#define ART_RUNTIME_MIRROR_OBJECT_INL_H_ 19 20#include "object.h" 21 22#include "art_field.h" 23#include "art_method.h" 24#include "atomic.h" 25#include "array-inl.h" 26#include "class.h" 27#include "lock_word-inl.h" 28#include "monitor.h" 29#include "object_array-inl.h" 30#include "read_barrier-inl.h" 31#include "runtime.h" 32#include "reference.h" 33#include "throwable.h" 34 35namespace art { 36namespace mirror { 37 38inline uint32_t Object::ClassSize() { 39 uint32_t vtable_entries = kVTableLength; 40 return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0); 41} 42 43template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 44inline Class* Object::GetClass() { 45 return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>( 46 OFFSET_OF_OBJECT_MEMBER(Object, klass_)); 47} 48 49template<VerifyObjectFlags kVerifyFlags> 50inline void Object::SetClass(Class* new_klass) { 51 // new_klass may be NULL prior to class linker initialization. 52 // We don't mark the card as this occurs as part of object allocation. Not all objects have 53 // backing cards, such as large objects. 54 // We use non transactional version since we can't undo this write. We also disable checking as 55 // we may run in transaction mode here. 56 SetFieldObjectWithoutWriteBarrier<false, false, 57 static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>( 58 OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass); 59} 60 61inline LockWord Object::GetLockWord(bool as_volatile) { 62 if (as_volatile) { 63 return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); 64 } 65 return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); 66} 67 68inline void Object::SetLockWord(LockWord new_val, bool as_volatile) { 69 // Force use of non-transactional mode and do not check. 70 if (as_volatile) { 71 SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); 72 } else { 73 SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); 74 } 75} 76 77inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) { 78 // Force use of non-transactional mode and do not check. 79 return CasFieldWeakSequentiallyConsistent32<false, false>( 80 OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); 81} 82 83inline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) { 84 // Force use of non-transactional mode and do not check. 85 return CasFieldWeakRelaxed32<false, false>( 86 OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); 87} 88 89inline uint32_t Object::GetLockOwnerThreadId() { 90 return Monitor::GetLockOwnerThreadId(this); 91} 92 93inline mirror::Object* Object::MonitorEnter(Thread* self) { 94 return Monitor::MonitorEnter(self, this); 95} 96 97inline bool Object::MonitorExit(Thread* self) { 98 return Monitor::MonitorExit(self, this); 99} 100 101inline void Object::Notify(Thread* self) { 102 Monitor::Notify(self, this); 103} 104 105inline void Object::NotifyAll(Thread* self) { 106 Monitor::NotifyAll(self, this); 107} 108 109inline void Object::Wait(Thread* self) { 110 Monitor::Wait(self, this, 0, 0, true, kWaiting); 111} 112 113inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 114 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 115} 116 117inline Object* Object::GetReadBarrierPointer() { 118#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 119 DCHECK(kUseBakerOrBrooksReadBarrier); 120 return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>( 121 OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_)); 122#else 123 LOG(FATAL) << "Unreachable"; 124 UNREACHABLE(); 125#endif 126} 127 128inline void Object::SetReadBarrierPointer(Object* rb_ptr) { 129#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 130 DCHECK(kUseBakerOrBrooksReadBarrier); 131 // We don't mark the card as this occurs as part of object allocation. Not all objects have 132 // backing cards, such as large objects. 133 SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 134 OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr); 135#else 136 LOG(FATAL) << "Unreachable"; 137 UNREACHABLE(); 138#endif 139} 140 141inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { 142#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 143 DCHECK(kUseBakerOrBrooksReadBarrier); 144 MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); 145 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue(); 146 Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 147 HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); 148 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); 149 do { 150 if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) { 151 // Lost the race. 152 return false; 153 } 154 } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_, 155 new_ref.reference_)); 156 DCHECK_EQ(new_ref.reference_, atomic_rb_ptr->LoadRelaxed()); 157 return true; 158#else 159 LOG(FATAL) << "Unreachable"; 160 UNREACHABLE(); 161#endif 162} 163 164inline void Object::AssertReadBarrierPointer() const { 165 if (kUseBakerReadBarrier) { 166 Object* obj = const_cast<Object*>(this); 167 DCHECK(obj->GetReadBarrierPointer() == nullptr) 168 << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 169 << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 170 } else { 171 CHECK(kUseBrooksReadBarrier); 172 Object* obj = const_cast<Object*>(this); 173 DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 174 << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 175 << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 176 } 177} 178 179template<VerifyObjectFlags kVerifyFlags> 180inline bool Object::VerifierInstanceOf(Class* klass) { 181 DCHECK(klass != NULL); 182 DCHECK(GetClass<kVerifyFlags>() != NULL); 183 return klass->IsInterface() || InstanceOf(klass); 184} 185 186template<VerifyObjectFlags kVerifyFlags> 187inline bool Object::InstanceOf(Class* klass) { 188 DCHECK(klass != NULL); 189 DCHECK(GetClass<kVerifyNone>() != NULL); 190 return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 191} 192 193template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 194inline bool Object::IsClass() { 195 Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 196 template GetClass<kVerifyFlags, kReadBarrierOption>(); 197 return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), 198 kReadBarrierOption>() == java_lang_Class; 199} 200 201template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 202inline Class* Object::AsClass() { 203 DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>())); 204 return down_cast<Class*>(this); 205} 206 207template<VerifyObjectFlags kVerifyFlags> 208inline bool Object::IsObjectArray() { 209 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 210 return IsArrayInstance<kVerifyFlags>() && 211 !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive(); 212} 213 214template<class T, VerifyObjectFlags kVerifyFlags> 215inline ObjectArray<T>* Object::AsObjectArray() { 216 DCHECK(IsObjectArray<kVerifyFlags>()); 217 return down_cast<ObjectArray<T>*>(this); 218} 219 220template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 221inline bool Object::IsArrayInstance() { 222 return GetClass<kVerifyFlags, kReadBarrierOption>()-> 223 template IsArrayClass<kVerifyFlags, kReadBarrierOption>(); 224} 225 226template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 227inline bool Object::IsArtField() { 228 return GetClass<kVerifyFlags, kReadBarrierOption>()-> 229 template IsArtFieldClass<kReadBarrierOption>(); 230} 231 232template<VerifyObjectFlags kVerifyFlags> 233inline ArtField* Object::AsArtField() { 234 DCHECK(IsArtField<kVerifyFlags>()); 235 return down_cast<ArtField*>(this); 236} 237 238template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 239inline bool Object::IsArtMethod() { 240 return GetClass<kVerifyFlags, kReadBarrierOption>()-> 241 template IsArtMethodClass<kReadBarrierOption>(); 242} 243 244template<VerifyObjectFlags kVerifyFlags> 245inline ArtMethod* Object::AsArtMethod() { 246 DCHECK(IsArtMethod<kVerifyFlags>()); 247 return down_cast<ArtMethod*>(this); 248} 249 250template<VerifyObjectFlags kVerifyFlags> 251inline bool Object::IsReferenceInstance() { 252 return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass(); 253} 254 255template<VerifyObjectFlags kVerifyFlags> 256inline Reference* Object::AsReference() { 257 DCHECK(IsReferenceInstance<kVerifyFlags>()); 258 return down_cast<Reference*>(this); 259} 260 261template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 262inline Array* Object::AsArray() { 263 DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>())); 264 return down_cast<Array*>(this); 265} 266 267template<VerifyObjectFlags kVerifyFlags> 268inline BooleanArray* Object::AsBooleanArray() { 269 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 270 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 271 DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 272 return down_cast<BooleanArray*>(this); 273} 274 275template<VerifyObjectFlags kVerifyFlags> 276inline ByteArray* Object::AsByteArray() { 277 static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 278 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 279 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 280 return down_cast<ByteArray*>(this); 281} 282 283template<VerifyObjectFlags kVerifyFlags> 284inline ByteArray* Object::AsByteSizedArray() { 285 constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 286 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 287 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 288 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 289 return down_cast<ByteArray*>(this); 290} 291 292template<VerifyObjectFlags kVerifyFlags> 293inline CharArray* Object::AsCharArray() { 294 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 295 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 296 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 297 return down_cast<CharArray*>(this); 298} 299 300template<VerifyObjectFlags kVerifyFlags> 301inline ShortArray* Object::AsShortArray() { 302 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 303 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 304 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 305 return down_cast<ShortArray*>(this); 306} 307 308template<VerifyObjectFlags kVerifyFlags> 309inline ShortArray* Object::AsShortSizedArray() { 310 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 311 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 312 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 313 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 314 return down_cast<ShortArray*>(this); 315} 316 317template<VerifyObjectFlags kVerifyFlags> 318inline IntArray* Object::AsIntArray() { 319 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 320 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 321 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() || 322 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 323 return down_cast<IntArray*>(this); 324} 325 326template<VerifyObjectFlags kVerifyFlags> 327inline LongArray* Object::AsLongArray() { 328 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 329 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 330 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() || 331 GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 332 return down_cast<LongArray*>(this); 333} 334 335template<VerifyObjectFlags kVerifyFlags> 336inline FloatArray* Object::AsFloatArray() { 337 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 338 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 339 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 340 return down_cast<FloatArray*>(this); 341} 342 343template<VerifyObjectFlags kVerifyFlags> 344inline DoubleArray* Object::AsDoubleArray() { 345 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 346 DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 347 DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 348 return down_cast<DoubleArray*>(this); 349} 350 351template<VerifyObjectFlags kVerifyFlags> 352inline String* Object::AsString() { 353 DCHECK(GetClass<kVerifyFlags>()->IsStringClass()); 354 return down_cast<String*>(this); 355} 356 357template<VerifyObjectFlags kVerifyFlags> 358inline Throwable* Object::AsThrowable() { 359 DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 360 return down_cast<Throwable*>(this); 361} 362 363template<VerifyObjectFlags kVerifyFlags> 364inline bool Object::IsWeakReferenceInstance() { 365 return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 366} 367 368template<VerifyObjectFlags kVerifyFlags> 369inline bool Object::IsSoftReferenceInstance() { 370 return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 371} 372 373template<VerifyObjectFlags kVerifyFlags> 374inline bool Object::IsFinalizerReferenceInstance() { 375 return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 376} 377 378template<VerifyObjectFlags kVerifyFlags> 379inline FinalizerReference* Object::AsFinalizerReference() { 380 DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 381 return down_cast<FinalizerReference*>(this); 382} 383 384template<VerifyObjectFlags kVerifyFlags> 385inline bool Object::IsPhantomReferenceInstance() { 386 return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 387} 388 389template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 390inline size_t Object::SizeOf() { 391 size_t result; 392 constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 393 if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) { 394 result = AsArray<kNewFlags, kReadBarrierOption>()-> 395 template SizeOf<kNewFlags, kReadBarrierOption>(); 396 } else if (IsClass<kNewFlags, kReadBarrierOption>()) { 397 result = AsClass<kNewFlags, kReadBarrierOption>()-> 398 template SizeOf<kNewFlags, kReadBarrierOption>(); 399 } else { 400 result = GetClass<kNewFlags, kReadBarrierOption>()-> 401 template GetObjectSize<kNewFlags, kReadBarrierOption>(); 402 } 403 DCHECK_GE(result, sizeof(Object)) 404 << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>()); 405 DCHECK(!(IsArtField<kNewFlags, kReadBarrierOption>()) || result == sizeof(ArtField)); 406 DCHECK(!(IsArtMethod<kNewFlags, kReadBarrierOption>()) || result == sizeof(ArtMethod)); 407 return result; 408} 409 410template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 411inline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) { 412 if (kVerifyFlags & kVerifyThis) { 413 VerifyObject(this); 414 } 415 return GetField<uint8_t, kIsVolatile>(field_offset); 416} 417 418template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 419inline int8_t Object::GetFieldByte(MemberOffset field_offset) { 420 if (kVerifyFlags & kVerifyThis) { 421 VerifyObject(this); 422 } 423 return GetField<int8_t, kIsVolatile>(field_offset); 424} 425 426template<VerifyObjectFlags kVerifyFlags> 427inline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) { 428 return GetFieldBoolean<kVerifyFlags, true>(field_offset); 429} 430 431template<VerifyObjectFlags kVerifyFlags> 432inline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) { 433 return GetFieldByte<kVerifyFlags, true>(field_offset); 434} 435 436template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 437 bool kIsVolatile> 438inline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value) 439 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 440 if (kCheckTransaction) { 441 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 442 } 443 if (kTransactionActive) { 444 Runtime::Current()->RecordWriteFieldBoolean(this, field_offset, 445 GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset), 446 kIsVolatile); 447 } 448 if (kVerifyFlags & kVerifyThis) { 449 VerifyObject(this); 450 } 451 SetField<uint8_t, kIsVolatile>(field_offset, new_value); 452} 453 454template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 455 bool kIsVolatile> 456inline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) 457 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 458 if (kCheckTransaction) { 459 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 460 } 461 if (kTransactionActive) { 462 Runtime::Current()->RecordWriteFieldByte(this, field_offset, 463 GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset), 464 kIsVolatile); 465 } 466 if (kVerifyFlags & kVerifyThis) { 467 VerifyObject(this); 468 } 469 SetField<int8_t, kIsVolatile>(field_offset, new_value); 470} 471 472template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 473inline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) { 474 return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 475 field_offset, new_value); 476} 477 478template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 479inline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) { 480 return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 481 field_offset, new_value); 482} 483 484template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 485inline uint16_t Object::GetFieldChar(MemberOffset field_offset) { 486 if (kVerifyFlags & kVerifyThis) { 487 VerifyObject(this); 488 } 489 return GetField<uint16_t, kIsVolatile>(field_offset); 490} 491 492template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 493inline int16_t Object::GetFieldShort(MemberOffset field_offset) { 494 if (kVerifyFlags & kVerifyThis) { 495 VerifyObject(this); 496 } 497 return GetField<int16_t, kIsVolatile>(field_offset); 498} 499 500template<VerifyObjectFlags kVerifyFlags> 501inline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) { 502 return GetFieldChar<kVerifyFlags, true>(field_offset); 503} 504 505template<VerifyObjectFlags kVerifyFlags> 506inline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) { 507 return GetFieldShort<kVerifyFlags, true>(field_offset); 508} 509 510template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 511 bool kIsVolatile> 512inline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) { 513 if (kCheckTransaction) { 514 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 515 } 516 if (kTransactionActive) { 517 Runtime::Current()->RecordWriteFieldChar(this, field_offset, 518 GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset), 519 kIsVolatile); 520 } 521 if (kVerifyFlags & kVerifyThis) { 522 VerifyObject(this); 523 } 524 SetField<uint16_t, kIsVolatile>(field_offset, new_value); 525} 526 527template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 528 bool kIsVolatile> 529inline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) { 530 if (kCheckTransaction) { 531 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 532 } 533 if (kTransactionActive) { 534 Runtime::Current()->RecordWriteFieldChar(this, field_offset, 535 GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset), 536 kIsVolatile); 537 } 538 if (kVerifyFlags & kVerifyThis) { 539 VerifyObject(this); 540 } 541 SetField<int16_t, kIsVolatile>(field_offset, new_value); 542} 543 544template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 545inline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) { 546 return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 547 field_offset, new_value); 548} 549 550template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 551inline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) { 552 return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 553 field_offset, new_value); 554} 555 556template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 557inline int32_t Object::GetField32(MemberOffset field_offset) { 558 if (kVerifyFlags & kVerifyThis) { 559 VerifyObject(this); 560 } 561 return GetField<int32_t, kIsVolatile>(field_offset); 562} 563 564template<VerifyObjectFlags kVerifyFlags> 565inline int32_t Object::GetField32Volatile(MemberOffset field_offset) { 566 return GetField32<kVerifyFlags, true>(field_offset); 567} 568 569template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 570 bool kIsVolatile> 571inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { 572 if (kCheckTransaction) { 573 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 574 } 575 if (kTransactionActive) { 576 Runtime::Current()->RecordWriteField32(this, field_offset, 577 GetField32<kVerifyFlags, kIsVolatile>(field_offset), 578 kIsVolatile); 579 } 580 if (kVerifyFlags & kVerifyThis) { 581 VerifyObject(this); 582 } 583 SetField<int32_t, kIsVolatile>(field_offset, new_value); 584} 585 586template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 587inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) { 588 SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value); 589} 590 591// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication? 592 593template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 594inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, 595 int32_t old_value, int32_t new_value) { 596 if (kCheckTransaction) { 597 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 598 } 599 if (kTransactionActive) { 600 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 601 } 602 if (kVerifyFlags & kVerifyThis) { 603 VerifyObject(this); 604 } 605 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 606 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 607 608 return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 609} 610 611template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 612inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, 613 int32_t old_value, int32_t new_value) { 614 if (kCheckTransaction) { 615 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 616 } 617 if (kTransactionActive) { 618 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 619 } 620 if (kVerifyFlags & kVerifyThis) { 621 VerifyObject(this); 622 } 623 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 624 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 625 626 return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value); 627} 628 629template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 630inline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset, 631 int32_t old_value, int32_t new_value) { 632 if (kCheckTransaction) { 633 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 634 } 635 if (kTransactionActive) { 636 Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 637 } 638 if (kVerifyFlags & kVerifyThis) { 639 VerifyObject(this); 640 } 641 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 642 AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 643 644 return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 645} 646 647template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 648inline int64_t Object::GetField64(MemberOffset field_offset) { 649 if (kVerifyFlags & kVerifyThis) { 650 VerifyObject(this); 651 } 652 return GetField<int64_t, kIsVolatile>(field_offset); 653} 654 655template<VerifyObjectFlags kVerifyFlags> 656inline int64_t Object::GetField64Volatile(MemberOffset field_offset) { 657 return GetField64<kVerifyFlags, true>(field_offset); 658} 659 660template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 661 bool kIsVolatile> 662inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) { 663 if (kCheckTransaction) { 664 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 665 } 666 if (kTransactionActive) { 667 Runtime::Current()->RecordWriteField64(this, field_offset, 668 GetField64<kVerifyFlags, kIsVolatile>(field_offset), 669 kIsVolatile); 670 } 671 if (kVerifyFlags & kVerifyThis) { 672 VerifyObject(this); 673 } 674 SetField<int64_t, kIsVolatile>(field_offset, new_value); 675} 676 677template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 678inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) { 679 return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 680 new_value); 681} 682 683template<typename kSize, bool kIsVolatile> 684inline void Object::SetField(MemberOffset field_offset, kSize new_value) { 685 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 686 kSize* addr = reinterpret_cast<kSize*>(raw_addr); 687 if (kIsVolatile) { 688 reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value); 689 } else { 690 reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value); 691 } 692} 693 694template<typename kSize, bool kIsVolatile> 695inline kSize Object::GetField(MemberOffset field_offset) { 696 const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value(); 697 const kSize* addr = reinterpret_cast<const kSize*>(raw_addr); 698 if (kIsVolatile) { 699 return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent(); 700 } else { 701 return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData(); 702 } 703} 704 705template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 706inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, 707 int64_t old_value, int64_t new_value) { 708 if (kCheckTransaction) { 709 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 710 } 711 if (kTransactionActive) { 712 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 713 } 714 if (kVerifyFlags & kVerifyThis) { 715 VerifyObject(this); 716 } 717 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 718 Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 719 return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 720} 721 722template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 723inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset, 724 int64_t old_value, int64_t new_value) { 725 if (kCheckTransaction) { 726 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 727 } 728 if (kTransactionActive) { 729 Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 730 } 731 if (kVerifyFlags & kVerifyThis) { 732 VerifyObject(this); 733 } 734 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 735 Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 736 return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 737} 738 739template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, 740 bool kIsVolatile> 741inline T* Object::GetFieldObject(MemberOffset field_offset) { 742 if (kVerifyFlags & kVerifyThis) { 743 VerifyObject(this); 744 } 745 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 746 HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 747 T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr); 748 if (kIsVolatile) { 749 // TODO: Refactor to use a SequentiallyConsistent load instead. 750 QuasiAtomic::ThreadFenceAcquire(); // Ensure visibility of operations preceding store. 751 } 752 if (kVerifyFlags & kVerifyReads) { 753 VerifyObject(result); 754 } 755 return result; 756} 757 758template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 759inline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) { 760 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset); 761} 762 763template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 764 bool kIsVolatile> 765inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, 766 Object* new_value) { 767 if (kCheckTransaction) { 768 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 769 } 770 if (kTransactionActive) { 771 mirror::Object* obj; 772 if (kIsVolatile) { 773 obj = GetFieldObjectVolatile<Object>(field_offset); 774 } else { 775 obj = GetFieldObject<Object>(field_offset); 776 } 777 Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true); 778 } 779 if (kVerifyFlags & kVerifyThis) { 780 VerifyObject(this); 781 } 782 if (kVerifyFlags & kVerifyWrites) { 783 VerifyObject(new_value); 784 } 785 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 786 HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 787 if (kIsVolatile) { 788 // TODO: Refactor to use a SequentiallyConsistent store instead. 789 QuasiAtomic::ThreadFenceRelease(); // Ensure that prior accesses are visible before store. 790 objref_addr->Assign(new_value); 791 QuasiAtomic::ThreadFenceSequentiallyConsistent(); 792 // Ensure this store occurs before any volatile loads. 793 } else { 794 objref_addr->Assign(new_value); 795 } 796} 797 798template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 799 bool kIsVolatile> 800inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) { 801 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags, 802 kIsVolatile>(field_offset, new_value); 803 if (new_value != nullptr) { 804 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 805 // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this. 806 CheckFieldAssignment(field_offset, new_value); 807 } 808} 809 810template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 811inline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) { 812 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 813 new_value); 814} 815 816template <VerifyObjectFlags kVerifyFlags> 817inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 818 if (kVerifyFlags & kVerifyThis) { 819 VerifyObject(this); 820 } 821 return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) + 822 field_offset.Int32Value()); 823} 824 825template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 826inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, 827 Object* old_value, Object* new_value) { 828 if (kCheckTransaction) { 829 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 830 } 831 if (kVerifyFlags & kVerifyThis) { 832 VerifyObject(this); 833 } 834 if (kVerifyFlags & kVerifyWrites) { 835 VerifyObject(new_value); 836 } 837 if (kVerifyFlags & kVerifyReads) { 838 VerifyObject(old_value); 839 } 840 if (kTransactionActive) { 841 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 842 } 843 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 844 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 845 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 846 Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 847 848 bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_, 849 new_ref.reference_); 850 851 if (success) { 852 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 853 } 854 return success; 855} 856 857template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 858inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset, 859 Object* old_value, Object* new_value) { 860 if (kCheckTransaction) { 861 DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 862 } 863 if (kVerifyFlags & kVerifyThis) { 864 VerifyObject(this); 865 } 866 if (kVerifyFlags & kVerifyWrites) { 867 VerifyObject(new_value); 868 } 869 if (kVerifyFlags & kVerifyReads) { 870 VerifyObject(old_value); 871 } 872 if (kTransactionActive) { 873 Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 874 } 875 HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 876 HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 877 uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 878 Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 879 880 bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_, 881 new_ref.reference_); 882 883 if (success) { 884 Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 885 } 886 return success; 887} 888 889template<bool kVisitClass, bool kIsStatic, typename Visitor> 890inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 891 if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) { 892 // Instance fields and not the slow-path. 893 if (kVisitClass) { 894 visitor(this, ClassOffset(), kIsStatic); 895 } 896 uint32_t field_offset = mirror::kObjectHeaderSize; 897 while (ref_offsets != 0) { 898 if ((ref_offsets & 1) != 0) { 899 visitor(this, MemberOffset(field_offset), kIsStatic); 900 } 901 ref_offsets >>= 1; 902 field_offset += sizeof(mirror::HeapReference<mirror::Object>); 903 } 904 } else { 905 // There is no reference offset bitmap. In the non-static case, walk up the class 906 // inheritance hierarchy and find reference offsets the hard way. In the static case, just 907 // consider this class. 908 for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr; 909 klass = kIsStatic ? nullptr : klass->GetSuperClass()) { 910 size_t num_reference_fields = 911 kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 912 for (size_t i = 0; i < num_reference_fields; ++i) { 913 mirror::ArtField* field = kIsStatic ? klass->GetStaticField(i) : klass->GetInstanceField(i); 914 MemberOffset field_offset = field->GetOffset(); 915 // TODO: Do a simpler check? 916 if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) { 917 visitor(this, field_offset, kIsStatic); 918 } 919 } 920 } 921 } 922} 923 924template<bool kVisitClass, typename Visitor> 925inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 926 VisitFieldsReferences<kVisitClass, false>( 927 klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); 928} 929 930template<bool kVisitClass, typename Visitor> 931inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 932 DCHECK(!klass->IsTemp()); 933 klass->VisitFieldsReferences<kVisitClass, true>(0, visitor); 934} 935 936template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor, 937 typename JavaLangRefVisitor> 938inline void Object::VisitReferences(const Visitor& visitor, 939 const JavaLangRefVisitor& ref_visitor) { 940 mirror::Class* klass = GetClass<kVerifyFlags>(); 941 if (klass == Class::GetJavaLangClass()) { 942 AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); 943 } else if (klass->IsArrayClass()) { 944 if (klass->IsObjectArrayClass<kVerifyNone>()) { 945 AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); 946 } else if (kVisitClass) { 947 visitor(this, ClassOffset(), false); 948 } 949 } else { 950 DCHECK(!klass->IsVariableSize()); 951 VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); 952 if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) { 953 ref_visitor(klass, AsReference()); 954 } 955 } 956} 957 958} // namespace mirror 959} // namespace art 960 961#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 962