object-inl.h revision 9103c86a98524e9ddfd14f8cee56e919f68eee9b
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 379103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 38ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() { 399103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>( 409103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, klass_), false); 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) { 45ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // new_klass may be NULL prior to class linker initialization. 46ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // We don't mark the card as this occurs as part of object allocation. Not all objects have 47ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // backing cards, such as large objects. 48d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We use non transactional version since we can't undo this write. We also disable checking as 49d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // we may run in transaction mode here. 504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier SetFieldObjectWithoutWriteBarrier<false, false, 514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>( 524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false); 532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 55ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline LockWord Object::GetLockWord() { 56d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), true)); 57d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 58d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 59d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline void Object::SetLockWord(LockWord new_val) { 60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 61d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue(), true); 62d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 63d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 64d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline bool Object::CasLockWord(LockWord old_val, LockWord new_val) { 65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 66d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return CasField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), 67d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz new_val.GetValue()); 68d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 69d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 70d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() { 71d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return Monitor::GetLockOwnerThreadId(this); 7205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 7305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 74e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) { 75e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier return Monitor::MonitorEnter(self, this); 7605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 7705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 7805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) { 7905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return Monitor::MonitorExit(self, this); 8005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 8205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) { 8305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Notify(self, this); 8405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 8605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) { 8705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::NotifyAll(self, this); 8805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 8905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 9005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) { 9105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, 0, 0, true, kWaiting); 9205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 9305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 9405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 9505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 9605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 9705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 98624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() { 99624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 100624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi DCHECK(kUseBakerOrBrooksReadBarrier); 101800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi return GetFieldObject<Object, kVerifyNone, false>(OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), false); 1029d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1039d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1049d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi return nullptr; 1059d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1079d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1089103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) { 109624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 110624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi DCHECK(kUseBakerOrBrooksReadBarrier); 1119d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // We don't mark the card as this occurs as part of object allocation. Not all objects have 1129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // backing cards, such as large objects. 1139d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 1149103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr, false); 1159103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else 1169103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1179103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif 1189103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi} 1199103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi 1209103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { 1219103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER 1229103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK(kUseBakerOrBrooksReadBarrier); 1239103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); 1249103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue(); 1259103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr); 1269103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); 1279103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); 1289103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi uint32_t expected_val = expected_ref.reference_; 1299103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi uint32_t new_val; 1309103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi do { 1319103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi uint32_t old_val = ref->reference_; 1329103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi if (old_val != expected_val) { 1339103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi // Lost the race. 1349103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return false; 1359103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } 1369103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi new_val = new_ref.reference_; 1379103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } while (!__sync_bool_compare_and_swap( 1389103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val)); 1399103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK_EQ(new_val, ref->reference_); 1409103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return true; 1419d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1429d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1439103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return false; 1449d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1459d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1469d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 147624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const { 148800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi if (kUseBakerReadBarrier) { 149800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 150800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK(obj->GetReadBarrierPointer() == nullptr) 151800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 152800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 153800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } else if (kUseBrooksReadBarrier) { 154800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 155800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 156800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 157800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 158800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } else { 159800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi LOG(FATAL) << "Unreachable"; 160800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } 1619d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1629d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 164ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) { 165a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao DCHECK(klass != NULL); 1664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>() != NULL); 167a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao return klass->IsInterface() || InstanceOf(klass); 168a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao} 169a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao 1704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 171ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) { 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DCHECK(klass != NULL); 1734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyNone>() != NULL); 1744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 1752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1779103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 178ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() { 1799103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi Class* java_lang_Class = 1809103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi GetClass<kVerifyFlags, kDoReadBarrier>()->template GetClass<kVerifyFlags, kDoReadBarrier>(); 1819103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), kDoReadBarrier>() == 1824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier java_lang_Class; 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() { 1879103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK((IsClass<kVerifyFlags, kDoReadBarrier>())); 1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<Class*>(this); 1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 192ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() { 1934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 1944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return IsArrayInstance<kVerifyFlags>() && 1954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive(); 1962dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 1972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags> 1992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() { 2004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsObjectArray<kVerifyFlags>()); 2012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<ObjectArray<T>*>(this); 2022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2049103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 205ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() { 2069103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return GetClass<kVerifyFlags, kDoReadBarrier>()-> 2079103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi template IsArrayClass<kVerifyFlags, kDoReadBarrier>(); 2082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2109103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 211ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtField() { 2129103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtFieldClass<kDoReadBarrier>(); 2132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 2164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline ArtField* Object::AsArtField() { 2174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsArtField<kVerifyFlags>()); 218ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return down_cast<ArtField*>(this); 2192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2219103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 222ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArtMethod() { 2239103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtMethodClass<kDoReadBarrier>(); 2242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 227ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrominline ArtMethod* Object::AsArtMethod() { 2284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsArtMethod<kVerifyFlags>()); 229ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom return down_cast<ArtMethod*>(this); 2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 233ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() { 2344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsReferenceClass(); 2352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 2388fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() { 2398fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsReferenceInstance<kVerifyFlags>()); 2408fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<Reference*>(this); 2418fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 2428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 2439103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 24405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() { 2459103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK((IsArrayInstance<kVerifyFlags, kDoReadBarrier>())); 24605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Array*>(this); 24705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 24805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 25005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() { 2514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 25405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<BooleanArray*>(this); 25505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 25605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 25805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() { 2594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 26205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ByteArray*>(this); 26305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 26405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() { 2674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 2704e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 271ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ByteArray*>(this); 272ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 273ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 2744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 27505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() { 2764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<CharArray*>(this); 28005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 28305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() { 2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 28705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ShortArray*>(this); 28805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 291ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() { 2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 2954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 296ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ShortArray*>(this); 297ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 298ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline IntArray* Object::AsIntArray() { 3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() || 3044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<IntArray*>(this); 30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 30705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline LongArray* Object::AsLongArray() { 3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3124e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() || 3134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<LongArray*>(this); 31505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 31605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 318d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() { 3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 322d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<FloatArray*>(this); 323d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 324d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 326d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() { 3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 330d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<DoubleArray*>(this); 331d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 332d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 33405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() { 3354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsStringClass()); 33605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<String*>(this); 33705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 33805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 34005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() { 3414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 34205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Throwable*>(this); 34305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 34405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 346ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() { 3474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 3482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 351ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() { 3524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 3532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 356ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() { 3574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 3582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 3618fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() { 3628fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 3638fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<FinalizerReference*>(this); 3648fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 3658fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 3668fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 367ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() { 3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 3692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3719103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 372ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() { 3732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t result; 3744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3759103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi if (IsArrayInstance<kVerifyFlags, kDoReadBarrier>()) { 3769103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi result = AsArray<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>(); 3779103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } else if (IsClass<kNewFlags, kDoReadBarrier>()) { 3789103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi result = AsClass<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>(); 3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 3809103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi result = GetClass<kNewFlags, kDoReadBarrier>()->GetObjectSize(); 3812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 3829103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK_GE(result, sizeof(Object)) 3839103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi << " class=" << PrettyTypeOf(GetClass<kNewFlags, kDoReadBarrier>()); 3849103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK(!(IsArtField<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtField)); 3859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK(!(IsArtMethod<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtMethod)); 3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 3872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 3882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 3894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 39029501cf5663c7951717bae3521815d121a778396Ian Rogersinline int32_t Object::GetField32(MemberOffset field_offset, bool is_volatile) { 3914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 3924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 3934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 394b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value(); 395b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr); 396b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (UNLIKELY(is_volatile)) { 397b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers int32_t result = *(reinterpret_cast<volatile int32_t*>(const_cast<int32_t*>(word_addr))); 398ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order. 399b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return result; 400b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 401b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return *word_addr; 402b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 403b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 404b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 4064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField32(MemberOffset field_offset, int32_t new_value, bool is_volatile) { 407d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 408d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 409d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 410d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 411d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, GetField32(field_offset, is_volatile), 412d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz is_volatile); 413d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 415b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers VerifyObject(this); 416b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 417b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 41829501cf5663c7951717bae3521815d121a778396Ian Rogers int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr); 419b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (UNLIKELY(is_volatile)) { 420b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 421b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers *word_addr = new_value; 422ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads. 423b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 424b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers *word_addr = new_value; 425b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 426b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 427b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 42929501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField32(MemberOffset field_offset, int32_t old_value, int32_t new_value) { 430d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 431d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 432d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 433d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 434d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 435d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 439d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 44029501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); 441b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers return __sync_bool_compare_and_swap(addr, old_value, new_value); 442d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 443d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 4444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 44529501cf5663c7951717bae3521815d121a778396Ian Rogersinline int64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) { 4464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 4492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value(); 4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr); 4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (UNLIKELY(is_volatile)) { 45229501cf5663c7951717bae3521815d121a778396Ian Rogers int64_t result = QuasiAtomic::Read64(addr); 453ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure volatile loads don't re-order. 4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 4552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 4562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return *addr; 4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 4614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetField64(MemberOffset field_offset, int64_t new_value, bool is_volatile) { 462d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 463d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 464d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 465d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 466d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, GetField64(field_offset, is_volatile), 467d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz is_volatile); 468d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 470ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 471ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int64_t* addr = reinterpret_cast<int64_t*>(raw_addr); 4742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (UNLIKELY(is_volatile)) { 475b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 4762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers QuasiAtomic::Write64(addr, new_value); 477b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers if (!QuasiAtomic::LongAtomicsUseMutexes()) { 478ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any volatile loads. 479b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } else { 480b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers // Fence from from mutex is enough. 481b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 4822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 4832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers *addr = new_value; 4842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 48829501cf5663c7951717bae3521815d121a778396Ian Rogersinline bool Object::CasField64(MemberOffset field_offset, int64_t old_value, int64_t new_value) { 489d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 490d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 491d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 492d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 493d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 494d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 4954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 498ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 49929501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int64_t* addr = reinterpret_cast<volatile int64_t*>(raw_addr); 50029501cf5663c7951717bae3521815d121a778396Ian Rogers return QuasiAtomic::Cas64(old_value, new_value, addr); 501ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 502ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 503800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> 504ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset, bool is_volatile) { 5054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 5064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 5074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 508ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 509ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 510800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi T* result = ReadBarrier::Barrier<T, kDoReadBarrier>(this, field_offset, objref_addr); 511ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (UNLIKELY(is_volatile)) { 512ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarLoadLoad(); // Ensure loads don't re-order. 513ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 5144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 5154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(result); 5164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 517ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return result; 518ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 519ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 5204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 521ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, Object* new_value, 5224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier bool is_volatile) { 523d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 524d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 525d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 526d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 527d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, 528d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz GetFieldObject<Object>(field_offset, is_volatile), 529d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz true); 530d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 5314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 532ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 533ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 5344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 5354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 5364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 537ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 538ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 539ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (UNLIKELY(is_volatile)) { 540ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreStore(); // Ensure this store occurs after others in the queue. 541ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 542ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers QuasiAtomic::MembarStoreLoad(); // Ensure this store occurs before any loads. 543ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 544ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 545ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 546ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 547ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 5484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 5494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value, bool is_volatile) { 5504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>( 5514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset, new_value, is_volatile); 552ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (new_value != nullptr) { 553ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CheckFieldAssignment(field_offset, new_value); 554ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 555ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 556ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 557ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 5584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags> 5594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 5604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 5614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 5624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) + 5644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset.Int32Value()); 5654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier} 5664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier 5674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 5684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline bool Object::CasFieldObject(MemberOffset field_offset, Object* old_value, 5694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier Object* new_value) { 570d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 571d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 572d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 5734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 5744e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 5754e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 5774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 5784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 5794e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 5804e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(old_value); 5814e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 582d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 583d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 584d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 585ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value(); 58629501cf5663c7951717bae3521815d121a778396Ian Rogers volatile int32_t* addr = reinterpret_cast<volatile int32_t*>(raw_addr); 587ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 588ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 589ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers bool success = __sync_bool_compare_and_swap(addr, old_ref.reference_, new_ref.reference_); 590ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (success) { 591ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 592ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 593ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return success; 5942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 5952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 596407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, bool kIsStatic, typename Visitor> 597407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 598407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) { 599407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (!kVisitClass) { 600407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // Mask out the class from the reference offsets. 601407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_offsets ^= kWordHighBitMask; 602407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 603407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier DCHECK_EQ(ClassOffset().Uint32Value(), 0U); 604407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // Found a reference offset bitmap. Visit the specified offsets. 605407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier while (ref_offsets != 0) { 606407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t right_shift = CLZ(ref_offsets); 607407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift); 608407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, field_offset, kIsStatic); 609407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift); 610407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 611407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 612407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // There is no reference offset bitmap. In the non-static case, walk up the class 613407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // inheritance hierarchy and find reference offsets the hard way. In the static case, just 614407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // consider this class. 615407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr; 616407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass = kIsStatic ? nullptr : klass->GetSuperClass()) { 617407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t num_reference_fields = 618407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 619407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (size_t i = 0; i < num_reference_fields; ++i) { 620407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::ArtField* field = kIsStatic ? klass->GetStaticField(i) 621407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier : klass->GetInstanceField(i); 622407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier MemberOffset field_offset = field->GetOffset(); 623407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // TODO: Do a simpler check? 624407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (!kVisitClass && UNLIKELY(field_offset.Uint32Value() == ClassOffset().Uint32Value())) { 625407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier continue; 626407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 627407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, field_offset, kIsStatic); 628407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 629407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 630407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 631407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 632407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 633407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor> 634407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 635407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier VisitFieldsReferences<kVisitClass, false>( 636407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); 637407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 638407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 639407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate<bool kVisitClass, typename Visitor> 640407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 641407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->VisitFieldsReferences<kVisitClass, true>( 642407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass->GetReferenceStaticOffsets<kVerifyNone>(), visitor); 643407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 644407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 645407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartiertemplate <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor, 646407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier typename JavaLangRefVisitor> 647407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor, 648407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier const JavaLangRefVisitor& ref_visitor) { 649407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags>(); 650407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (UNLIKELY(klass == Class::GetJavaLangClass())) { 651580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier DCHECK_EQ(klass->GetClass<kVerifyNone>(), Class::GetJavaLangClass()); 652407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor); 653407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else if (UNLIKELY(klass->IsArrayClass<kVerifyFlags>())) { 654407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier if (klass->IsObjectArrayClass<kVerifyNone>()) { 655580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor); 656407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else if (kVisitClass) { 657407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier visitor(this, ClassOffset(), false); 658407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 659407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 660580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier VisitInstanceFieldsReferences<kVisitClass>(klass, visitor); 661580a8dfda74e7999f6b3e28e239ae8461a39dfcbMathieu Chartier if (UNLIKELY(klass->IsReferenceClass<kVerifyNone>())) { 662407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier ref_visitor(klass, AsReference()); 663407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 664407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 665407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 666407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 6672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 6682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 6692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 670fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 671