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