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