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