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