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