object-inl.h revision 800ac2defde5d12b2f1f313c6b6162560cfa6fc7
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" 29800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h" 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "runtime.h" 318fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h" 3205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h" 332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() { 394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetFieldObject<Class, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false); 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) { 44ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // new_klass may be NULL prior to class linker initialization. 45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // We don't mark the card as this occurs as part of object allocation. Not all objects have 46ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // backing cards, such as large objects. 47d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We use non transactional version since we can't undo this write. We also disable checking as 48d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // we may run in transaction mode here. 494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier SetFieldObjectWithoutWriteBarrier<false, false, 504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>( 514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false); 522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 54ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline LockWord Object::GetLockWord() { 55d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true)); 56d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 57d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 58d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline void Object::SetLockWord(LockWord new_val) { 59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true); 61d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 63d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline bool Object::CasLockWord(LockWord old_val, LockWord new_val) { 64d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), 66d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz new_val.GetValue()); 67d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 68d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() { 70d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return Monitor::GetLockOwnerThreadId(this); 7105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 7205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 73e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) { 74e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier return Monitor::MonitorEnter(self, this); 7505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 7605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 7705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) { 7805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return Monitor::MonitorExit(self, this); 7905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 8105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) { 8205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Notify(self, this); 8305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 8505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) { 8605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::NotifyAll(self, this); 8705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 8905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) { 9005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, 0, 0, true, kWaiting); 9105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 9205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 9305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 9405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 9505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 9605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 97624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() { 98624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 99624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi DCHECK(kUseBakerOrBrooksReadBarrier); 100800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi return GetFieldObject<Object, kVerifyNone, false>(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false); 1019d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1029d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1039d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi return nullptr; 1049d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1059d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 107624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_pointer) { 108624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 109624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi DCHECK(kUseBakerOrBrooksReadBarrier); 1109d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // We don't mark the card as this occurs as part of object allocation. Not all objects have 1119d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // backing cards, such as large objects. 1129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 113624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_pointer, false); 1149d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1159d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1169d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1179d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1189d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 119624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const { 120800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi if (kUseBakerReadBarrier) { 121800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 122800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK(obj->GetReadBarrierPointer() == nullptr) 123800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 124800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 125800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } else if (kUseBrooksReadBarrier) { 126800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 127800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 128800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 129800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 130800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } else { 131800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi LOG(FATAL) << "Unreachable"; 132800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } 1339d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1349d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 136ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) { 137a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao DCHECK(klass != NULL); 1384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>() != NULL); 139a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao return klass->IsInterface() || InstanceOf(klass); 140a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao} 141a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao 1424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 143ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) { 1442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(klass != NULL); 1454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyNone>() != NULL); 1464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 1472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 150ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() { 1514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier Class* java_lang_Class = GetClass<kVerifyFlags>()->GetClass(); 1524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() == 1534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier java_lang_Class; 1542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() { 1584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsClass<kVerifyFlags>()); 1592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<Class*>(this); 1602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 163ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() { 1644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 1654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return IsArrayInstance<kVerifyFlags>() && 1664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive(); 1672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags> 1702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() { 1714e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsObjectArray<kVerifyFlags>()); 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<ObjectArray<T>*>(this); 1732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 176ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() { 1774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsArrayClass(); 1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 181ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtField() { 1824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsArtFieldClass(); 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline ArtField* Object::AsArtField() { 1874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsArtField<kVerifyFlags>()); 188ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return down_cast<ArtField*>(this); 1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 192ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtMethod() { 1934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsArtMethodClass(); 1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 197ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline ArtMethod* Object::AsArtMethod() { 1984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsArtMethod<kVerifyFlags>()); 199ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return down_cast<ArtMethod*>(this); 2002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 203ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() { 2044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsReferenceClass(); 2052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 2088fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() { 2098fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsReferenceInstance<kVerifyFlags>()); 2108fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<Reference*>(this); 2118fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 2128fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 2138fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 21405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() { 2154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsArrayInstance<kVerifyFlags>()); 21605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Array*>(this); 21705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 21805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 22005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() { 2214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 22405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<BooleanArray*>(this); 22505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 22605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 22805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() { 2294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 23205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ByteArray*>(this); 23305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 23405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 236ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() { 2374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 2404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ByteArray*>(this); 242ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 243ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 2444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 24505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() { 2464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 24905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<CharArray*>(this); 25005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 25105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 25305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() { 2544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 25705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ShortArray*>(this); 25805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 25905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 261ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() { 2624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 2654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ShortArray*>(this); 267ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 268ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 2694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 27005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline IntArray* Object::AsIntArray() { 2714e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2724e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() || 2744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 27505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<IntArray*>(this); 27605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 27705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline LongArray* Object::AsLongArray() { 2804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2814e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() || 2834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 28405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<LongArray*>(this); 28505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 288d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() { 2894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 292d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<FloatArray*>(this); 293d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 294d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 2954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 296d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() { 2974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 300d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<DoubleArray*>(this); 301d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 302d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() { 3054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsStringClass()); 30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<String*>(this); 30705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 30805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 31005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() { 3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 31205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Throwable*>(this); 31305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 316ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() { 3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 3182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 321ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() { 3224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 326ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() { 3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 3282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 3318fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() { 3328fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 3338fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<FinalizerReference*>(this); 3348fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 3358fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 3368fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 337ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() { 3384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 3392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 342ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() { 3432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t result; 3444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (IsArrayInstance<kVerifyFlags>()) { 346b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers result = AsArray<kNewFlags>()->template SizeOf<kNewFlags>(); 3474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } else if (IsClass<kNewFlags>()) { 348b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers result = AsClass<kNewFlags>()->template SizeOf<kNewFlags>(); 3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 3504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier result = GetClass<kNewFlags>()->GetObjectSize(); 3512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass<kNewFlags>()); 3534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(!IsArtField<kNewFlags>() || result == sizeof(ArtField)); 3544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(!IsArtMethod<kNewFlags>() || result == sizeof(ArtMethod)); 3552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 3562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 35929501cf5663c7951717bae3521815d121a778396Ian Rogersinline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) { 3604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 3614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 3624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 363b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value(); 364b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr); 365b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (UNLIKELY(is_volatile)) { 366b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr))); 367ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order. 368b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return result; 369b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 370b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return *word_addr; 371b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 372b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 373b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 3744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 3754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile) { 376d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 377d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 378d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 380d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile), 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz is_volatile); 382d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 384b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers VerifyObject(this); 385b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 386b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 38729501cf5663c7951717bae3521815d121a778396Ian Rogers int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr); 388b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (UNLIKELY(is_volatile)) { 389b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 390b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers *word_addr = new_value; 391ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads. 392b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 393b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers *word_addr = new_value; 394b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 395b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 396b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 3974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 39829501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) { 399d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 400d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 401d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 402d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 403d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 404d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 408d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 40929501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); 410b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return __sync_bool_compare_and_swap(addr, old_value, new_value); 411d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 412d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 4134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 41429501cf5663c7951717bae3521815d121a778396Ian Rogersinline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) { 4154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 4182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value(); 4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr); 4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (UNLIKELY(is_volatile)) { 42129501cf5663c7951717bae3521815d121a778396Ian Rogers int64_t result = QuasiAtomic::Read64(addr); 422ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order. 4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 4242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 4252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return *addr; 4262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 4304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile) { 431d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 432d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 433d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 434d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 435d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile), 436d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz is_volatile); 437d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 439ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 440ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 4412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 4422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int64_t* addr = reinterpret_cast<int64_t*>(raw_addr); 4432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (UNLIKELY(is_volatile)) { 444b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 4452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers QuasiAtomic::Write64(addr, new_value); 446b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (!QuasiAtomic::LongAtomicsUseMutexes()) { 447ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads. 448b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 449b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers // Fence from from mutex is enough. 450b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *addr = new_value; 4532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 45729501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) { 458d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 459d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 460d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 461d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 462d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 463d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 467ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 46829501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr); 46929501cf5663c7951717bae3521815d121a778396Ian Rogers return QuasiAtomic::Cas64(old_value, new_value, addr); 470ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 471ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 472800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 473ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) { 4744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 477ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 478ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 479800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi T* result = ReadBarrier::Barrier<T, kDoReadBarrier>(this, field_offset, objref_addr); 480ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (UNLIKELY(is_volatile)) { 481ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order. 482ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 4834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 4844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(result); 4854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 486ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return result; 487ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 488ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 4894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 490ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value, 4914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier bool is_volatile) { 492d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 493d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 494d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 495d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 496d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, 497d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz GetFieldObject<Object>(field_offset, is_volatile), 498d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz true); 499d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 5004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 501ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 502ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 5034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 5044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 5054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 506ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 507ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 508ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (UNLIKELY(is_volatile)) { 509ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 510ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 511ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any loads. 512ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 513ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 514ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 515ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 516ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 5174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 5184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile) { 5194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>( 5204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset, new_value, is_volatile); 521ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (new_value != nullptr) { 522ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CheckFieldAssignment(field_offset, new_value); 523ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 524ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 525ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 526ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 5274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags> 5284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 5294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 5304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 5314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) + 5334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset.Int32Value()); 5344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier} 5354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier 5364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 5374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, 5384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier Object* new_value) { 539d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 540d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 541d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 5424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 5434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 5444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 5464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 5474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 5494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(old_value); 5504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 551d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 552d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 553d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 554ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 55529501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); 556ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 557ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 558ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_); 559ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (success) { 560ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 561ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 562ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return success; 5632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 565407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, bool kIsStatic, typename Visitor> 566407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 567407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) { 568407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (!kVisitClass) { 569407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // Mask out the class from the reference offsets. 570407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_offsets ^= kWordHighBitMask; 571407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 572407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier DCHECK_EQ(ClassOffset().Uint32Value(), 0U); 573407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // Found a reference offset bitmap. Visit the specified offsets. 574407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier while (ref_offsets != 0) { 575407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t right_shift = CLZ(ref_offsets); 576407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift); 577407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, field_offset, kIsStatic); 578407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift); 579407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 580407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 581407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // There is no reference offset bitmap. In the non-static case, walk up the class 582407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // inheritance hierarchy and find reference offsets the hard way. In the static case, just 583407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // consider this class. 584407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr; 585407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass = kIsStatic ? nullptr : klass->GetSuperClass()) { 586407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t num_reference_fields = 587407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 588407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (size_t i = 0; i < num_reference_fields; ++i) { 589407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::ArtField* field = kIsStatic ? klass->GetStaticField(i) 590407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier : klass->GetInstanceField(i); 591407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier MemberOffset field_offset = field->GetOffset(); 592407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // TODO: Do a simpler check? 593407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (!kVisitClass && UNLIKELY(field_offset.Uint32Value() == ClassOffset().Uint32Value())) { 594407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier continue; 595407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 596407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, field_offset, kIsStatic); 597407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 598407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 599407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 600407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 601407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 602407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor> 603407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 604407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier VisitFieldsReferences<kVisitClass, false>( 605407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); 606407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 607407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 608407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor> 609407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 610407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->VisitFieldsReferences<kVisitClass, true>( 611407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->GetReferenceStaticOffsets<kVerifyNone>(), visitor); 612407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 613407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 614407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor, 615407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier typename JavaLangRefVisitor> 616407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor, 617407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier const JavaLangRefVisitor& ref_visitor) { 618407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags>(); 619407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (UNLIKELY(klass == Class::GetJavaLangClass())) { 620580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier DCHECK_EQ(klass->GetClass<kVerifyNone>(), Class::GetJavaLangClass()); 621407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); 622407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else if (UNLIKELY(klass->IsArrayClass<kVerifyFlags>())) { 623407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (klass->IsObjectArrayClass<kVerifyNone>()) { 624580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); 625407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else if (kVisitClass) { 626407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, ClassOffset(), false); 627407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 628407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 629580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); 630580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) { 631407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_visitor(klass, AsReference()); 632407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 633407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 634407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 635407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 6362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 6372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 6382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 639fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 640