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