object-inl.h revision 9103c86a98524e9ddfd14f8cee56e919f68eee9b
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/*
22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project
32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License.
62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at
72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software
112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and
142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License.
152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */
162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_OBJECT_INL_H_
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
22ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_field.h"
23ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_method.h"
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "atomic.h"
254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "array-inl.h"
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h"
27d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word-inl.h"
2805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "monitor.h"
29800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h"
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h"
318fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h"
3205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h"
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
379103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() {
399103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>(
409103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) {
45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // new_klass may be NULL prior to class linker initialization.
46ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // We don't mark the card as this occurs as part of object allocation. Not all objects have
47ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // backing cards, such as large objects.
48d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // We use non transactional version since we can't undo this write. We also disable checking as
49d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // we may run in transaction mode here.
504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<false, false,
514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false);
532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
55ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline LockWord Object::GetLockWord() {
56d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
57d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
58d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
59d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline void Object::SetLockWord(LockWord new_val) {
60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
61d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
63d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
64d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
66d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
67d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                  new_val.GetValue());
68d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
70d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() {
71d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return Monitor::GetLockOwnerThreadId(this);
7205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
7305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
74e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) {
75e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return Monitor::MonitorEnter(self, this);
7605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
7705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
7805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) {
7905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return Monitor::MonitorExit(self, this);
8005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
8105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
8205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) {
8305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Notify(self, this);
8405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
8505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
8605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) {
8705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::NotifyAll(self, this);
8805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
8905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
9005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) {
9105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, 0, 0, true, kWaiting);
9205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
9405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
9505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
9605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
98624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() {
99624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
100624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi  DCHECK(kUseBakerOrBrooksReadBarrier);
101800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  return GetFieldObject<Object, kVerifyNone, false>(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false);
1029d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1039d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1049d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  return nullptr;
1059d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1079d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1089103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) {
109624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
110624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi  DCHECK(kUseBakerOrBrooksReadBarrier);
1119d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // We don't mark the card as this occurs as part of object allocation. Not all objects have
1129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // backing cards, such as large objects.
1139d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
1149103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr, false);
1159103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else
1169103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1179103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif
1189103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi}
1199103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi
1209103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
1219103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
1229103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK(kUseBakerOrBrooksReadBarrier);
1239103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
1249103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue();
1259103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr);
1269103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
1279103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
1289103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  uint32_t expected_val = expected_ref.reference_;
1299103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  uint32_t new_val;
1309103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  do {
1319103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    uint32_t old_val = ref->reference_;
1329103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    if (old_val != expected_val) {
1339103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      // Lost the race.
1349103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      return false;
1359103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    }
1369103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    new_val = new_ref.reference_;
1379103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  } while (!__sync_bool_compare_and_swap(
1389103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val));
1399103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK_EQ(new_val, ref->reference_);
1409103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return true;
1419d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1429d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1439103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return false;
1449d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1459d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1469d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
147624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const {
148800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  if (kUseBakerReadBarrier) {
149800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
150800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK(obj->GetReadBarrierPointer() == nullptr)
151800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
152800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
153800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  } else if (kUseBrooksReadBarrier) {
154800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
155800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK_EQ(obj, obj->GetReadBarrierPointer())
156800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
157800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
158800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  } else {
159800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    LOG(FATAL) << "Unreachable";
160800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  }
1619d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1629d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
164ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) {
165a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  DCHECK(klass != NULL);
1664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>() != NULL);
167a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  return klass->IsInterface() || InstanceOf(klass);
168a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao}
169a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao
1704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
171ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) {
1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(klass != NULL);
1734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyNone>() != NULL);
1744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
1752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1779103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
178ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() {
1799103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  Class* java_lang_Class =
1809103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      GetClass<kVerifyFlags, kDoReadBarrier>()->template GetClass<kVerifyFlags, kDoReadBarrier>();
1819103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), kDoReadBarrier>() ==
1824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      java_lang_Class;
1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() {
1879103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK((IsClass<kVerifyFlags, kDoReadBarrier>()));
1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<Class*>(this);
1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
192ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() {
1934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
1944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return IsArrayInstance<kVerifyFlags>() &&
1954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
1962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags>
1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() {
2004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsObjectArray<kVerifyFlags>());
2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<ObjectArray<T>*>(this);
2022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2049103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
205ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() {
2069103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return GetClass<kVerifyFlags, kDoReadBarrier>()->
2079103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      template IsArrayClass<kVerifyFlags, kDoReadBarrier>();
2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2109103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
211ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtField() {
2129103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtFieldClass<kDoReadBarrier>();
2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
2164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline ArtField* Object::AsArtField() {
2174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArtField<kVerifyFlags>());
218ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  return down_cast<ArtField*>(this);
2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2219103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
222ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtMethod() {
2239103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtMethodClass<kDoReadBarrier>();
2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
227ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline ArtMethod* Object::AsArtMethod() {
2284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArtMethod<kVerifyFlags>());
229ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  return down_cast<ArtMethod*>(this);
2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
233ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() {
2344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsReferenceClass();
2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
2388fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() {
2398fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsReferenceInstance<kVerifyFlags>());
2408fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<Reference*>(this);
2418fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
2428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
2439103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
24405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() {
2459103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK((IsArrayInstance<kVerifyFlags, kDoReadBarrier>()));
24605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Array*>(this);
24705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
24805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
25005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() {
2514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
25405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<BooleanArray*>(this);
25505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
25605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
25805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() {
2594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
26205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ByteArray*>(this);
26305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
26405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() {
2674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
2704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
271ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ByteArray*>(this);
272ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
273ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
2744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
27505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() {
2764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<CharArray*>(this);
28005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
28105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
28305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() {
2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
28705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ShortArray*>(this);
28805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
28905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
291ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() {
2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
2954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
296ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ShortArray*>(this);
297ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
298ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline IntArray* Object::AsIntArray() {
3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
3044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<IntArray*>(this);
30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
30705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline LongArray* Object::AsLongArray() {
3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
3134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<LongArray*>(this);
31505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
31605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
318d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() {
3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
322d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<FloatArray*>(this);
323d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
324d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
326d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() {
3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
330d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<DoubleArray*>(this);
331d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
332d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
33405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() {
3354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
33605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<String*>(this);
33705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
33805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
34005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() {
3414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
34205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Throwable*>(this);
34305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
34405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
346ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() {
3474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
3482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
351ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() {
3524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
3532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
356ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() {
3574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
3582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
3618fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() {
3628fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
3638fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<FinalizerReference*>(this);
3648fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
3658fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
3668fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
367ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() {
3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
3692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3719103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
372ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() {
3732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t result;
3744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3759103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  if (IsArrayInstance<kVerifyFlags, kDoReadBarrier>()) {
3769103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    result = AsArray<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>();
3779103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  } else if (IsClass<kNewFlags, kDoReadBarrier>()) {
3789103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    result = AsClass<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>();
3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
3809103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    result = GetClass<kNewFlags, kDoReadBarrier>()->GetObjectSize();
3812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
3829103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK_GE(result, sizeof(Object))
3839103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      << " class=" << PrettyTypeOf(GetClass<kNewFlags, kDoReadBarrier>());
3849103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK(!(IsArtField<kNewFlags, kDoReadBarrier>())  || result == sizeof(ArtField));
3859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK(!(IsArtMethod<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtMethod));
3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return result;
3872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
39029501cf5663c7951717bae3521815d121a778396Ian Rogersinline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) {
3914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
3924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
3934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
394b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
395b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
396b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  if (UNLIKELY(is_volatile)) {
397b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr)));
398ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure volatile loads don't re-order.
399b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    return result;
400b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  } else {
401b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    return *word_addr;
402b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
403b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
404b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
4064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile) {
407d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
408d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
409d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
410d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
411d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile),
412d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                           is_volatile);
413d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
415b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    VerifyObject(this);
416b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
417b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
41829501cf5663c7951717bae3521815d121a778396Ian Rogers  int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
419b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  if (UNLIKELY(is_volatile)) {
420b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
421b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    *word_addr = new_value;
422ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any volatile loads.
423b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  } else {
424b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    *word_addr = new_value;
425b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
426b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
427b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
42929501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) {
430d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
431d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
432d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
433d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
434d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
435d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
439d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
44029501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
441b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  return __sync_bool_compare_and_swap(addr, old_value, new_value);
442d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
443d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
4444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
44529501cf5663c7951717bae3521815d121a778396Ian Rogersinline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) {
4464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
4492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  if (UNLIKELY(is_volatile)) {
45229501cf5663c7951717bae3521815d121a778396Ian Rogers    int64_t result = QuasiAtomic::Read64(addr);
453ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure volatile loads don't re-order.
4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return result;
4552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
4562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return *addr;
4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
4614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile) {
462d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
463d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
464d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
465d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
466d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile),
467d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                           is_volatile);
468d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
470ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
471ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
4742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  if (UNLIKELY(is_volatile)) {
475b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    QuasiAtomic::Write64(addr, new_value);
477b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    if (!QuasiAtomic::LongAtomicsUseMutexes()) {
478ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any volatile loads.
479b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    } else {
480b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers      // Fence from from mutex is enough.
481b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    }
4822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
4832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    *addr = new_value;
4842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
48829501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) {
489d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
490d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
491d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
492d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
493d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
494d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
498ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
49929501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr);
50029501cf5663c7951717bae3521815d121a778396Ian Rogers  return QuasiAtomic::Cas64(old_value, new_value, addr);
501ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
502ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
503800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
504ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) {
5054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
5064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
5074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
508ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
509ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
510800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  T* result = ReadBarrier::Barrier<T, kDoReadBarrier>(this, field_offset, objref_addr);
511ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(is_volatile)) {
512ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure loads don't re-order.
513ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
5144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
5154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(result);
5164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
517ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return result;
518ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
519ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
5204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
521ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
5224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier                                                      bool is_volatile) {
523d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
524d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
525d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
526d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
527d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset,
528d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                                  GetFieldObject<Object>(field_offset, is_volatile),
529d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                                  true);
530d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
5314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
532ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
533ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
5344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
5354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
5364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
537ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
538ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
539ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(is_volatile)) {
540ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
541ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
542ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any loads.
543ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
544ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
545ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
546ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
547ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
5484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
5494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile) {
5504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>(
5514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset, new_value, is_volatile);
552ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (new_value != nullptr) {
553ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    CheckFieldAssignment(field_offset, new_value);
554ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
555ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
556ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
557ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
5584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags>
5594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
5604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
5614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
5624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) +
5644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset.Int32Value());
5654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier}
5664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier
5674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
5684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value,
5694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier                                   Object* new_value) {
570d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
571d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
572d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
5734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
5744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
5754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
5774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
5784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5794e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
5804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(old_value);
5814e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
582d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
583d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
584d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
585ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
58629501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
587ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
588ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
589ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  bool success =  __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
590ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (success) {
591ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
592ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
593ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return success;
5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
596407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, bool kIsStatic, typename Visitor>
597407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
598407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
599407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    if (!kVisitClass) {
600407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier     // Mask out the class from the reference offsets.
601407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      ref_offsets ^= kWordHighBitMask;
602407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
603407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    DCHECK_EQ(ClassOffset().Uint32Value(), 0U);
604407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // Found a reference offset bitmap. Visit the specified offsets.
605407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    while (ref_offsets != 0) {
606407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      size_t right_shift = CLZ(ref_offsets);
607407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
608407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      visitor(this, field_offset, kIsStatic);
609407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
610407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
611407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
612407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // There is no reference offset bitmap.  In the non-static case, walk up the class
613407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // inheritance hierarchy and find reference offsets the hard way. In the static case, just
614407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // consider this class.
615407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
616407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        klass = kIsStatic ? nullptr : klass->GetSuperClass()) {
617407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      size_t num_reference_fields =
618407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier          kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
619407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      for (size_t i = 0; i < num_reference_fields; ++i) {
620407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        mirror::ArtField* field = kIsStatic ? klass->GetStaticField(i)
621407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier            : klass->GetInstanceField(i);
622407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        MemberOffset field_offset = field->GetOffset();
623407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        // TODO: Do a simpler check?
624407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        if (!kVisitClass && UNLIKELY(field_offset.Uint32Value() == ClassOffset().Uint32Value())) {
625407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier          continue;
626407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        }
627407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        visitor(this, field_offset, kIsStatic);
628407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      }
629407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
630407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
631407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
632407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
633407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor>
634407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
635407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  VisitFieldsReferences<kVisitClass, false>(
636407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor);
637407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
638407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
639407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor>
640407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
641407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  klass->VisitFieldsReferences<kVisitClass, true>(
642407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      klass->GetReferenceStaticOffsets<kVerifyNone>(), visitor);
643407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
644407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
645407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor,
646407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    typename JavaLangRefVisitor>
647407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor,
648407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier                                    const JavaLangRefVisitor& ref_visitor) {
649407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags>();
650407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  if (UNLIKELY(klass == Class::GetJavaLangClass())) {
651580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier    DCHECK_EQ(klass->GetClass<kVerifyNone>(), Class::GetJavaLangClass());
652407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor);
653407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else if (UNLIKELY(klass->IsArrayClass<kVerifyFlags>())) {
654407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    if (klass->IsObjectArrayClass<kVerifyNone>()) {
655580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier      AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor);
656407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    } else if (kVisitClass) {
657407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      visitor(this, ClassOffset(), false);
658407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
659407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
660580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier    VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
661580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier    if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) {
662407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      ref_visitor(klass, AsReference());
663407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
664407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
665407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
666407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
6672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
6682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
6692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
670fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
671