object-inl.h revision fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49
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 98fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasLockWordWeakRelease(LockWord old_val, LockWord new_val) { 99fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi // Force use of non-transactional mode and do not check. 100fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return CasFieldWeakRelease32<false, false>( 101fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue()); 102fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 103fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 104d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogersinline uint32_t Object::GetLockOwnerThreadId() { 105d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers return Monitor::GetLockOwnerThreadId(this); 10605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 10705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 108e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierinline mirror::Object* Object::MonitorEnter(Thread* self) { 109e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier return Monitor::MonitorEnter(self, this); 11005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) { 11305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return Monitor::MonitorExit(self, this); 11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) { 11705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Notify(self, this); 11805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) { 12105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::NotifyAll(self, this); 12205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) { 12505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, 0, 0, true, kWaiting); 12605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 12905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 13005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 13105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 132624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() { 13360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 13460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 13560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState()); 13660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 13760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1386a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>( 1396a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_)); 1409d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1419d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1422c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1439d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1449d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1459d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1469103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) { 14760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 14860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 14960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 15060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 15160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 15260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi SetLockWord(lw, false); 15360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 15460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1559d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // We don't mark the card as this occurs as part of object allocation. Not all objects have 1569d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // backing cards, such as large objects. 1579d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 1586a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr); 1599103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else 1609103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1612c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1626a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(rb_ptr); 1639103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif 1649103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi} 1659103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi 1669103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { 16760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 16860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 16960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U); 17060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 17160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord expected_lw; 17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord new_lw; 17360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi do { 17460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 17560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) { 17660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi // Lost the race. 17760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return false; 17860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi } 17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw = lw; 18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw.SetReadBarrierState( 18160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr))); 18260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw = lw; 18360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 184fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi // This CAS is a CAS release so that when GC updates all the fields of an object and then 185fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi // changes the object from gray to black, the field updates (stores) will be visible (won't be 186fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi // reordered after this CAS.) 187fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } while (!CasLockWordWeakRelease(expected_lw, new_lw)); 18860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return true; 18960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 19060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1919103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); 19213735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue(); 193228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 1949103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); 1959103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); 1969103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi do { 197228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) { 1989103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi // Lost the race. 1999103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return false; 2009103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } 201228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_, 202228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_)); 2039103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return true; 2049d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 2056a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(expected_rb_ptr, rb_ptr); 2069d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 2072c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 2089d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 2099d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2109d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 211624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const { 212800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi if (kUseBakerReadBarrier) { 213800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 214800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK(obj->GetReadBarrierPointer() == nullptr) 215800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 216800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 2172c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers } else { 2182c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers CHECK(kUseBrooksReadBarrier); 219800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 220800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 221800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 222800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 223800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } 2249d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2259d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 2264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 227ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) { 2282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyFlags>() != nullptr); 230a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao return klass->IsInterface() || InstanceOf(klass); 231a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao} 232a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao 2334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 234ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) { 2352cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyNone>() != nullptr); 2374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 2382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() { 2426e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 2436e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template GetClass<kVerifyFlags, kReadBarrierOption>(); 2446e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), 2456e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi kReadBarrierOption>() == java_lang_Class; 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 2492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() { 2506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>())); 2512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<Class*>(this); 2522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 255ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() { 2564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return IsArrayInstance<kVerifyFlags>() && 2584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive(); 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags> 2622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() { 2634e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(IsObjectArray<kVerifyFlags>()); 2642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<ObjectArray<T>*>(this); 2652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2676e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 268ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() { 2696e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<kVerifyFlags, kReadBarrierOption>()-> 2706e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template IsArrayClass<kVerifyFlags, kReadBarrierOption>(); 2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2734e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 274ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() { 2754ee7a665e7f9cd2c5ace2d6304e33f64067b209fFred Shih return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass(); 2762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 2798fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() { 2808fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsReferenceInstance<kVerifyFlags>()); 2818fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<Reference*>(this); 2828fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 2838fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 2846e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 28505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() { 2866e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>())); 28705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Array*>(this); 28805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 28905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 29105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() { 2924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 2934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 2944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 29505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<BooleanArray*>(this); 29605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 29705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 29905f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() { 300e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 30305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ByteArray*>(this); 30405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 307ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() { 308e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 312ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ByteArray*>(this); 313ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 314ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 31605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() { 3174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 32005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<CharArray*>(this); 32105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 32205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 32405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() { 3254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 32805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ShortArray*>(this); 32905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 33005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 332ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() { 3334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 3364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 337ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ShortArray*>(this); 338ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 339ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 3404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 341e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsIntArray() { 3424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 343e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 344e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>(); 345e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 346e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 347e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 348e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline IntArray* Object::AsIntArray() { 349e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsIntArray<kVerifyFlags>()); 35005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<IntArray*>(this); 35105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 35205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 354e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsLongArray() { 3554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 356e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 357e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>(); 358e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 359e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 361e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline LongArray* Object::AsLongArray() { 362e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsLongArray<kVerifyFlags>()); 36305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<LongArray*>(this); 36405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 36505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 367e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsFloatArray() { 368e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 369e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 370e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>(); 371e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 372e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 373e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 374d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() { 375e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsFloatArray<kVerifyFlags>()); 3764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<FloatArray*>(this); 380d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3824e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsDoubleArray() { 384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 385e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 386e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>(); 387e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 388e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 389e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() { 391e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsDoubleArray<kVerifyFlags>()); 3924e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 395d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<DoubleArray*>(this); 396d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 397d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 398848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 399848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoinline bool Object::IsString() { 400848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass(); 401848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 402848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 403848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 40405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() { 405848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK((IsString<kVerifyFlags, kReadBarrierOption>())); 40605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<String*>(this); 40705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 40805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4094e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 41005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() { 4114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 41205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Throwable*>(this); 41305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 41405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 416ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() { 4174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 4182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 421ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() { 4224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 4232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 426ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() { 4274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 4282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 4318fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() { 4328fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 4338fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<FinalizerReference*>(this); 4348fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 4358fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 4368fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 437ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() { 4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 4392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4416e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 442ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() { 4432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t result; 4444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 4456e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) { 4466e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsArray<kNewFlags, kReadBarrierOption>()-> 4476e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 4486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi } else if (IsClass<kNewFlags, kReadBarrierOption>()) { 4496e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsClass<kNewFlags, kReadBarrierOption>()-> 4506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 451848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) { 452848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao result = AsString<kNewFlags, kReadBarrierOption>()-> 453848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template SizeOf<kNewFlags>(); 4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 45525023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi result = GetClass<kNewFlags, kReadBarrierOption>()-> 45625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi template GetObjectSize<kNewFlags, kReadBarrierOption>(); 4572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4589103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK_GE(result, sizeof(Object)) 4596e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>()); 4602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 4612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 463b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 46437f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) { 4654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 46837f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint8_t, kIsVolatile>(field_offset); 46937f05ef45e0393de812d51261dc293240c17294dFred Shih} 47037f05ef45e0393de812d51261dc293240c17294dFred Shih 47137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 47237f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) { 47337f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 47437f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 47537f05ef45e0393de812d51261dc293240c17294dFred Shih } 47637f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int8_t, kIsVolatile>(field_offset); 47737f05ef45e0393de812d51261dc293240c17294dFred Shih} 47837f05ef45e0393de812d51261dc293240c17294dFred Shih 47937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 48037f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) { 48137f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldBoolean<kVerifyFlags, true>(field_offset); 48237f05ef45e0393de812d51261dc293240c17294dFred Shih} 48337f05ef45e0393de812d51261dc293240c17294dFred Shih 48437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 48537f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) { 48637f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldByte<kVerifyFlags, true>(field_offset); 48737f05ef45e0393de812d51261dc293240c17294dFred Shih} 48837f05ef45e0393de812d51261dc293240c17294dFred Shih 48937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 49037f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 49137f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value) 49290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 49337f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 49437f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 49537f05ef45e0393de812d51261dc293240c17294dFred Shih } 49637f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 49737f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldBoolean(this, field_offset, 49837f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset), 49937f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 50037f05ef45e0393de812d51261dc293240c17294dFred Shih } 50137f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 50237f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 50337f05ef45e0393de812d51261dc293240c17294dFred Shih } 50437f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint8_t, kIsVolatile>(field_offset, new_value); 50537f05ef45e0393de812d51261dc293240c17294dFred Shih} 50637f05ef45e0393de812d51261dc293240c17294dFred Shih 50737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 50837f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 50937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) 51090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 51137f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 51237f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 51337f05ef45e0393de812d51261dc293240c17294dFred Shih } 51437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 51537f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldByte(this, field_offset, 51637f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset), 51737f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 51837f05ef45e0393de812d51261dc293240c17294dFred Shih } 51937f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 52037f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 52137f05ef45e0393de812d51261dc293240c17294dFred Shih } 52237f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int8_t, kIsVolatile>(field_offset, new_value); 52337f05ef45e0393de812d51261dc293240c17294dFred Shih} 52437f05ef45e0393de812d51261dc293240c17294dFred Shih 52537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 52637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) { 52737f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 52837f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 52937f05ef45e0393de812d51261dc293240c17294dFred Shih} 53037f05ef45e0393de812d51261dc293240c17294dFred Shih 53137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 53237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) { 53337f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 53437f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 53537f05ef45e0393de812d51261dc293240c17294dFred Shih} 53637f05ef45e0393de812d51261dc293240c17294dFred Shih 53737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 53837f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) { 53937f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 54037f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 54137f05ef45e0393de812d51261dc293240c17294dFred Shih } 54237f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint16_t, kIsVolatile>(field_offset); 54337f05ef45e0393de812d51261dc293240c17294dFred Shih} 54437f05ef45e0393de812d51261dc293240c17294dFred Shih 54537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 54637f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) { 54737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 54837f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 549b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 55037f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int16_t, kIsVolatile>(field_offset); 55137f05ef45e0393de812d51261dc293240c17294dFred Shih} 55237f05ef45e0393de812d51261dc293240c17294dFred Shih 55337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 55437f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) { 55537f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldChar<kVerifyFlags, true>(field_offset); 55637f05ef45e0393de812d51261dc293240c17294dFred Shih} 55737f05ef45e0393de812d51261dc293240c17294dFred Shih 55837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 55937f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) { 56037f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldShort<kVerifyFlags, true>(field_offset); 56137f05ef45e0393de812d51261dc293240c17294dFred Shih} 56237f05ef45e0393de812d51261dc293240c17294dFred Shih 56337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 56437f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 56537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) { 56637f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 56737f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 56837f05ef45e0393de812d51261dc293240c17294dFred Shih } 56937f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 57037f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 57137f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset), 57237f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 57337f05ef45e0393de812d51261dc293240c17294dFred Shih } 57437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 57537f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 57637f05ef45e0393de812d51261dc293240c17294dFred Shih } 57737f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint16_t, kIsVolatile>(field_offset, new_value); 57837f05ef45e0393de812d51261dc293240c17294dFred Shih} 57937f05ef45e0393de812d51261dc293240c17294dFred Shih 58037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 58137f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 58237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) { 58337f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 58437f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 58537f05ef45e0393de812d51261dc293240c17294dFred Shih } 58637f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 58737f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 58837f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset), 58937f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 59037f05ef45e0393de812d51261dc293240c17294dFred Shih } 59137f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 59237f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 59337f05ef45e0393de812d51261dc293240c17294dFred Shih } 59437f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int16_t, kIsVolatile>(field_offset, new_value); 59537f05ef45e0393de812d51261dc293240c17294dFred Shih} 59637f05ef45e0393de812d51261dc293240c17294dFred Shih 59737f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 59837f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) { 59937f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 60037f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 60137f05ef45e0393de812d51261dc293240c17294dFred Shih} 60237f05ef45e0393de812d51261dc293240c17294dFred Shih 60337f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 60437f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) { 60537f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 60637f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 60737f05ef45e0393de812d51261dc293240c17294dFred Shih} 60837f05ef45e0393de812d51261dc293240c17294dFred Shih 60937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 61037f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) { 61137f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 61237f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 61337f05ef45e0393de812d51261dc293240c17294dFred Shih } 61437f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int32_t, kIsVolatile>(field_offset); 615b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 616b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 617b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 618b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) { 619b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags, true>(field_offset); 620b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 621b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 622b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 623b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 624b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { 625d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 626d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 627d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 628d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 629b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField32(this, field_offset, 630b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField32<kVerifyFlags, kIsVolatile>(field_offset), 631b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 632d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 634b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers VerifyObject(this); 635b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 63637f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int32_t, kIsVolatile>(field_offset, new_value); 637b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 638b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 6394e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 640b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) { 641b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value); 642b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 643b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 644d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication? 645d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 646b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 647228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, 648228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int32_t old_value, int32_t new_value) { 649d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 650d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 651d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 652d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 653d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 654d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 6564e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 6574e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 65813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 659228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 6603035961cb41865b80b927546be0c708b6389cec6Hans Boehm 661228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 662d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 663d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 664d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 665d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, 666d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 667d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 668d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 669d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 670d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 671d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 672d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 673d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 674d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 675d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 67613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 677d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 678d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 679d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value); 680d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 681d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 682d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 683fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelease32(MemberOffset field_offset, 684fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi int32_t old_value, int32_t new_value) { 685fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 686fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 687fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 688fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 689fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 690fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 691fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 692fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 693fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 694fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 695fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 696fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 697fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return atomic_addr->CompareExchangeWeakRelease(old_value, new_value); 698fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 699fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 700fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 701d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset, 702d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 703d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 704d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 705d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 706d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 707d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 708d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 709d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 710d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 711d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 71213735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 713d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 714d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 715d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 716d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 717d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 718b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 719b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) { 7204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 72337f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int64_t, kIsVolatile>(field_offset); 7242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 7252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 726b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 727b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) { 728b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField64<kVerifyFlags, true>(field_offset); 729b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 730b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 731b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 732b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 733b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) { 734d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 735d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 736d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 737d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 738b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField64(this, field_offset, 739b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField64<kVerifyFlags, kIsVolatile>(field_offset), 740b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 741d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 743ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 744ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 74537f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int64_t, kIsVolatile>(field_offset, new_value); 7462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 7472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 749b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) { 750b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 751b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 752b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 753b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 75437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 75537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) { 75613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 75737f05ef45e0393de812d51261dc293240c17294dFred Shih kSize* addr = reinterpret_cast<kSize*>(raw_addr); 75837f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 75937f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value); 76037f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 76137f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value); 76237f05ef45e0393de812d51261dc293240c17294dFred Shih } 76337f05ef45e0393de812d51261dc293240c17294dFred Shih} 76437f05ef45e0393de812d51261dc293240c17294dFred Shih 76537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 76637f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) { 76713735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value(); 76837f05ef45e0393de812d51261dc293240c17294dFred Shih const kSize* addr = reinterpret_cast<const kSize*>(raw_addr); 76937f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 77037f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent(); 77137f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 77237f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData(); 77337f05ef45e0393de812d51261dc293240c17294dFred Shih } 77437f05ef45e0393de812d51261dc293240c17294dFred Shih} 77537f05ef45e0393de812d51261dc293240c17294dFred Shih 776b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 777228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, 778228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int64_t old_value, int64_t new_value) { 779d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 780d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 781d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 782d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 783d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 784d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7854e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7864e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 78813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 789228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 790228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 791ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 792ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 793d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 794d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset, 795d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int64_t old_value, int64_t new_value) { 796d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 797d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 798d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 799d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 800d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 801d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 802d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 803d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 804d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 80513735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 806d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 807d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 808d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 809d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 8106e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, 8116e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi bool kIsVolatile> 812b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) { 8134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 8144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 8154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 81613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 817ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 8186e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr); 819b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 8203035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent load instead. 8213035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceAcquire(); // Ensure visibility of operations preceding store. 822ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 8234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 8244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(result); 8254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 826ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return result; 827ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 828ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 8296e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 830b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) { 8316e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset); 832b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 833b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 834b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 835b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 836b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, 837b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Object* new_value) { 838d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 839d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 840d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 841d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 842b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers mirror::Object* obj; 843b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 844b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObjectVolatile<Object>(field_offset); 845b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 846b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObject<Object>(field_offset); 847b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 848b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true); 849d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 8504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 851ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 852ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 8534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 8544e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 8554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 85613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 857ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 858b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 8593035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent store instead. 8603035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceRelease(); // Ensure that prior accesses are visible before store. 861ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 8623035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceSequentiallyConsistent(); 8633035961cb41865b80b927546be0c708b6389cec6Hans Boehm // Ensure this store occurs before any volatile loads. 864ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 865ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 866ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 867ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 868ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 869b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 870b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 871b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) { 872b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags, 873b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile>(field_offset, new_value); 874ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (new_value != nullptr) { 875ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 87661c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this. 87761c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier CheckFieldAssignment(field_offset, new_value); 878ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 879ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 880ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 881b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 882b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) { 883b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 884b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 885b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 886b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 8874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags> 8884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 8894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 8904e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 8914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 89213735955f39b3b304c37d2b2840663c131262c18Ian Rogers return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) + 8934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset.Int32Value()); 8944e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier} 8954e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier 8964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 897228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, 898228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Object* old_value, Object* new_value) { 8992cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier< 9002cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 9012cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (success) { 9022cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 9032cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 9042cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 9052cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 9062cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 9072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier( 9092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 910d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 911d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 912d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 9134e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 9144e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 9154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 9164e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 9174e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 9184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 9194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 9204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(old_value); 9214e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 922d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 923d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 924d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 925ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 926ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 92713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 928228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 929228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 930228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_, 931228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_); 9322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 9332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 934228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 9352cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9362cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset, 9372cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Object* old_value, Object* new_value) { 9382cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier< 9392cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 940ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (success) { 941ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 942ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 943ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return success; 9442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 9452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 946d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier( 9482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 949d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 950d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 951d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 952d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 953d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 954d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 955d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyWrites) { 956d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(new_value); 957d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 958d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyReads) { 959d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(old_value); 960d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 961d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 962d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 963d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 964d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 965d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 96613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 967d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 968d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 969d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_, 970d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm new_ref.reference_); 971d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return success; 972d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 973d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 974fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 975fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier( 976fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 977fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 978fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 979fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 980fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 981fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 982fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 983fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyWrites) { 984fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(new_value); 985fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 986fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyReads) { 987fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(old_value); 988fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 989fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 990fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 991fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 992fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 993fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 994fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 995fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 996fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 997fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi bool success = atomic_addr->CompareExchangeWeakRelaxed(old_ref.reference_, 998fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi new_ref.reference_); 999fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return success; 1000fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 1001fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1002fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 1003fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier( 1004fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 1005fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 1006fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 1007fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1008fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 1009fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 1010fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1011fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyWrites) { 1012fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(new_value); 1013fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1014fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyReads) { 1015fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(old_value); 1016fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1017fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 1018fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 1019fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1020fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 1021fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 1022fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 1023fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 1024fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1025fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi bool success = atomic_addr->CompareExchangeStrongRelaxed(old_ref.reference_, 1026fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi new_ref.reference_); 1027fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return success; 1028fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 1029fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1030059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<bool kIsStatic, typename Visitor> 1031407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 1032cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) { 1033cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers // Instance fields and not the slow-path. 1034cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers uint32_t field_offset = mirror::kObjectHeaderSize; 1035407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier while (ref_offsets != 0) { 1036cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if ((ref_offsets & 1) != 0) { 1037cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers visitor(this, MemberOffset(field_offset), kIsStatic); 1038cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers } 1039cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers ref_offsets >>= 1; 1040cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers field_offset += sizeof(mirror::HeapReference<mirror::Object>); 1041407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1042407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 1043faff0f05fef90577c9744505555675185832aacdMingyao Yang // There is no reference offset bitmap. In the non-static case, walk up the class 1044407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // inheritance hierarchy and find reference offsets the hard way. In the static case, just 1045407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // consider this class. 1046407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr; 1047407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier klass = kIsStatic ? nullptr : klass->GetSuperClass()) { 1048407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier size_t num_reference_fields = 1049407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 105076649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko if (num_reference_fields == 0u) { 105176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko continue; 105276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 1053e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Presumably GC can happen when we are cross compiling, it should not cause performance 1054e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // problems to do pointer size logic. 105576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko MemberOffset field_offset = kIsStatic 1056e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ? klass->GetFirstReferenceStaticFieldOffset( 1057e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier Runtime::Current()->GetClassLinker()->GetImagePointerSize()) 105876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko : klass->GetFirstReferenceInstanceFieldOffset(); 1059059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier for (size_t i = 0u; i < num_reference_fields; ++i) { 1060407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // TODO: Do a simpler check? 1061059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) { 106252e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor(this, field_offset, kIsStatic); 1063407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 106476649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko field_offset = MemberOffset(field_offset.Uint32Value() + 106576649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko sizeof(mirror::HeapReference<mirror::Object>)); 1066407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1067407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1068407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1069407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1070407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1071059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor> 1072407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 1073059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitFieldsReferences<false>(klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor); 1074407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1075407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1076059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate<typename Visitor> 1077407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 107898d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK(!klass->IsTemp()); 1079059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier klass->VisitFieldsReferences<true>(0, visitor); 1080407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1081407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1082e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1083e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline bool Object::IsClassLoader() { 1084e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier return GetClass<kVerifyFlags>()->IsClassLoaderClass(); 1085e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1086e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1087e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 1088e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline mirror::ClassLoader* Object::AsClassLoader() { 1089e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier DCHECK(IsClassLoader<kVerifyFlags>()); 1090e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier return down_cast<mirror::ClassLoader*>(this); 1091e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1092e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 109305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markotemplate<VerifyObjectFlags kVerifyFlags> 109405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool Object::IsDexCache() { 109505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return GetClass<kVerifyFlags>()->IsDexCacheClass(); 109605792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 109705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 109805792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markotemplate<VerifyObjectFlags kVerifyFlags> 109905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::DexCache* Object::AsDexCache() { 110005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko DCHECK(IsDexCache<kVerifyFlags>()); 110105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return down_cast<mirror::DexCache*>(this); 110205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 110305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 1104059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags, typename Visitor, typename JavaLangRefVisitor> 1105407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor, 1106407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier const JavaLangRefVisitor& ref_visitor) { 1107407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags>(); 1108059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier visitor(this, ClassOffset(), false); 110952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>(); 111052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (LIKELY(class_flags == kClassFlagNormal)) { 111152e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier DCHECK(!klass->IsVariableSize()); 1112059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier VisitInstanceFieldsReferences(klass, visitor); 111352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(!klass->IsClassClass()); 111466c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsStringClass()); 111566c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsClassLoaderClass()); 111666c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsArrayClass()); 111752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 111852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if ((class_flags & kClassFlagNoReferenceFields) == 0) { 111952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(!klass->IsStringClass()); 112052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (class_flags == kClassFlagClass) { 112152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(klass->IsClassClass()); 112252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier AsClass<kVerifyNone>()->VisitReferences(klass, visitor); 112352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (class_flags == kClassFlagObjectArray) { 112452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(klass->IsObjectArrayClass()); 112552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences(visitor); 112652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if ((class_flags & kClassFlagReference) != 0) { 112752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier VisitInstanceFieldsReferences(klass, visitor); 112852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier ref_visitor(klass, AsReference()); 112905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko } else if (class_flags == kClassFlagDexCache) { 113005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko mirror::DexCache* const dex_cache = AsDexCache<kVerifyFlags>(); 113105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko dex_cache->VisitReferences<kVerifyFlags>(klass, visitor); 113252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 113352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags>(); 113452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier class_loader->VisitReferences<kVerifyFlags>(klass, visitor); 113552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 113652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (kIsDebugBuild) { 113752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK(!klass->IsClassClass()); 113852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK(!klass->IsObjectArrayClass()); 113952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // String still has instance fields for reflection purposes but these don't exist in 114052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // actual string instances. 114152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (!klass->IsStringClass()) { 114252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier size_t total_reference_instance_fields = 0; 114352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier mirror::Class* super_class = klass; 114452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier do { 114552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier total_reference_instance_fields += super_class->NumReferenceInstanceFields(); 114652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier super_class = super_class->GetSuperClass(); 114752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } while (super_class != nullptr); 114852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // The only reference field should be the object's class. This field is handled at the 114952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // beginning of the function. 115052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK_EQ(total_reference_instance_fields, 1u); 115152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 1152407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1153407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1154407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 11552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 11562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 11572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1158fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 1159