object-inl.h revision 66c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2
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"
30d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word-inl.h"
3105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "monitor.h"
3252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "object_array-inl.h"
33800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h"
348fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h"
35848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "runtime.h"
36848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "string-inl.h"
3705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h"
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
42e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline uint32_t Object::ClassSize(size_t pointer_size) {
4398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  uint32_t vtable_entries = kVTableLength;
44e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size);
4598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
4698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
476e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
48ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() {
496e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
50b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_));
512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) {
552cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // new_klass may be null prior to class linker initialization.
56ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // We don't mark the card as this occurs as part of object allocation. Not all objects have
57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // backing cards, such as large objects.
58d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // We use non transactional version since we can't undo this write. We also disable checking as
59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // we may run in transaction mode here.
604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<false, false,
614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
62b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
653b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags>
66bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline LockWord Object::GetLockWord(bool as_volatile) {
67b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
683b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
69b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
703b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe  return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
71d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
72d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
733b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags>
74bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
75d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
76b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (as_volatile) {
773b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    SetField32Volatile<false, false, kVerifyFlags>(
783b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe        OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
79b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
803b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe    SetField32<false, false, kVerifyFlags>(
813b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe        OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
82b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
83d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
84d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
85228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
86d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
87228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return CasFieldWeakSequentiallyConsistent32<false, false>(
88228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
89d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
90d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
91d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
92d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  // Force use of non-transactional mode and do not check.
93d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return CasFieldWeakRelaxed32<false, false>(
94d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
95d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
96d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
97d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() {
98d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return Monitor::GetLockOwnerThreadId(this);
9905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
101e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) {
102e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return Monitor::MonitorEnter(self, this);
10305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
10505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) {
10605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return Monitor::MonitorExit(self, this);
10705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
10805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
10905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) {
11005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Notify(self, this);
11105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
11305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) {
11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::NotifyAll(self, this);
11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
11705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) {
11805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, 0, 0, true, kWaiting);
11905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
12005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
12105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
12205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
12305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
12405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
125624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() {
12660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
12760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
12860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState());
12960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
13060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1316a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi  return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
1326a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
1339d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1349d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1352c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1369d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1379d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1389d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1399103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) {
14060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
14160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
14260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
14360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord lw = GetLockWord(false);
14460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
14560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  SetLockWord(lw, false);
14660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
14760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1489d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // We don't mark the card as this occurs as part of object allocation. Not all objects have
1499d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // backing cards, such as large objects.
1509d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
1516a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
1529103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else
1539103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1542c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1556a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(rb_ptr);
1569103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif
1579103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi}
1589103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi
1599103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
16060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER
16160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBakerReadBarrier);
16260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U);
16360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
16460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord expected_lw;
16560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  LockWord new_lw;
16660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  do {
16760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    LockWord lw = GetLockWord(false);
16860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) {
16960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      // Lost the race.
17060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi      return false;
17160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    }
17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw = lw;
17360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    expected_lw.SetReadBarrierState(
17460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr)));
17560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw = lw;
17660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi    new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
17760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  } while (!CasLockWordWeakSequentiallyConsistent(expected_lw, new_lw));
17860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  return true;
17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER
18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi  DCHECK(kUseBrooksReadBarrier);
1819103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
18213735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue();
183228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1849103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
1859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
1869103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  do {
187228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers    if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
1889103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      // Lost the race.
1899103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      return false;
1909103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi    }
191228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
192228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                     new_ref.reference_));
1939103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  return true;
1949d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1956a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(expected_rb_ptr, rb_ptr);
1969d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1972c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
1989d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1999d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
2009d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
201624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const {
202800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  if (kUseBakerReadBarrier) {
203800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
204800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK(obj->GetReadBarrierPointer() == nullptr)
205800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
206800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
2072c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  } else {
2082c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers    CHECK(kUseBrooksReadBarrier);
209800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    Object* obj = const_cast<Object*>(this);
210800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi    DCHECK_EQ(obj, obj->GetReadBarrierPointer())
211800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
212800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
213800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi  }
2149d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
2159d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
2164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
217ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) {
2182cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2192cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyFlags>() != nullptr);
220a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  return klass->IsInterface() || InstanceOf(klass);
221a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao}
222a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao
2234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
224ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) {
2252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(klass != nullptr);
2262cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  DCHECK(GetClass<kVerifyNone>() != nullptr);
2274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
2282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2306e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
231ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() {
2326e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
2336e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template GetClass<kVerifyFlags, kReadBarrierOption>();
2346e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
2356e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      kReadBarrierOption>() == java_lang_Class;
2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2386e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() {
2406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
2412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<Class*>(this);
2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
245ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() {
2464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return IsArrayInstance<kVerifyFlags>() &&
2484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags>
2522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() {
2534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsObjectArray<kVerifyFlags>());
2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<ObjectArray<T>*>(this);
2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2576e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
258ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() {
2596e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetClass<kVerifyFlags, kReadBarrierOption>()->
2606e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
264ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() {
2654ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih  return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
2698fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() {
2708fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsReferenceInstance<kVerifyFlags>());
2718fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<Reference*>(this);
2728fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
2738fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
2746e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
27505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() {
2766e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
27705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Array*>(this);
27805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
28105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() {
2824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
28505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<BooleanArray*>(this);
28605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
28705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
28905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() {
290e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
29305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ByteArray*>(this);
29405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
29505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
297ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() {
298e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
302ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ByteArray*>(this);
303ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
304ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() {
3074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
31005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<CharArray*>(this);
31105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
31205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() {
3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
31805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ShortArray*>(this);
31905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
32005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
322ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() {
3234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
3264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
327ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ShortArray*>(this);
328ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
329ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
331e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsIntArray() {
3324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
333e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
334e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>();
335e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
336e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
338e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline IntArray* Object::AsIntArray() {
339e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsIntArray<kVerifyFlags>());
34005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<IntArray*>(this);
34105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
34205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
344e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsLongArray() {
3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
346e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
347e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>();
348e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
349e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
350e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
351e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline LongArray* Object::AsLongArray() {
352e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsLongArray<kVerifyFlags>());
35305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<LongArray*>(this);
35405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
35505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
357e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsFloatArray() {
358e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
359e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>();
361e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
362e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
363e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
364d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() {
365e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsFloatArray<kVerifyFlags>());
3664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
369d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<FloatArray*>(this);
370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
371d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
3724e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
373e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsDoubleArray() {
374e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
375e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
376e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>();
377e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier}
378e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
379e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
380d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() {
381e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  DCHECK(IsDoubleArray<kVerifyFlags>());
3824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
3844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
385d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<DoubleArray*>(this);
386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
388848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
389848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoinline bool Object::IsString() {
390848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass();
391848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao}
392848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao
393848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
39405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() {
395848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  DCHECK((IsString<kVerifyFlags, kReadBarrierOption>()));
39605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<String*>(this);
39705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
39805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
40005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() {
4014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
40205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Throwable*>(this);
40305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
40405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
406ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() {
4074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
4082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
411ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() {
4124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
4132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
416ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() {
4174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
4182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
4218fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() {
4228fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
4238fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<FinalizerReference*>(this);
4248fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
4258fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
4268fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
427ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() {
4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4316e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
432ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() {
4332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t result;
4344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
4356e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
4366e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsArray<kNewFlags, kReadBarrierOption>()->
4376e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
4386e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
4396e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi    result = AsClass<kNewFlags, kReadBarrierOption>()->
4406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi        template SizeOf<kNewFlags, kReadBarrierOption>();
441848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao  } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) {
442848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    result = AsString<kNewFlags, kReadBarrierOption>()->
443848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao        template SizeOf<kNewFlags>();
4442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
44525023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi    result = GetClass<kNewFlags, kReadBarrierOption>()->
44625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi        template GetObjectSize<kNewFlags, kReadBarrierOption>();
4472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4489103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  DCHECK_GE(result, sizeof(Object))
4496e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return result;
4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
453b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
45437f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) {
4554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
45837f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint8_t, kIsVolatile>(field_offset);
45937f05ef45e0393de812d51261dc293240c17294dFred Shih}
46037f05ef45e0393de812d51261dc293240c17294dFred Shih
46137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
46237f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) {
46337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
46437f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
46537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
46637f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int8_t, kIsVolatile>(field_offset);
46737f05ef45e0393de812d51261dc293240c17294dFred Shih}
46837f05ef45e0393de812d51261dc293240c17294dFred Shih
46937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
47037f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
47137f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldBoolean<kVerifyFlags, true>(field_offset);
47237f05ef45e0393de812d51261dc293240c17294dFred Shih}
47337f05ef45e0393de812d51261dc293240c17294dFred Shih
47437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
47537f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
47637f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldByte<kVerifyFlags, true>(field_offset);
47737f05ef45e0393de812d51261dc293240c17294dFred Shih}
47837f05ef45e0393de812d51261dc293240c17294dFred Shih
47937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
48037f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
48137f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value)
48290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
48337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
48437f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
48537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
48637f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
48737f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldBoolean(this, field_offset,
48837f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset),
48937f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
49037f05ef45e0393de812d51261dc293240c17294dFred Shih  }
49137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
49237f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
49337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
49437f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint8_t, kIsVolatile>(field_offset, new_value);
49537f05ef45e0393de812d51261dc293240c17294dFred Shih}
49637f05ef45e0393de812d51261dc293240c17294dFred Shih
49737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
49837f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
49937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value)
50090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
50137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
50237f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
50337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
50437f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
50537f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldByte(this, field_offset,
50637f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset),
50737f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
50837f05ef45e0393de812d51261dc293240c17294dFred Shih  }
50937f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
51037f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
51137f05ef45e0393de812d51261dc293240c17294dFred Shih  }
51237f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int8_t, kIsVolatile>(field_offset, new_value);
51337f05ef45e0393de812d51261dc293240c17294dFred Shih}
51437f05ef45e0393de812d51261dc293240c17294dFred Shih
51537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
51637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
51737f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
51837f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
51937f05ef45e0393de812d51261dc293240c17294dFred Shih}
52037f05ef45e0393de812d51261dc293240c17294dFred Shih
52137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
52237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
52337f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
52437f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
52537f05ef45e0393de812d51261dc293240c17294dFred Shih}
52637f05ef45e0393de812d51261dc293240c17294dFred Shih
52737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
52837f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
52937f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
53037f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
53137f05ef45e0393de812d51261dc293240c17294dFred Shih  }
53237f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<uint16_t, kIsVolatile>(field_offset);
53337f05ef45e0393de812d51261dc293240c17294dFred Shih}
53437f05ef45e0393de812d51261dc293240c17294dFred Shih
53537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
53637f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) {
53737f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
53837f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
539b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
54037f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int16_t, kIsVolatile>(field_offset);
54137f05ef45e0393de812d51261dc293240c17294dFred Shih}
54237f05ef45e0393de812d51261dc293240c17294dFred Shih
54337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
54437f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
54537f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldChar<kVerifyFlags, true>(field_offset);
54637f05ef45e0393de812d51261dc293240c17294dFred Shih}
54737f05ef45e0393de812d51261dc293240c17294dFred Shih
54837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags>
54937f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
55037f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetFieldShort<kVerifyFlags, true>(field_offset);
55137f05ef45e0393de812d51261dc293240c17294dFred Shih}
55237f05ef45e0393de812d51261dc293240c17294dFred Shih
55337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
55437f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
55537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
55637f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
55737f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
55837f05ef45e0393de812d51261dc293240c17294dFred Shih  }
55937f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
56037f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
56137f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset),
56237f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
56337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
56437f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
56537f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
56637f05ef45e0393de812d51261dc293240c17294dFred Shih  }
56737f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<uint16_t, kIsVolatile>(field_offset, new_value);
56837f05ef45e0393de812d51261dc293240c17294dFred Shih}
56937f05ef45e0393de812d51261dc293240c17294dFred Shih
57037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
57137f05ef45e0393de812d51261dc293240c17294dFred Shih    bool kIsVolatile>
57237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
57337f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kCheckTransaction) {
57437f05ef45e0393de812d51261dc293240c17294dFred Shih    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
57537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
57637f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kTransactionActive) {
57737f05ef45e0393de812d51261dc293240c17294dFred Shih    Runtime::Current()->RecordWriteFieldChar(this, field_offset,
57837f05ef45e0393de812d51261dc293240c17294dFred Shih                                           GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset),
57937f05ef45e0393de812d51261dc293240c17294dFred Shih                                           kIsVolatile);
58037f05ef45e0393de812d51261dc293240c17294dFred Shih  }
58137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
58237f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
58337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
58437f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int16_t, kIsVolatile>(field_offset, new_value);
58537f05ef45e0393de812d51261dc293240c17294dFred Shih}
58637f05ef45e0393de812d51261dc293240c17294dFred Shih
58737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
58837f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
58937f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
59037f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
59137f05ef45e0393de812d51261dc293240c17294dFred Shih}
59237f05ef45e0393de812d51261dc293240c17294dFred Shih
59337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
59437f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
59537f05ef45e0393de812d51261dc293240c17294dFred Shih  return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
59637f05ef45e0393de812d51261dc293240c17294dFred Shih      field_offset, new_value);
59737f05ef45e0393de812d51261dc293240c17294dFred Shih}
59837f05ef45e0393de812d51261dc293240c17294dFred Shih
59937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
60037f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) {
60137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kVerifyFlags & kVerifyThis) {
60237f05ef45e0393de812d51261dc293240c17294dFred Shih    VerifyObject(this);
60337f05ef45e0393de812d51261dc293240c17294dFred Shih  }
60437f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int32_t, kIsVolatile>(field_offset);
605b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
606b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
607b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
608b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
609b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField32<kVerifyFlags, true>(field_offset);
610b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
611b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
612b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
613b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
614b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
615d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
616d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
617d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
618d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
619b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField32(this, field_offset,
620b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField32<kVerifyFlags, kIsVolatile>(field_offset),
621b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
622d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
624b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    VerifyObject(this);
625b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
62637f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int32_t, kIsVolatile>(field_offset, new_value);
627b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
628b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
6294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
630b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
631b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
632b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
633b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
634d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
635d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
636b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
637228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
638228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int32_t old_value, int32_t new_value) {
639d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
640d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
641d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
642d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
643d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
644d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
6454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
6464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
6474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
64813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
649228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
6503035961cb41865b80b927546be0c708b6389cec6Hans Boehm
651228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
652d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
653d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
654d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
655d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
656d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                          int32_t old_value, int32_t new_value) {
657d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
658d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
659d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
660d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
661d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
662d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
663d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
664d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
665d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
66613735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
667d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
668d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
669d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
670d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
671d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
672d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
673d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
674d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int32_t old_value, int32_t new_value) {
675d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
676d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
677d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
678d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
679d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
680d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
681d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
682d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
683d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
68413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
685d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
686d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
687d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
688d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
689d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
690b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
691b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) {
6924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
6934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
6944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
69537f05ef45e0393de812d51261dc293240c17294dFred Shih  return GetField<int64_t, kIsVolatile>(field_offset);
6962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
6972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
698b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
699b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
700b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetField64<kVerifyFlags, true>(field_offset);
701b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
702b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
703b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
704b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
705b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
706d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
707d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
708d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
709d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
710b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteField64(this, field_offset,
711b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           GetField64<kVerifyFlags, kIsVolatile>(field_offset),
712b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                           kIsVolatile);
713d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
715ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
716ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
71737f05ef45e0393de812d51261dc293240c17294dFred Shih  SetField<int64_t, kIsVolatile>(field_offset, new_value);
7182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
7192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
7204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
721b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
722b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
723b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                               new_value);
724b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
725b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
72637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
72737f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) {
72813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
72937f05ef45e0393de812d51261dc293240c17294dFred Shih  kSize* addr = reinterpret_cast<kSize*>(raw_addr);
73037f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
73137f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value);
73237f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
73337f05ef45e0393de812d51261dc293240c17294dFred Shih    reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
73437f05ef45e0393de812d51261dc293240c17294dFred Shih  }
73537f05ef45e0393de812d51261dc293240c17294dFred Shih}
73637f05ef45e0393de812d51261dc293240c17294dFred Shih
73737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile>
73837f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) {
73913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
74037f05ef45e0393de812d51261dc293240c17294dFred Shih  const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
74137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (kIsVolatile) {
74237f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent();
74337f05ef45e0393de812d51261dc293240c17294dFred Shih  } else {
74437f05ef45e0393de812d51261dc293240c17294dFred Shih    return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
74537f05ef45e0393de812d51261dc293240c17294dFred Shih  }
74637f05ef45e0393de812d51261dc293240c17294dFred Shih}
74737f05ef45e0393de812d51261dc293240c17294dFred Shih
748b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
749228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
750228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                         int64_t old_value, int64_t new_value) {
751d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
752d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
753d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
754d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
755d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
756d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
7574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
76013735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
761228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
762228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
763ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
764ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
765d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
766d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
767d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                           int64_t old_value, int64_t new_value) {
768d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
769d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
770d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
771d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
772d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
773d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
774d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
775d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
776d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
77713735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
778d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
779d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
780d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
781d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
7826e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
7836e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi         bool kIsVolatile>
784b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) {
7854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
7864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
7874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
78813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
789ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
7906e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
791b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
7923035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent load instead.
7933035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceAcquire();  // Ensure visibility of operations preceding store.
794ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
7954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
7964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(result);
7974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
798ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return result;
799ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
800ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
8016e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
802b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
8036e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
804b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
805b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
806b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
807b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
808b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
809b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                      Object* new_value) {
810d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
811d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
812d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
813d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
814b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    mirror::Object* obj;
815b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    if (kIsVolatile) {
816b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObjectVolatile<Object>(field_offset);
817b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    } else {
818b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      obj = GetFieldObject<Object>(field_offset);
819b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    }
820b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
821d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
8224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
823ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
824ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
8254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
8264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
8274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
82813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
829ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
830b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kIsVolatile) {
8313035961cb41865b80b927546be0c708b6389cec6Hans Boehm    // TODO: Refactor to use a SequentiallyConsistent store instead.
8323035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceRelease();  // Ensure that prior accesses are visible before store.
833ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
8343035961cb41865b80b927546be0c708b6389cec6Hans Boehm    QuasiAtomic::ThreadFenceSequentiallyConsistent();
8353035961cb41865b80b927546be0c708b6389cec6Hans Boehm                                // Ensure this store occurs before any volatile loads.
836ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
837ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
838ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
839ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
840ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
841b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
842b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    bool kIsVolatile>
843b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
844b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
845b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers      kIsVolatile>(field_offset, new_value);
846ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (new_value != nullptr) {
847ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
84861c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
84961c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier    CheckFieldAssignment(field_offset, new_value);
850ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
851ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
852ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
853b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
854b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
855b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
856b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers                                                                            new_value);
857b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
858b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
8594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags>
8604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
8614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
8624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
8634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
86413735955f39b3b304c37d2b2840663c131262c18Ian Rogers  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
8654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset.Int32Value());
8664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier}
8674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier
8684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
869228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
870228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                             Object* old_value, Object* new_value) {
8712cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
8722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
8732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  if (success) {
8742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
8752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  }
8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
8772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
8782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi
8792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
8802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
8812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
882d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
883d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
884d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
8854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
8864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
8874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
8884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
8894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
8904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
8914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
8924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(old_value);
8934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
894d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
895d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
896d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
897ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
898ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
89913735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
900228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
901228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
902228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers  bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
903228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers                                                                        new_ref.reference_);
9042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  return success;
9052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi}
906228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers
9072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
9082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
9092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi                                                               Object* old_value, Object* new_value) {
9102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi  bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
9112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi      kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
912ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (success) {
913ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
914ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
915ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return success;
9162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
9172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
918d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
9192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
9202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi    MemberOffset field_offset, Object* old_value, Object* new_value) {
921d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kCheckTransaction) {
922d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
923d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
924d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyThis) {
925d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(this);
926d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
927d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyWrites) {
928d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(new_value);
929d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
930d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kVerifyFlags & kVerifyReads) {
931d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    VerifyObject(old_value);
932d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
933d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  if (kTransactionActive) {
934d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
935d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  }
936d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
937d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
93813735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
939d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
940d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
941d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
942d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm                                                                          new_ref.reference_);
943d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm  return success;
944d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm}
945d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm
946059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<bool kIsStatic, typename Visitor>
947407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
948cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers  if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
949cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    // Instance fields and not the slow-path.
950cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers    uint32_t field_offset = mirror::kObjectHeaderSize;
951407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    while (ref_offsets != 0) {
952cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      if ((ref_offsets & 1) != 0) {
953cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers        visitor(this, MemberOffset(field_offset), kIsStatic);
954cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      }
955cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      ref_offsets >>= 1;
956cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers      field_offset += sizeof(mirror::HeapReference<mirror::Object>);
957407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
958407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  } else {
959faff0f05fef90577c9744505555675185832aacdMingyao Yang    // There is no reference offset bitmap. In the non-static case, walk up the class
960407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // inheritance hierarchy and find reference offsets the hard way. In the static case, just
961407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    // consider this class.
962407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
963407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        klass = kIsStatic ? nullptr : klass->GetSuperClass()) {
964407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      size_t num_reference_fields =
965407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier          kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
96676649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      if (num_reference_fields == 0u) {
96776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        continue;
96876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      }
969e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      // Presumably GC can happen when we are cross compiling, it should not cause performance
970e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier      // problems to do pointer size logic.
97176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko      MemberOffset field_offset = kIsStatic
972e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier          ? klass->GetFirstReferenceStaticFieldOffset(
973e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier              Runtime::Current()->GetClassLinker()->GetImagePointerSize())
97476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko          : klass->GetFirstReferenceInstanceFieldOffset();
975059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier      for (size_t i = 0u; i < num_reference_fields; ++i) {
976407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        // TODO: Do a simpler check?
977059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier        if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
97852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier          visitor(this, field_offset, kIsStatic);
979407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier        }
98076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko        field_offset = MemberOffset(field_offset.Uint32Value() +
98176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko                                    sizeof(mirror::HeapReference<mirror::Object>));
982407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier      }
983407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
984407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
985407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
986407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
987059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor>
988407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
989059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier  VisitFieldsReferences<false>(klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor);
990407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
991407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
992059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor>
993407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
99498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  DCHECK(!klass->IsTemp());
995059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier  klass->VisitFieldsReferences<true>(0, visitor);
996407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
997407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier
998e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
999e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline bool Object::IsClassLoader() {
1000e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier  return GetClass<kVerifyFlags>()->IsClassLoaderClass();
1001e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier}
1002e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier
1003e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
1004e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline mirror::ClassLoader* Object::AsClassLoader() {
1005e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier  DCHECK(IsClassLoader<kVerifyFlags>());
1006e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier  return down_cast<mirror::ClassLoader*>(this);
1007e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier}
1008e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier
1009059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, typename Visitor, typename JavaLangRefVisitor>
1010407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor,
1011407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier                                    const JavaLangRefVisitor& ref_visitor) {
1012407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  mirror::Class* klass = GetClass<kVerifyFlags>();
1013059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier  visitor(this, ClassOffset(), false);
101452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>();
101552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  if (LIKELY(class_flags == kClassFlagNormal)) {
101652e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier    DCHECK(!klass->IsVariableSize());
1017059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier    VisitInstanceFieldsReferences(klass, visitor);
101852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    DCHECK(!klass->IsClassClass());
101966c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier    DCHECK(!klass->IsStringClass());
102066c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier    DCHECK(!klass->IsClassLoaderClass());
102166c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier    DCHECK(!klass->IsArrayClass());
102252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier  } else {
102352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    if ((class_flags & kClassFlagNoReferenceFields) == 0) {
102452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      DCHECK(!klass->IsStringClass());
102552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      if (class_flags == kClassFlagClass) {
102652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        DCHECK(klass->IsClassClass());
102752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        AsClass<kVerifyNone>()->VisitReferences(klass, visitor);
102852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else if (class_flags == kClassFlagObjectArray) {
102952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        DCHECK(klass->IsObjectArrayClass());
103052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences(visitor);
103152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else if ((class_flags & kClassFlagReference) != 0) {
103252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        VisitInstanceFieldsReferences(klass, visitor);
103352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        ref_visitor(klass, AsReference());
103452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      } else {
103552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags>();
103652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        class_loader->VisitReferences<kVerifyFlags>(klass, visitor);
103752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      }
103852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier    } else if (kIsDebugBuild) {
103952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      CHECK(!klass->IsClassClass());
104052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      CHECK(!klass->IsObjectArrayClass());
104152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      // String still has instance fields for reflection purposes but these don't exist in
104252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      // actual string instances.
104352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      if (!klass->IsStringClass()) {
104452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        size_t total_reference_instance_fields = 0;
104552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        mirror::Class* super_class = klass;
104652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        do {
104752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier          total_reference_instance_fields += super_class->NumReferenceInstanceFields();
104852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier          super_class = super_class->GetSuperClass();
104952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        } while (super_class != nullptr);
105052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        // The only reference field should be the object's class. This field is handled at the
105152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        // beginning of the function.
105252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier        CHECK_EQ(total_reference_instance_fields, 1u);
105352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier      }
1054407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier    }
1055407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier  }
1056407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier}
10572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
10582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
10592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1060fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
1061