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"
2752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier#include "class_flags.h"
28e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "class_linker.h"
29e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier#include "class_loader-inl.h"
3005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko#include "dex_cache-inl.h"
31d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word-inl.h"
3205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "monitor.h"
3352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "object_array-inl.h"
34800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h"
358fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h"
36848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "runtime.h"
37848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "string-inl.h"
3805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h"
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
43e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline uint32_t Object::ClassSize(size_t pointer_size) {
4498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  uint32_t vtable_entries = kVTableLength;
45e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size);
4698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
4798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() {
506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
51b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_));
522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) {
562cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // new_klass may be null prior to class linker initialization.
57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // We don't mark the card as this occurs as part of object allocation. Not all objects have
58ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // backing cards, such as large objects.
59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // We use non transactional version since we can't undo this write. We also disable checking as
60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // we may run in transaction mode here.
614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<false, false,
624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
63b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
663b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags>
67bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline LockWord Object::GetLockWord(bool as_volatile) {
68b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
693b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
70b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
713b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe  return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
72d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
73d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
743b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags>
75bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
76d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
77b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
783b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    SetField32Volatile<false, false, kVerifyFlags>(
793b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe        OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
80b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
813b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    SetField32<false, false, kVerifyFlags>(
823b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe        OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
83b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
84d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
85d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
86228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
87d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
88228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return CasFieldWeakSequentiallyConsistent32<false, false>(
89228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
90d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
91d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
92d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
93d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  // Force use of non-transactional mode and do not check.
94d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return CasFieldWeakRelaxed32<false, false>(
95d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
96d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
97d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
98fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasLockWordWeakRelease(LockWord old_val, LockWord new_val) {
99fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  // Force use of non-transactional mode and do not check.
100fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  return CasFieldWeakRelease32<false, false>(
101fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
102fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi}
103fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
104d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() {
105d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return Monitor::GetLockOwnerThreadId(this);
10605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
108e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) {
10923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  return Monitor::MonitorEnter(self, this, /*trylock*/false);
11023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier}
11123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier
11223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartierinline mirror::Object* Object::MonitorTryEnter(Thread* self) {
11323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier  return Monitor::MonitorEnter(self, this, /*trylock*/true);
11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) {
11705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return Monitor::MonitorExit(self, this);
11805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
12005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) {
12105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Notify(self, this);
12205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
12305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
12405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) {
12505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::NotifyAll(self, this);
12605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
12705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
12805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) {
12905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, 0, 0, true, kWaiting);
13005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
13105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
13205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
13305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
13405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
13505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
136624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() {
13760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
13860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
13960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState());
14060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
14160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1426a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi  return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
1436a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
1449d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1459d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1462c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1479d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1489d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1499d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1509103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) {
15160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
15260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
15360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
15460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord lw = GetLockWord(false);
15560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
15660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  SetLockWord(lw, false);
15760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
15860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1599d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // We don't mark the card as this occurs as part of object allocation. Not all objects have
1609d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // backing cards, such as large objects.
1619d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
1626a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
1639103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else
1649103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1652c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1666a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(rb_ptr);
1679103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif
1689103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi}
1699103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi
170ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchitemplate<bool kCasRelease>
1719103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
17360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
17460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U);
17560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
17660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord expected_lw;
17760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord new_lw;
17860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  do {
17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    LockWord lw = GetLockWord(false);
18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) {
18160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      // Lost the race.
18260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      return false;
18360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    }
18460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw = lw;
18560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw.SetReadBarrierState(
18660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr)));
18760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw = lw;
18860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
189ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi    // ConcurrentCopying::ProcessMarkStackRef uses this with kCasRelease == true.
190ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi    // If kCasRelease == true, use a CAS release so that when GC updates all the fields of
191ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi    // an object and then changes the object from gray to black, the field updates (stores) will be
192ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi    // visible (won't be reordered after this CAS.)
193ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi  } while (!(kCasRelease ?
194ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi             CasLockWordWeakRelease(expected_lw, new_lw) :
195ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi             CasLockWordWeakRelaxed(expected_lw, new_lw)));
19660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return true;
19760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
19860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1999103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
20013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue();
201228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
2029103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
2039103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
2049103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  do {
205228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers    if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
2069103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      // Lost the race.
2079103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      return false;
2089103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    }
209228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
210228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                     new_ref.reference_));
2119103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return true;
2129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
2136a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(expected_rb_ptr, rb_ptr);
2149d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
2152c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
2169d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
2179d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
2189d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
219624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const {
220800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  if (kUseBakerReadBarrier) {
221800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
222800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK(obj->GetReadBarrierPointer() == nullptr)
223800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
224800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
2252c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  } else {
2262c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers    CHECK(kUseBrooksReadBarrier);
227800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
228800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK_EQ(obj, obj->GetReadBarrierPointer())
229800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
230800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
231800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  }
2329d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
2339d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
2344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
235ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) {
2362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyFlags>() != nullptr);
238a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  return klass->IsInterface() || InstanceOf(klass);
239a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao}
240a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao
2414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
242ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) {
2432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyNone>() != nullptr);
2454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
249ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() {
2506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
2516e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template GetClass<kVerifyFlags, kReadBarrierOption>();
2526e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
2536e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      kReadBarrierOption>() == java_lang_Class;
2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2566e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() {
2586e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<Class*>(this);
2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
262dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
263ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() {
2644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
265dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  return IsArrayInstance<kVerifyFlags, kReadBarrierOption>() &&
266dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier      !GetClass<kNewFlags, kReadBarrierOption>()->
267dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier          template GetComponentType<kNewFlags, kReadBarrierOption>()->IsPrimitive();
2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
270dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() {
272dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  DCHECK((IsObjectArray<kVerifyFlags, kReadBarrierOption>()));
2732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<ObjectArray<T>*>(this);
2742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2766e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
277ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() {
2786e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<kVerifyFlags, kReadBarrierOption>()->
2796e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
282dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
283ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() {
284dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsTypeOfReferenceClass();
2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
287dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
2888fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() {
289dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  DCHECK((IsReferenceInstance<kVerifyFlags, kReadBarrierOption>()));
2908fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<Reference*>(this);
2918fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
2928fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
2936e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
29405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() {
2956e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
29605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Array*>(this);
29705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
29805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() {
3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
30405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<BooleanArray*>(this);
30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() {
309e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
31205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ByteArray*>(this);
31305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
316ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() {
317e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
321ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ByteArray*>(this);
322ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
323ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
32505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() {
3264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
32905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<CharArray*>(this);
33005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
33105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
33305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() {
3344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
33705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ShortArray*>(this);
33805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
33905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
341ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() {
3424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
346ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ShortArray*>(this);
347ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
348ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
349dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
350e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsIntArray() {
3514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
352dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
353dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
354e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>();
355e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
356e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
357dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
358e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline IntArray* Object::AsIntArray() {
359dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  DCHECK((IsIntArray<kVerifyFlags, kReadBarrierOption>()));
36005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<IntArray*>(this);
36105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
36205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
363dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
364e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsLongArray() {
3654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
366dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
367dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
368e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>();
369e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
370e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
371dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
372e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline LongArray* Object::AsLongArray() {
373dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  DCHECK((IsLongArray<kVerifyFlags, kReadBarrierOption>()));
37405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<LongArray*>(this);
37505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
37605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
378e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsFloatArray() {
379e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
380e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
381e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>();
382e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
385d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() {
386e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsFloatArray<kVerifyFlags>());
3874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<FloatArray*>(this);
391d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
392d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
394e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsDoubleArray() {
395e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
396e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
397e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>();
398e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
399e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
400e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
401d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() {
402e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsDoubleArray<kVerifyFlags>());
4034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
4044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
406d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<DoubleArray*>(this);
407d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
408d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
409848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
410848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoinline bool Object::IsString() {
411848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass();
412848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao}
413848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
414848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
41505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() {
416848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  DCHECK((IsString<kVerifyFlags, kReadBarrierOption>()));
41705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<String*>(this);
41805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
41905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
4204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
42105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() {
4224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
42305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Throwable*>(this);
42405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
42505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
4264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
427ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() {
4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
432ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() {
4334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
4342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
437ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() {
4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
4392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
4428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() {
4438fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
4448fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<FinalizerReference*>(this);
4458fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
4468fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
4478fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
448ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() {
4494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4526e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
453ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() {
4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t result;
4554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
4566e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
4576e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsArray<kNewFlags, kReadBarrierOption>()->
4586e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
4596e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
4606e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsClass<kNewFlags, kReadBarrierOption>()->
4616e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
462848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) {
463848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    result = AsString<kNewFlags, kReadBarrierOption>()->
464848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao        template SizeOf<kNewFlags>();
4652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
46625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi    result = GetClass<kNewFlags, kReadBarrierOption>()->
46725023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi        template GetObjectSize<kNewFlags, kReadBarrierOption>();
4682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4699103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK_GE(result, sizeof(Object))
4706e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
4712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return result;
4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
474b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
47537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) {
4764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
47937f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint8_t, kIsVolatile>(field_offset);
48037f05ef45e0393de812d51261dc293240c17294dFred Shih}
48137f05ef45e0393de812d51261dc293240c17294dFred Shih
48237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
48337f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) {
48437f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
48537f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
48637f05ef45e0393de812d51261dc293240c17294dFred Shih  }
48737f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int8_t, kIsVolatile>(field_offset);
48837f05ef45e0393de812d51261dc293240c17294dFred Shih}
48937f05ef45e0393de812d51261dc293240c17294dFred Shih
49037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
49137f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
49237f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldBoolean<kVerifyFlags, true>(field_offset);
49337f05ef45e0393de812d51261dc293240c17294dFred Shih}
49437f05ef45e0393de812d51261dc293240c17294dFred Shih
49537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
49637f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
49737f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldByte<kVerifyFlags, true>(field_offset);
49837f05ef45e0393de812d51261dc293240c17294dFred Shih}
49937f05ef45e0393de812d51261dc293240c17294dFred Shih
50037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
50137f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
50237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value)
50390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
50437f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
50537f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
50637f05ef45e0393de812d51261dc293240c17294dFred Shih  }
50737f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
50837f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldBoolean(this, field_offset,
50937f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset),
51037f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
51137f05ef45e0393de812d51261dc293240c17294dFred Shih  }
51237f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
51337f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
51437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
51537f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint8_t, kIsVolatile>(field_offset, new_value);
51637f05ef45e0393de812d51261dc293240c17294dFred Shih}
51737f05ef45e0393de812d51261dc293240c17294dFred Shih
51837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
51937f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
52037f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value)
52190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
52237f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
52337f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
52437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
52537f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
52637f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldByte(this, field_offset,
52737f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset),
52837f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
52937f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53037f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
53137f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
53237f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53337f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int8_t, kIsVolatile>(field_offset, new_value);
53437f05ef45e0393de812d51261dc293240c17294dFred Shih}
53537f05ef45e0393de812d51261dc293240c17294dFred Shih
53637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
53737f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
53837f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
53937f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
54037f05ef45e0393de812d51261dc293240c17294dFred Shih}
54137f05ef45e0393de812d51261dc293240c17294dFred Shih
54237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
54337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
54437f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
54537f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
54637f05ef45e0393de812d51261dc293240c17294dFred Shih}
54737f05ef45e0393de812d51261dc293240c17294dFred Shih
54837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
54937f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
55037f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
55137f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
55237f05ef45e0393de812d51261dc293240c17294dFred Shih  }
55337f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint16_t, kIsVolatile>(field_offset);
55437f05ef45e0393de812d51261dc293240c17294dFred Shih}
55537f05ef45e0393de812d51261dc293240c17294dFred Shih
55637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
55737f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) {
55837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
55937f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
560b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
56137f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int16_t, kIsVolatile>(field_offset);
56237f05ef45e0393de812d51261dc293240c17294dFred Shih}
56337f05ef45e0393de812d51261dc293240c17294dFred Shih
56437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
56537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
56637f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldChar<kVerifyFlags, true>(field_offset);
56737f05ef45e0393de812d51261dc293240c17294dFred Shih}
56837f05ef45e0393de812d51261dc293240c17294dFred Shih
56937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
57037f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
57137f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldShort<kVerifyFlags, true>(field_offset);
57237f05ef45e0393de812d51261dc293240c17294dFred Shih}
57337f05ef45e0393de812d51261dc293240c17294dFred Shih
57437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
57537f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
57637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
57737f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
57837f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
57937f05ef45e0393de812d51261dc293240c17294dFred Shih  }
58037f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
58137f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
58237f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset),
58337f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
58437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
58537f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
58637f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
58737f05ef45e0393de812d51261dc293240c17294dFred Shih  }
58837f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint16_t, kIsVolatile>(field_offset, new_value);
58937f05ef45e0393de812d51261dc293240c17294dFred Shih}
59037f05ef45e0393de812d51261dc293240c17294dFred Shih
59137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
59237f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
59337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
59437f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
59537f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
59637f05ef45e0393de812d51261dc293240c17294dFred Shih  }
59737f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
59837f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
59937f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset),
60037f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
60137f05ef45e0393de812d51261dc293240c17294dFred Shih  }
60237f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
60337f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
60437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
60537f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int16_t, kIsVolatile>(field_offset, new_value);
60637f05ef45e0393de812d51261dc293240c17294dFred Shih}
60737f05ef45e0393de812d51261dc293240c17294dFred Shih
60837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
60937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
61037f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
61137f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
61237f05ef45e0393de812d51261dc293240c17294dFred Shih}
61337f05ef45e0393de812d51261dc293240c17294dFred Shih
61437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
61537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
61637f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
61737f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
61837f05ef45e0393de812d51261dc293240c17294dFred Shih}
61937f05ef45e0393de812d51261dc293240c17294dFred Shih
62037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
62137f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) {
62237f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
62337f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
62437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
62537f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int32_t, kIsVolatile>(field_offset);
626b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
627b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
628b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
629b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
630b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField32<kVerifyFlags, true>(field_offset);
631b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
632b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
633b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
634b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
635b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
636d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
637d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
638d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
639d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
640b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField32(this, field_offset,
641b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField32<kVerifyFlags, kIsVolatile>(field_offset),
642b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
643d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
645b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    VerifyObject(this);
646b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
64737f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int32_t, kIsVolatile>(field_offset, new_value);
648b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
649b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
6504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
651b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
652b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
653b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
654b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
655d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
656d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
657b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
658228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
659228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int32_t old_value, int32_t new_value) {
660d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
661d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
662d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
663d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
664d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
665d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
6674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
6684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
66913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
670228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
6713035961cb41865b80b927546be0c708b6389cec6Hans Boehm
672228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
673d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
674d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
675d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
676d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
677d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                          int32_t old_value, int32_t new_value) {
678d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
679d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
680d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
681d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
682d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
683d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
684d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
685d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
686d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
68713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
688d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
689d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
690d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
691d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
692d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
693d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
694fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelease32(MemberOffset field_offset,
695fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi                                          int32_t old_value, int32_t new_value) {
696fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kCheckTransaction) {
697fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
698fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
699fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kTransactionActive) {
700fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
701fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
702fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyThis) {
703fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(this);
704fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
705fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
706fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
707fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
708fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  return atomic_addr->CompareExchangeWeakRelease(old_value, new_value);
709fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi}
710fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
711fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
712d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
713d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int32_t old_value, int32_t new_value) {
714d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
715d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
716d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
717d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
718d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
719d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
720d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
721d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
722d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
72313735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
724d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
725d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
726d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
727d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
728d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
729b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
730b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) {
7314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
73437f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int64_t, kIsVolatile>(field_offset);
7352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
7362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
737b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
738b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
739b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField64<kVerifyFlags, true>(field_offset);
740b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
741b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
742b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
743b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
744b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
745d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
746d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
747d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
748d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
749b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField64(this, field_offset,
750b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField64<kVerifyFlags, kIsVolatile>(field_offset),
751b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
752d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
754ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
755ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
75637f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int64_t, kIsVolatile>(field_offset, new_value);
7572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
7582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
7594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
760b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
761b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
762b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                               new_value);
763b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
764b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
76537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
76637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) {
76713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
76837f05ef45e0393de812d51261dc293240c17294dFred Shih  kSize* addr = reinterpret_cast<kSize*>(raw_addr);
76937f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
77037f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value);
77137f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
77237f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
77337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
77437f05ef45e0393de812d51261dc293240c17294dFred Shih}
77537f05ef45e0393de812d51261dc293240c17294dFred Shih
77637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
77737f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) {
77813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
77937f05ef45e0393de812d51261dc293240c17294dFred Shih  const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
78037f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
78137f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent();
78237f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
78337f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
78437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
78537f05ef45e0393de812d51261dc293240c17294dFred Shih}
78637f05ef45e0393de812d51261dc293240c17294dFred Shih
787b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
788228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
789228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int64_t old_value, int64_t new_value) {
790d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
791d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
792d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
793d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
794d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
795d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
79913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
800228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
801228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
802ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
803ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
804d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
805d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
806d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int64_t old_value, int64_t new_value) {
807d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
808d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
809d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
810d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
811d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
812d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
813d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
814d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
815d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
81613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
817d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
818d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
819d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
820d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
8216e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
8226e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi         bool kIsVolatile>
823b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) {
8244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
8254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
8264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
82713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
828ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
8296e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
830b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
8313035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent load instead.
8323035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceAcquire();  // Ensure visibility of operations preceding store.
833ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
8344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
8354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(result);
8364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
837ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return result;
838ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
839ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
8406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
841b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
8426e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
843b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
844b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
845b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
846b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
847b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
848b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                      Object* new_value) {
849d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
850d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
851d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
852d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
853b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    mirror::Object* obj;
854b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    if (kIsVolatile) {
855b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObjectVolatile<Object>(field_offset);
856b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    } else {
857b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObject<Object>(field_offset);
858b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    }
859b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
860d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
8614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
862ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
863ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
8644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
8654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
8664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
86713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
868ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
869b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
8703035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent store instead.
8713035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceRelease();  // Ensure that prior accesses are visible before store.
872ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
8733035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceSequentiallyConsistent();
8743035961cb41865b80b927546be0c708b6389cec6Hans Boehm                                // Ensure this store occurs before any volatile loads.
875ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
876ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
877ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
878ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
879ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
880b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
881b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
882b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
883b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
884b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      kIsVolatile>(field_offset, new_value);
885ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (new_value != nullptr) {
886ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
88761c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
88861c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    CheckFieldAssignment(field_offset, new_value);
889ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
890ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
891ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
892b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
893b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
894b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
895b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                            new_value);
896b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
897b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
8984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags>
8994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
9004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
9014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
9024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
90313735955f39b3b304c37d2b2840663c131262c18Ian Rogers  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
9044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset.Int32Value());
9054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier}
9064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier
9074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
908228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
909228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                             Object* old_value, Object* new_value) {
9102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
9112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
9122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  if (success) {
9132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
9142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  }
9152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
9162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
9172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi
9182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
9192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
9202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
921d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
922d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
923d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
9244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
9254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
9264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
9274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
9284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
9294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
9304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
9314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(old_value);
9324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
933d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
934d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
935d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
936ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
937ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
93813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
939228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
940228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
941228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
942228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                        new_ref.reference_);
9432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
9442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
945228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
9462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
9472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
9482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi                                                               Object* old_value, Object* new_value) {
9492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
9502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
951ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (success) {
952ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
953ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
954ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return success;
9552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
9562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
957d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
9582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
9592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
960d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
961d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
962d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
963d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
964d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
965d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
966d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyWrites) {
967d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(new_value);
968d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
969d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyReads) {
970d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(old_value);
971d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
972d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
973d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
974d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
975d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
976d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
97713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
978d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
979d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
980d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
981d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                                          new_ref.reference_);
982d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return success;
983d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
984d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
985fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
986fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier(
987fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
988fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kCheckTransaction) {
989fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
990fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
991fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyThis) {
992fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(this);
993fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
994fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyWrites) {
995fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(new_value);
996fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
997fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyReads) {
998fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(old_value);
999fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1000fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kTransactionActive) {
1001fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
1002fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1003fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
1004fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
1005fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
1006fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1007fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
1008fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  bool success = atomic_addr->CompareExchangeWeakRelaxed(old_ref.reference_,
1009fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi                                                         new_ref.reference_);
1010fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  return success;
1011fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi}
1012fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
1013fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
1014fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier(
1015fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
1016fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kCheckTransaction) {
1017fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
1018fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1019fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyThis) {
1020fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(this);
1021fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1022fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyWrites) {
1023fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(new_value);
1024fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1025fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kVerifyFlags & kVerifyReads) {
1026fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    VerifyObject(old_value);
1027fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1028fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  if (kTransactionActive) {
1029fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
1030fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  }
1031fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
1032fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
1033fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
1034fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1035fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
1036fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  bool success = atomic_addr->CompareExchangeStrongRelaxed(old_ref.reference_,
1037fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi                                                           new_ref.reference_);
1038fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi  return success;
1039fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi}
1040fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi
1041fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<bool kIsStatic,
1042fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         VerifyObjectFlags kVerifyFlags,
1043fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         ReadBarrierOption kReadBarrierOption,
1044fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier         typename Visitor>
1045407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
1046cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers  if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
1047cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    // Instance fields and not the slow-path.
1048cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    uint32_t field_offset = mirror::kObjectHeaderSize;
1049407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    while (ref_offsets != 0) {
1050cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      if ((ref_offsets & 1) != 0) {
1051cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers        visitor(this, MemberOffset(field_offset), kIsStatic);
1052cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      }
1053cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      ref_offsets >>= 1;
1054cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      field_offset += sizeof(mirror::HeapReference<mirror::Object>);
1055407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
1056407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
1057faff0f05fef90577c9744505555675185832aacdMingyao Yang    // There is no reference offset bitmap. In the non-static case, walk up the class
1058407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // inheritance hierarchy and find reference offsets the hard way. In the static case, just
1059407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // consider this class.
1060fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    for (mirror::Class* klass = kIsStatic
1061fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier            ? AsClass<kVerifyFlags, kReadBarrierOption>()
1062fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier            : GetClass<kVerifyFlags, kReadBarrierOption>();
1063fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        klass != nullptr;
1064fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        klass = kIsStatic ? nullptr : klass->GetSuperClass<kVerifyFlags, kReadBarrierOption>()) {
1065fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      const size_t num_reference_fields =
1066407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier          kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
106776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      if (num_reference_fields == 0u) {
106876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        continue;
106976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      }
1070e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      // Presumably GC can happen when we are cross compiling, it should not cause performance
1071e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      // problems to do pointer size logic.
107276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      MemberOffset field_offset = kIsStatic
1073dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier          ? klass->GetFirstReferenceStaticFieldOffset<kVerifyFlags, kReadBarrierOption>(
1074e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier              Runtime::Current()->GetClassLinker()->GetImagePointerSize())
10755496f69c0a4c2cc357a065f57b7f4ff5d9ad2fa9Hiroshi Yamauchi          : klass->GetFirstReferenceInstanceFieldOffset<kVerifyFlags, kReadBarrierOption>();
1076059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier      for (size_t i = 0u; i < num_reference_fields; ++i) {
1077407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        // TODO: Do a simpler check?
1078059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier        if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
107952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier          visitor(this, field_offset, kIsStatic);
1080407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        }
108176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        field_offset = MemberOffset(field_offset.Uint32Value() +
108276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko                                    sizeof(mirror::HeapReference<mirror::Object>));
1083407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      }
1084407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
1085407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
1086407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
1087407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
1088fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
1089407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
1090fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  VisitFieldsReferences<false, kVerifyFlags, kReadBarrierOption>(
1091fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      klass->GetReferenceInstanceOffsets<kVerifyFlags>(), visitor);
1092407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
1093407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
1094fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
1095407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
109698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  DCHECK(!klass->IsTemp());
1097fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  klass->VisitFieldsReferences<true, kVerifyFlags, kReadBarrierOption>(0, visitor);
1098407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
1099407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
1100fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
1101e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline bool Object::IsClassLoader() {
1102fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsClassLoaderClass();
1103e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier}
1104e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier
1105fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
1106e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline mirror::ClassLoader* Object::AsClassLoader() {
1107fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  DCHECK((IsClassLoader<kVerifyFlags, kReadBarrierOption>()));
1108e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier  return down_cast<mirror::ClassLoader*>(this);
1109e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier}
1110e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier
1111fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
111205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool Object::IsDexCache() {
1113fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsDexCacheClass();
111405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko}
111505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko
1116fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
111705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::DexCache* Object::AsDexCache() {
1118fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  DCHECK((IsDexCache<kVerifyFlags, kReadBarrierOption>()));
111905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko  return down_cast<mirror::DexCache*>(this);
112005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko}
112105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko
1122fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate <bool kVisitNativeRoots,
1123fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier          VerifyObjectFlags kVerifyFlags,
1124fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier          ReadBarrierOption kReadBarrierOption,
1125fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier          typename Visitor,
1126fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier          typename JavaLangRefVisitor>
1127407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor,
1128407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier                                    const JavaLangRefVisitor& ref_visitor) {
1129fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
1130059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier  visitor(this, ClassOffset(), false);
113152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>();
113252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  if (LIKELY(class_flags == kClassFlagNormal)) {
1133dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier    DCHECK((!klass->IsVariableSize<kVerifyFlags, kReadBarrierOption>()));
1134dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier    VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
1135fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier    DCHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
113666c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier    DCHECK(!klass->IsStringClass());
113766c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier    DCHECK(!klass->IsClassLoaderClass());
1138dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier    DCHECK((!klass->IsArrayClass<kVerifyFlags, kReadBarrierOption>()));
113952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  } else {
114052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    if ((class_flags & kClassFlagNoReferenceFields) == 0) {
114152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      DCHECK(!klass->IsStringClass());
114252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      if (class_flags == kClassFlagClass) {
1143dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        DCHECK((klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
1144dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        mirror::Class* as_klass = AsClass<kVerifyNone, kReadBarrierOption>();
1145dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass,
1146dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier                                                                                       visitor);
114752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else if (class_flags == kClassFlagObjectArray) {
1148fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        DCHECK((klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
1149dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        AsObjectArray<mirror::Object, kVerifyNone, kReadBarrierOption>()->VisitReferences(visitor);
115052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else if ((class_flags & kClassFlagReference) != 0) {
1151dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
1152dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier        ref_visitor(klass, AsReference<kVerifyFlags, kReadBarrierOption>());
115305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko      } else if (class_flags == kClassFlagDexCache) {
1154fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        mirror::DexCache* const dex_cache = AsDexCache<kVerifyFlags, kReadBarrierOption>();
1155fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        dex_cache->VisitReferences<kVisitNativeRoots,
1156fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                   kVerifyFlags,
1157fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                   kReadBarrierOption>(klass, visitor);
115852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else {
1159fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags, kReadBarrierOption>();
1160fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier        class_loader->VisitReferences<kVisitNativeRoots,
1161fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                      kVerifyFlags,
1162fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier                                      kReadBarrierOption>(klass, visitor);
116352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      }
116452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    } else if (kIsDebugBuild) {
1165fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      CHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
1166fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier      CHECK((!klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
116752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      // String still has instance fields for reflection purposes but these don't exist in
116852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      // actual string instances.
116952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      if (!klass->IsStringClass()) {
117052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        size_t total_reference_instance_fields = 0;
117152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        mirror::Class* super_class = klass;
117252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        do {
117352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier          total_reference_instance_fields += super_class->NumReferenceInstanceFields();
1174fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier          super_class = super_class->GetSuperClass<kVerifyFlags, kReadBarrierOption>();
117552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        } while (super_class != nullptr);
117652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        // The only reference field should be the object's class. This field is handled at the
117752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        // beginning of the function.
117852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        CHECK_EQ(total_reference_instance_fields, 1u);
117952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      }
1180407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
1181407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
1182407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
11832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
11842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
11852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1186fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
1187