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) { 10923da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier return Monitor::MonitorEnter(self, this, /*trylock*/false); 11023da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier} 11123da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier 11223da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartierinline mirror::Object* Object::MonitorTryEnter(Thread* self) { 11323da026ec7a7fae22833ed2f61a80d9f9bf7e732Mathieu Chartier return Monitor::MonitorEnter(self, this, /*trylock*/true); 11405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 11605f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline bool Object::MonitorExit(Thread* self) { 11705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return Monitor::MonitorExit(self, this); 11805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 11905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Notify(Thread* self) { 12105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Notify(self, this); 12205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::NotifyAll(Thread* self) { 12505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::NotifyAll(self, this); 12605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 12705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 12805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self) { 12905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, 0, 0, true, kWaiting); 13005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 13105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 13205f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 13305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 13405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 13505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 136624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline Object* Object::GetReadBarrierPointer() { 13760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 13860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 13960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState()); 14060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 14160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1426a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>( 1436a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_)); 1449d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 1459d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1462c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1479d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 1489d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 1499d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 1509103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline void Object::SetReadBarrierPointer(Object* rb_ptr) { 15160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 15260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 15360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 15460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 15560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 15660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi SetLockWord(lw, false); 15760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 15860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1599d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // We don't mark the card as this occurs as part of object allocation. Not all objects have 1609d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi // backing cards, such as large objects. 1619d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( 1626a154a419022e2caed4edfd1f311edf733278f35Hiroshi Yamauchi OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr); 1639103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#else 1649103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 1652c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 1666a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(rb_ptr); 1679103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi#endif 1689103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi} 1699103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi 170ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchitemplate<bool kCasRelease> 1719103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchiinline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { 17260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#ifdef USE_BAKER_READ_BARRIER 17360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBakerReadBarrier); 17460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U); 17560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U); 17660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord expected_lw; 17760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord new_lw; 17860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi do { 17960f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi LockWord lw = GetLockWord(false); 18060f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) { 18160f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi // Lost the race. 18260f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return false; 18360f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi } 18460f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw = lw; 18560f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi expected_lw.SetReadBarrierState( 18660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr))); 18760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw = lw; 18860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr))); 189ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi // ConcurrentCopying::ProcessMarkStackRef uses this with kCasRelease == true. 190ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi // If kCasRelease == true, use a CAS release so that when GC updates all the fields of 191ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi // an object and then changes the object from gray to black, the field updates (stores) will be 192ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi // visible (won't be reordered after this CAS.) 193ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi } while (!(kCasRelease ? 194ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi CasLockWordWeakRelease(expected_lw, new_lw) : 195ed70b4a439acea537d55266bb9b1f309de8cbec9Hiroshi Yamauchi CasLockWordWeakRelaxed(expected_lw, new_lw))); 19660f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi return true; 19760f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi#elif USE_BROOKS_READ_BARRIER 19860f63f53c01cb38ca18a815603282e802a6cf918Hiroshi Yamauchi DCHECK(kUseBrooksReadBarrier); 1999103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); 20013735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue(); 201228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 2029103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); 2039103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); 2049103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi do { 205228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) { 2069103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi // Lost the race. 2079103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return false; 2089103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi } 209228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_, 210228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_)); 2119103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi return true; 2129d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#else 2136a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(expected_rb_ptr, rb_ptr); 2149d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi LOG(FATAL) << "Unreachable"; 2152c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 2169d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi#endif 2179d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2189d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 219624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchiinline void Object::AssertReadBarrierPointer() const { 220800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi if (kUseBakerReadBarrier) { 221800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 222800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK(obj->GetReadBarrierPointer() == nullptr) 223800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj) 224800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 2252c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers } else { 2262c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers CHECK(kUseBrooksReadBarrier); 227800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi Object* obj = const_cast<Object*>(this); 228800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi DCHECK_EQ(obj, obj->GetReadBarrierPointer()) 229800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj) 230800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer()); 231800ac2defde5d12b2f1f313c6b6162560cfa6fc7Hiroshi Yamauchi } 2329d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi} 2339d04a20bde1b1855cefc64aebc1a44e253b1a13bHiroshi Yamauchi 2344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 235ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::VerifierInstanceOf(Class* klass) { 2362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyFlags>() != nullptr); 238a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao return klass->IsInterface() || InstanceOf(klass); 239a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao} 240a3faaf4bece7f42529c013fe87bd41de59798656Jeff Hao 2414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 242ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::InstanceOf(Class* klass) { 2432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(klass != nullptr); 2442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(GetClass<kVerifyNone>() != nullptr); 2454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); 2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2486e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 249ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsClass() { 2506e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()-> 2516e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template GetClass<kVerifyFlags, kReadBarrierOption>(); 2526e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), 2536e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi kReadBarrierOption>() == java_lang_Class; 2542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2566e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 2572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline Class* Object::AsClass() { 2586e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>())); 2592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<Class*>(this); 2602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 262dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 263ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsObjectArray() { 2644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 265dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier return IsArrayInstance<kVerifyFlags, kReadBarrierOption>() && 266dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier !GetClass<kNewFlags, kReadBarrierOption>()-> 267dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier template GetComponentType<kNewFlags, kReadBarrierOption>()->IsPrimitive(); 2682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 270dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 2712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersinline ObjectArray<T>* Object::AsObjectArray() { 272dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((IsObjectArray<kVerifyFlags, kReadBarrierOption>())); 2732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return down_cast<ObjectArray<T>*>(this); 2742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2766e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 277ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsArrayInstance() { 2786e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetClass<kVerifyFlags, kReadBarrierOption>()-> 2796e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template IsArrayClass<kVerifyFlags, kReadBarrierOption>(); 2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 282dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 283ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsReferenceInstance() { 284dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier return GetClass<kVerifyFlags, kReadBarrierOption>()->IsTypeOfReferenceClass(); 2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 2862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 287dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 2888fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline Reference* Object::AsReference() { 289dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((IsReferenceInstance<kVerifyFlags, kReadBarrierOption>())); 2908fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<Reference*>(this); 2918fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 2928fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 2936e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 29405f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Array* Object::AsArray() { 2956e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>())); 29605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Array*>(this); 29705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 29805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 2994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30005f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline BooleanArray* Object::AsBooleanArray() { 3014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); 30405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<BooleanArray*>(this); 30505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 30605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 30805f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ByteArray* Object::AsByteArray() { 309e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3104e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); 31205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ByteArray*>(this); 31305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 31405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3154e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 316ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ByteArray* Object::AsByteSizedArray() { 317e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3184e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3194e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || 3204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); 321ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ByteArray*>(this); 322ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 323ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 3244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 32505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline CharArray* Object::AsCharArray() { 3264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 32905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<CharArray*>(this); 33005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 33105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 33305f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline ShortArray* Object::AsShortArray() { 3344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); 33705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<ShortArray*>(this); 33805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 33905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 341ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline ShortArray* Object::AsShortSizedArray() { 3424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3434e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || 3454e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); 346ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return down_cast<ShortArray*>(this); 347ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 348ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 349dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 350e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsIntArray() { 3514e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 352dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>(); 353dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>(); 354e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>(); 355e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 356e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 357dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 358e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline IntArray* Object::AsIntArray() { 359dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((IsIntArray<kVerifyFlags, kReadBarrierOption>())); 36005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<IntArray*>(this); 36105f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 36205f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 363dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 364e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsLongArray() { 3654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 366dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>(); 367dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>(); 368e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>(); 369e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 370e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 371dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 372e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline LongArray* Object::AsLongArray() { 373dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((IsLongArray<kVerifyFlags, kReadBarrierOption>())); 37405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<LongArray*>(this); 37505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 37605f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 3774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 378e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsFloatArray() { 379e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 380e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 381e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>(); 382e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 383e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 385d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline FloatArray* Object::AsFloatArray() { 386e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsFloatArray<kVerifyFlags>()); 3874e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 3884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 3894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); 390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<FloatArray*>(this); 391d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 392d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 3934e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 394e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierinline bool Object::IsDoubleArray() { 395e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 396e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); 397e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>(); 398e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier} 399e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier 400e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 401d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertzinline DoubleArray* Object::AsDoubleArray() { 402e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier DCHECK(IsDoubleArray<kVerifyFlags>()); 4034e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 4044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); 4054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); 406d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return down_cast<DoubleArray*>(this); 407d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz} 408d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 409848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 410848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haoinline bool Object::IsString() { 411848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass(); 412848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao} 413848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 414848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Haotemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 41505f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline String* Object::AsString() { 416848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao DCHECK((IsString<kVerifyFlags, kReadBarrierOption>())); 41705f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<String*>(this); 41805f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 41905f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4204e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 42105f3057d6a4d23d712092ccd36a531590bff323bIan Rogersinline Throwable* Object::AsThrowable() { 4224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 42305f3057d6a4d23d712092ccd36a531590bff323bIan Rogers return down_cast<Throwable*>(this); 42405f3057d6a4d23d712092ccd36a531590bff323bIan Rogers} 42505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers 4264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 427ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsWeakReferenceInstance() { 4284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 432ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsSoftReferenceInstance() { 4334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 4342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 437ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsFinalizerReferenceInstance() { 4384e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 4392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 4428fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartierinline FinalizerReference* Object::AsFinalizerReference() { 4438fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 4448fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier return down_cast<FinalizerReference*>(this); 4458fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier} 4468fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartier 4478fa2dad7fe7909c8335101d6c8904ae997cdf29fMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags> 448ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline bool Object::IsPhantomReferenceInstance() { 4494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 4502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 4526e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 453ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Object::SizeOf() { 4542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers size_t result; 4554e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); 4566e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) { 4576e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsArray<kNewFlags, kReadBarrierOption>()-> 4586e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 4596e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi } else if (IsClass<kNewFlags, kReadBarrierOption>()) { 4606e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi result = AsClass<kNewFlags, kReadBarrierOption>()-> 4616e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template SizeOf<kNewFlags, kReadBarrierOption>(); 462848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) { 463848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao result = AsString<kNewFlags, kReadBarrierOption>()-> 464848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao template SizeOf<kNewFlags>(); 4652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 46625023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi result = GetClass<kNewFlags, kReadBarrierOption>()-> 46725023c744c4388a6459b21cc3babf8c602b024a2Hiroshi Yamauchi template GetObjectSize<kNewFlags, kReadBarrierOption>(); 4682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 4699103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi DCHECK_GE(result, sizeof(Object)) 4706e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>()); 4712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return result; 4722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 4732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 474b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 47537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) { 4764e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 4774e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 4784e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 47937f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint8_t, kIsVolatile>(field_offset); 48037f05ef45e0393de812d51261dc293240c17294dFred Shih} 48137f05ef45e0393de812d51261dc293240c17294dFred Shih 48237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 48337f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByte(MemberOffset field_offset) { 48437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 48537f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 48637f05ef45e0393de812d51261dc293240c17294dFred Shih } 48737f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int8_t, kIsVolatile>(field_offset); 48837f05ef45e0393de812d51261dc293240c17294dFred Shih} 48937f05ef45e0393de812d51261dc293240c17294dFred Shih 49037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 49137f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) { 49237f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldBoolean<kVerifyFlags, true>(field_offset); 49337f05ef45e0393de812d51261dc293240c17294dFred Shih} 49437f05ef45e0393de812d51261dc293240c17294dFred Shih 49537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 49637f05ef45e0393de812d51261dc293240c17294dFred Shihinline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) { 49737f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldByte<kVerifyFlags, true>(field_offset); 49837f05ef45e0393de812d51261dc293240c17294dFred Shih} 49937f05ef45e0393de812d51261dc293240c17294dFred Shih 50037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 50137f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 50237f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value) 50390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 50437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 50537f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 50637f05ef45e0393de812d51261dc293240c17294dFred Shih } 50737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 50837f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldBoolean(this, field_offset, 50937f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset), 51037f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 51137f05ef45e0393de812d51261dc293240c17294dFred Shih } 51237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 51337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 51437f05ef45e0393de812d51261dc293240c17294dFred Shih } 51537f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint8_t, kIsVolatile>(field_offset, new_value); 51637f05ef45e0393de812d51261dc293240c17294dFred Shih} 51737f05ef45e0393de812d51261dc293240c17294dFred Shih 51837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 51937f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 52037f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) 52190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 52237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 52337f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 52437f05ef45e0393de812d51261dc293240c17294dFred Shih } 52537f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 52637f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldByte(this, field_offset, 52737f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset), 52837f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 52937f05ef45e0393de812d51261dc293240c17294dFred Shih } 53037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 53137f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 53237f05ef45e0393de812d51261dc293240c17294dFred Shih } 53337f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int8_t, kIsVolatile>(field_offset, new_value); 53437f05ef45e0393de812d51261dc293240c17294dFred Shih} 53537f05ef45e0393de812d51261dc293240c17294dFred Shih 53637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 53737f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) { 53837f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 53937f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 54037f05ef45e0393de812d51261dc293240c17294dFred Shih} 54137f05ef45e0393de812d51261dc293240c17294dFred Shih 54237f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 54337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) { 54437f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 54537f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 54637f05ef45e0393de812d51261dc293240c17294dFred Shih} 54737f05ef45e0393de812d51261dc293240c17294dFred Shih 54837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 54937f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldChar(MemberOffset field_offset) { 55037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 55137f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 55237f05ef45e0393de812d51261dc293240c17294dFred Shih } 55337f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<uint16_t, kIsVolatile>(field_offset); 55437f05ef45e0393de812d51261dc293240c17294dFred Shih} 55537f05ef45e0393de812d51261dc293240c17294dFred Shih 55637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 55737f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShort(MemberOffset field_offset) { 55837f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 55937f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 560b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 56137f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int16_t, kIsVolatile>(field_offset); 56237f05ef45e0393de812d51261dc293240c17294dFred Shih} 56337f05ef45e0393de812d51261dc293240c17294dFred Shih 56437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 56537f05ef45e0393de812d51261dc293240c17294dFred Shihinline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) { 56637f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldChar<kVerifyFlags, true>(field_offset); 56737f05ef45e0393de812d51261dc293240c17294dFred Shih} 56837f05ef45e0393de812d51261dc293240c17294dFred Shih 56937f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags> 57037f05ef45e0393de812d51261dc293240c17294dFred Shihinline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) { 57137f05ef45e0393de812d51261dc293240c17294dFred Shih return GetFieldShort<kVerifyFlags, true>(field_offset); 57237f05ef45e0393de812d51261dc293240c17294dFred Shih} 57337f05ef45e0393de812d51261dc293240c17294dFred Shih 57437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 57537f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 57637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) { 57737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 57837f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 57937f05ef45e0393de812d51261dc293240c17294dFred Shih } 58037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 58137f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 58237f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset), 58337f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 58437f05ef45e0393de812d51261dc293240c17294dFred Shih } 58537f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 58637f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 58737f05ef45e0393de812d51261dc293240c17294dFred Shih } 58837f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<uint16_t, kIsVolatile>(field_offset, new_value); 58937f05ef45e0393de812d51261dc293240c17294dFred Shih} 59037f05ef45e0393de812d51261dc293240c17294dFred Shih 59137f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 59237f05ef45e0393de812d51261dc293240c17294dFred Shih bool kIsVolatile> 59337f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) { 59437f05ef45e0393de812d51261dc293240c17294dFred Shih if (kCheckTransaction) { 59537f05ef45e0393de812d51261dc293240c17294dFred Shih DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 59637f05ef45e0393de812d51261dc293240c17294dFred Shih } 59737f05ef45e0393de812d51261dc293240c17294dFred Shih if (kTransactionActive) { 59837f05ef45e0393de812d51261dc293240c17294dFred Shih Runtime::Current()->RecordWriteFieldChar(this, field_offset, 59937f05ef45e0393de812d51261dc293240c17294dFred Shih GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset), 60037f05ef45e0393de812d51261dc293240c17294dFred Shih kIsVolatile); 60137f05ef45e0393de812d51261dc293240c17294dFred Shih } 60237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 60337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 60437f05ef45e0393de812d51261dc293240c17294dFred Shih } 60537f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int16_t, kIsVolatile>(field_offset, new_value); 60637f05ef45e0393de812d51261dc293240c17294dFred Shih} 60737f05ef45e0393de812d51261dc293240c17294dFred Shih 60837f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 60937f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) { 61037f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 61137f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 61237f05ef45e0393de812d51261dc293240c17294dFred Shih} 61337f05ef45e0393de812d51261dc293240c17294dFred Shih 61437f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 61537f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) { 61637f05ef45e0393de812d51261dc293240c17294dFred Shih return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>( 61737f05ef45e0393de812d51261dc293240c17294dFred Shih field_offset, new_value); 61837f05ef45e0393de812d51261dc293240c17294dFred Shih} 61937f05ef45e0393de812d51261dc293240c17294dFred Shih 62037f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 62137f05ef45e0393de812d51261dc293240c17294dFred Shihinline int32_t Object::GetField32(MemberOffset field_offset) { 62237f05ef45e0393de812d51261dc293240c17294dFred Shih if (kVerifyFlags & kVerifyThis) { 62337f05ef45e0393de812d51261dc293240c17294dFred Shih VerifyObject(this); 62437f05ef45e0393de812d51261dc293240c17294dFred Shih } 62537f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int32_t, kIsVolatile>(field_offset); 626b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 627b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 628b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 629b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int32_t Object::GetField32Volatile(MemberOffset field_offset) { 630b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags, true>(field_offset); 631b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 632b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 633b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 634b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 635b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { 636d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 637d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 638d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 639d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 640b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField32(this, field_offset, 641b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField32<kVerifyFlags, kIsVolatile>(field_offset), 642b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 643d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6444e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 645b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers VerifyObject(this); 646b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers } 64737f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int32_t, kIsVolatile>(field_offset, new_value); 648b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers} 649b122a4bbed34ab22b4c1541ee25e5cf22f12a926Ian Rogers 6504e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 651b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) { 652b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value); 653b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 654b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 655d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication? 656d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 657b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 658228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset, 659228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int32_t old_value, int32_t new_value) { 660d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 661d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 662d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 663d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 664d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 665d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 6664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 6674e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 6684e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 66913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 670228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 6713035961cb41865b80b927546be0c708b6389cec6Hans Boehm 672228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 673d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers} 674d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 675d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 676d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset, 677d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 678d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 679d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 680d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 681d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 682d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 683d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 684d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 685d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 686d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 68713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 688d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 689d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 690d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value); 691d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 692d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 693d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 694fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelease32(MemberOffset field_offset, 695fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi int32_t old_value, int32_t new_value) { 696fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 697fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 698fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 699fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 700fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 701fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 702fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 703fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 704fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 705fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 706fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 707fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 708fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return atomic_addr->CompareExchangeWeakRelease(old_value, new_value); 709fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 710fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 711fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 712d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset, 713d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int32_t old_value, int32_t new_value) { 714d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 715d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 716d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 717d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 718d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); 719d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 720d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 721d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 722d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 72313735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 724d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); 725d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 726d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 727d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 728d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 729b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags, bool kIsVolatile> 730b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64(MemberOffset field_offset) { 7314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7334e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 73437f05ef45e0393de812d51261dc293240c17294dFred Shih return GetField<int64_t, kIsVolatile>(field_offset); 7352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 7362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 737b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags> 738b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline int64_t Object::GetField64Volatile(MemberOffset field_offset) { 739b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField64<kVerifyFlags, true>(field_offset); 740b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 741b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 742b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 743b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 744b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64(MemberOffset field_offset, int64_t new_value) { 745d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 746d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 747d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 748d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 749b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteField64(this, field_offset, 750b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers GetField64<kVerifyFlags, kIsVolatile>(field_offset), 751b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile); 752d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7534e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 754ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 755ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 75637f05ef45e0393de812d51261dc293240c17294dFred Shih SetField<int64_t, kIsVolatile>(field_offset, new_value); 7572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 7582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 7594e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 760b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) { 761b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 762b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 763b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 764b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 76537f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 76637f05ef45e0393de812d51261dc293240c17294dFred Shihinline void Object::SetField(MemberOffset field_offset, kSize new_value) { 76713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 76837f05ef45e0393de812d51261dc293240c17294dFred Shih kSize* addr = reinterpret_cast<kSize*>(raw_addr); 76937f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 77037f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value); 77137f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 77237f05ef45e0393de812d51261dc293240c17294dFred Shih reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value); 77337f05ef45e0393de812d51261dc293240c17294dFred Shih } 77437f05ef45e0393de812d51261dc293240c17294dFred Shih} 77537f05ef45e0393de812d51261dc293240c17294dFred Shih 77637f05ef45e0393de812d51261dc293240c17294dFred Shihtemplate<typename kSize, bool kIsVolatile> 77737f05ef45e0393de812d51261dc293240c17294dFred Shihinline kSize Object::GetField(MemberOffset field_offset) { 77813735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value(); 77937f05ef45e0393de812d51261dc293240c17294dFred Shih const kSize* addr = reinterpret_cast<const kSize*>(raw_addr); 78037f05ef45e0393de812d51261dc293240c17294dFred Shih if (kIsVolatile) { 78137f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent(); 78237f05ef45e0393de812d51261dc293240c17294dFred Shih } else { 78337f05ef45e0393de812d51261dc293240c17294dFred Shih return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData(); 78437f05ef45e0393de812d51261dc293240c17294dFred Shih } 78537f05ef45e0393de812d51261dc293240c17294dFred Shih} 78637f05ef45e0393de812d51261dc293240c17294dFred Shih 787b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 788228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset, 789228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers int64_t old_value, int64_t new_value) { 790d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 791d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 792d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 793d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 794d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 795d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 7964e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 7974e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 7984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 79913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 800228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 801228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value); 802ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 803ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 804d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 805d8434439dc64add41cdfa69ddf96b960af9050deHans Boehminline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset, 806d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm int64_t old_value, int64_t new_value) { 807d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 808d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 809d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 810d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 811d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); 812d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 813d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 814d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 815d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 81613735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 817d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); 818d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value); 819d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 820d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 8216e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, 8226e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi bool kIsVolatile> 823b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObject(MemberOffset field_offset) { 8244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 8254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 8264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 82713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 828ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr); 8296e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr); 830b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 8313035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent load instead. 8323035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceAcquire(); // Ensure visibility of operations preceding store. 833ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 8344e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 8354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(result); 8364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 837ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return result; 838ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 839ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 8406e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 841b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) { 8426e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset); 843b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 844b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 845b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 846b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 847b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, 848b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Object* new_value) { 849d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 850d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 851d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 852d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 853b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers mirror::Object* obj; 854b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 855b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObjectVolatile<Object>(field_offset); 856b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } else { 857b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers obj = GetFieldObject<Object>(field_offset); 858b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers } 859b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true); 860d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 8614e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 862ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers VerifyObject(this); 863ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 8644e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 8654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 8664e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 86713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 868ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr); 869b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers if (kIsVolatile) { 8703035961cb41865b80b927546be0c708b6389cec6Hans Boehm // TODO: Refactor to use a SequentiallyConsistent store instead. 8713035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceRelease(); // Ensure that prior accesses are visible before store. 872ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 8733035961cb41865b80b927546be0c708b6389cec6Hans Boehm QuasiAtomic::ThreadFenceSequentiallyConsistent(); 8743035961cb41865b80b927546be0c708b6389cec6Hans Boehm // Ensure this store occurs before any volatile loads. 875ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } else { 876ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers objref_addr->Assign(new_value); 877ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 878ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 879ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 880b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, 881b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool kIsVolatile> 882b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) { 883b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags, 884b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers kIsVolatile>(field_offset, new_value); 885ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (new_value != nullptr) { 886ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 88761c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this. 88861c5ebc6aee2cac1c363de6fbdac25ada1697fdbMathieu Chartier CheckFieldAssignment(field_offset, new_value); 889ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 890ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers} 891ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 892b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 893b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) { 894b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, 895b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers new_value); 896b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers} 897b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 8984e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate <VerifyObjectFlags kVerifyFlags> 8994e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartierinline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) { 9004e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 9014e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 9024e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 90313735955f39b3b304c37d2b2840663c131262c18Ian Rogers return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) + 9044e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier field_offset.Int32Value()); 9054e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier} 9064e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier 9074e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartiertemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 908228602f562f1d130d06e60a98752d99c2d467d6aIan Rogersinline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset, 909228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Object* old_value, Object* new_value) { 9102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier< 9112cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 9122cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (success) { 9132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 9142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 9152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 9162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 9172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 9182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier( 9202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 921d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kCheckTransaction) { 922d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 923d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 9244e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyThis) { 9254e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(this); 9264e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 9274e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyWrites) { 9284e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(new_value); 9294e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 9304e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier if (kVerifyFlags & kVerifyReads) { 9314e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier VerifyObject(old_value); 9324e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier } 933d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (kTransactionActive) { 934d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 935d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 936ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 937ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 93813735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 939228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 940228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 941228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_, 942228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers new_ref.reference_); 9432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi return success; 9442cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi} 945228602f562f1d130d06e60a98752d99c2d467d6aIan Rogers 9462cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9472cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset, 9482cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Object* old_value, Object* new_value) { 9492cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier< 9502cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value); 951ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers if (success) { 952ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value); 953ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 954ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return success; 9552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} 9562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 957d8434439dc64add41cdfa69ddf96b960af9050deHans Boehmtemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 9582cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchiinline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier( 9592cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 960d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kCheckTransaction) { 961d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 962d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 963d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyThis) { 964d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(this); 965d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 966d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyWrites) { 967d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(new_value); 968d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 969d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kVerifyFlags & kVerifyReads) { 970d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm VerifyObject(old_value); 971d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 972d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm if (kTransactionActive) { 973d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 974d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm } 975d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 976d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 97713735955f39b3b304c37d2b2840663c131262c18Ian Rogers uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 978d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 979d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 980d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_, 981d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm new_ref.reference_); 982d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm return success; 983d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm} 984d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm 985fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 986fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier( 987fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 988fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 989fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 990fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 991fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 992fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 993fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 994fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyWrites) { 995fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(new_value); 996fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 997fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyReads) { 998fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(old_value); 999fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1000fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 1001fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 1002fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1003fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 1004fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 1005fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 1006fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 1007fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1008fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi bool success = atomic_addr->CompareExchangeWeakRelaxed(old_ref.reference_, 1009fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi new_ref.reference_); 1010fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return success; 1011fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 1012fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1013fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchitemplate<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> 1014fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchiinline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier( 1015fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi MemberOffset field_offset, Object* old_value, Object* new_value) { 1016fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kCheckTransaction) { 1017fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); 1018fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1019fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyThis) { 1020fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(this); 1021fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1022fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyWrites) { 1023fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(new_value); 1024fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1025fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kVerifyFlags & kVerifyReads) { 1026fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi VerifyObject(old_value); 1027fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1028fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi if (kTransactionActive) { 1029fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); 1030fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi } 1031fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value)); 1032fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value)); 1033fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); 1034fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); 1035fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1036fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi bool success = atomic_addr->CompareExchangeStrongRelaxed(old_ref.reference_, 1037fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi new_ref.reference_); 1038fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi return success; 1039fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi} 1040fed3e2fd4919b58f8e4f8cbc317ee101f3b9af49Hiroshi Yamauchi 1041fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<bool kIsStatic, 1042fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier VerifyObjectFlags kVerifyFlags, 1043fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ReadBarrierOption kReadBarrierOption, 1044fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier typename Visitor> 1045407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) { 1046cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) { 1047cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers // Instance fields and not the slow-path. 1048cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers uint32_t field_offset = mirror::kObjectHeaderSize; 1049407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier while (ref_offsets != 0) { 1050cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers if ((ref_offsets & 1) != 0) { 1051cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers visitor(this, MemberOffset(field_offset), kIsStatic); 1052cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers } 1053cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers ref_offsets >>= 1; 1054cdc1aaffabbdf417d29b203b2cd2763ed2d623f8Ian Rogers field_offset += sizeof(mirror::HeapReference<mirror::Object>); 1055407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1056407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } else { 1057faff0f05fef90577c9744505555675185832aacdMingyao Yang // There is no reference offset bitmap. In the non-static case, walk up the class 1058407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // inheritance hierarchy and find reference offsets the hard way. In the static case, just 1059407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // consider this class. 1060fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier for (mirror::Class* klass = kIsStatic 1061fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ? AsClass<kVerifyFlags, kReadBarrierOption>() 1062fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier : GetClass<kVerifyFlags, kReadBarrierOption>(); 1063fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier klass != nullptr; 1064fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier klass = kIsStatic ? nullptr : klass->GetSuperClass<kVerifyFlags, kReadBarrierOption>()) { 1065fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const size_t num_reference_fields = 1066407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields(); 106776649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko if (num_reference_fields == 0u) { 106876649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko continue; 106976649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko } 1070e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Presumably GC can happen when we are cross compiling, it should not cause performance 1071e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // problems to do pointer size logic. 107276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko MemberOffset field_offset = kIsStatic 1073dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier ? klass->GetFirstReferenceStaticFieldOffset<kVerifyFlags, kReadBarrierOption>( 1074e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier Runtime::Current()->GetClassLinker()->GetImagePointerSize()) 10755496f69c0a4c2cc357a065f57b7f4ff5d9ad2fa9Hiroshi Yamauchi : klass->GetFirstReferenceInstanceFieldOffset<kVerifyFlags, kReadBarrierOption>(); 1076059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier for (size_t i = 0u; i < num_reference_fields; ++i) { 1077407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier // TODO: Do a simpler check? 1078059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) { 107952e4b43d62896b56f8c2bd041e528472bb4a0d8dMathieu Chartier visitor(this, field_offset, kIsStatic); 1080407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 108176649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko field_offset = MemberOffset(field_offset.Uint32Value() + 108276649e8d775519fe19f2b14d18ac488c13296054Vladimir Marko sizeof(mirror::HeapReference<mirror::Object>)); 1083407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1084407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1085407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1086407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1087407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1088fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor> 1089407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 1090fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier VisitFieldsReferences<false, kVerifyFlags, kReadBarrierOption>( 1091fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier klass->GetReferenceInstanceOffsets<kVerifyFlags>(), visitor); 1092407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1093407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1094fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor> 1095407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) { 109698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang DCHECK(!klass->IsTemp()); 1097fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier klass->VisitFieldsReferences<true, kVerifyFlags, kReadBarrierOption>(0, visitor); 1098407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 1099407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier 1100fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 1101e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline bool Object::IsClassLoader() { 1102fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return GetClass<kVerifyFlags, kReadBarrierOption>()->IsClassLoaderClass(); 1103e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1104e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1105fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 1106e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierinline mirror::ClassLoader* Object::AsClassLoader() { 1107fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK((IsClassLoader<kVerifyFlags, kReadBarrierOption>())); 1108e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier return down_cast<mirror::ClassLoader*>(this); 1109e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 1110e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1111fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 111205792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline bool Object::IsDexCache() { 1113fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return GetClass<kVerifyFlags, kReadBarrierOption>()->IsDexCacheClass(); 111405792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 111505792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 1116fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 111705792b98980741111b4d0a24d68cff2a8e070a3aVladimir Markoinline mirror::DexCache* Object::AsDexCache() { 1118fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK((IsDexCache<kVerifyFlags, kReadBarrierOption>())); 111905792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko return down_cast<mirror::DexCache*>(this); 112005792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko} 112105792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko 1122fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiertemplate <bool kVisitNativeRoots, 1123fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier VerifyObjectFlags kVerifyFlags, 1124fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ReadBarrierOption kReadBarrierOption, 1125fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier typename Visitor, 1126fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier typename JavaLangRefVisitor> 1127407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartierinline void Object::VisitReferences(const Visitor& visitor, 1128407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier const JavaLangRefVisitor& ref_visitor) { 1129fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>(); 1130059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier visitor(this, ClassOffset(), false); 113152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>(); 113252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (LIKELY(class_flags == kClassFlagNormal)) { 1133dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((!klass->IsVariableSize<kVerifyFlags, kReadBarrierOption>())); 1134dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor); 1135fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>())); 113666c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsStringClass()); 113766c2d2d64d7ea75602eb63de7ae9bd2eaeb0a3c2Mathieu Chartier DCHECK(!klass->IsClassLoaderClass()); 1138dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((!klass->IsArrayClass<kVerifyFlags, kReadBarrierOption>())); 113952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 114052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if ((class_flags & kClassFlagNoReferenceFields) == 0) { 114152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier DCHECK(!klass->IsStringClass()); 114252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (class_flags == kClassFlagClass) { 1143dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier DCHECK((klass->IsClassClass<kVerifyFlags, kReadBarrierOption>())); 1144dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier mirror::Class* as_klass = AsClass<kVerifyNone, kReadBarrierOption>(); 1145dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass, 1146dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier visitor); 114752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (class_flags == kClassFlagObjectArray) { 1148fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK((klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>())); 1149dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier AsObjectArray<mirror::Object, kVerifyNone, kReadBarrierOption>()->VisitReferences(visitor); 115052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if ((class_flags & kClassFlagReference) != 0) { 1151dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor); 1152dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier ref_visitor(klass, AsReference<kVerifyFlags, kReadBarrierOption>()); 115305792b98980741111b4d0a24d68cff2a8e070a3aVladimir Marko } else if (class_flags == kClassFlagDexCache) { 1154fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier mirror::DexCache* const dex_cache = AsDexCache<kVerifyFlags, kReadBarrierOption>(); 1155fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier dex_cache->VisitReferences<kVisitNativeRoots, 1156fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier kVerifyFlags, 1157fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier kReadBarrierOption>(klass, visitor); 115852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else { 1159fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags, kReadBarrierOption>(); 1160fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier class_loader->VisitReferences<kVisitNativeRoots, 1161fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier kVerifyFlags, 1162fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier kReadBarrierOption>(klass, visitor); 116352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 116452a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } else if (kIsDebugBuild) { 1165fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier CHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>())); 1166fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier CHECK((!klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>())); 116752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // String still has instance fields for reflection purposes but these don't exist in 116852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // actual string instances. 116952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier if (!klass->IsStringClass()) { 117052a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier size_t total_reference_instance_fields = 0; 117152a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier mirror::Class* super_class = klass; 117252a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier do { 117352a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier total_reference_instance_fields += super_class->NumReferenceInstanceFields(); 1174fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier super_class = super_class->GetSuperClass<kVerifyFlags, kReadBarrierOption>(); 117552a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } while (super_class != nullptr); 117652a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // The only reference field should be the object's class. This field is handled at the 117752a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier // beginning of the function. 117852a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier CHECK_EQ(total_reference_instance_fields, 1u); 117952a7f5caebdf359ab877f1928aad59f1e9ad29faMathieu Chartier } 1180407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1181407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier } 1182407f702da4f867c074fc3c8c688b8f8c32279effMathieu Chartier} 11832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 11842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 11852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1186fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_OBJECT_INL_H_ 1187