object-inl.h revision 60f63f53c01cb38ca18a815603282e802a6cf918
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"
2952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "object_array-inl.h"
30800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h"
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h"
328fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h"
3305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h"
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yanginline uint32_t Object::ClassSize() {
3998d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  uint32_t vtable_entries = kVTableLength;
4037f05ef45e0393de812d51261dc293240c17294dFred Shih  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0);
4198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
4298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
436e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() {
456e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
46b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_));
472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) {
512cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // new_klass may be null prior to class linker initialization.
52ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // We don't mark the card as this occurs as part of object allocation. Not all objects have
53ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // backing cards, such as large objects.
54d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // We use non transactional version since we can't undo this write. We also disable checking as
55d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // we may run in transaction mode here.
564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<false, false,
574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
58b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
61bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline LockWord Object::GetLockWord(bool as_volatile) {
62b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
63b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
64b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
65b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
66d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
67d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
68bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
69d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
70b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
71b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
72b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
73b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
74b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
75d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
76d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
77228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
78d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
79228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return CasFieldWeakSequentiallyConsistent32<false, false>(
80228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
81d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
82d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
83d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
84d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  // Force use of non-transactional mode and do not check.
85d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return CasFieldWeakRelaxed32<false, false>(
86d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
87d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
88d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
89d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() {
90d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return Monitor::GetLockOwnerThreadId(this);
9105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
93e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) {
94e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return Monitor::MonitorEnter(self, this);
9505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
9705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) {
9805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return Monitor::MonitorExit(self, this);
9905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
10105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) {
10205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Notify(self, this);
10305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
10505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) {
10605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::NotifyAll(self, this);
10705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
10905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) {
11005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, 0, 0, true, kWaiting);
11105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
11305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
117624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() {
11860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
11960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
12060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState());
12160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
12260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1236a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi  return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
1246a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
1259d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1269d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1272c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1289d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1299d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1309d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1319103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) {
13260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
13360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
13460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
13560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord lw = GetLockWord(false);
13660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
13760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  SetLockWord(lw, false);
13860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
13960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1409d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // We don't mark the card as this occurs as part of object allocation. Not all objects have
1419d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // backing cards, such as large objects.
1429d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
1436a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
1449103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else
1459103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1462c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1476a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(rb_ptr);
1489103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif
1499103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi}
1509103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi
1519103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
15260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
15360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
15460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U);
15560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
15660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord expected_lw;
15760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord new_lw;
15860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  do {
15960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    LockWord lw = GetLockWord(false);
16060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) {
16160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      // Lost the race.
16260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      return false;
16360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    }
16460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw = lw;
16560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw.SetReadBarrierState(
16660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr)));
16760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw = lw;
16860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
16960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  } while (!CasLockWordWeakSequentiallyConsistent(expected_lw, new_lw));
17060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return true;
17160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1739103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
17413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue();
175228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1769103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
1779103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
1789103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  do {
179228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers    if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
1809103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      // Lost the race.
1819103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      return false;
1829103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    }
183228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
184228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                     new_ref.reference_));
1859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return true;
1869d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1876a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(expected_rb_ptr, rb_ptr);
1889d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1892c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1909d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1919d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1929d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
193624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const {
194800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  if (kUseBakerReadBarrier) {
195800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
196800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK(obj->GetReadBarrierPointer() == nullptr)
197800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
198800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
1992c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  } else {
2002c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers    CHECK(kUseBrooksReadBarrier);
201800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
202800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK_EQ(obj, obj->GetReadBarrierPointer())
203800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
204800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
205800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  }
2069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
2079d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
2084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
209ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) {
2102cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2112cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyFlags>() != nullptr);
212a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  return klass->IsInterface() || InstanceOf(klass);
213a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao}
214a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao
2154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
216ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) {
2172cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyNone>() != nullptr);
2194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2226e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
223ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() {
2246e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
2256e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template GetClass<kVerifyFlags, kReadBarrierOption>();
2266e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
2276e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      kReadBarrierOption>() == java_lang_Class;
2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2306e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() {
2326e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
2332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<Class*>(this);
2342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
237ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() {
2384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return IsArrayInstance<kVerifyFlags>() &&
2404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags>
2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() {
2454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsObjectArray<kVerifyFlags>());
2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<ObjectArray<T>*>(this);
2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2496e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
250ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() {
2516e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<kVerifyFlags, kReadBarrierOption>()->
2526e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2556e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
256ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtMethod() {
2574f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi  return GetClass<kVerifyFlags, kReadBarrierOption>()->
2584f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi      template IsArtMethodClass<kReadBarrierOption>();
2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
262ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline ArtMethod* Object::AsArtMethod() {
2634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArtMethod<kVerifyFlags>());
264ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  return down_cast<ArtMethod*>(this);
2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
268ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() {
2694ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
2702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2724e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
2738fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() {
2748fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsReferenceInstance<kVerifyFlags>());
2758fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<Reference*>(this);
2768fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
2778fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
2786e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() {
2806e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
28105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Array*>(this);
28205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
28305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
28505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() {
2864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
28905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<BooleanArray*>(this);
29005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
29105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
29305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() {
2944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
29705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ByteArray*>(this);
29805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
29905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
301ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() {
3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
3054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
306ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ByteArray*>(this);
307ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
308ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
31005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() {
3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<CharArray*>(this);
31505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
31605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
31805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() {
3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
32205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ShortArray*>(this);
32305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
32405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
326ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() {
3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
3304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
331ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ShortArray*>(this);
332ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
333ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
33505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline IntArray* Object::AsIntArray() {
3364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
337c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
338c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
3394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
34005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<IntArray*>(this);
34105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
34205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
34405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline LongArray* Object::AsLongArray() {
3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
346c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
347c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
3484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
34905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<LongArray*>(this);
35005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
35105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
353d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() {
3544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
357d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<FloatArray*>(this);
358d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
359d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
361d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() {
3624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
365d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<DoubleArray*>(this);
366d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
367d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
36905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() {
3704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
37105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<String*>(this);
37205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
37305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
37505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() {
3764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
37705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Throwable*>(this);
37805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
37905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
381ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() {
3824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
3832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
386ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() {
3874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
3882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
391ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() {
3924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
3932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
3968fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() {
3978fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
3988fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<FinalizerReference*>(this);
3998fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
4008fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
4018fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
402ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() {
4034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
4042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4066e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
407ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() {
4082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t result;
4094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
4106e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
4116e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsArray<kNewFlags, kReadBarrierOption>()->
4126e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
4136e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
4146e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsClass<kNewFlags, kReadBarrierOption>()->
4156e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
41725023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi    result = GetClass<kNewFlags, kReadBarrierOption>()->
41825023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi        template GetObjectSize<kNewFlags, kReadBarrierOption>();
4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4209103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK_GE(result, sizeof(Object))
4216e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
4222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return result;
4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
425b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
42637f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) {
4274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
43037f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint8_t, kIsVolatile>(field_offset);
43137f05ef45e0393de812d51261dc293240c17294dFred Shih}
43237f05ef45e0393de812d51261dc293240c17294dFred Shih
43337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
43437f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) {
43537f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
43637f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
43737f05ef45e0393de812d51261dc293240c17294dFred Shih  }
43837f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int8_t, kIsVolatile>(field_offset);
43937f05ef45e0393de812d51261dc293240c17294dFred Shih}
44037f05ef45e0393de812d51261dc293240c17294dFred Shih
44137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
44237f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
44337f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldBoolean<kVerifyFlags, true>(field_offset);
44437f05ef45e0393de812d51261dc293240c17294dFred Shih}
44537f05ef45e0393de812d51261dc293240c17294dFred Shih
44637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
44737f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
44837f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldByte<kVerifyFlags, true>(field_offset);
44937f05ef45e0393de812d51261dc293240c17294dFred Shih}
45037f05ef45e0393de812d51261dc293240c17294dFred Shih
45137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
45237f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
45337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value)
45437f05ef45e0393de812d51261dc293240c17294dFred Shih    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
45537f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
45637f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
45737f05ef45e0393de812d51261dc293240c17294dFred Shih  }
45837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
45937f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldBoolean(this, field_offset,
46037f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset),
46137f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
46237f05ef45e0393de812d51261dc293240c17294dFred Shih  }
46337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
46437f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
46537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
46637f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint8_t, kIsVolatile>(field_offset, new_value);
46737f05ef45e0393de812d51261dc293240c17294dFred Shih}
46837f05ef45e0393de812d51261dc293240c17294dFred Shih
46937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
47037f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
47137f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value)
47237f05ef45e0393de812d51261dc293240c17294dFred Shih    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
47337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
47437f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
47537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
47637f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
47737f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldByte(this, field_offset,
47837f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset),
47937f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
48037f05ef45e0393de812d51261dc293240c17294dFred Shih  }
48137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
48237f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
48337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
48437f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int8_t, kIsVolatile>(field_offset, new_value);
48537f05ef45e0393de812d51261dc293240c17294dFred Shih}
48637f05ef45e0393de812d51261dc293240c17294dFred Shih
48737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
48837f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
48937f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
49037f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
49137f05ef45e0393de812d51261dc293240c17294dFred Shih}
49237f05ef45e0393de812d51261dc293240c17294dFred Shih
49337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
49437f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
49537f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
49637f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
49737f05ef45e0393de812d51261dc293240c17294dFred Shih}
49837f05ef45e0393de812d51261dc293240c17294dFred Shih
49937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
50037f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
50137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
50237f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
50337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
50437f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint16_t, kIsVolatile>(field_offset);
50537f05ef45e0393de812d51261dc293240c17294dFred Shih}
50637f05ef45e0393de812d51261dc293240c17294dFred Shih
50737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
50837f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) {
50937f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
51037f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
511b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
51237f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int16_t, kIsVolatile>(field_offset);
51337f05ef45e0393de812d51261dc293240c17294dFred Shih}
51437f05ef45e0393de812d51261dc293240c17294dFred Shih
51537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
51637f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
51737f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldChar<kVerifyFlags, true>(field_offset);
51837f05ef45e0393de812d51261dc293240c17294dFred Shih}
51937f05ef45e0393de812d51261dc293240c17294dFred Shih
52037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
52137f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
52237f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldShort<kVerifyFlags, true>(field_offset);
52337f05ef45e0393de812d51261dc293240c17294dFred Shih}
52437f05ef45e0393de812d51261dc293240c17294dFred Shih
52537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
52637f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
52737f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
52837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
52937f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
53037f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
53237f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
53337f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset),
53437f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
53537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53637f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
53737f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
53837f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53937f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint16_t, kIsVolatile>(field_offset, new_value);
54037f05ef45e0393de812d51261dc293240c17294dFred Shih}
54137f05ef45e0393de812d51261dc293240c17294dFred Shih
54237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
54337f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
54437f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
54537f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
54637f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
54737f05ef45e0393de812d51261dc293240c17294dFred Shih  }
54837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
54937f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
55037f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset),
55137f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
55237f05ef45e0393de812d51261dc293240c17294dFred Shih  }
55337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
55437f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
55537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
55637f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int16_t, kIsVolatile>(field_offset, new_value);
55737f05ef45e0393de812d51261dc293240c17294dFred Shih}
55837f05ef45e0393de812d51261dc293240c17294dFred Shih
55937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
56037f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
56137f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
56237f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
56337f05ef45e0393de812d51261dc293240c17294dFred Shih}
56437f05ef45e0393de812d51261dc293240c17294dFred Shih
56537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
56637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
56737f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
56837f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
56937f05ef45e0393de812d51261dc293240c17294dFred Shih}
57037f05ef45e0393de812d51261dc293240c17294dFred Shih
57137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
57237f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) {
57337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
57437f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
57537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
57637f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int32_t, kIsVolatile>(field_offset);
577b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
578b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
579b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
580b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
581b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField32<kVerifyFlags, true>(field_offset);
582b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
583b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
584b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
585b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
586b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
587d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
588d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
589d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
590d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
591b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField32(this, field_offset,
592b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField32<kVerifyFlags, kIsVolatile>(field_offset),
593b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
594d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
5954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
596b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    VerifyObject(this);
597b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
59837f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int32_t, kIsVolatile>(field_offset, new_value);
599b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
600b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
6014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
602b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
603b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
604b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
605b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
606d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
607d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
608b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
609228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
610228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int32_t old_value, int32_t new_value) {
611d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
612d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
613d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
614d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
615d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
616d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
6184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
6194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
62013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
621228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
6223035961cb41865b80b927546be0c708b6389cec6Hans Boehm
623228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
624d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
625d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
626d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
627d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
628d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                          int32_t old_value, int32_t new_value) {
629d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
630d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
631d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
632d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
633d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
634d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
635d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
636d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
637d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
63813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
639d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
640d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
641d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
642d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
643d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
644d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
645d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
646d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int32_t old_value, int32_t new_value) {
647d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
648d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
649d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
650d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
651d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
652d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
653d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
654d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
655d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
65613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
657d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
658d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
659d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
660d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
661d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
662b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
663b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) {
6644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
6654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
6664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
66737f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int64_t, kIsVolatile>(field_offset);
6682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
670b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
671b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
672b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField64<kVerifyFlags, true>(field_offset);
673b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
674b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
675b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
676b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
677b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
678d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
679d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
680d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
681d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
682b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField64(this, field_offset,
683b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField64<kVerifyFlags, kIsVolatile>(field_offset),
684b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
685d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
687ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
688ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
68937f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int64_t, kIsVolatile>(field_offset, new_value);
6902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
6924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
693b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
694b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
695b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                               new_value);
696b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
697b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
69837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
69937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) {
70013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
70137f05ef45e0393de812d51261dc293240c17294dFred Shih  kSize* addr = reinterpret_cast<kSize*>(raw_addr);
70237f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
70337f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value);
70437f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
70537f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
70637f05ef45e0393de812d51261dc293240c17294dFred Shih  }
70737f05ef45e0393de812d51261dc293240c17294dFred Shih}
70837f05ef45e0393de812d51261dc293240c17294dFred Shih
70937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
71037f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) {
71113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
71237f05ef45e0393de812d51261dc293240c17294dFred Shih  const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
71337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
71437f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent();
71537f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
71637f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
71737f05ef45e0393de812d51261dc293240c17294dFred Shih  }
71837f05ef45e0393de812d51261dc293240c17294dFred Shih}
71937f05ef45e0393de812d51261dc293240c17294dFred Shih
720b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
721228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
722228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int64_t old_value, int64_t new_value) {
723d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
724d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
725d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
726d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
727d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
728d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
73213735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
733228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
734228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
735ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
736ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
737d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
738d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
739d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int64_t old_value, int64_t new_value) {
740d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
741d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
742d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
743d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
744d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
745d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
746d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
747d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
748d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
74913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
750d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
751d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
752d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
753d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
7546e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
7556e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi         bool kIsVolatile>
756b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) {
7574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
76013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
761ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
7626e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
763b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
7643035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent load instead.
7653035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceAcquire();  // Ensure visibility of operations preceding store.
766ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
7674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
7684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(result);
7694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
770ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return result;
771ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
772ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
7736e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
774b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
7756e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
776b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
777b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
778b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
779b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
780b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
781b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                      Object* new_value) {
782d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
783d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
784d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
785d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
786b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    mirror::Object* obj;
787b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    if (kIsVolatile) {
788b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObjectVolatile<Object>(field_offset);
789b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    } else {
790b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObject<Object>(field_offset);
791b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    }
792b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
793d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
795ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
796ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
7974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
7984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
7994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
80013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
801ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
802b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
8033035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent store instead.
8043035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceRelease();  // Ensure that prior accesses are visible before store.
805ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
8063035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceSequentiallyConsistent();
8073035961cb41865b80b927546be0c708b6389cec6Hans Boehm                                // Ensure this store occurs before any volatile loads.
808ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
809ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
810ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
811ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
812ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
813b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
814b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
815b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
816b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
817b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      kIsVolatile>(field_offset, new_value);
818ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (new_value != nullptr) {
819ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
82061c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
82161c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    CheckFieldAssignment(field_offset, new_value);
822ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
823ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
824ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
825b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
826b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
827b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
828b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                            new_value);
829b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
830b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
8314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags>
8324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
8334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
8344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
8354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
83613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
8374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset.Int32Value());
8384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier}
8394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier
8404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
841228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
842228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                             Object* old_value, Object* new_value) {
8432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
8442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
8452cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  if (success) {
8462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
8472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  }
8482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
8492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
8502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi
8512cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
8522cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
8532cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
854d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
855d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
856d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
8574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
8584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
8594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
8604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
8614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
8624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
8634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
8644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(old_value);
8654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
866d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
867d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
868d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
869ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
870ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
87113735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
872228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
873228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
874228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
875228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                        new_ref.reference_);
8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
8772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
878228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
8792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
8802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
8812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi                                                               Object* old_value, Object* new_value) {
8822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
8832cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
884ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (success) {
885ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
886ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
887ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return success;
8882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
8892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
890d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
8912cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
8922cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
893d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
894d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
895d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
896d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
897d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
898d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
899d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyWrites) {
900d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(new_value);
901d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
902d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyReads) {
903d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(old_value);
904d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
905d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
906d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
907d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
908d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
909d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
91013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
911d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
912d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
913d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
914d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                                          new_ref.reference_);
915d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return success;
916d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
917d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
918407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, bool kIsStatic, typename Visitor>
919407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
920cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers  if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
921cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    // Instance fields and not the slow-path.
922cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    if (kVisitClass) {
923cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      visitor(this, ClassOffset(), kIsStatic);
924407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
925cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    uint32_t field_offset = mirror::kObjectHeaderSize;
926407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    while (ref_offsets != 0) {
927cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      if ((ref_offsets & 1) != 0) {
928cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers        visitor(this, MemberOffset(field_offset), kIsStatic);
929cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      }
930cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      ref_offsets >>= 1;
931cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      field_offset += sizeof(mirror::HeapReference<mirror::Object>);
932407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
933407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
934faff0f05fef90577c9744505555675185832aacdMingyao Yang    // There is no reference offset bitmap. In the non-static case, walk up the class
935407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // inheritance hierarchy and find reference offsets the hard way. In the static case, just
936407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // consider this class.
937407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
938407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        klass = kIsStatic ? nullptr : klass->GetSuperClass()) {
939407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      size_t num_reference_fields =
940407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier          kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
94176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      if (num_reference_fields == 0u) {
94276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        continue;
94376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      }
94476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      MemberOffset field_offset = kIsStatic
94576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko          ? klass->GetFirstReferenceStaticFieldOffset()
94676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko          : klass->GetFirstReferenceInstanceFieldOffset();
947407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      for (size_t i = 0; i < num_reference_fields; ++i) {
948407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        // TODO: Do a simpler check?
94952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier        if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
95052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier          visitor(this, field_offset, kIsStatic);
951407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        }
95276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        field_offset = MemberOffset(field_offset.Uint32Value() +
95376649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko                                    sizeof(mirror::HeapReference<mirror::Object>));
954407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      }
955407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
956407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
957407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
958407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
959407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor>
960407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
961407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  VisitFieldsReferences<kVisitClass, false>(
962407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor);
963407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
964407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
965407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor>
966407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
96798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  DCHECK(!klass->IsTemp());
968faff0f05fef90577c9744505555675185832aacdMingyao Yang  klass->VisitFieldsReferences<kVisitClass, true>(0, visitor);
969407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
970407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
971407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor,
972407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    typename JavaLangRefVisitor>
973407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor,
974407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier                                    const JavaLangRefVisitor& ref_visitor) {
975407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags>();
97652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier  if (klass == Class::GetJavaLangClass()) {
97752e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier    AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor);
97852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier  } else if (klass->IsArrayClass()) {
97952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier    if (klass->IsObjectArrayClass<kVerifyNone>()) {
98052e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier      AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor);
98152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier    } else if (kVisitClass) {
98252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier      visitor(this, ClassOffset(), false);
983407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
984407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
98552e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier    DCHECK(!klass->IsVariableSize());
986580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier    VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
9874ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih    if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) {
988407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      ref_visitor(klass, AsReference());
989407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
990407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
991407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
9922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
9932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
9942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
995fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
996