• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_MIRROR_OBJECT_INL_H_
18 #define ART_RUNTIME_MIRROR_OBJECT_INL_H_
19 
20 #include "object.h"
21 
22 #include "art_field.h"
23 #include "art_method.h"
24 #include "atomic.h"
25 #include "array-inl.h"
26 #include "class.h"
27 #include "class_flags.h"
28 #include "class_linker.h"
29 #include "class_loader-inl.h"
30 #include "dex_cache-inl.h"
31 #include "lock_word-inl.h"
32 #include "monitor.h"
33 #include "object_array-inl.h"
34 #include "read_barrier-inl.h"
35 #include "reference.h"
36 #include "runtime.h"
37 #include "string-inl.h"
38 #include "throwable.h"
39 
40 namespace art {
41 namespace mirror {
42 
ClassSize(size_t pointer_size)43 inline uint32_t Object::ClassSize(size_t pointer_size) {
44   uint32_t vtable_entries = kVTableLength;
45   return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size);
46 }
47 
48 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetClass()49 inline Class* Object::GetClass() {
50   return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
51       OFFSET_OF_OBJECT_MEMBER(Object, klass_));
52 }
53 
54 template<VerifyObjectFlags kVerifyFlags>
SetClass(Class * new_klass)55 inline void Object::SetClass(Class* new_klass) {
56   // new_klass may be null prior to class linker initialization.
57   // We don't mark the card as this occurs as part of object allocation. Not all objects have
58   // backing cards, such as large objects.
59   // We use non transactional version since we can't undo this write. We also disable checking as
60   // we may run in transaction mode here.
61   SetFieldObjectWithoutWriteBarrier<false, false,
62       static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
63       OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
64 }
65 
66 template<VerifyObjectFlags kVerifyFlags>
GetLockWord(bool as_volatile)67 inline LockWord Object::GetLockWord(bool as_volatile) {
68   if (as_volatile) {
69     return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
70   }
71   return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
72 }
73 
74 template<VerifyObjectFlags kVerifyFlags>
SetLockWord(LockWord new_val,bool as_volatile)75 inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
76   // Force use of non-transactional mode and do not check.
77   if (as_volatile) {
78     SetField32Volatile<false, false, kVerifyFlags>(
79         OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
80   } else {
81     SetField32<false, false, kVerifyFlags>(
82         OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
83   }
84 }
85 
CasLockWordWeakSequentiallyConsistent(LockWord old_val,LockWord new_val)86 inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
87   // Force use of non-transactional mode and do not check.
88   return CasFieldWeakSequentiallyConsistent32<false, false>(
89       OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
90 }
91 
CasLockWordWeakRelaxed(LockWord old_val,LockWord new_val)92 inline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
93   // Force use of non-transactional mode and do not check.
94   return CasFieldWeakRelaxed32<false, false>(
95       OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
96 }
97 
CasLockWordWeakRelease(LockWord old_val,LockWord new_val)98 inline bool Object::CasLockWordWeakRelease(LockWord old_val, LockWord new_val) {
99   // Force use of non-transactional mode and do not check.
100   return CasFieldWeakRelease32<false, false>(
101       OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
102 }
103 
GetLockOwnerThreadId()104 inline uint32_t Object::GetLockOwnerThreadId() {
105   return Monitor::GetLockOwnerThreadId(this);
106 }
107 
MonitorEnter(Thread * self)108 inline mirror::Object* Object::MonitorEnter(Thread* self) {
109   return Monitor::MonitorEnter(self, this);
110 }
111 
MonitorExit(Thread * self)112 inline bool Object::MonitorExit(Thread* self) {
113   return Monitor::MonitorExit(self, this);
114 }
115 
Notify(Thread * self)116 inline void Object::Notify(Thread* self) {
117   Monitor::Notify(self, this);
118 }
119 
NotifyAll(Thread * self)120 inline void Object::NotifyAll(Thread* self) {
121   Monitor::NotifyAll(self, this);
122 }
123 
Wait(Thread * self)124 inline void Object::Wait(Thread* self) {
125   Monitor::Wait(self, this, 0, 0, true, kWaiting);
126 }
127 
Wait(Thread * self,int64_t ms,int32_t ns)128 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
129   Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
130 }
131 
GetReadBarrierPointer()132 inline Object* Object::GetReadBarrierPointer() {
133 #ifdef USE_BAKER_READ_BARRIER
134   DCHECK(kUseBakerReadBarrier);
135   return reinterpret_cast<Object*>(GetLockWord(false).ReadBarrierState());
136 #elif USE_BROOKS_READ_BARRIER
137   DCHECK(kUseBrooksReadBarrier);
138   return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
139       OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
140 #else
141   LOG(FATAL) << "Unreachable";
142   UNREACHABLE();
143 #endif
144 }
145 
SetReadBarrierPointer(Object * rb_ptr)146 inline void Object::SetReadBarrierPointer(Object* rb_ptr) {
147 #ifdef USE_BAKER_READ_BARRIER
148   DCHECK(kUseBakerReadBarrier);
149   DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
150   LockWord lw = GetLockWord(false);
151   lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
152   SetLockWord(lw, false);
153 #elif USE_BROOKS_READ_BARRIER
154   DCHECK(kUseBrooksReadBarrier);
155   // We don't mark the card as this occurs as part of object allocation. Not all objects have
156   // backing cards, such as large objects.
157   SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
158       OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
159 #else
160   LOG(FATAL) << "Unreachable";
161   UNREACHABLE();
162   UNUSED(rb_ptr);
163 #endif
164 }
165 
166 template<bool kCasRelease>
AtomicSetReadBarrierPointer(Object * expected_rb_ptr,Object * rb_ptr)167 inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
168 #ifdef USE_BAKER_READ_BARRIER
169   DCHECK(kUseBakerReadBarrier);
170   DCHECK_EQ(reinterpret_cast<uint64_t>(expected_rb_ptr) >> 32, 0U);
171   DCHECK_EQ(reinterpret_cast<uint64_t>(rb_ptr) >> 32, 0U);
172   LockWord expected_lw;
173   LockWord new_lw;
174   do {
175     LockWord lw = GetLockWord(false);
176     if (UNLIKELY(reinterpret_cast<Object*>(lw.ReadBarrierState()) != expected_rb_ptr)) {
177       // Lost the race.
178       return false;
179     }
180     expected_lw = lw;
181     expected_lw.SetReadBarrierState(
182         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(expected_rb_ptr)));
183     new_lw = lw;
184     new_lw.SetReadBarrierState(static_cast<uint32_t>(reinterpret_cast<uintptr_t>(rb_ptr)));
185     // ConcurrentCopying::ProcessMarkStackRef uses this with kCasRelease == true.
186     // If kCasRelease == true, use a CAS release so that when GC updates all the fields of
187     // an object and then changes the object from gray to black, the field updates (stores) will be
188     // visible (won't be reordered after this CAS.)
189   } while (!(kCasRelease ?
190              CasLockWordWeakRelease(expected_lw, new_lw) :
191              CasLockWordWeakRelaxed(expected_lw, new_lw)));
192   return true;
193 #elif USE_BROOKS_READ_BARRIER
194   DCHECK(kUseBrooksReadBarrier);
195   MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
196   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + offset.SizeValue();
197   Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
198   HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
199   HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
200   do {
201     if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
202       // Lost the race.
203       return false;
204     }
205   } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
206                                                                      new_ref.reference_));
207   return true;
208 #else
209   UNUSED(expected_rb_ptr, rb_ptr);
210   LOG(FATAL) << "Unreachable";
211   UNREACHABLE();
212 #endif
213 }
214 
AssertReadBarrierPointer()215 inline void Object::AssertReadBarrierPointer() const {
216   if (kUseBakerReadBarrier) {
217     Object* obj = const_cast<Object*>(this);
218     DCHECK(obj->GetReadBarrierPointer() == nullptr)
219         << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
220         << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
221   } else {
222     CHECK(kUseBrooksReadBarrier);
223     Object* obj = const_cast<Object*>(this);
224     DCHECK_EQ(obj, obj->GetReadBarrierPointer())
225         << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
226         << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
227   }
228 }
229 
230 template<VerifyObjectFlags kVerifyFlags>
VerifierInstanceOf(Class * klass)231 inline bool Object::VerifierInstanceOf(Class* klass) {
232   DCHECK(klass != nullptr);
233   DCHECK(GetClass<kVerifyFlags>() != nullptr);
234   return klass->IsInterface() || InstanceOf(klass);
235 }
236 
237 template<VerifyObjectFlags kVerifyFlags>
InstanceOf(Class * klass)238 inline bool Object::InstanceOf(Class* klass) {
239   DCHECK(klass != nullptr);
240   DCHECK(GetClass<kVerifyNone>() != nullptr);
241   return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
242 }
243 
244 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsClass()245 inline bool Object::IsClass() {
246   Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
247       template GetClass<kVerifyFlags, kReadBarrierOption>();
248   return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
249       kReadBarrierOption>() == java_lang_Class;
250 }
251 
252 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsClass()253 inline Class* Object::AsClass() {
254   DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
255   return down_cast<Class*>(this);
256 }
257 
258 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsObjectArray()259 inline bool Object::IsObjectArray() {
260   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
261   return IsArrayInstance<kVerifyFlags, kReadBarrierOption>() &&
262       !GetClass<kNewFlags, kReadBarrierOption>()->
263           template GetComponentType<kNewFlags, kReadBarrierOption>()->IsPrimitive();
264 }
265 
266 template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsObjectArray()267 inline ObjectArray<T>* Object::AsObjectArray() {
268   DCHECK((IsObjectArray<kVerifyFlags, kReadBarrierOption>()));
269   return down_cast<ObjectArray<T>*>(this);
270 }
271 
272 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsArrayInstance()273 inline bool Object::IsArrayInstance() {
274   return GetClass<kVerifyFlags, kReadBarrierOption>()->
275       template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
276 }
277 
278 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsReferenceInstance()279 inline bool Object::IsReferenceInstance() {
280   return GetClass<kVerifyFlags, kReadBarrierOption>()->IsTypeOfReferenceClass();
281 }
282 
283 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsReference()284 inline Reference* Object::AsReference() {
285   DCHECK((IsReferenceInstance<kVerifyFlags, kReadBarrierOption>()));
286   return down_cast<Reference*>(this);
287 }
288 
289 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsArray()290 inline Array* Object::AsArray() {
291   DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
292   return down_cast<Array*>(this);
293 }
294 
295 template<VerifyObjectFlags kVerifyFlags>
AsBooleanArray()296 inline BooleanArray* Object::AsBooleanArray() {
297   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
298   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
299   DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
300   return down_cast<BooleanArray*>(this);
301 }
302 
303 template<VerifyObjectFlags kVerifyFlags>
AsByteArray()304 inline ByteArray* Object::AsByteArray() {
305   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
306   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
307   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
308   return down_cast<ByteArray*>(this);
309 }
310 
311 template<VerifyObjectFlags kVerifyFlags>
AsByteSizedArray()312 inline ByteArray* Object::AsByteSizedArray() {
313   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
314   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
315   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
316          GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
317   return down_cast<ByteArray*>(this);
318 }
319 
320 template<VerifyObjectFlags kVerifyFlags>
AsCharArray()321 inline CharArray* Object::AsCharArray() {
322   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
323   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
324   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
325   return down_cast<CharArray*>(this);
326 }
327 
328 template<VerifyObjectFlags kVerifyFlags>
AsShortArray()329 inline ShortArray* Object::AsShortArray() {
330   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
331   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
332   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
333   return down_cast<ShortArray*>(this);
334 }
335 
336 template<VerifyObjectFlags kVerifyFlags>
AsShortSizedArray()337 inline ShortArray* Object::AsShortSizedArray() {
338   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
339   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
340   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
341          GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
342   return down_cast<ShortArray*>(this);
343 }
344 
345 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsIntArray()346 inline bool Object::IsIntArray() {
347   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
348   mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
349   mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
350   return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>();
351 }
352 
353 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsIntArray()354 inline IntArray* Object::AsIntArray() {
355   DCHECK((IsIntArray<kVerifyFlags, kReadBarrierOption>()));
356   return down_cast<IntArray*>(this);
357 }
358 
359 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsLongArray()360 inline bool Object::IsLongArray() {
361   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
362   mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
363   mirror::Class* component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>();
364   return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>();
365 }
366 
367 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsLongArray()368 inline LongArray* Object::AsLongArray() {
369   DCHECK((IsLongArray<kVerifyFlags, kReadBarrierOption>()));
370   return down_cast<LongArray*>(this);
371 }
372 
373 template<VerifyObjectFlags kVerifyFlags>
IsFloatArray()374 inline bool Object::IsFloatArray() {
375   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
376   auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
377   return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>();
378 }
379 
380 template<VerifyObjectFlags kVerifyFlags>
AsFloatArray()381 inline FloatArray* Object::AsFloatArray() {
382   DCHECK(IsFloatArray<kVerifyFlags>());
383   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
384   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
385   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
386   return down_cast<FloatArray*>(this);
387 }
388 
389 template<VerifyObjectFlags kVerifyFlags>
IsDoubleArray()390 inline bool Object::IsDoubleArray() {
391   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
392   auto* component_type = GetClass<kVerifyFlags>()->GetComponentType();
393   return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>();
394 }
395 
396 template<VerifyObjectFlags kVerifyFlags>
AsDoubleArray()397 inline DoubleArray* Object::AsDoubleArray() {
398   DCHECK(IsDoubleArray<kVerifyFlags>());
399   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
400   DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
401   DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
402   return down_cast<DoubleArray*>(this);
403 }
404 
405 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsString()406 inline bool Object::IsString() {
407   return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass();
408 }
409 
410 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsString()411 inline String* Object::AsString() {
412   DCHECK((IsString<kVerifyFlags, kReadBarrierOption>()));
413   return down_cast<String*>(this);
414 }
415 
416 template<VerifyObjectFlags kVerifyFlags>
AsThrowable()417 inline Throwable* Object::AsThrowable() {
418   DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
419   return down_cast<Throwable*>(this);
420 }
421 
422 template<VerifyObjectFlags kVerifyFlags>
IsWeakReferenceInstance()423 inline bool Object::IsWeakReferenceInstance() {
424   return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
425 }
426 
427 template<VerifyObjectFlags kVerifyFlags>
IsSoftReferenceInstance()428 inline bool Object::IsSoftReferenceInstance() {
429   return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
430 }
431 
432 template<VerifyObjectFlags kVerifyFlags>
IsFinalizerReferenceInstance()433 inline bool Object::IsFinalizerReferenceInstance() {
434   return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
435 }
436 
437 template<VerifyObjectFlags kVerifyFlags>
AsFinalizerReference()438 inline FinalizerReference* Object::AsFinalizerReference() {
439   DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
440   return down_cast<FinalizerReference*>(this);
441 }
442 
443 template<VerifyObjectFlags kVerifyFlags>
IsPhantomReferenceInstance()444 inline bool Object::IsPhantomReferenceInstance() {
445   return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
446 }
447 
448 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
SizeOf()449 inline size_t Object::SizeOf() {
450   size_t result;
451   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
452   if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
453     result = AsArray<kNewFlags, kReadBarrierOption>()->
454         template SizeOf<kNewFlags, kReadBarrierOption>();
455   } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
456     result = AsClass<kNewFlags, kReadBarrierOption>()->
457         template SizeOf<kNewFlags, kReadBarrierOption>();
458   } else if (GetClass<kNewFlags, kReadBarrierOption>()->IsStringClass()) {
459     result = AsString<kNewFlags, kReadBarrierOption>()->
460         template SizeOf<kNewFlags>();
461   } else {
462     result = GetClass<kNewFlags, kReadBarrierOption>()->
463         template GetObjectSize<kNewFlags, kReadBarrierOption>();
464   }
465   DCHECK_GE(result, sizeof(Object))
466       << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
467   return result;
468 }
469 
470 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldBoolean(MemberOffset field_offset)471 inline uint8_t Object::GetFieldBoolean(MemberOffset field_offset) {
472   if (kVerifyFlags & kVerifyThis) {
473     VerifyObject(this);
474   }
475   return GetField<uint8_t, kIsVolatile>(field_offset);
476 }
477 
478 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldByte(MemberOffset field_offset)479 inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
480   if (kVerifyFlags & kVerifyThis) {
481     VerifyObject(this);
482   }
483   return GetField<int8_t, kIsVolatile>(field_offset);
484 }
485 
486 template<VerifyObjectFlags kVerifyFlags>
GetFieldBooleanVolatile(MemberOffset field_offset)487 inline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) {
488   return GetFieldBoolean<kVerifyFlags, true>(field_offset);
489 }
490 
491 template<VerifyObjectFlags kVerifyFlags>
GetFieldByteVolatile(MemberOffset field_offset)492 inline int8_t Object::GetFieldByteVolatile(MemberOffset field_offset) {
493   return GetFieldByte<kVerifyFlags, true>(field_offset);
494 }
495 
496 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
497     bool kIsVolatile>
SetFieldBoolean(MemberOffset field_offset,uint8_t new_value)498 inline void Object::SetFieldBoolean(MemberOffset field_offset, uint8_t new_value)
499     SHARED_REQUIRES(Locks::mutator_lock_) {
500   if (kCheckTransaction) {
501     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
502   }
503   if (kTransactionActive) {
504     Runtime::Current()->RecordWriteFieldBoolean(this, field_offset,
505                                            GetFieldBoolean<kVerifyFlags, kIsVolatile>(field_offset),
506                                            kIsVolatile);
507   }
508   if (kVerifyFlags & kVerifyThis) {
509     VerifyObject(this);
510   }
511   SetField<uint8_t, kIsVolatile>(field_offset, new_value);
512 }
513 
514 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
515     bool kIsVolatile>
SetFieldByte(MemberOffset field_offset,int8_t new_value)516 inline void Object::SetFieldByte(MemberOffset field_offset, int8_t new_value)
517     SHARED_REQUIRES(Locks::mutator_lock_) {
518   if (kCheckTransaction) {
519     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
520   }
521   if (kTransactionActive) {
522     Runtime::Current()->RecordWriteFieldByte(this, field_offset,
523                                            GetFieldByte<kVerifyFlags, kIsVolatile>(field_offset),
524                                            kIsVolatile);
525   }
526   if (kVerifyFlags & kVerifyThis) {
527     VerifyObject(this);
528   }
529   SetField<int8_t, kIsVolatile>(field_offset, new_value);
530 }
531 
532 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldBooleanVolatile(MemberOffset field_offset,uint8_t new_value)533 inline void Object::SetFieldBooleanVolatile(MemberOffset field_offset, uint8_t new_value) {
534   return SetFieldBoolean<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
535       field_offset, new_value);
536 }
537 
538 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldByteVolatile(MemberOffset field_offset,int8_t new_value)539 inline void Object::SetFieldByteVolatile(MemberOffset field_offset, int8_t new_value) {
540   return SetFieldByte<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
541       field_offset, new_value);
542 }
543 
544 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldChar(MemberOffset field_offset)545 inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
546   if (kVerifyFlags & kVerifyThis) {
547     VerifyObject(this);
548   }
549   return GetField<uint16_t, kIsVolatile>(field_offset);
550 }
551 
552 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetFieldShort(MemberOffset field_offset)553 inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
554   if (kVerifyFlags & kVerifyThis) {
555     VerifyObject(this);
556   }
557   return GetField<int16_t, kIsVolatile>(field_offset);
558 }
559 
560 template<VerifyObjectFlags kVerifyFlags>
GetFieldCharVolatile(MemberOffset field_offset)561 inline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) {
562   return GetFieldChar<kVerifyFlags, true>(field_offset);
563 }
564 
565 template<VerifyObjectFlags kVerifyFlags>
GetFieldShortVolatile(MemberOffset field_offset)566 inline int16_t Object::GetFieldShortVolatile(MemberOffset field_offset) {
567   return GetFieldShort<kVerifyFlags, true>(field_offset);
568 }
569 
570 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
571     bool kIsVolatile>
SetFieldChar(MemberOffset field_offset,uint16_t new_value)572 inline void Object::SetFieldChar(MemberOffset field_offset, uint16_t new_value) {
573   if (kCheckTransaction) {
574     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
575   }
576   if (kTransactionActive) {
577     Runtime::Current()->RecordWriteFieldChar(this, field_offset,
578                                            GetFieldChar<kVerifyFlags, kIsVolatile>(field_offset),
579                                            kIsVolatile);
580   }
581   if (kVerifyFlags & kVerifyThis) {
582     VerifyObject(this);
583   }
584   SetField<uint16_t, kIsVolatile>(field_offset, new_value);
585 }
586 
587 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
588     bool kIsVolatile>
SetFieldShort(MemberOffset field_offset,int16_t new_value)589 inline void Object::SetFieldShort(MemberOffset field_offset, int16_t new_value) {
590   if (kCheckTransaction) {
591     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
592   }
593   if (kTransactionActive) {
594     Runtime::Current()->RecordWriteFieldChar(this, field_offset,
595                                            GetFieldShort<kVerifyFlags, kIsVolatile>(field_offset),
596                                            kIsVolatile);
597   }
598   if (kVerifyFlags & kVerifyThis) {
599     VerifyObject(this);
600   }
601   SetField<int16_t, kIsVolatile>(field_offset, new_value);
602 }
603 
604 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldCharVolatile(MemberOffset field_offset,uint16_t new_value)605 inline void Object::SetFieldCharVolatile(MemberOffset field_offset, uint16_t new_value) {
606   return SetFieldChar<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
607       field_offset, new_value);
608 }
609 
610 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldShortVolatile(MemberOffset field_offset,int16_t new_value)611 inline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new_value) {
612   return SetFieldShort<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(
613       field_offset, new_value);
614 }
615 
616 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetField32(MemberOffset field_offset)617 inline int32_t Object::GetField32(MemberOffset field_offset) {
618   if (kVerifyFlags & kVerifyThis) {
619     VerifyObject(this);
620   }
621   return GetField<int32_t, kIsVolatile>(field_offset);
622 }
623 
624 template<VerifyObjectFlags kVerifyFlags>
GetField32Volatile(MemberOffset field_offset)625 inline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
626   return GetField32<kVerifyFlags, true>(field_offset);
627 }
628 
629 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
630     bool kIsVolatile>
SetField32(MemberOffset field_offset,int32_t new_value)631 inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
632   if (kCheckTransaction) {
633     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
634   }
635   if (kTransactionActive) {
636     Runtime::Current()->RecordWriteField32(this, field_offset,
637                                            GetField32<kVerifyFlags, kIsVolatile>(field_offset),
638                                            kIsVolatile);
639   }
640   if (kVerifyFlags & kVerifyThis) {
641     VerifyObject(this);
642   }
643   SetField<int32_t, kIsVolatile>(field_offset, new_value);
644 }
645 
646 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetField32Volatile(MemberOffset field_offset,int32_t new_value)647 inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
648   SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
649 }
650 
651 // TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
652 
653 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,int32_t old_value,int32_t new_value)654 inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
655                                                          int32_t old_value, int32_t new_value) {
656   if (kCheckTransaction) {
657     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
658   }
659   if (kTransactionActive) {
660     Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
661   }
662   if (kVerifyFlags & kVerifyThis) {
663     VerifyObject(this);
664   }
665   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
666   AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
667 
668   return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
669 }
670 
671 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakRelaxed32(MemberOffset field_offset,int32_t old_value,int32_t new_value)672 inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
673                                           int32_t old_value, int32_t new_value) {
674   if (kCheckTransaction) {
675     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
676   }
677   if (kTransactionActive) {
678     Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
679   }
680   if (kVerifyFlags & kVerifyThis) {
681     VerifyObject(this);
682   }
683   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
684   AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
685 
686   return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
687 }
688 
689 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakRelease32(MemberOffset field_offset,int32_t old_value,int32_t new_value)690 inline bool Object::CasFieldWeakRelease32(MemberOffset field_offset,
691                                           int32_t old_value, int32_t new_value) {
692   if (kCheckTransaction) {
693     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
694   }
695   if (kTransactionActive) {
696     Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
697   }
698   if (kVerifyFlags & kVerifyThis) {
699     VerifyObject(this);
700   }
701   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
702   AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
703 
704   return atomic_addr->CompareExchangeWeakRelease(old_value, new_value);
705 }
706 
707 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,int32_t old_value,int32_t new_value)708 inline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
709                                                            int32_t old_value, int32_t new_value) {
710   if (kCheckTransaction) {
711     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
712   }
713   if (kTransactionActive) {
714     Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
715   }
716   if (kVerifyFlags & kVerifyThis) {
717     VerifyObject(this);
718   }
719   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
720   AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
721 
722   return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
723 }
724 
725 template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
GetField64(MemberOffset field_offset)726 inline int64_t Object::GetField64(MemberOffset field_offset) {
727   if (kVerifyFlags & kVerifyThis) {
728     VerifyObject(this);
729   }
730   return GetField<int64_t, kIsVolatile>(field_offset);
731 }
732 
733 template<VerifyObjectFlags kVerifyFlags>
GetField64Volatile(MemberOffset field_offset)734 inline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
735   return GetField64<kVerifyFlags, true>(field_offset);
736 }
737 
738 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
739     bool kIsVolatile>
SetField64(MemberOffset field_offset,int64_t new_value)740 inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
741   if (kCheckTransaction) {
742     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
743   }
744   if (kTransactionActive) {
745     Runtime::Current()->RecordWriteField64(this, field_offset,
746                                            GetField64<kVerifyFlags, kIsVolatile>(field_offset),
747                                            kIsVolatile);
748   }
749   if (kVerifyFlags & kVerifyThis) {
750     VerifyObject(this);
751   }
752   SetField<int64_t, kIsVolatile>(field_offset, new_value);
753 }
754 
755 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetField64Volatile(MemberOffset field_offset,int64_t new_value)756 inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
757   return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
758                                                                                new_value);
759 }
760 
761 template<typename kSize, bool kIsVolatile>
SetField(MemberOffset field_offset,kSize new_value)762 inline void Object::SetField(MemberOffset field_offset, kSize new_value) {
763   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
764   kSize* addr = reinterpret_cast<kSize*>(raw_addr);
765   if (kIsVolatile) {
766     reinterpret_cast<Atomic<kSize>*>(addr)->StoreSequentiallyConsistent(new_value);
767   } else {
768     reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
769   }
770 }
771 
772 template<typename kSize, bool kIsVolatile>
GetField(MemberOffset field_offset)773 inline kSize Object::GetField(MemberOffset field_offset) {
774   const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
775   const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
776   if (kIsVolatile) {
777     return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadSequentiallyConsistent();
778   } else {
779     return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
780   }
781 }
782 
783 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,int64_t old_value,int64_t new_value)784 inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
785                                                          int64_t old_value, int64_t new_value) {
786   if (kCheckTransaction) {
787     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
788   }
789   if (kTransactionActive) {
790     Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
791   }
792   if (kVerifyFlags & kVerifyThis) {
793     VerifyObject(this);
794   }
795   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
796   Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
797   return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
798 }
799 
800 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,int64_t old_value,int64_t new_value)801 inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
802                                                            int64_t old_value, int64_t new_value) {
803   if (kCheckTransaction) {
804     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
805   }
806   if (kTransactionActive) {
807     Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
808   }
809   if (kVerifyFlags & kVerifyThis) {
810     VerifyObject(this);
811   }
812   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
813   Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
814   return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
815 }
816 
817 template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
818          bool kIsVolatile>
GetFieldObject(MemberOffset field_offset)819 inline T* Object::GetFieldObject(MemberOffset field_offset) {
820   if (kVerifyFlags & kVerifyThis) {
821     VerifyObject(this);
822   }
823   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
824   HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
825   T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
826   if (kIsVolatile) {
827     // TODO: Refactor to use a SequentiallyConsistent load instead.
828     QuasiAtomic::ThreadFenceAcquire();  // Ensure visibility of operations preceding store.
829   }
830   if (kVerifyFlags & kVerifyReads) {
831     VerifyObject(result);
832   }
833   return result;
834 }
835 
836 template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
GetFieldObjectVolatile(MemberOffset field_offset)837 inline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
838   return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
839 }
840 
841 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
842     bool kIsVolatile>
SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,Object * new_value)843 inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
844                                                       Object* new_value) {
845   if (kCheckTransaction) {
846     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
847   }
848   if (kTransactionActive) {
849     mirror::Object* obj;
850     if (kIsVolatile) {
851       obj = GetFieldObjectVolatile<Object>(field_offset);
852     } else {
853       obj = GetFieldObject<Object>(field_offset);
854     }
855     Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
856   }
857   if (kVerifyFlags & kVerifyThis) {
858     VerifyObject(this);
859   }
860   if (kVerifyFlags & kVerifyWrites) {
861     VerifyObject(new_value);
862   }
863   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
864   HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
865   if (kIsVolatile) {
866     // TODO: Refactor to use a SequentiallyConsistent store instead.
867     QuasiAtomic::ThreadFenceRelease();  // Ensure that prior accesses are visible before store.
868     objref_addr->Assign(new_value);
869     QuasiAtomic::ThreadFenceSequentiallyConsistent();
870                                 // Ensure this store occurs before any volatile loads.
871   } else {
872     objref_addr->Assign(new_value);
873   }
874 }
875 
876 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
877     bool kIsVolatile>
SetFieldObject(MemberOffset field_offset,Object * new_value)878 inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
879   SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
880       kIsVolatile>(field_offset, new_value);
881   if (new_value != nullptr) {
882     Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
883     // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
884     CheckFieldAssignment(field_offset, new_value);
885   }
886 }
887 
888 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
SetFieldObjectVolatile(MemberOffset field_offset,Object * new_value)889 inline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
890   SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
891                                                                             new_value);
892 }
893 
894 template <VerifyObjectFlags kVerifyFlags>
GetFieldObjectReferenceAddr(MemberOffset field_offset)895 inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
896   if (kVerifyFlags & kVerifyThis) {
897     VerifyObject(this);
898   }
899   return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<uint8_t*>(this) +
900       field_offset.Int32Value());
901 }
902 
903 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,Object * old_value,Object * new_value)904 inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
905                                                              Object* old_value, Object* new_value) {
906   bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
907       kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
908   if (success) {
909     Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
910   }
911   return success;
912 }
913 
914 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,Object * old_value,Object * new_value)915 inline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
916     MemberOffset field_offset, Object* old_value, Object* new_value) {
917   if (kCheckTransaction) {
918     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
919   }
920   if (kVerifyFlags & kVerifyThis) {
921     VerifyObject(this);
922   }
923   if (kVerifyFlags & kVerifyWrites) {
924     VerifyObject(new_value);
925   }
926   if (kVerifyFlags & kVerifyReads) {
927     VerifyObject(old_value);
928   }
929   if (kTransactionActive) {
930     Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
931   }
932   HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
933   HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
934   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
935   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
936 
937   bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
938                                                                         new_ref.reference_);
939   return success;
940 }
941 
942 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,Object * old_value,Object * new_value)943 inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
944                                                                Object* old_value, Object* new_value) {
945   bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
946       kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
947   if (success) {
948     Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
949   }
950   return success;
951 }
952 
953 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,Object * old_value,Object * new_value)954 inline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
955     MemberOffset field_offset, Object* old_value, Object* new_value) {
956   if (kCheckTransaction) {
957     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
958   }
959   if (kVerifyFlags & kVerifyThis) {
960     VerifyObject(this);
961   }
962   if (kVerifyFlags & kVerifyWrites) {
963     VerifyObject(new_value);
964   }
965   if (kVerifyFlags & kVerifyReads) {
966     VerifyObject(old_value);
967   }
968   if (kTransactionActive) {
969     Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
970   }
971   HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
972   HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
973   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
974   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
975 
976   bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
977                                                                           new_ref.reference_);
978   return success;
979 }
980 
981 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldWeakRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,Object * old_value,Object * new_value)982 inline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier(
983     MemberOffset field_offset, Object* old_value, Object* new_value) {
984   if (kCheckTransaction) {
985     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
986   }
987   if (kVerifyFlags & kVerifyThis) {
988     VerifyObject(this);
989   }
990   if (kVerifyFlags & kVerifyWrites) {
991     VerifyObject(new_value);
992   }
993   if (kVerifyFlags & kVerifyReads) {
994     VerifyObject(old_value);
995   }
996   if (kTransactionActive) {
997     Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
998   }
999   HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
1000   HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
1001   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
1002   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1003 
1004   bool success = atomic_addr->CompareExchangeWeakRelaxed(old_ref.reference_,
1005                                                          new_ref.reference_);
1006   return success;
1007 }
1008 
1009 template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
CasFieldStrongRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,Object * old_value,Object * new_value)1010 inline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier(
1011     MemberOffset field_offset, Object* old_value, Object* new_value) {
1012   if (kCheckTransaction) {
1013     DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
1014   }
1015   if (kVerifyFlags & kVerifyThis) {
1016     VerifyObject(this);
1017   }
1018   if (kVerifyFlags & kVerifyWrites) {
1019     VerifyObject(new_value);
1020   }
1021   if (kVerifyFlags & kVerifyReads) {
1022     VerifyObject(old_value);
1023   }
1024   if (kTransactionActive) {
1025     Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
1026   }
1027   HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
1028   HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
1029   uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
1030   Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
1031 
1032   bool success = atomic_addr->CompareExchangeStrongRelaxed(old_ref.reference_,
1033                                                            new_ref.reference_);
1034   return success;
1035 }
1036 
1037 template<bool kIsStatic,
1038          VerifyObjectFlags kVerifyFlags,
1039          ReadBarrierOption kReadBarrierOption,
1040          typename Visitor>
VisitFieldsReferences(uint32_t ref_offsets,const Visitor & visitor)1041 inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
1042   if (!kIsStatic && (ref_offsets != mirror::Class::kClassWalkSuper)) {
1043     // Instance fields and not the slow-path.
1044     uint32_t field_offset = mirror::kObjectHeaderSize;
1045     while (ref_offsets != 0) {
1046       if ((ref_offsets & 1) != 0) {
1047         visitor(this, MemberOffset(field_offset), kIsStatic);
1048       }
1049       ref_offsets >>= 1;
1050       field_offset += sizeof(mirror::HeapReference<mirror::Object>);
1051     }
1052   } else {
1053     // There is no reference offset bitmap. In the non-static case, walk up the class
1054     // inheritance hierarchy and find reference offsets the hard way. In the static case, just
1055     // consider this class.
1056     for (mirror::Class* klass = kIsStatic
1057             ? AsClass<kVerifyFlags, kReadBarrierOption>()
1058             : GetClass<kVerifyFlags, kReadBarrierOption>();
1059         klass != nullptr;
1060         klass = kIsStatic ? nullptr : klass->GetSuperClass<kVerifyFlags, kReadBarrierOption>()) {
1061       const size_t num_reference_fields =
1062           kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
1063       if (num_reference_fields == 0u) {
1064         continue;
1065       }
1066       // Presumably GC can happen when we are cross compiling, it should not cause performance
1067       // problems to do pointer size logic.
1068       MemberOffset field_offset = kIsStatic
1069           ? klass->GetFirstReferenceStaticFieldOffset<kVerifyFlags, kReadBarrierOption>(
1070               Runtime::Current()->GetClassLinker()->GetImagePointerSize())
1071           : klass->GetFirstReferenceInstanceFieldOffset<kVerifyFlags, kReadBarrierOption>();
1072       for (size_t i = 0u; i < num_reference_fields; ++i) {
1073         // TODO: Do a simpler check?
1074         if (field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
1075           visitor(this, field_offset, kIsStatic);
1076         }
1077         field_offset = MemberOffset(field_offset.Uint32Value() +
1078                                     sizeof(mirror::HeapReference<mirror::Object>));
1079       }
1080     }
1081   }
1082 }
1083 
1084 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
VisitInstanceFieldsReferences(mirror::Class * klass,const Visitor & visitor)1085 inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
1086   VisitFieldsReferences<false, kVerifyFlags, kReadBarrierOption>(
1087       klass->GetReferenceInstanceOffsets<kVerifyFlags>(), visitor);
1088 }
1089 
1090 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, typename Visitor>
VisitStaticFieldsReferences(mirror::Class * klass,const Visitor & visitor)1091 inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
1092   DCHECK(!klass->IsTemp());
1093   klass->VisitFieldsReferences<true, kVerifyFlags, kReadBarrierOption>(0, visitor);
1094 }
1095 
1096 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsClassLoader()1097 inline bool Object::IsClassLoader() {
1098   return GetClass<kVerifyFlags, kReadBarrierOption>()->IsClassLoaderClass();
1099 }
1100 
1101 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsClassLoader()1102 inline mirror::ClassLoader* Object::AsClassLoader() {
1103   DCHECK((IsClassLoader<kVerifyFlags, kReadBarrierOption>()));
1104   return down_cast<mirror::ClassLoader*>(this);
1105 }
1106 
1107 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
IsDexCache()1108 inline bool Object::IsDexCache() {
1109   return GetClass<kVerifyFlags, kReadBarrierOption>()->IsDexCacheClass();
1110 }
1111 
1112 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
AsDexCache()1113 inline mirror::DexCache* Object::AsDexCache() {
1114   DCHECK((IsDexCache<kVerifyFlags, kReadBarrierOption>()));
1115   return down_cast<mirror::DexCache*>(this);
1116 }
1117 
1118 template <bool kVisitNativeRoots,
1119           VerifyObjectFlags kVerifyFlags,
1120           ReadBarrierOption kReadBarrierOption,
1121           typename Visitor,
1122           typename JavaLangRefVisitor>
VisitReferences(const Visitor & visitor,const JavaLangRefVisitor & ref_visitor)1123 inline void Object::VisitReferences(const Visitor& visitor,
1124                                     const JavaLangRefVisitor& ref_visitor) {
1125   mirror::Class* klass = GetClass<kVerifyFlags, kReadBarrierOption>();
1126   visitor(this, ClassOffset(), false);
1127   const uint32_t class_flags = klass->GetClassFlags<kVerifyNone>();
1128   if (LIKELY(class_flags == kClassFlagNormal)) {
1129     DCHECK((!klass->IsVariableSize<kVerifyFlags, kReadBarrierOption>()));
1130     VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
1131     DCHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
1132     DCHECK(!klass->IsStringClass());
1133     DCHECK(!klass->IsClassLoaderClass());
1134     DCHECK((!klass->IsArrayClass<kVerifyFlags, kReadBarrierOption>()));
1135   } else {
1136     if ((class_flags & kClassFlagNoReferenceFields) == 0) {
1137       DCHECK(!klass->IsStringClass());
1138       if (class_flags == kClassFlagClass) {
1139         DCHECK((klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
1140         mirror::Class* as_klass = AsClass<kVerifyNone, kReadBarrierOption>();
1141         as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass,
1142                                                                                        visitor);
1143       } else if (class_flags == kClassFlagObjectArray) {
1144         DCHECK((klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
1145         AsObjectArray<mirror::Object, kVerifyNone, kReadBarrierOption>()->VisitReferences(visitor);
1146       } else if ((class_flags & kClassFlagReference) != 0) {
1147         VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
1148         ref_visitor(klass, AsReference<kVerifyFlags, kReadBarrierOption>());
1149       } else if (class_flags == kClassFlagDexCache) {
1150         mirror::DexCache* const dex_cache = AsDexCache<kVerifyFlags, kReadBarrierOption>();
1151         dex_cache->VisitReferences<kVisitNativeRoots,
1152                                    kVerifyFlags,
1153                                    kReadBarrierOption>(klass, visitor);
1154       } else {
1155         mirror::ClassLoader* const class_loader = AsClassLoader<kVerifyFlags, kReadBarrierOption>();
1156         class_loader->VisitReferences<kVisitNativeRoots,
1157                                       kVerifyFlags,
1158                                       kReadBarrierOption>(klass, visitor);
1159       }
1160     } else if (kIsDebugBuild) {
1161       CHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
1162       CHECK((!klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
1163       // String still has instance fields for reflection purposes but these don't exist in
1164       // actual string instances.
1165       if (!klass->IsStringClass()) {
1166         size_t total_reference_instance_fields = 0;
1167         mirror::Class* super_class = klass;
1168         do {
1169           total_reference_instance_fields += super_class->NumReferenceInstanceFields();
1170           super_class = super_class->GetSuperClass<kVerifyFlags, kReadBarrierOption>();
1171         } while (super_class != nullptr);
1172         // The only reference field should be the object's class. This field is handled at the
1173         // beginning of the function.
1174         CHECK_EQ(total_reference_instance_fields, 1u);
1175       }
1176     }
1177   }
1178 }
1179 }  // namespace mirror
1180 }  // namespace art
1181 
1182 #endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
1183