xref: /aosp_15_r20/art/runtime/mirror/object-inl.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_MIRROR_OBJECT_INL_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "object.h"
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "array-inl.h"
23*795d594fSAndroid Build Coastguard Worker #include "art_field.h"
24*795d594fSAndroid Build Coastguard Worker #include "art_method.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h"
26*795d594fSAndroid Build Coastguard Worker #include "class-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "class_flags.h"
28*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex_cache.h"
30*795d594fSAndroid Build Coastguard Worker #include "heap_poisoning.h"
31*795d594fSAndroid Build Coastguard Worker #include "lock_word-inl.h"
32*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
33*795d594fSAndroid Build Coastguard Worker #include "obj_ptr-inl.h"
34*795d594fSAndroid Build Coastguard Worker #include "object-readbarrier-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "object_array-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "object_reference-inl.h"
37*795d594fSAndroid Build Coastguard Worker #include "read_barrier-inl.h"
38*795d594fSAndroid Build Coastguard Worker #include "reference.h"
39*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
40*795d594fSAndroid Build Coastguard Worker #include "string.h"
41*795d594fSAndroid Build Coastguard Worker #include "throwable.h"
42*795d594fSAndroid Build Coastguard Worker #include "write_barrier-inl.h"
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
45*795d594fSAndroid Build Coastguard Worker namespace mirror {
46*795d594fSAndroid Build Coastguard Worker 
ClassSize(PointerSize pointer_size)47*795d594fSAndroid Build Coastguard Worker inline uint32_t Object::ClassSize(PointerSize pointer_size) {
48*795d594fSAndroid Build Coastguard Worker   uint32_t vtable_entries = kVTableLength;
49*795d594fSAndroid Build Coastguard Worker   return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, 0, pointer_size);
50*795d594fSAndroid Build Coastguard Worker }
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetClass()53*795d594fSAndroid Build Coastguard Worker inline Class* Object::GetClass() {
54*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(ClassOffset());
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
SetClass(ObjPtr<Class> new_klass)58*795d594fSAndroid Build Coastguard Worker inline void Object::SetClass(ObjPtr<Class> new_klass) {
59*795d594fSAndroid Build Coastguard Worker   // new_klass may be null prior to class linker initialization.
60*795d594fSAndroid Build Coastguard Worker   // We don't mark the card as this occurs as part of object allocation. Not all objects have
61*795d594fSAndroid Build Coastguard Worker   // backing cards, such as large objects.
62*795d594fSAndroid Build Coastguard Worker   // We use non transactional version since we can't undo this write. We also disable checking as
63*795d594fSAndroid Build Coastguard Worker   // we may run in transaction mode here.
64*795d594fSAndroid Build Coastguard Worker   SetFieldObjectWithoutWriteBarrier<false, false, RemoveThisFlags(kVerifyFlags)>(ClassOffset(),
65*795d594fSAndroid Build Coastguard Worker                                                                                  new_klass);
66*795d594fSAndroid Build Coastguard Worker }
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
SetLockWord(LockWord new_val,bool as_volatile)69*795d594fSAndroid Build Coastguard Worker inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
70*795d594fSAndroid Build Coastguard Worker   // Force use of non-transactional mode and do not check.
71*795d594fSAndroid Build Coastguard Worker   if (as_volatile) {
72*795d594fSAndroid Build Coastguard Worker     SetField32Volatile<false, false, kVerifyFlags>(MonitorOffset(), new_val.GetValue());
73*795d594fSAndroid Build Coastguard Worker   } else {
74*795d594fSAndroid Build Coastguard Worker     SetField32<false, false, kVerifyFlags>(MonitorOffset(), new_val.GetValue());
75*795d594fSAndroid Build Coastguard Worker   }
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker 
GetLockOwnerThreadId()78*795d594fSAndroid Build Coastguard Worker inline uint32_t Object::GetLockOwnerThreadId() {
79*795d594fSAndroid Build Coastguard Worker   return Monitor::GetLockOwnerThreadId(this);
80*795d594fSAndroid Build Coastguard Worker }
81*795d594fSAndroid Build Coastguard Worker 
MonitorEnter(Thread * self)82*795d594fSAndroid Build Coastguard Worker inline ObjPtr<mirror::Object> Object::MonitorEnter(Thread* self) {
83*795d594fSAndroid Build Coastguard Worker   return Monitor::MonitorEnter(self, this, /*trylock=*/false);
84*795d594fSAndroid Build Coastguard Worker }
85*795d594fSAndroid Build Coastguard Worker 
MonitorTryEnter(Thread * self)86*795d594fSAndroid Build Coastguard Worker inline ObjPtr<mirror::Object> Object::MonitorTryEnter(Thread* self) {
87*795d594fSAndroid Build Coastguard Worker   return Monitor::MonitorEnter(self, this, /*trylock=*/true);
88*795d594fSAndroid Build Coastguard Worker }
89*795d594fSAndroid Build Coastguard Worker 
MonitorExit(Thread * self)90*795d594fSAndroid Build Coastguard Worker inline bool Object::MonitorExit(Thread* self) {
91*795d594fSAndroid Build Coastguard Worker   return Monitor::MonitorExit(self, this);
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker 
Notify(Thread * self)94*795d594fSAndroid Build Coastguard Worker inline void Object::Notify(Thread* self) {
95*795d594fSAndroid Build Coastguard Worker   Monitor::Notify(self, this);
96*795d594fSAndroid Build Coastguard Worker }
97*795d594fSAndroid Build Coastguard Worker 
NotifyAll(Thread * self)98*795d594fSAndroid Build Coastguard Worker inline void Object::NotifyAll(Thread* self) {
99*795d594fSAndroid Build Coastguard Worker   Monitor::NotifyAll(self, this);
100*795d594fSAndroid Build Coastguard Worker }
101*795d594fSAndroid Build Coastguard Worker 
Wait(Thread * self,int64_t ms,int32_t ns)102*795d594fSAndroid Build Coastguard Worker inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
103*795d594fSAndroid Build Coastguard Worker   Monitor::Wait(self, this, ms, ns, true, ThreadState::kTimedWaiting);
104*795d594fSAndroid Build Coastguard Worker }
105*795d594fSAndroid Build Coastguard Worker 
GetMarkBit()106*795d594fSAndroid Build Coastguard Worker inline uint32_t Object::GetMarkBit() {
107*795d594fSAndroid Build Coastguard Worker   CHECK(gUseReadBarrier);
108*795d594fSAndroid Build Coastguard Worker   return GetLockWord(false).MarkBitState();
109*795d594fSAndroid Build Coastguard Worker }
110*795d594fSAndroid Build Coastguard Worker 
SetReadBarrierState(uint32_t rb_state)111*795d594fSAndroid Build Coastguard Worker inline void Object::SetReadBarrierState(uint32_t rb_state) {
112*795d594fSAndroid Build Coastguard Worker   CHECK(kUseBakerReadBarrier);
113*795d594fSAndroid Build Coastguard Worker   DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state;
114*795d594fSAndroid Build Coastguard Worker   LockWord lw = GetLockWord(false);
115*795d594fSAndroid Build Coastguard Worker   lw.SetReadBarrierState(rb_state);
116*795d594fSAndroid Build Coastguard Worker   SetLockWord(lw, false);
117*795d594fSAndroid Build Coastguard Worker }
118*795d594fSAndroid Build Coastguard Worker 
AssertReadBarrierState()119*795d594fSAndroid Build Coastguard Worker inline void Object::AssertReadBarrierState() const {
120*795d594fSAndroid Build Coastguard Worker   CHECK(kUseBakerReadBarrier);
121*795d594fSAndroid Build Coastguard Worker   Object* obj = const_cast<Object*>(this);
122*795d594fSAndroid Build Coastguard Worker   DCHECK_EQ(obj->GetReadBarrierState(), ReadBarrier::NonGrayState())
123*795d594fSAndroid Build Coastguard Worker       << "Bad Baker pointer: obj=" << obj << " rb_state" << obj->GetReadBarrierState();
124*795d594fSAndroid Build Coastguard Worker }
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
VerifierInstanceOf(ObjPtr<Class> klass)127*795d594fSAndroid Build Coastguard Worker inline bool Object::VerifierInstanceOf(ObjPtr<Class> klass) {
128*795d594fSAndroid Build Coastguard Worker   DCHECK(klass != nullptr);
129*795d594fSAndroid Build Coastguard Worker   DCHECK(GetClass<kVerifyFlags>() != nullptr);
130*795d594fSAndroid Build Coastguard Worker   return klass->IsInterface() || InstanceOf(klass);
131*795d594fSAndroid Build Coastguard Worker }
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
InstanceOf(ObjPtr<Class> klass)134*795d594fSAndroid Build Coastguard Worker inline bool Object::InstanceOf(ObjPtr<Class> klass) {
135*795d594fSAndroid Build Coastguard Worker   DCHECK(klass != nullptr);
136*795d594fSAndroid Build Coastguard Worker   DCHECK(GetClass<kVerifyNone>() != nullptr) << "this=" << this;
137*795d594fSAndroid Build Coastguard Worker   return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
138*795d594fSAndroid Build Coastguard Worker }
139*795d594fSAndroid Build Coastguard Worker 
140*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsClass()141*795d594fSAndroid Build Coastguard Worker inline bool Object::IsClass() {
142*795d594fSAndroid Build Coastguard Worker   // OK to look at from-space copies since java.lang.Class.class is non-moveable
143*795d594fSAndroid Build Coastguard Worker   // (even when running without boot image, see ClassLinker::InitWithoutImage())
144*795d594fSAndroid Build Coastguard Worker   // and we're reading constant references for comparison only. See ReadBarrierOption.
145*795d594fSAndroid Build Coastguard Worker   ObjPtr<Class> klass = GetClass<kVerifyFlags, kWithoutReadBarrier>();
146*795d594fSAndroid Build Coastguard Worker   ObjPtr<Class> java_lang_Class = klass->GetClass<kVerifyFlags, kWithoutReadBarrier>();
147*795d594fSAndroid Build Coastguard Worker   return klass == java_lang_Class;
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsClass()151*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Class> Object::AsClass() {
152*795d594fSAndroid Build Coastguard Worker   DCHECK((IsClass<kVerifyFlags>()));
153*795d594fSAndroid Build Coastguard Worker   return ObjPtr<Class>::DownCast(this);
154*795d594fSAndroid Build Coastguard Worker }
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsObjectArray()157*795d594fSAndroid Build Coastguard Worker inline bool Object::IsObjectArray() {
158*795d594fSAndroid Build Coastguard Worker   // We do not need a read barrier here as the primitive type is constant,
159*795d594fSAndroid Build Coastguard Worker   // both from-space and to-space component type classes shall yield the same result.
160*795d594fSAndroid Build Coastguard Worker   constexpr VerifyObjectFlags kNewFlags = RemoveThisFlags(kVerifyFlags);
161*795d594fSAndroid Build Coastguard Worker   return IsArrayInstance<kVerifyFlags>() &&
162*795d594fSAndroid Build Coastguard Worker       !GetClass<kNewFlags, kWithoutReadBarrier>()->
163*795d594fSAndroid Build Coastguard Worker           template GetComponentType<kNewFlags, kWithoutReadBarrier>()->IsPrimitive();
164*795d594fSAndroid Build Coastguard Worker }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker template<class T, VerifyObjectFlags kVerifyFlags>
AsObjectArray()167*795d594fSAndroid Build Coastguard Worker inline ObjPtr<ObjectArray<T>> Object::AsObjectArray() {
168*795d594fSAndroid Build Coastguard Worker   DCHECK((IsObjectArray<kVerifyFlags>()));
169*795d594fSAndroid Build Coastguard Worker   return ObjPtr<ObjectArray<T>>::DownCast(this);
170*795d594fSAndroid Build Coastguard Worker }
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsArrayInstance()173*795d594fSAndroid Build Coastguard Worker inline bool Object::IsArrayInstance() {
174*795d594fSAndroid Build Coastguard Worker   // We do not need a read barrier here, both from-space and to-space version of the class
175*795d594fSAndroid Build Coastguard Worker   // shall return the same result from IsArrayClass().
176*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags, kWithoutReadBarrier>()->template IsArrayClass<kVerifyFlags>();
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsReferenceInstance()180*795d594fSAndroid Build Coastguard Worker inline bool Object::IsReferenceInstance() {
181*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags, kReadBarrierOption>()->IsTypeOfReferenceClass();
182*795d594fSAndroid Build Coastguard Worker }
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsReference()185*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Reference> Object::AsReference() {
186*795d594fSAndroid Build Coastguard Worker   DCHECK((IsReferenceInstance<kVerifyFlags, kReadBarrierOption>()));
187*795d594fSAndroid Build Coastguard Worker   return ObjPtr<Reference>::DownCast(this);
188*795d594fSAndroid Build Coastguard Worker }
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsArray()191*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Array> Object::AsArray() {
192*795d594fSAndroid Build Coastguard Worker   DCHECK((IsArrayInstance<kVerifyFlags>()));
193*795d594fSAndroid Build Coastguard Worker   return ObjPtr<Array>::DownCast(this);
194*795d594fSAndroid Build Coastguard Worker }
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, Primitive::Type kType>
IsSpecificPrimitiveArray()197*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool Object::IsSpecificPrimitiveArray() {
198*795d594fSAndroid Build Coastguard Worker   // We do not need a read barrier here as the primitive type is constant, both from-space
199*795d594fSAndroid Build Coastguard Worker   // and to-space component type classes shall yield the same result. See ReadBarrierOption.
200*795d594fSAndroid Build Coastguard Worker   const ObjPtr<Class> klass = GetClass<kVerifyFlags, kWithoutReadBarrier>();
201*795d594fSAndroid Build Coastguard Worker   constexpr VerifyObjectFlags kNewFlags = RemoveThisFlags(kVerifyFlags);
202*795d594fSAndroid Build Coastguard Worker   const ObjPtr<Class> component_type = klass->GetComponentType<kNewFlags, kWithoutReadBarrier>();
203*795d594fSAndroid Build Coastguard Worker   return component_type != nullptr &&
204*795d594fSAndroid Build Coastguard Worker          component_type->GetPrimitiveType<kNewFlags>() == kType;
205*795d594fSAndroid Build Coastguard Worker }
206*795d594fSAndroid Build Coastguard Worker 
207*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsBooleanArray()208*795d594fSAndroid Build Coastguard Worker inline bool Object::IsBooleanArray() {
209*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimBoolean>();
210*795d594fSAndroid Build Coastguard Worker }
211*795d594fSAndroid Build Coastguard Worker 
212*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsBooleanArray()213*795d594fSAndroid Build Coastguard Worker inline ObjPtr<BooleanArray> Object::AsBooleanArray() {
214*795d594fSAndroid Build Coastguard Worker   DCHECK(IsBooleanArray<kVerifyFlags>());
215*795d594fSAndroid Build Coastguard Worker   return ObjPtr<BooleanArray>::DownCast(this);
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker 
218*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsByteArray()219*795d594fSAndroid Build Coastguard Worker inline bool Object::IsByteArray() {
220*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimByte>();
221*795d594fSAndroid Build Coastguard Worker }
222*795d594fSAndroid Build Coastguard Worker 
223*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsByteArray()224*795d594fSAndroid Build Coastguard Worker inline ObjPtr<ByteArray> Object::AsByteArray() {
225*795d594fSAndroid Build Coastguard Worker   DCHECK(IsByteArray<kVerifyFlags>());
226*795d594fSAndroid Build Coastguard Worker   return ObjPtr<ByteArray>::DownCast(this);
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsCharArray()230*795d594fSAndroid Build Coastguard Worker inline bool Object::IsCharArray() {
231*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimChar>();
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsCharArray()235*795d594fSAndroid Build Coastguard Worker inline ObjPtr<CharArray> Object::AsCharArray() {
236*795d594fSAndroid Build Coastguard Worker   DCHECK(IsCharArray<kVerifyFlags>());
237*795d594fSAndroid Build Coastguard Worker   return ObjPtr<CharArray>::DownCast(this);
238*795d594fSAndroid Build Coastguard Worker }
239*795d594fSAndroid Build Coastguard Worker 
240*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsShortArray()241*795d594fSAndroid Build Coastguard Worker inline bool Object::IsShortArray() {
242*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimShort>();
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker 
245*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsShortArray()246*795d594fSAndroid Build Coastguard Worker inline ObjPtr<ShortArray> Object::AsShortArray() {
247*795d594fSAndroid Build Coastguard Worker   DCHECK(IsShortArray<kVerifyFlags>());
248*795d594fSAndroid Build Coastguard Worker   return ObjPtr<ShortArray>::DownCast(this);
249*795d594fSAndroid Build Coastguard Worker }
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsIntArray()252*795d594fSAndroid Build Coastguard Worker inline bool Object::IsIntArray() {
253*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimInt>();
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsIntArrayUnchecked()257*795d594fSAndroid Build Coastguard Worker inline ObjPtr<IntArray> Object::AsIntArrayUnchecked() {
258*795d594fSAndroid Build Coastguard Worker   return ObjPtr<IntArray>::DownCast(this);
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsIntArray()261*795d594fSAndroid Build Coastguard Worker inline ObjPtr<IntArray> Object::AsIntArray() {
262*795d594fSAndroid Build Coastguard Worker   DCHECK((IsIntArray<kVerifyFlags>()));
263*795d594fSAndroid Build Coastguard Worker   return AsIntArrayUnchecked<kVerifyFlags>();
264*795d594fSAndroid Build Coastguard Worker }
265*795d594fSAndroid Build Coastguard Worker 
266*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsLongArray()267*795d594fSAndroid Build Coastguard Worker inline bool Object::IsLongArray() {
268*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimLong>();
269*795d594fSAndroid Build Coastguard Worker }
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsLongArrayUnchecked()272*795d594fSAndroid Build Coastguard Worker inline ObjPtr<LongArray> Object::AsLongArrayUnchecked() {
273*795d594fSAndroid Build Coastguard Worker   return ObjPtr<LongArray>::DownCast(this);
274*795d594fSAndroid Build Coastguard Worker }
275*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsLongArray()276*795d594fSAndroid Build Coastguard Worker inline ObjPtr<LongArray> Object::AsLongArray() {
277*795d594fSAndroid Build Coastguard Worker   DCHECK((IsLongArray<kVerifyFlags>()));
278*795d594fSAndroid Build Coastguard Worker   return AsLongArrayUnchecked<kVerifyFlags>();
279*795d594fSAndroid Build Coastguard Worker }
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsFloatArray()282*795d594fSAndroid Build Coastguard Worker inline bool Object::IsFloatArray() {
283*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimFloat>();
284*795d594fSAndroid Build Coastguard Worker }
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsFloatArray()287*795d594fSAndroid Build Coastguard Worker inline ObjPtr<FloatArray> Object::AsFloatArray() {
288*795d594fSAndroid Build Coastguard Worker   DCHECK(IsFloatArray<kVerifyFlags>());
289*795d594fSAndroid Build Coastguard Worker   return ObjPtr<FloatArray>::DownCast(this);
290*795d594fSAndroid Build Coastguard Worker }
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsDoubleArray()293*795d594fSAndroid Build Coastguard Worker inline bool Object::IsDoubleArray() {
294*795d594fSAndroid Build Coastguard Worker   return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimDouble>();
295*795d594fSAndroid Build Coastguard Worker }
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsDoubleArray()298*795d594fSAndroid Build Coastguard Worker inline ObjPtr<DoubleArray> Object::AsDoubleArray() {
299*795d594fSAndroid Build Coastguard Worker   DCHECK(IsDoubleArray<kVerifyFlags>());
300*795d594fSAndroid Build Coastguard Worker   return ObjPtr<DoubleArray>::DownCast(this);
301*795d594fSAndroid Build Coastguard Worker }
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsString()304*795d594fSAndroid Build Coastguard Worker inline bool Object::IsString() {
305*795d594fSAndroid Build Coastguard Worker   // No read barrier is needed for reading a constant primitive field through
306*795d594fSAndroid Build Coastguard Worker   // constant reference field. See ReadBarrierOption.
307*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags, kWithoutReadBarrier>()->IsStringClass();
308*795d594fSAndroid Build Coastguard Worker }
309*795d594fSAndroid Build Coastguard Worker 
310*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsString()311*795d594fSAndroid Build Coastguard Worker inline ObjPtr<String> Object::AsString() {
312*795d594fSAndroid Build Coastguard Worker   DCHECK((IsString<kVerifyFlags>()));
313*795d594fSAndroid Build Coastguard Worker   return ObjPtr<String>::DownCast(this);
314*795d594fSAndroid Build Coastguard Worker }
315*795d594fSAndroid Build Coastguard Worker 
316*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsThrowable()317*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Throwable> Object::AsThrowable() {
318*795d594fSAndroid Build Coastguard Worker   DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
319*795d594fSAndroid Build Coastguard Worker   return ObjPtr<Throwable>::DownCast(this);
320*795d594fSAndroid Build Coastguard Worker }
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsWeakReferenceInstance()323*795d594fSAndroid Build Coastguard Worker inline bool Object::IsWeakReferenceInstance() {
324*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker 
327*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsSoftReferenceInstance()328*795d594fSAndroid Build Coastguard Worker inline bool Object::IsSoftReferenceInstance() {
329*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
330*795d594fSAndroid Build Coastguard Worker }
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsFinalizerReferenceInstance()333*795d594fSAndroid Build Coastguard Worker inline bool Object::IsFinalizerReferenceInstance() {
334*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
335*795d594fSAndroid Build Coastguard Worker }
336*795d594fSAndroid Build Coastguard Worker 
337*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
AsFinalizerReference()338*795d594fSAndroid Build Coastguard Worker inline ObjPtr<FinalizerReference> Object::AsFinalizerReference() {
339*795d594fSAndroid Build Coastguard Worker   DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
340*795d594fSAndroid Build Coastguard Worker   return ObjPtr<FinalizerReference>::DownCast(this);
341*795d594fSAndroid Build Coastguard Worker }
342*795d594fSAndroid Build Coastguard Worker 
343*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
IsPhantomReferenceInstance()344*795d594fSAndroid Build Coastguard Worker inline bool Object::IsPhantomReferenceInstance() {
345*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker // TODO: optimize this by using class_flags_ to determine type
349*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
SizeOf()350*795d594fSAndroid Build Coastguard Worker inline size_t Object::SizeOf() {
351*795d594fSAndroid Build Coastguard Worker   // Read barrier is never required for SizeOf since objects sizes are constant. Reading from-space
352*795d594fSAndroid Build Coastguard Worker   // values is OK because of that.
353*795d594fSAndroid Build Coastguard Worker   size_t result;
354*795d594fSAndroid Build Coastguard Worker   constexpr VerifyObjectFlags kNewFlags = RemoveThisFlags(kVerifyFlags);
355*795d594fSAndroid Build Coastguard Worker   if (IsArrayInstance<kVerifyFlags>()) {
356*795d594fSAndroid Build Coastguard Worker     result = AsArray<kNewFlags>()->template SizeOf<kNewFlags>();
357*795d594fSAndroid Build Coastguard Worker   } else if (IsClass<kNewFlags>()) {
358*795d594fSAndroid Build Coastguard Worker     result = AsClass<kNewFlags>()->template SizeOf<kNewFlags>();
359*795d594fSAndroid Build Coastguard Worker   } else if (IsString<kNewFlags>()) {
360*795d594fSAndroid Build Coastguard Worker     result = AsString<kNewFlags>()->template SizeOf<kNewFlags>();
361*795d594fSAndroid Build Coastguard Worker   } else {
362*795d594fSAndroid Build Coastguard Worker     result = GetClass<kNewFlags, kWithoutReadBarrier>()->template GetObjectSize<kNewFlags>();
363*795d594fSAndroid Build Coastguard Worker   }
364*795d594fSAndroid Build Coastguard Worker   DCHECK_GE(result, sizeof(Object)) << " class="
365*795d594fSAndroid Build Coastguard Worker       // Note: Class::PrettyClass() is reading constant reference fields to get to constant
366*795d594fSAndroid Build Coastguard Worker       // primitive fields and safely avoids read barriers, so it is safe to call on a Class
367*795d594fSAndroid Build Coastguard Worker       // reference read without read barrier from a constant reference field.
368*795d594fSAndroid Build Coastguard Worker       // See ReadBarrierOption. And, for correctness, we actually have to avoid the read
369*795d594fSAndroid Build Coastguard Worker       // barrier here if Object::SizeOf() is called on a from-space reference.
370*795d594fSAndroid Build Coastguard Worker       << GetClass<kNewFlags, kWithoutReadBarrier>()->PrettyClass();
371*795d594fSAndroid Build Coastguard Worker   return result;
372*795d594fSAndroid Build Coastguard Worker }
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldByte(MemberOffset field_offset)375*795d594fSAndroid Build Coastguard Worker inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
376*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
377*795d594fSAndroid Build Coastguard Worker   return GetFieldPrimitive<int8_t, kIsVolatile>(field_offset);
378*795d594fSAndroid Build Coastguard Worker }
379*795d594fSAndroid Build Coastguard Worker 
380*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
GetFieldBooleanVolatile(MemberOffset field_offset)381*795d594fSAndroid Build Coastguard Worker inline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
382*795d594fSAndroid Build Coastguard Worker   return GetFieldBoolean<kVerifyFlags, true>(field_offset);
383*795d594fSAndroid Build Coastguard Worker }
384*795d594fSAndroid Build Coastguard Worker 
385*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
GetFieldByteVolatile(MemberOffset field_offset)386*795d594fSAndroid Build Coastguard Worker inline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
387*795d594fSAndroid Build Coastguard Worker   return GetFieldByte<kVerifyFlags, true>(field_offset);
388*795d594fSAndroid Build Coastguard Worker }
389*795d594fSAndroid Build Coastguard Worker 
390*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
391*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
392*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
393*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldBoolean(MemberOffset field_offset,uint8_t new_value)394*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value) {
395*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
396*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
397*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldBoolean(
398*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
399*795d594fSAndroid Build Coastguard Worker   }
400*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
401*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<uint8_t, kIsVolatile>(field_offset, new_value);
402*795d594fSAndroid Build Coastguard Worker }
403*795d594fSAndroid Build Coastguard Worker 
404*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
405*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
406*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
407*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldByte(MemberOffset field_offset,int8_t new_value)408*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value) {
409*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
410*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
411*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldByte(
412*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
413*795d594fSAndroid Build Coastguard Worker   }
414*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
415*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<int8_t, kIsVolatile>(field_offset, new_value);
416*795d594fSAndroid Build Coastguard Worker }
417*795d594fSAndroid Build Coastguard Worker 
418*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldBooleanVolatile(MemberOffset field_offset,uint8_t new_value)419*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
420*795d594fSAndroid Build Coastguard Worker   return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
421*795d594fSAndroid Build Coastguard Worker       field_offset, new_value);
422*795d594fSAndroid Build Coastguard Worker }
423*795d594fSAndroid Build Coastguard Worker 
424*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldByteVolatile(MemberOffset field_offset,int8_t new_value)425*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
426*795d594fSAndroid Build Coastguard Worker   return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
427*795d594fSAndroid Build Coastguard Worker       field_offset, new_value);
428*795d594fSAndroid Build Coastguard Worker }
429*795d594fSAndroid Build Coastguard Worker 
430*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldChar(MemberOffset field_offset)431*795d594fSAndroid Build Coastguard Worker inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
432*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
433*795d594fSAndroid Build Coastguard Worker   return GetFieldPrimitive<uint16_t, kIsVolatile>(field_offset);
434*795d594fSAndroid Build Coastguard Worker }
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldShort(MemberOffset field_offset)437*795d594fSAndroid Build Coastguard Worker inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
438*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
439*795d594fSAndroid Build Coastguard Worker   return GetFieldPrimitive<int16_t, kIsVolatile>(field_offset);
440*795d594fSAndroid Build Coastguard Worker }
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
GetFieldCharVolatile(MemberOffset field_offset)443*795d594fSAndroid Build Coastguard Worker inline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
444*795d594fSAndroid Build Coastguard Worker   return GetFieldChar<kVerifyFlags, true>(field_offset);
445*795d594fSAndroid Build Coastguard Worker }
446*795d594fSAndroid Build Coastguard Worker 
447*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags>
GetFieldShortVolatile(MemberOffset field_offset)448*795d594fSAndroid Build Coastguard Worker inline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
449*795d594fSAndroid Build Coastguard Worker   return GetFieldShort<kVerifyFlags, true>(field_offset);
450*795d594fSAndroid Build Coastguard Worker }
451*795d594fSAndroid Build Coastguard Worker 
452*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
453*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
454*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
455*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldChar(MemberOffset field_offset,uint16_t new_value)456*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
457*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
458*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
459*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldChar(
460*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
461*795d594fSAndroid Build Coastguard Worker   }
462*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
463*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<uint16_t, kIsVolatile>(field_offset, new_value);
464*795d594fSAndroid Build Coastguard Worker }
465*795d594fSAndroid Build Coastguard Worker 
466*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
467*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
468*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
469*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldShort(MemberOffset field_offset,int16_t new_value)470*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
471*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
472*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
473*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldChar(
474*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
475*795d594fSAndroid Build Coastguard Worker   }
476*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
477*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<int16_t, kIsVolatile>(field_offset, new_value);
478*795d594fSAndroid Build Coastguard Worker }
479*795d594fSAndroid Build Coastguard Worker 
480*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldCharVolatile(MemberOffset field_offset,uint16_t new_value)481*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
482*795d594fSAndroid Build Coastguard Worker   return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
483*795d594fSAndroid Build Coastguard Worker       field_offset, new_value);
484*795d594fSAndroid Build Coastguard Worker }
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldShortVolatile(MemberOffset field_offset,int16_t new_value)487*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
488*795d594fSAndroid Build Coastguard Worker   return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
489*795d594fSAndroid Build Coastguard Worker       field_offset, new_value);
490*795d594fSAndroid Build Coastguard Worker }
491*795d594fSAndroid Build Coastguard Worker 
492*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
493*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
494*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
495*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetField32(MemberOffset field_offset,int32_t new_value)496*795d594fSAndroid Build Coastguard Worker inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
497*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
498*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
499*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField32(
500*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetField32<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
501*795d594fSAndroid Build Coastguard Worker   }
502*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
503*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<int32_t, kIsVolatile>(field_offset, new_value);
504*795d594fSAndroid Build Coastguard Worker }
505*795d594fSAndroid Build Coastguard Worker 
506*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetField32Volatile(MemberOffset field_offset,int32_t new_value)507*795d594fSAndroid Build Coastguard Worker inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
508*795d594fSAndroid Build Coastguard Worker   SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
509*795d594fSAndroid Build Coastguard Worker }
510*795d594fSAndroid Build Coastguard Worker 
511*795d594fSAndroid Build Coastguard Worker template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
SetField32Transaction(MemberOffset field_offset,int32_t new_value)512*795d594fSAndroid Build Coastguard Worker inline void Object::SetField32Transaction(MemberOffset field_offset, int32_t new_value) {
513*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsActiveTransaction()) {
514*795d594fSAndroid Build Coastguard Worker     SetField32<true, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
515*795d594fSAndroid Build Coastguard Worker   } else {
516*795d594fSAndroid Build Coastguard Worker     SetField32<false, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
517*795d594fSAndroid Build Coastguard Worker   }
518*795d594fSAndroid Build Coastguard Worker }
519*795d594fSAndroid Build Coastguard Worker 
520*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
521*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
522*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
523*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetField64(MemberOffset field_offset,int64_t new_value)524*795d594fSAndroid Build Coastguard Worker inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
525*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
526*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
527*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField64(
528*795d594fSAndroid Build Coastguard Worker         this, field_offset, GetField64<kVerifyFlags, kIsVolatile>(field_offset), kIsVolatile);
529*795d594fSAndroid Build Coastguard Worker   }
530*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
531*795d594fSAndroid Build Coastguard Worker   SetFieldPrimitive<int64_t, kIsVolatile>(field_offset, new_value);
532*795d594fSAndroid Build Coastguard Worker }
533*795d594fSAndroid Build Coastguard Worker 
534*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetField64Volatile(MemberOffset field_offset,int64_t new_value)535*795d594fSAndroid Build Coastguard Worker inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
536*795d594fSAndroid Build Coastguard Worker   return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
537*795d594fSAndroid Build Coastguard Worker                                                                                new_value);
538*795d594fSAndroid Build Coastguard Worker }
539*795d594fSAndroid Build Coastguard Worker 
540*795d594fSAndroid Build Coastguard Worker template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
SetField64Transaction(MemberOffset field_offset,int32_t new_value)541*795d594fSAndroid Build Coastguard Worker inline void Object::SetField64Transaction(MemberOffset field_offset, int32_t new_value) {
542*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsActiveTransaction()) {
543*795d594fSAndroid Build Coastguard Worker     SetField64<true, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
544*795d594fSAndroid Build Coastguard Worker   } else {
545*795d594fSAndroid Build Coastguard Worker     SetField64<false, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
546*795d594fSAndroid Build Coastguard Worker   }
547*795d594fSAndroid Build Coastguard Worker }
548*795d594fSAndroid Build Coastguard Worker 
549*795d594fSAndroid Build Coastguard Worker template<typename kSize>
GetFieldAcquire(MemberOffset field_offset)550*795d594fSAndroid Build Coastguard Worker inline kSize Object::GetFieldAcquire(MemberOffset field_offset) {
551*795d594fSAndroid Build Coastguard Worker   const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
552*795d594fSAndroid Build Coastguard Worker   const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
553*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<const Atomic<kSize>*>(addr)->load(std::memory_order_acquire);
554*795d594fSAndroid Build Coastguard Worker }
555*795d594fSAndroid Build Coastguard Worker 
556*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,int64_t old_value,int64_t new_value)557*795d594fSAndroid Build Coastguard Worker inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
558*795d594fSAndroid Build Coastguard Worker                                                          int64_t old_value,
559*795d594fSAndroid Build Coastguard Worker                                                          int64_t new_value) {
560*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
561*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
562*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
563*795d594fSAndroid Build Coastguard Worker   Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
564*795d594fSAndroid Build Coastguard Worker   bool success = atomic_addr->CompareAndSetWeakSequentiallyConsistent(old_value, new_value);
565*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive && success) {
566*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField64(
567*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, /*is_volatile=*/ true);
568*795d594fSAndroid Build Coastguard Worker   }
569*795d594fSAndroid Build Coastguard Worker   return success;
570*795d594fSAndroid Build Coastguard Worker }
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,int64_t old_value,int64_t new_value)573*795d594fSAndroid Build Coastguard Worker inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
574*795d594fSAndroid Build Coastguard Worker                                                            int64_t old_value,
575*795d594fSAndroid Build Coastguard Worker                                                            int64_t new_value) {
576*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
577*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
578*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
579*795d594fSAndroid Build Coastguard Worker   Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
580*795d594fSAndroid Build Coastguard Worker   bool success = atomic_addr->CompareAndSetStrongSequentiallyConsistent(old_value, new_value);
581*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive && success) {
582*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField64(
583*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, /*is_volatile=*/ true);
584*795d594fSAndroid Build Coastguard Worker   }
585*795d594fSAndroid Build Coastguard Worker   return success;
586*795d594fSAndroid Build Coastguard Worker }
587*795d594fSAndroid Build Coastguard Worker 
588*795d594fSAndroid Build Coastguard Worker template <bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CaeFieldStrongSequentiallyConsistent64(MemberOffset field_offset,int64_t old_value,int64_t new_value)589*795d594fSAndroid Build Coastguard Worker inline int64_t Object::CaeFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
590*795d594fSAndroid Build Coastguard Worker                                                               int64_t old_value,
591*795d594fSAndroid Build Coastguard Worker                                                               int64_t new_value) {
592*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
593*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
594*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
595*795d594fSAndroid Build Coastguard Worker   Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
596*795d594fSAndroid Build Coastguard Worker   int64_t found_value =
597*795d594fSAndroid Build Coastguard Worker       atomic_addr->CompareAndExchangeStrongSequentiallyConsistent(old_value, new_value);
598*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive && found_value == old_value) {
599*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField64(
600*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, /*is_volatile=*/true);
601*795d594fSAndroid Build Coastguard Worker   }
602*795d594fSAndroid Build Coastguard Worker   return found_value;
603*795d594fSAndroid Build Coastguard Worker }
604*795d594fSAndroid Build Coastguard Worker 
605*795d594fSAndroid Build Coastguard Worker /*
606*795d594fSAndroid Build Coastguard Worker  * Returns a pointer to an object representing what the field points to, not an
607*795d594fSAndroid Build Coastguard Worker  * object representing the field.
608*795d594fSAndroid Build Coastguard Worker  */
609*795d594fSAndroid Build Coastguard Worker template<class T,
610*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
611*795d594fSAndroid Build Coastguard Worker          ReadBarrierOption kReadBarrierOption,
612*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
GetFieldObject(MemberOffset field_offset)613*795d594fSAndroid Build Coastguard Worker inline T* Object::GetFieldObject(MemberOffset field_offset) {
614*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
615*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
616*795d594fSAndroid Build Coastguard Worker   HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
617*795d594fSAndroid Build Coastguard Worker   T* result = ReadBarrier::Barrier<T, kIsVolatile, kReadBarrierOption>(
618*795d594fSAndroid Build Coastguard Worker       this,
619*795d594fSAndroid Build Coastguard Worker       field_offset,
620*795d594fSAndroid Build Coastguard Worker       objref_addr);
621*795d594fSAndroid Build Coastguard Worker   VerifyRead<kVerifyFlags>(result);
622*795d594fSAndroid Build Coastguard Worker   return result;
623*795d594fSAndroid Build Coastguard Worker }
624*795d594fSAndroid Build Coastguard Worker 
625*795d594fSAndroid Build Coastguard Worker template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetFieldObjectVolatile(MemberOffset field_offset)626*795d594fSAndroid Build Coastguard Worker inline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
627*795d594fSAndroid Build Coastguard Worker   return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
628*795d594fSAndroid Build Coastguard Worker }
629*795d594fSAndroid Build Coastguard Worker 
630*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
631*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
632*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
633*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,ObjPtr<Object> new_value)634*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
635*795d594fSAndroid Build Coastguard Worker                                                       ObjPtr<Object> new_value) {
636*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
637*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
638*795d594fSAndroid Build Coastguard Worker     ObjPtr<Object> old_value =
639*795d594fSAndroid Build Coastguard Worker         GetFieldObject<Object, kVerifyFlags, kWithReadBarrier, kIsVolatile>(field_offset);
640*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldReference(
641*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
642*795d594fSAndroid Build Coastguard Worker   }
643*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
644*795d594fSAndroid Build Coastguard Worker   VerifyWrite<kVerifyFlags>(new_value);
645*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
646*795d594fSAndroid Build Coastguard Worker   HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
647*795d594fSAndroid Build Coastguard Worker   objref_addr->Assign<kIsVolatile>(new_value.Ptr());
648*795d594fSAndroid Build Coastguard Worker }
649*795d594fSAndroid Build Coastguard Worker 
650*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive,
651*795d594fSAndroid Build Coastguard Worker          bool kCheckTransaction,
652*795d594fSAndroid Build Coastguard Worker          VerifyObjectFlags kVerifyFlags,
653*795d594fSAndroid Build Coastguard Worker          bool kIsVolatile>
SetFieldObject(MemberOffset field_offset,ObjPtr<Object> new_value)654*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldObject(MemberOffset field_offset, ObjPtr<Object> new_value) {
655*795d594fSAndroid Build Coastguard Worker   SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
656*795d594fSAndroid Build Coastguard Worker       kIsVolatile>(field_offset, new_value);
657*795d594fSAndroid Build Coastguard Worker   if (new_value != nullptr) {
658*795d594fSAndroid Build Coastguard Worker     WriteBarrier::ForFieldWrite<WriteBarrier::kWithoutNullCheck>(this, field_offset, new_value);
659*795d594fSAndroid Build Coastguard Worker     // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
660*795d594fSAndroid Build Coastguard Worker     CheckFieldAssignment(field_offset, new_value);
661*795d594fSAndroid Build Coastguard Worker   }
662*795d594fSAndroid Build Coastguard Worker }
663*795d594fSAndroid Build Coastguard Worker 
664*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldObjectVolatile(MemberOffset field_offset,ObjPtr<Object> new_value)665*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldObjectVolatile(MemberOffset field_offset, ObjPtr<Object> new_value) {
666*795d594fSAndroid Build Coastguard Worker   SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
667*795d594fSAndroid Build Coastguard Worker                                                                             new_value);
668*795d594fSAndroid Build Coastguard Worker }
669*795d594fSAndroid Build Coastguard Worker 
670*795d594fSAndroid Build Coastguard Worker template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
SetFieldObjectTransaction(MemberOffset field_offset,ObjPtr<Object> new_value)671*795d594fSAndroid Build Coastguard Worker inline void Object::SetFieldObjectTransaction(MemberOffset field_offset, ObjPtr<Object> new_value) {
672*795d594fSAndroid Build Coastguard Worker   if (Runtime::Current()->IsActiveTransaction()) {
673*795d594fSAndroid Build Coastguard Worker     SetFieldObject<true, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
674*795d594fSAndroid Build Coastguard Worker   } else {
675*795d594fSAndroid Build Coastguard Worker     SetFieldObject<false, kCheckTransaction, kVerifyFlags, kIsVolatile>(field_offset, new_value);
676*795d594fSAndroid Build Coastguard Worker   }
677*795d594fSAndroid Build Coastguard Worker }
678*795d594fSAndroid Build Coastguard Worker 
679*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags>
GetFieldObjectReferenceAddr(MemberOffset field_offset)680*795d594fSAndroid Build Coastguard Worker inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
681*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
682*795d594fSAndroid Build Coastguard Worker   return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
683*795d594fSAndroid Build Coastguard Worker       field_offset.Int32Value());
684*795d594fSAndroid Build Coastguard Worker }
685*795d594fSAndroid Build Coastguard Worker 
686*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,ObjPtr<Object> old_value,ObjPtr<Object> new_value,CASMode mode,std::memory_order memory_order)687*795d594fSAndroid Build Coastguard Worker inline bool Object::CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
688*795d594fSAndroid Build Coastguard Worker                                                       ObjPtr<Object> old_value,
689*795d594fSAndroid Build Coastguard Worker                                                       ObjPtr<Object> new_value,
690*795d594fSAndroid Build Coastguard Worker                                                       CASMode mode,
691*795d594fSAndroid Build Coastguard Worker                                                       std::memory_order memory_order) {
692*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
693*795d594fSAndroid Build Coastguard Worker   VerifyCAS<kVerifyFlags>(new_value, old_value);
694*795d594fSAndroid Build Coastguard Worker   uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
695*795d594fSAndroid Build Coastguard Worker   uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
696*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
697*795d594fSAndroid Build Coastguard Worker   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
698*795d594fSAndroid Build Coastguard Worker   bool success = atomic_addr->CompareAndSet(old_ref, new_ref, mode, memory_order);
699*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive && success) {
700*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldReference(
701*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, /*is_volatile=*/ true);
702*795d594fSAndroid Build Coastguard Worker   }
703*795d594fSAndroid Build Coastguard Worker   return success;
704*795d594fSAndroid Build Coastguard Worker }
705*795d594fSAndroid Build Coastguard Worker 
706*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldObject(MemberOffset field_offset,ObjPtr<Object> old_value,ObjPtr<Object> new_value,CASMode mode,std::memory_order memory_order)707*795d594fSAndroid Build Coastguard Worker inline bool Object::CasFieldObject(MemberOffset field_offset,
708*795d594fSAndroid Build Coastguard Worker                                    ObjPtr<Object> old_value,
709*795d594fSAndroid Build Coastguard Worker                                    ObjPtr<Object> new_value,
710*795d594fSAndroid Build Coastguard Worker                                    CASMode mode,
711*795d594fSAndroid Build Coastguard Worker                                    std::memory_order memory_order) {
712*795d594fSAndroid Build Coastguard Worker   bool success = CasFieldObjectWithoutWriteBarrier<
713*795d594fSAndroid Build Coastguard Worker       kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset,
714*795d594fSAndroid Build Coastguard Worker                                                            old_value,
715*795d594fSAndroid Build Coastguard Worker                                                            new_value,
716*795d594fSAndroid Build Coastguard Worker                                                            mode,
717*795d594fSAndroid Build Coastguard Worker                                                            memory_order);
718*795d594fSAndroid Build Coastguard Worker   if (success) {
719*795d594fSAndroid Build Coastguard Worker     WriteBarrier::ForFieldWrite(this, field_offset, new_value);
720*795d594fSAndroid Build Coastguard Worker   }
721*795d594fSAndroid Build Coastguard Worker   return success;
722*795d594fSAndroid Build Coastguard Worker }
723*795d594fSAndroid Build Coastguard Worker 
724*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CompareAndExchangeFieldObject(MemberOffset field_offset,ObjPtr<Object> old_value,ObjPtr<Object> new_value)725*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> Object::CompareAndExchangeFieldObject(MemberOffset field_offset,
726*795d594fSAndroid Build Coastguard Worker                                                             ObjPtr<Object> old_value,
727*795d594fSAndroid Build Coastguard Worker                                                             ObjPtr<Object> new_value) {
728*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
729*795d594fSAndroid Build Coastguard Worker   VerifyCAS<kVerifyFlags>(new_value, old_value);
730*795d594fSAndroid Build Coastguard Worker   uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
731*795d594fSAndroid Build Coastguard Worker   uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
732*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
733*795d594fSAndroid Build Coastguard Worker   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
734*795d594fSAndroid Build Coastguard Worker   bool success = atomic_addr->compare_exchange_strong(old_ref, new_ref, std::memory_order_seq_cst);
735*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> witness_value(PtrCompression<kPoisonHeapReferences, Object>::Decompress(old_ref));
736*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
737*795d594fSAndroid Build Coastguard Worker     // Ensure caller has done read barrier on the reference field so it's in the to-space.
738*795d594fSAndroid Build Coastguard Worker     ReadBarrier::AssertToSpaceInvariant(witness_value.Ptr());
739*795d594fSAndroid Build Coastguard Worker   }
740*795d594fSAndroid Build Coastguard Worker   if (success) {
741*795d594fSAndroid Build Coastguard Worker     if (kTransactionActive) {
742*795d594fSAndroid Build Coastguard Worker       Runtime::Current()->GetClassLinker()->RecordWriteFieldReference(
743*795d594fSAndroid Build Coastguard Worker           this, field_offset, witness_value, /*is_volatile=*/ true);
744*795d594fSAndroid Build Coastguard Worker     }
745*795d594fSAndroid Build Coastguard Worker     WriteBarrier::ForFieldWrite(this, field_offset, new_value);
746*795d594fSAndroid Build Coastguard Worker   }
747*795d594fSAndroid Build Coastguard Worker   VerifyRead<kVerifyFlags>(witness_value);
748*795d594fSAndroid Build Coastguard Worker   return witness_value;
749*795d594fSAndroid Build Coastguard Worker }
750*795d594fSAndroid Build Coastguard Worker 
751*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
ExchangeFieldObject(MemberOffset field_offset,ObjPtr<Object> new_value)752*795d594fSAndroid Build Coastguard Worker inline ObjPtr<Object> Object::ExchangeFieldObject(MemberOffset field_offset,
753*795d594fSAndroid Build Coastguard Worker                                                   ObjPtr<Object> new_value) {
754*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
755*795d594fSAndroid Build Coastguard Worker   VerifyCAS<kVerifyFlags>(new_value, /*old_value=*/ nullptr);
756*795d594fSAndroid Build Coastguard Worker 
757*795d594fSAndroid Build Coastguard Worker   uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
758*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
759*795d594fSAndroid Build Coastguard Worker   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
760*795d594fSAndroid Build Coastguard Worker   uint32_t old_ref = atomic_addr->exchange(new_ref, std::memory_order_seq_cst);
761*795d594fSAndroid Build Coastguard Worker   ObjPtr<Object> old_value(PtrCompression<kPoisonHeapReferences, Object>::Decompress(old_ref));
762*795d594fSAndroid Build Coastguard Worker   if (kIsDebugBuild) {
763*795d594fSAndroid Build Coastguard Worker     // Ensure caller has done read barrier on the reference field so it's in the to-space.
764*795d594fSAndroid Build Coastguard Worker     ReadBarrier::AssertToSpaceInvariant(old_value.Ptr());
765*795d594fSAndroid Build Coastguard Worker   }
766*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
767*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldReference(
768*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, /*is_volatile=*/ true);
769*795d594fSAndroid Build Coastguard Worker   }
770*795d594fSAndroid Build Coastguard Worker   WriteBarrier::ForFieldWrite(this, field_offset, new_value);
771*795d594fSAndroid Build Coastguard Worker   VerifyRead<kVerifyFlags>(old_value);
772*795d594fSAndroid Build Coastguard Worker   return old_value;
773*795d594fSAndroid Build Coastguard Worker }
774*795d594fSAndroid Build Coastguard Worker 
775*795d594fSAndroid Build Coastguard Worker template<typename T, VerifyObjectFlags kVerifyFlags>
GetPrimitiveFieldViaAccessor(MemberOffset field_offset,Accessor<T> * accessor)776*795d594fSAndroid Build Coastguard Worker inline void Object::GetPrimitiveFieldViaAccessor(MemberOffset field_offset, Accessor<T>* accessor) {
777*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
778*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
779*795d594fSAndroid Build Coastguard Worker   T* addr = reinterpret_cast<T*>(raw_addr);
780*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
781*795d594fSAndroid Build Coastguard Worker }
782*795d594fSAndroid Build Coastguard Worker 
783*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateFieldBooleanViaAccessor(MemberOffset field_offset,Accessor<uint8_t> * accessor)784*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateFieldBooleanViaAccessor(MemberOffset field_offset,
785*795d594fSAndroid Build Coastguard Worker                                                   Accessor<uint8_t>* accessor) {
786*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
787*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
788*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
789*795d594fSAndroid Build Coastguard Worker     uint8_t old_value = GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset);
790*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldBoolean(
791*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
792*795d594fSAndroid Build Coastguard Worker   }
793*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
794*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
795*795d594fSAndroid Build Coastguard Worker   uint8_t* addr = raw_addr;
796*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
797*795d594fSAndroid Build Coastguard Worker }
798*795d594fSAndroid Build Coastguard Worker 
799*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateFieldByteViaAccessor(MemberOffset field_offset,Accessor<int8_t> * accessor)800*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateFieldByteViaAccessor(MemberOffset field_offset,
801*795d594fSAndroid Build Coastguard Worker                                                Accessor<int8_t>* accessor) {
802*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
803*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
804*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
805*795d594fSAndroid Build Coastguard Worker     int8_t old_value = GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset);
806*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldByte(
807*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
808*795d594fSAndroid Build Coastguard Worker   }
809*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
810*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
811*795d594fSAndroid Build Coastguard Worker   int8_t* addr = reinterpret_cast<int8_t*>(raw_addr);
812*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
813*795d594fSAndroid Build Coastguard Worker }
814*795d594fSAndroid Build Coastguard Worker 
815*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateFieldCharViaAccessor(MemberOffset field_offset,Accessor<uint16_t> * accessor)816*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateFieldCharViaAccessor(MemberOffset field_offset,
817*795d594fSAndroid Build Coastguard Worker                                                Accessor<uint16_t>* accessor) {
818*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
819*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
820*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
821*795d594fSAndroid Build Coastguard Worker     uint16_t old_value = GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset);
822*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldChar(
823*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
824*795d594fSAndroid Build Coastguard Worker   }
825*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
826*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
827*795d594fSAndroid Build Coastguard Worker   uint16_t* addr = reinterpret_cast<uint16_t*>(raw_addr);
828*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
829*795d594fSAndroid Build Coastguard Worker }
830*795d594fSAndroid Build Coastguard Worker 
831*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateFieldShortViaAccessor(MemberOffset field_offset,Accessor<int16_t> * accessor)832*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateFieldShortViaAccessor(MemberOffset field_offset,
833*795d594fSAndroid Build Coastguard Worker                                                 Accessor<int16_t>* accessor) {
834*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
835*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
836*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
837*795d594fSAndroid Build Coastguard Worker     int16_t old_value = GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset);
838*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteFieldShort(
839*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
840*795d594fSAndroid Build Coastguard Worker   }
841*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
842*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
843*795d594fSAndroid Build Coastguard Worker   int16_t* addr = reinterpret_cast<int16_t*>(raw_addr);
844*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
845*795d594fSAndroid Build Coastguard Worker }
846*795d594fSAndroid Build Coastguard Worker 
847*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateField32ViaAccessor(MemberOffset field_offset,Accessor<int32_t> * accessor)848*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateField32ViaAccessor(MemberOffset field_offset,
849*795d594fSAndroid Build Coastguard Worker                                              Accessor<int32_t>* accessor) {
850*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
851*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
852*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
853*795d594fSAndroid Build Coastguard Worker     int32_t old_value = GetField32<kVerifyFlags, kIsVolatile>(field_offset);
854*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField32(
855*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
856*795d594fSAndroid Build Coastguard Worker   }
857*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
858*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
859*795d594fSAndroid Build Coastguard Worker   int32_t* addr = reinterpret_cast<int32_t*>(raw_addr);
860*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
861*795d594fSAndroid Build Coastguard Worker }
862*795d594fSAndroid Build Coastguard Worker 
863*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
UpdateField64ViaAccessor(MemberOffset field_offset,Accessor<int64_t> * accessor)864*795d594fSAndroid Build Coastguard Worker inline void Object::UpdateField64ViaAccessor(MemberOffset field_offset,
865*795d594fSAndroid Build Coastguard Worker                                              Accessor<int64_t>* accessor) {
866*795d594fSAndroid Build Coastguard Worker   VerifyTransaction<kTransactionActive, kCheckTransaction>();
867*795d594fSAndroid Build Coastguard Worker   if (kTransactionActive) {
868*795d594fSAndroid Build Coastguard Worker     static const bool kIsVolatile = true;
869*795d594fSAndroid Build Coastguard Worker     int64_t old_value = GetField64<kVerifyFlags, kIsVolatile>(field_offset);
870*795d594fSAndroid Build Coastguard Worker     Runtime::Current()->GetClassLinker()->RecordWriteField64(
871*795d594fSAndroid Build Coastguard Worker         this, field_offset, old_value, kIsVolatile);
872*795d594fSAndroid Build Coastguard Worker   }
873*795d594fSAndroid Build Coastguard Worker   Verify<kVerifyFlags>();
874*795d594fSAndroid Build Coastguard Worker   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
875*795d594fSAndroid Build Coastguard Worker   int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
876*795d594fSAndroid Build Coastguard Worker   accessor->Access(addr);
877*795d594fSAndroid Build Coastguard Worker }
878*795d594fSAndroid Build Coastguard Worker 
879*795d594fSAndroid Build Coastguard Worker template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
VisitInstanceFieldsReferences(ObjPtr<Class> klass,const Visitor & visitor)880*795d594fSAndroid Build Coastguard Worker inline void Object::VisitInstanceFieldsReferences(ObjPtr<Class> klass, const Visitor& visitor) {
881*795d594fSAndroid Build Coastguard Worker   // Using NO_THREAD_SAFETY_ANALYSIS as heap_bitmap_lock_ and mutator_lock_ are
882*795d594fSAndroid Build Coastguard Worker   // required in shared/exclusive modes in all possible combinations.
883*795d594fSAndroid Build Coastguard Worker   auto visit_one_word = [&visitor, this](uint32_t field_offset, uint32_t ref_offsets)
884*795d594fSAndroid Build Coastguard Worker                             NO_THREAD_SAFETY_ANALYSIS {
885*795d594fSAndroid Build Coastguard Worker                               while (ref_offsets != 0) {
886*795d594fSAndroid Build Coastguard Worker                                 if ((ref_offsets & 1) != 0) {
887*795d594fSAndroid Build Coastguard Worker                                   visitor(this, MemberOffset(field_offset), /*is_static=*/false);
888*795d594fSAndroid Build Coastguard Worker                                 }
889*795d594fSAndroid Build Coastguard Worker                                 ref_offsets >>= 1;
890*795d594fSAndroid Build Coastguard Worker                                 field_offset += sizeof(HeapReference<Object>);
891*795d594fSAndroid Build Coastguard Worker                               }
892*795d594fSAndroid Build Coastguard Worker                             };
893*795d594fSAndroid Build Coastguard Worker 
894*795d594fSAndroid Build Coastguard Worker   uint32_t ref_offsets = klass->GetReferenceInstanceOffsets<kVerifyFlags>();
895*795d594fSAndroid Build Coastguard Worker   DCHECK_NE(ref_offsets, 0u) << klass->PrettyDescriptor();
896*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY((ref_offsets & Class::kVisitReferencesSlowpathMask) != 0)) {
897*795d594fSAndroid Build Coastguard Worker     if (kIsDebugBuild) {
898*795d594fSAndroid Build Coastguard Worker       klass->VerifyOverflowReferenceBitmap<kVerifyFlags, kReadBarrierOption>();
899*795d594fSAndroid Build Coastguard Worker     }
900*795d594fSAndroid Build Coastguard Worker     uint32_t bitmap_num_words = ref_offsets & ~Class::kVisitReferencesSlowpathMask;
901*795d594fSAndroid Build Coastguard Worker     uint32_t* overflow_bitmap = reinterpret_cast<uint32_t*>(
902*795d594fSAndroid Build Coastguard Worker         reinterpret_cast<uint8_t*>(klass.Ptr()) +
903*795d594fSAndroid Build Coastguard Worker         (klass->GetClassSize<kVerifyFlags>() - bitmap_num_words * sizeof(uint32_t)));
904*795d594fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < bitmap_num_words; i++) {
905*795d594fSAndroid Build Coastguard Worker       visit_one_word(kObjectHeaderSize + i * sizeof(HeapReference<Object>) * 32,
906*795d594fSAndroid Build Coastguard Worker                      overflow_bitmap[i]);
907*795d594fSAndroid Build Coastguard Worker     }
908*795d594fSAndroid Build Coastguard Worker   } else {
909*795d594fSAndroid Build Coastguard Worker     visit_one_word(mirror::kObjectHeaderSize, ref_offsets);
910*795d594fSAndroid Build Coastguard Worker   }
911*795d594fSAndroid Build Coastguard Worker }
912*795d594fSAndroid Build Coastguard Worker 
913*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsClassLoader()914*795d594fSAndroid Build Coastguard Worker inline bool Object::IsClassLoader() {
915*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags, kReadBarrierOption>()->template IsClassLoaderClass<kVerifyFlags>();
916*795d594fSAndroid Build Coastguard Worker }
917*795d594fSAndroid Build Coastguard Worker 
918*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsClassLoader()919*795d594fSAndroid Build Coastguard Worker inline ObjPtr<ClassLoader> Object::AsClassLoader() {
920*795d594fSAndroid Build Coastguard Worker   DCHECK((IsClassLoader<kVerifyFlags, kReadBarrierOption>()));
921*795d594fSAndroid Build Coastguard Worker   return ObjPtr<ClassLoader>::DownCast(this);
922*795d594fSAndroid Build Coastguard Worker }
923*795d594fSAndroid Build Coastguard Worker 
924*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsDexCache()925*795d594fSAndroid Build Coastguard Worker inline bool Object::IsDexCache() {
926*795d594fSAndroid Build Coastguard Worker   return GetClass<kVerifyFlags, kReadBarrierOption>()->template IsDexCacheClass<kVerifyFlags>();
927*795d594fSAndroid Build Coastguard Worker }
928*795d594fSAndroid Build Coastguard Worker 
929*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsDexCache()930*795d594fSAndroid Build Coastguard Worker inline ObjPtr<mirror::DexCache> Object::AsDexCache() {
931*795d594fSAndroid Build Coastguard Worker   DCHECK((IsDexCache<kVerifyFlags, kReadBarrierOption>()));
932*795d594fSAndroid Build Coastguard Worker   return ObjPtr<DexCache>::DownCast(this);
933*795d594fSAndroid Build Coastguard Worker }
934*795d594fSAndroid Build Coastguard Worker 
935*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction>
VerifyTransaction()936*795d594fSAndroid Build Coastguard Worker inline void Object::VerifyTransaction() {
937*795d594fSAndroid Build Coastguard Worker   if (kCheckTransaction) {
938*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
939*795d594fSAndroid Build Coastguard Worker   }
940*795d594fSAndroid Build Coastguard Worker }
941*795d594fSAndroid Build Coastguard Worker 
942*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
943*795d594fSAndroid Build Coastguard Worker }  // namespace art
944*795d594fSAndroid Build Coastguard Worker 
945*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
946