object-inl.h revision 8fa2dad7fe7909c8335101d6c8904ae997cdf29f
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/*
22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project
32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License.
62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at
72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *
102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software
112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and
142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License.
152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */
162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_OBJECT_INL_H_
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
22ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_field.h"
23ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "art_method.h"
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "atomic.h"
254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "array-inl.h"
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h"
27d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word-inl.h"
2805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "monitor.h"
292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h"
308fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h"
3105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h"
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
37ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() {
384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetFieldObject<Class, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) {
43ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // new_klass may be NULL prior to class linker initialization.
44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // We don't mark the card as this occurs as part of object allocation. Not all objects have
45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // backing cards, such as large objects.
46d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // We use non transactional version since we can't undo this write. We also disable checking as
47d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // we may run in transaction mode here.
484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<false, false,
494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false);
512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
53ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline LockWord Object::GetLockWord() {
54d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true));
55d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
56d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
57d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline void Object::SetLockWord(LockWord new_val) {
58d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true);
60d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
61d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline bool Object::CasLockWord(LockWord old_val, LockWord new_val) {
63d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // Force use of non-transactional mode and do not check.
64d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(),
65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                  new_val.GetValue());
66d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
67d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
68d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() {
69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  return Monitor::GetLockOwnerThreadId(this);
7005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
7105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
72e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) {
73e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return Monitor::MonitorEnter(self, this);
7405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
7505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
7605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) {
7705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return Monitor::MonitorExit(self, this);
7805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
7905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
8005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) {
8105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Notify(self, this);
8205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
8305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
8405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) {
8505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::NotifyAll(self, this);
8605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
8705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
8805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) {
8905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, 0, 0, true, kWaiting);
9005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
9205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
9305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
9405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
9505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
969d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchiinline Object* Object::GetBrooksPointer() {
979d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#ifdef USE_BROOKS_POINTER
989d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  DCHECK(kUseBrooksPointer);
999d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  return GetFieldObject<Object, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), false);
1009d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1019d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1029d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  return nullptr;
1039d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1049d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1059d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchiinline void Object::SetBrooksPointer(Object* brooks_pointer) {
1079d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#ifdef USE_BROOKS_POINTER
1089d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  DCHECK(kUseBrooksPointer);
1099d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // We don't mark the card as this occurs as part of object allocation. Not all objects have
1109d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  // backing cards, such as large objects.
1119d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
1129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi      OFFSET_OF_OBJECT_MEMBER(Object, x_brooks_ptr_), brooks_pointer, false);
1139d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1149d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1159d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1169d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1179d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1189d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchiinline void Object::AssertSelfBrooksPointer() const {
1199d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#ifdef USE_BROOKS_POINTER
1209d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  DCHECK(kUseBrooksPointer);
1219d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  Object* obj = const_cast<Object*>(this);
1229d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  DCHECK_EQ(obj, obj->GetBrooksPointer());
1239d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else
1249d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi  LOG(FATAL) << "Unreachable";
1259d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif
1269d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi}
1279d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi
1284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
129ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) {
130a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  DCHECK(klass != NULL);
1314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>() != NULL);
132a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao  return klass->IsInterface() || InstanceOf(klass);
133a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao}
134a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao
1354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
136ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) {
1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DCHECK(klass != NULL);
1384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyNone>() != NULL);
1394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
1402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
143ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() {
1444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  Class* java_lang_Class = GetClass<kVerifyFlags>()->GetClass();
1454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ==
1464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      java_lang_Class;
1472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
1502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() {
1514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsClass<kVerifyFlags>());
1522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<Class*>(this);
1532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
156ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() {
1574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
1584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return IsArrayInstance<kVerifyFlags>() &&
1594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
1602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags>
1632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() {
1644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsObjectArray<kVerifyFlags>());
1652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return down_cast<ObjectArray<T>*>(this);
1662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
169ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() {
1704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsArrayClass();
1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
174ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtField() {
1754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsArtFieldClass();
1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
1794e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline ArtField* Object::AsArtField() {
1804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArtField<kVerifyFlags>());
181ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  return down_cast<ArtField*>(this);
1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
185ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtMethod() {
1864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsArtMethodClass();
1872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
190ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline ArtMethod* Object::AsArtMethod() {
1914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArtMethod<kVerifyFlags>());
192ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  return down_cast<ArtMethod*>(this);
1932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
196ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() {
1974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsReferenceClass();
1982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
2018fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() {
2028fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsReferenceInstance<kVerifyFlags>());
2038fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<Reference*>(this);
2048fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
2058fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
2068fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
20705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() {
2084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(IsArrayInstance<kVerifyFlags>());
20905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Array*>(this);
21005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
21105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
21305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() {
2144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
21705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<BooleanArray*>(this);
21805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
21905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
22105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() {
2224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
22505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ByteArray*>(this);
22605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
22705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
229ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() {
2304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
2334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
234ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ByteArray*>(this);
235ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
236ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
2374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
23805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() {
2394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
24205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<CharArray*>(this);
24305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
24405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
24605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() {
2474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
25005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<ShortArray*>(this);
25105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
25205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
254ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() {
2554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
2584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
259ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return down_cast<ShortArray*>(this);
260ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
261ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
2624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
26305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline IntArray* Object::AsIntArray() {
2644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
2674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
26805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<IntArray*>(this);
26905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
27005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2714e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
27205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline LongArray* Object::AsLongArray() {
2734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
2764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
27705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<LongArray*>(this);
27805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
2804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
281d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() {
2824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
285d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<FloatArray*>(this);
286d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
287d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
2884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
289d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() {
2904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
2914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
293d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  return down_cast<DoubleArray*>(this);
294d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz}
295d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
2964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
29705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() {
2984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
29905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<String*>(this);
30005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
30105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
30305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() {
3044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers  return down_cast<Throwable*>(this);
30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers}
30705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers
3084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
309ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() {
3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
3112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
314ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() {
3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
3162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
319ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() {
3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
3212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
3248fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() {
3258fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
3268fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier  return down_cast<FinalizerReference*>(this);
3278fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier}
3288fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier
3298fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
330ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() {
3314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
3322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
335ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() {
3362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t result;
3374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
3384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (IsArrayInstance<kVerifyFlags>()) {
339b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers    result = AsArray<kNewFlags>()->template SizeOf<kNewFlags>();
3404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  } else if (IsClass<kNewFlags>()) {
341b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers    result = AsClass<kNewFlags>()->template SizeOf<kNewFlags>();
3422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
3434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    result = GetClass<kNewFlags>()->GetObjectSize();
3442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass<kNewFlags>());
3464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(!IsArtField<kNewFlags>()  || result == sizeof(ArtField));
3474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  DCHECK(!IsArtMethod<kNewFlags>() || result == sizeof(ArtMethod));
3482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return result;
3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
3502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
35229501cf5663c7951717bae3521815d121a778396Ian Rogersinline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) {
3534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
3544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
3554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
356b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
357b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
358b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  if (UNLIKELY(is_volatile)) {
359b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr)));
360ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure volatile loads don't re-order.
361b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    return result;
362b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  } else {
363b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    return *word_addr;
364b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
365b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
366b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
3674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile) {
369d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
371d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
372d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
373d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile),
374d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                           is_volatile);
375d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
3764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
377b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    VerifyObject(this);
378b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
379b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
38029501cf5663c7951717bae3521815d121a778396Ian Rogers  int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
381b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  if (UNLIKELY(is_volatile)) {
382b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
383b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    *word_addr = new_value;
384ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any volatile loads.
385b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  } else {
386b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    *word_addr = new_value;
387b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  }
388b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers}
389b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers
3904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
39129501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) {
392d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
393d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
394d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
395d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
396d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
397d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
3984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
3994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
401d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
40229501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
403b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers  return __sync_bool_compare_and_swap(addr, old_value, new_value);
404d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers}
405d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers
4064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags>
40729501cf5663c7951717bae3521815d121a778396Ian Rogersinline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) {
4084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
4122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
4132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  if (UNLIKELY(is_volatile)) {
41429501cf5663c7951717bae3521815d121a778396Ian Rogers    int64_t result = QuasiAtomic::Read64(addr);
415ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure volatile loads don't re-order.
4162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return result;
4172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
4182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return *addr;
4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
4234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile) {
424d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
425d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
426d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
427d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
428d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile),
429d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                           is_volatile);
430d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
432ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
433ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
4342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
4362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  if (UNLIKELY(is_volatile)) {
437b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
4382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    QuasiAtomic::Write64(addr, new_value);
439b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    if (!QuasiAtomic::LongAtomicsUseMutexes()) {
440ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any volatile loads.
441b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    } else {
442b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers      // Fence from from mutex is enough.
443b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers    }
4442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  } else {
4452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    *addr = new_value;
4462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
4472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
4482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
45029501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) {
451d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
452d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
453d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
454d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
455d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
456d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
460ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
46129501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr);
46229501cf5663c7951717bae3521815d121a778396Ian Rogers  return QuasiAtomic::Cas64(old_value, new_value, addr);
463ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
464ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
4654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags>
466ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) {
4674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
4684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
4694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
470ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
471ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
472ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<T> objref = *objref_addr;
473ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
474ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(is_volatile)) {
475ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarLoadLoad();  // Ensure loads don't re-order.
476ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
477ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  T* result = objref.AsMirrorPtr();
4784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
4794e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(result);
4804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
481ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return result;
482ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
483ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
4844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
485ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value,
4864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier                                                      bool is_volatile) {
487d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
488d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
489d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
490d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
491d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset,
492d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                                  GetFieldObject<Object>(field_offset, is_volatile),
493d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                                                  true);
494d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
4954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
496ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    VerifyObject(this);
497ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
4984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
4994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
5004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
501ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
502ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
503ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(is_volatile)) {
504ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreStore();  // Ensure this store occurs after others in the queue.
505ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
506ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    QuasiAtomic::MembarStoreLoad();  // Ensure this store occurs before any loads.
507ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
508ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    objref_addr->Assign(new_value);
509ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
510ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
511ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
5124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
5134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile) {
5144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>(
5154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset, new_value, is_volatile);
516ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (new_value != nullptr) {
517ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    CheckFieldAssignment(field_offset, new_value);
518ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
519ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
520ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
521ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
5224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags>
5234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
5244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
5254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
5264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) +
5284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      field_offset.Int32Value());
5294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier}
5304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier
5314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
5324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value,
5334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier                                   Object* new_value) {
534d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kCheckTransaction) {
535d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
536d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
5374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyThis) {
5384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(this);
5394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyWrites) {
5414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(new_value);
5424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
5434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  if (kVerifyFlags & kVerifyReads) {
5444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    VerifyObject(old_value);
5454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  }
546d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  if (kTransactionActive) {
547d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
548d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  }
549ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
55029501cf5663c7951717bae3521815d121a778396Ian Rogers  volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr);
551ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
552ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
553ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  bool success =  __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_);
554ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (success) {
555ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
556ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
557ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  return success;
5582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
5592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
5602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
5612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
5622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
563fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
564