object-inl.h revision 05792b98980741111b4d0a24d68cff2a8e070a3a
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" 3005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko#include "dex_cache-inl.h" 31d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers#include "lock_word-inl.h" 3205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "monitor.h" 3352e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier#include "object_array-inl.h" 34800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi#include "read_barrier-inl.h" 358fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier#include "reference.h" 36848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "runtime.h" 37848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "string-inl.h" 3805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers#include "throwable.h" 392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 43e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline uint32_t Object::ClassSize(size_t pointer_size) { 4498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang uint32_t vtable_entries = kVTableLength; 45e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size); 4698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang} 4798d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang 486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline Class* Object::GetClass() { 506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>( 51b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers OFFSET_OF_OBJECT_MEMBER(Object, klass_)); 522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline void Object::SetClass(Class* new_klass) { 562cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // new_klass may be null prior to class linker initialization. 57ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // We don't mark the card as this occurs as part of object allocation. Not all objects have 58ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // backing cards, such as large objects. 59d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We use non transactional version since we can't undo this write. We also disable checking as 60d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // we may run in transaction mode here. 614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier SetFieldObjectWithoutWriteBarrier<false, false, 624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>( 63b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass); 642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 663b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags> 67bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline LockWord Object::GetLockWord(bool as_volatile) { 68b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (as_volatile) { 693b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); 70b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 713b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); 72d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 73d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 743b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampetemplate<VerifyObjectFlags kVerifyFlags> 75bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierinline void Object::SetLockWord(LockWord new_val, bool as_volatile) { 76d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 77b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (as_volatile) { 783b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe SetField32Volatile<false, false, kVerifyFlags>( 793b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); 80b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 813b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe SetField32<false, false, kVerifyFlags>( 823b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); 83b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 84d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 85d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 86228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) { 87d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Force use of non-transactional mode and do not check. 88228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return CasFieldWeakSequentiallyConsistent32<false, false>( 89228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); 90d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 91d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 92d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) { 93d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm // Force use of non-transactional mode and do not check. 94d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return CasFieldWeakRelaxed32<false, false>( 95d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); 96d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 97d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 98d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() { 99d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return Monitor::GetLockOwnerThreadId(this); 10005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 10105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 102e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) { 103e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier return Monitor::MonitorEnter(self, this); 10405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 10505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 10605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) { 10705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return Monitor::MonitorExit(self, this); 10805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 10905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) { 11105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Notify(self, this); 11205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) { 11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::NotifyAll(self, this); 11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) { 11905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, 0, 0, true, kWaiting); 12005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 12305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 12405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 126624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() { 12760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 12860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 12960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState()); 13060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 13160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1326a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>( 1336a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_)); 1349d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1359d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1362c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1379d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1389d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1399d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1409103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) { 14160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 14260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 14360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 14460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 14560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 14660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi SetLockWord(lw, false); 14760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 14860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1499d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // We don't mark the card as this occurs as part of object allocation. Not all objects have 1509d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // backing cards, such as large objects. 1519d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 1526a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr); 1539103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else 1549103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1552c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1566a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(rb_ptr); 1579103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif 1589103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi} 1599103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi 1609103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { 16160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 16260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 16360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U); 16460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 16560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord expected_lw; 16660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord new_lw; 16760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi do { 16860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 16960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) { 17060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi // Lost the race. 17160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return false; 17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi } 17360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw = lw; 17460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw.SetReadBarrierState( 17560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr))); 17660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw = lw; 17760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 17860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi } while (!CasLockWordWeakSequentiallyConsistent(expected_lw, new_lw)); 17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return true; 18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 18160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1829103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); 18313735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue(); 184228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 1859103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); 1869103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); 1879103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi do { 188228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) { 1899103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi // Lost the race. 1909103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return false; 1919103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } 192228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_, 193228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_)); 1949103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return true; 1959d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1966a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(expected_rb_ptr, rb_ptr); 1979d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1982c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1999d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 2009d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2019d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 202624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const { 203800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi if (kUseBakerReadBarrier) { 204800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 205800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK(obj->GetReadBarrierPointer() == nullptr) 206800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 207800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 2082c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers } else { 2092c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers CHECK(kUseBrooksReadBarrier); 210800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 211800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 212800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 213800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 214800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } 2159d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2169d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 2174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 218ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) { 2192cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2202cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyFlags>() != nullptr); 221a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao return klass->IsInterface() || InstanceOf(klass); 222a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao} 223a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao 2244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 225ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) { 2262cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyNone>() != nullptr); 2284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 2292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2316e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 232ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() { 2336e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 2346e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template GetClass<kVerifyFlags, kReadBarrierOption>(); 2356e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), 2366e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi kReadBarrierOption>() == java_lang_Class; 2372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2396e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 2402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() { 2416e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>())); 2422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<Class*>(this); 2432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 246ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() { 2474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return IsArrayInstance<kVerifyFlags>() && 2494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive(); 2502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2524e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags> 2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() { 2544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsObjectArray<kVerifyFlags>()); 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<ObjectArray<T>*>(this); 2562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2586e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 259ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() { 2606e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<kVerifyFlags, kReadBarrierOption>()-> 2616e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template IsArrayClass<kVerifyFlags, kReadBarrierOption>(); 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 265ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() { 2664ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass(); 2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 2708fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() { 2718fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsReferenceInstance<kVerifyFlags>()); 2728fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<Reference*>(this); 2738fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 2748fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 2756e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 27605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() { 2776e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>())); 27805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Array*>(this); 27905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2814e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 28205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() { 2834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 28605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<BooleanArray*>(this); 28705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 29005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() { 291e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 29405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ByteArray*>(this); 29505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 29605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 298ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() { 299e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 303ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ByteArray*>(this); 304ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 305ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 3064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30705f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() { 3084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 31105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<CharArray*>(this); 31205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 31305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 31505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() { 3164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 31905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ShortArray*>(this); 32005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 32105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 323ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() { 3244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 328ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ShortArray*>(this); 329ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 330ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 3314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 332e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsIntArray() { 3334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 334e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 335e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>(); 336e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 338e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 339e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline IntArray* Object::AsIntArray() { 340e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsIntArray<kVerifyFlags>()); 34105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<IntArray*>(this); 34205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 34305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 345e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsLongArray() { 3464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 347e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 348e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>(); 349e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 350e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 351e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 352e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline LongArray* Object::AsLongArray() { 353e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsLongArray<kVerifyFlags>()); 35405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<LongArray*>(this); 35505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 35605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 358e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsFloatArray() { 359e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 361e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>(); 362e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 363e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 364e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 365d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() { 366e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsFloatArray<kVerifyFlags>()); 3674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<FloatArray*>(this); 371d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 372d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 374e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsDoubleArray() { 375e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 376e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 377e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>(); 378e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 379e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 380e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() { 382e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsDoubleArray<kVerifyFlags>()); 3834e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3844e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<DoubleArray*>(this); 387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 388d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 389848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 390848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoinline bool Object::IsString() { 391848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass(); 392848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 393848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 394848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 39505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() { 396848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK((IsString<kVerifyFlags, kReadBarrierOption>())); 39705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<String*>(this); 39805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 39905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 40105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() { 4024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 40305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Throwable*>(this); 40405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 40505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 407ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() { 4084e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 4092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 412ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() { 4134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 4142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 417ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() { 4184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 4228fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() { 4238fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 4248fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<FinalizerReference*>(this); 4258fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 4268fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 4278fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 428ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() { 4294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4326e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 433ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() { 4342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t result; 4354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 4366e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) { 4376e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsArray<kNewFlags, kReadBarrierOption>()-> 4386e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 4396e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi } else if (IsClass<kNewFlags, kReadBarrierOption>()) { 4406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsClass<kNewFlags, kReadBarrierOption>()-> 4416e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 442848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) { 443848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao result = AsString<kNewFlags, kReadBarrierOption>()-> 444848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template SizeOf<kNewFlags>(); 4452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 44625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi result = GetClass<kNewFlags, kReadBarrierOption>()-> 44725023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi template GetObjectSize<kNewFlags, kReadBarrierOption>(); 4482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4499103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK_GE(result, sizeof(Object)) 4506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>()); 4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 4522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 454b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 45537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) { 4564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 45937f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint8_t, kIsVolatile>(field_offset); 46037f05ef45e0393de812d51261dc293240c17294dFred Shih} 46137f05ef45e0393de812d51261dc293240c17294dFred Shih 46237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 46337f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) { 46437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 46537f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 46637f05ef45e0393de812d51261dc293240c17294dFred Shih } 46737f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int8_t, kIsVolatile>(field_offset); 46837f05ef45e0393de812d51261dc293240c17294dFred Shih} 46937f05ef45e0393de812d51261dc293240c17294dFred Shih 47037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 47137f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) { 47237f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldBoolean<kVerifyFlags, true>(field_offset); 47337f05ef45e0393de812d51261dc293240c17294dFred Shih} 47437f05ef45e0393de812d51261dc293240c17294dFred Shih 47537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 47637f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) { 47737f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldByte<kVerifyFlags, true>(field_offset); 47837f05ef45e0393de812d51261dc293240c17294dFred Shih} 47937f05ef45e0393de812d51261dc293240c17294dFred Shih 48037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 48137f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 48237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value) 48390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 48437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 48537f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 48637f05ef45e0393de812d51261dc293240c17294dFred Shih } 48737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 48837f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldBoolean(this, field_offset, 48937f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset), 49037f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 49137f05ef45e0393de812d51261dc293240c17294dFred Shih } 49237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 49337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 49437f05ef45e0393de812d51261dc293240c17294dFred Shih } 49537f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint8_t, kIsVolatile>(field_offset, new_value); 49637f05ef45e0393de812d51261dc293240c17294dFred Shih} 49737f05ef45e0393de812d51261dc293240c17294dFred Shih 49837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 49937f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 50037f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) 50190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 50237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 50337f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 50437f05ef45e0393de812d51261dc293240c17294dFred Shih } 50537f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 50637f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldByte(this, field_offset, 50737f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset), 50837f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 50937f05ef45e0393de812d51261dc293240c17294dFred Shih } 51037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 51137f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 51237f05ef45e0393de812d51261dc293240c17294dFred Shih } 51337f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int8_t, kIsVolatile>(field_offset, new_value); 51437f05ef45e0393de812d51261dc293240c17294dFred Shih} 51537f05ef45e0393de812d51261dc293240c17294dFred Shih 51637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 51737f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) { 51837f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 51937f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 52037f05ef45e0393de812d51261dc293240c17294dFred Shih} 52137f05ef45e0393de812d51261dc293240c17294dFred Shih 52237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 52337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) { 52437f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 52537f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 52637f05ef45e0393de812d51261dc293240c17294dFred Shih} 52737f05ef45e0393de812d51261dc293240c17294dFred Shih 52837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 52937f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) { 53037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 53137f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 53237f05ef45e0393de812d51261dc293240c17294dFred Shih } 53337f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint16_t, kIsVolatile>(field_offset); 53437f05ef45e0393de812d51261dc293240c17294dFred Shih} 53537f05ef45e0393de812d51261dc293240c17294dFred Shih 53637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 53737f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) { 53837f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 53937f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 540b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 54137f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int16_t, kIsVolatile>(field_offset); 54237f05ef45e0393de812d51261dc293240c17294dFred Shih} 54337f05ef45e0393de812d51261dc293240c17294dFred Shih 54437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 54537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) { 54637f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldChar<kVerifyFlags, true>(field_offset); 54737f05ef45e0393de812d51261dc293240c17294dFred Shih} 54837f05ef45e0393de812d51261dc293240c17294dFred Shih 54937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 55037f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) { 55137f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldShort<kVerifyFlags, true>(field_offset); 55237f05ef45e0393de812d51261dc293240c17294dFred Shih} 55337f05ef45e0393de812d51261dc293240c17294dFred Shih 55437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 55537f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 55637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) { 55737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 55837f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 55937f05ef45e0393de812d51261dc293240c17294dFred Shih } 56037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 56137f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 56237f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset), 56337f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 56437f05ef45e0393de812d51261dc293240c17294dFred Shih } 56537f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 56637f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 56737f05ef45e0393de812d51261dc293240c17294dFred Shih } 56837f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint16_t, kIsVolatile>(field_offset, new_value); 56937f05ef45e0393de812d51261dc293240c17294dFred Shih} 57037f05ef45e0393de812d51261dc293240c17294dFred Shih 57137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 57237f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 57337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) { 57437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 57537f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 57637f05ef45e0393de812d51261dc293240c17294dFred Shih } 57737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 57837f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 57937f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset), 58037f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 58137f05ef45e0393de812d51261dc293240c17294dFred Shih } 58237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 58337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 58437f05ef45e0393de812d51261dc293240c17294dFred Shih } 58537f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int16_t, kIsVolatile>(field_offset, new_value); 58637f05ef45e0393de812d51261dc293240c17294dFred Shih} 58737f05ef45e0393de812d51261dc293240c17294dFred Shih 58837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 58937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) { 59037f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 59137f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 59237f05ef45e0393de812d51261dc293240c17294dFred Shih} 59337f05ef45e0393de812d51261dc293240c17294dFred Shih 59437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 59537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) { 59637f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 59737f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 59837f05ef45e0393de812d51261dc293240c17294dFred Shih} 59937f05ef45e0393de812d51261dc293240c17294dFred Shih 60037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 60137f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) { 60237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 60337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 60437f05ef45e0393de812d51261dc293240c17294dFred Shih } 60537f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int32_t, kIsVolatile>(field_offset); 606b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 607b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 608b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 609b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) { 610b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags, true>(field_offset); 611b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 612b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 613b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 614b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 615b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { 616d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 617d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 618d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 619d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 620b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField32(this, field_offset, 621b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField32<kVerifyFlags, kIsVolatile>(field_offset), 622b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 623d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 625b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers VerifyObject(this); 626b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 62737f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int32_t, kIsVolatile>(field_offset, new_value); 628b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 629b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 6304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 631b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) { 632b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value); 633b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 634b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 635d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication? 636d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 637b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 638228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, 639228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int32_t old_value, int32_t new_value) { 640d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 641d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 642d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 643d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 644d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 645d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6464e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 6474e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 6484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 64913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 650228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 6513035961cb41865b80b927546be0c708b6389cec6Hans Boehm 652228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 653d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 654d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 655d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 656d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, 657d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 658d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 659d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 660d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 661d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 662d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 663d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 664d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 665d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 666d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 66713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 668d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 669d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 670d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value); 671d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 672d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 673d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 674d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset, 675d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 676d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 677d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 678d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 679d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 680d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 681d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 682d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 683d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 684d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 68513735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 686d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 687d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 688d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 689d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 690d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 691b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 692b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) { 6934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 6944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 6954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 69637f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int64_t, kIsVolatile>(field_offset); 6972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 6982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 699b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 700b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) { 701b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField64<kVerifyFlags, true>(field_offset); 702b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 703b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 704b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 705b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 706b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) { 707d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 708d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 709d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 710d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 711b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField64(this, field_offset, 712b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField64<kVerifyFlags, kIsVolatile>(field_offset), 713b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 714d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 716ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 717ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 71837f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int64_t, kIsVolatile>(field_offset, new_value); 7192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 7202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 722b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) { 723b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 724b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 725b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 726b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 72737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 72837f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) { 72913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 73037f05ef45e0393de812d51261dc293240c17294dFred Shih kSize* addr = reinterpret_cast<kSize*>(raw_addr); 73137f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 73237f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value); 73337f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 73437f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value); 73537f05ef45e0393de812d51261dc293240c17294dFred Shih } 73637f05ef45e0393de812d51261dc293240c17294dFred Shih} 73737f05ef45e0393de812d51261dc293240c17294dFred Shih 73837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 73937f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) { 74013735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value(); 74137f05ef45e0393de812d51261dc293240c17294dFred Shih const kSize* addr = reinterpret_cast<const kSize*>(raw_addr); 74237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 74337f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent(); 74437f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 74537f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData(); 74637f05ef45e0393de812d51261dc293240c17294dFred Shih } 74737f05ef45e0393de812d51261dc293240c17294dFred Shih} 74837f05ef45e0393de812d51261dc293240c17294dFred Shih 749b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 750228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, 751228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int64_t old_value, int64_t new_value) { 752d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 753d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 754d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 755d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 756d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 757d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 76113735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 762228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 763228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 764ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 765ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 766d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 767d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset, 768d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int64_t old_value, int64_t new_value) { 769d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 770d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 771d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 772d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 773d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 774d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 775d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 776d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 777d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 77813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 779d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 780d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 781d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 782d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 7836e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, 7846e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi bool kIsVolatile> 785b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) { 7864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 78913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 790ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 7916e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr); 792b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 7933035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent load instead. 7943035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceAcquire(); // Ensure visibility of operations preceding store. 795ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 7964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 7974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(result); 7984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 799ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return result; 800ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 801ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 8026e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 803b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) { 8046e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset); 805b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 806b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 807b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 808b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 809b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, 810b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Object* new_value) { 811d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 812d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 813d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 814d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 815b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers mirror::Object* obj; 816b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 817b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObjectVolatile<Object>(field_offset); 818b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 819b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObject<Object>(field_offset); 820b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 821b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true); 822d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 8234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 824ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 825ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 8264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 8274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 8284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 82913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 830ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 831b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 8323035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent store instead. 8333035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceRelease(); // Ensure that prior accesses are visible before store. 834ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 8353035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceSequentiallyConsistent(); 8363035961cb41865b80b927546be0c708b6389cec6Hans Boehm // Ensure this store occurs before any volatile loads. 837ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 838ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 839ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 840ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 841ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 842b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 843b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 844b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) { 845b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags, 846b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile>(field_offset, new_value); 847ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (new_value != nullptr) { 848ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 84961c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this. 85061c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier CheckFieldAssignment(field_offset, new_value); 851ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 852ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 853ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 854b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 855b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) { 856b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 857b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 858b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 859b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 8604e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags> 8614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 8624e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 8634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 8644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 86513735955f39b3b304c37d2b2840663c131262c18Ian Rogers return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) + 8664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset.Int32Value()); 8674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier} 8684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier 8694e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 870228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, 871228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Object* old_value, Object* new_value) { 8722cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier< 8732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 8742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (success) { 8752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 8772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 8782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 8792cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 8802cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 8812cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier( 8822cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 883d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 884d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 885d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 8864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 8874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 8884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 8894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 8904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 8914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 8924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 8934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(old_value); 8944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 895d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 896d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 897d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 898ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 899ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 90013735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 901228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 902228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 903228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_, 904228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_); 9052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 9062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 907228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 9082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset, 9102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Object* old_value, Object* new_value) { 9112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier< 9122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 913ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (success) { 914ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 915ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 916ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return success; 9172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 9182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 919d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier( 9212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 922d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 923d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 924d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 925d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 926d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 927d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 928d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyWrites) { 929d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(new_value); 930d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 931d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyReads) { 932d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(old_value); 933d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 934d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 935d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 936d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 937d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 938d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 93913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 940d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 941d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 942d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_, 943d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm new_ref.reference_); 944d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return success; 945d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 946d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 947059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<bool kIsStatic, typename Visitor> 948407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 949cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) { 950cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers // Instance fields and not the slow-path. 951cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers uint32_t field_offset = mirror::kObjectHeaderSize; 952407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier while (ref_offsets != 0) { 953cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if ((ref_offsets & 1) != 0) { 954cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers visitor(this, MemberOffset(field_offset), kIsStatic); 955cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers } 956cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers ref_offsets >>= 1; 957cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers field_offset += sizeof(mirror::HeapReference<mirror::Object>); 958407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 959407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 960faff0f05fef90577c9744505555675185832aacdMingyao Yang // There is no reference offset bitmap. In the non-static case, walk up the class 961407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // inheritance hierarchy and find reference offsets the hard way. In the static case, just 962407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // consider this class. 963407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr; 964407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass = kIsStatic ? nullptr : klass->GetSuperClass()) { 965407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t num_reference_fields = 966407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 96776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko if (num_reference_fields == 0u) { 96876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko continue; 96976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 970e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Presumably GC can happen when we are cross compiling, it should not cause performance 971e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // problems to do pointer size logic. 97276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko MemberOffset field_offset = kIsStatic 973e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ? klass->GetFirstReferenceStaticFieldOffset( 974e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier Runtime::Current()->GetClassLinker()->GetImagePointerSize()) 97576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko : klass->GetFirstReferenceInstanceFieldOffset(); 976059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier for (size_t i = 0u; i < num_reference_fields; ++i) { 977407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // TODO: Do a simpler check? 978059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) { 97952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor(this, field_offset, kIsStatic); 980407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 98176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko field_offset = MemberOffset(field_offset.Uint32Value() + 98276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko sizeof(mirror::HeapReference<mirror::Object>)); 983407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 984407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 985407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 986407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 987407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 988059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor> 989407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 990059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitFieldsReferences<false>(klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); 991407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 992407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 993059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor> 994407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 99598d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK(!klass->IsTemp()); 996059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier klass->VisitFieldsReferences<true>(0, visitor); 997407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 998407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 999e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1000e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline bool Object::IsClassLoader() { 1001e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier return GetClass<kVerifyFlags>()->IsClassLoaderClass(); 1002e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1003e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1004e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1005e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline mirror::ClassLoader* Object::AsClassLoader() { 1006e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier DCHECK(IsClassLoader<kVerifyFlags>()); 1007e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier return down_cast<mirror::ClassLoader*>(this); 1008e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1009e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 101005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markotemplate<VerifyObjectFlags kVerifyFlags> 101105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool Object::IsDexCache() { 101205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetClass<kVerifyFlags>()->IsDexCacheClass(); 101305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 101405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 101505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markotemplate<VerifyObjectFlags kVerifyFlags> 101605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::DexCache* Object::AsDexCache() { 101705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko DCHECK(IsDexCache<kVerifyFlags>()); 101805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return down_cast<mirror::DexCache*>(this); 101905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 102005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 1021059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, typename Visitor, typename JavaLangRefVisitor> 1022407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor, 1023407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier const JavaLangRefVisitor& ref_visitor) { 1024407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags>(); 1025059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier visitor(this, ClassOffset(), false); 102652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>(); 102752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (LIKELY(class_flags == kClassFlagNormal)) { 102852e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(!klass->IsVariableSize()); 1029059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitInstanceFieldsReferences(klass, visitor); 103052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(!klass->IsClassClass()); 103166c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsStringClass()); 103266c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsClassLoaderClass()); 103366c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsArrayClass()); 103452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 103552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if ((class_flags & kClassFlagNoReferenceFields) == 0) { 103652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(!klass->IsStringClass()); 103752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (class_flags == kClassFlagClass) { 103852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(klass->IsClassClass()); 103952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier AsClass<kVerifyNone>()->VisitReferences(klass, visitor); 104052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (class_flags == kClassFlagObjectArray) { 104152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(klass->IsObjectArrayClass()); 104252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences(visitor); 104352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if ((class_flags & kClassFlagReference) != 0) { 104452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier VisitInstanceFieldsReferences(klass, visitor); 104552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier ref_visitor(klass, AsReference()); 104605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko } else if (class_flags == kClassFlagDexCache) { 104705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::DexCache* const dex_cache = AsDexCache<kVerifyFlags>(); 104805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko dex_cache->VisitReferences<kVerifyFlags>(klass, visitor); 104952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 105052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags>(); 105152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier class_loader->VisitReferences<kVerifyFlags>(klass, visitor); 105252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 105352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (kIsDebugBuild) { 105452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK(!klass->IsClassClass()); 105552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK(!klass->IsObjectArrayClass()); 105652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // String still has instance fields for reflection purposes but these don't exist in 105752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // actual string instances. 105852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (!klass->IsStringClass()) { 105952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier size_t total_reference_instance_fields = 0; 106052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier mirror::Class* super_class = klass; 106152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier do { 106252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier total_reference_instance_fields += super_class->NumReferenceInstanceFields(); 106352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier super_class = super_class->GetSuperClass(); 106452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } while (super_class != nullptr); 106552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // The only reference field should be the object's class. This field is handled at the 106652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // beginning of the function. 106752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK_EQ(total_reference_instance_fields, 1u); 106852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 1069407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1070407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1071407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 10722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 10732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 10742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1075fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 1076