object-inl.h revision 5abc6f913bc77aa3b9c05ad07905d4c1c28b2661
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 "lock_word-inl.h"
28#include "monitor.h"
29#include "object_array-inl.h"
30#include "read_barrier-inl.h"
31#include "runtime.h"
32#include "reference.h"
33#include "throwable.h"
34
35namespace art {
36namespace mirror {
37
38inline uint32_t Object::ClassSize() {
39  uint32_t vtable_entries = kVTableLength;
40  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0);
41}
42
43template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
44inline Class* Object::GetClass() {
45  return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>(
46      OFFSET_OF_OBJECT_MEMBER(Object, klass_));
47}
48
49template<VerifyObjectFlags kVerifyFlags>
50inline void Object::SetClass(Class* new_klass) {
51  // new_klass may be NULL prior to class linker initialization.
52  // We don't mark the card as this occurs as part of object allocation. Not all objects have
53  // backing cards, such as large objects.
54  // We use non transactional version since we can't undo this write. We also disable checking as
55  // we may run in transaction mode here.
56  SetFieldObjectWithoutWriteBarrier<false, false,
57      static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(
58      OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
59}
60
61inline LockWord Object::GetLockWord(bool as_volatile) {
62  if (as_volatile) {
63    return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
64  }
65  return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
66}
67
68inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
69  // Force use of non-transactional mode and do not check.
70  if (as_volatile) {
71    SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
72  } else {
73    SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
74  }
75}
76
77inline bool Object::CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) {
78  // Force use of non-transactional mode and do not check.
79  return CasFieldWeakSequentiallyConsistent32<false, false>(
80      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
81}
82
83inline bool Object::CasLockWordWeakRelaxed(LockWord old_val, LockWord new_val) {
84  // Force use of non-transactional mode and do not check.
85  return CasFieldWeakRelaxed32<false, false>(
86      OFFSET_OF_OBJECT_MEMBER(Object, monitor_), old_val.GetValue(), new_val.GetValue());
87}
88
89inline uint32_t Object::GetLockOwnerThreadId() {
90  return Monitor::GetLockOwnerThreadId(this);
91}
92
93inline mirror::Object* Object::MonitorEnter(Thread* self) {
94  return Monitor::MonitorEnter(self, this);
95}
96
97inline bool Object::MonitorExit(Thread* self) {
98  return Monitor::MonitorExit(self, this);
99}
100
101inline void Object::Notify(Thread* self) {
102  Monitor::Notify(self, this);
103}
104
105inline void Object::NotifyAll(Thread* self) {
106  Monitor::NotifyAll(self, this);
107}
108
109inline void Object::Wait(Thread* self) {
110  Monitor::Wait(self, this, 0, 0, true, kWaiting);
111}
112
113inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) {
114  Monitor::Wait(self, this, ms, ns, true, kTimedWaiting);
115}
116
117inline Object* Object::GetReadBarrierPointer() {
118#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
119  DCHECK(kUseBakerOrBrooksReadBarrier);
120  return GetFieldObject<Object, kVerifyNone, kWithoutReadBarrier>(
121      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_));
122#else
123  LOG(FATAL) << "Unreachable";
124  return nullptr;
125#endif
126}
127
128inline void Object::SetReadBarrierPointer(Object* rb_ptr) {
129#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
130  DCHECK(kUseBakerOrBrooksReadBarrier);
131  // We don't mark the card as this occurs as part of object allocation. Not all objects have
132  // backing cards, such as large objects.
133  SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
134      OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr);
135#else
136  LOG(FATAL) << "Unreachable";
137#endif
138}
139
140inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) {
141#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER
142  DCHECK(kUseBakerOrBrooksReadBarrier);
143  MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_);
144  byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue();
145  Atomic<uint32_t>* atomic_rb_ptr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
146  HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr));
147  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr));
148  do {
149    if (UNLIKELY(atomic_rb_ptr->LoadRelaxed() != expected_ref.reference_)) {
150      // Lost the race.
151      return false;
152    }
153  } while (!atomic_rb_ptr->CompareExchangeWeakSequentiallyConsistent(expected_ref.reference_,
154                                                                     new_ref.reference_));
155  DCHECK_EQ(new_ref.reference_, atomic_rb_ptr->LoadRelaxed());
156  return true;
157#else
158  LOG(FATAL) << "Unreachable";
159  return false;
160#endif
161}
162
163inline void Object::AssertReadBarrierPointer() const {
164  if (kUseBakerReadBarrier) {
165    Object* obj = const_cast<Object*>(this);
166    DCHECK(obj->GetReadBarrierPointer() == nullptr)
167        << "Bad Baker pointer: obj=" << reinterpret_cast<void*>(obj)
168        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
169  } else if (kUseBrooksReadBarrier) {
170    Object* obj = const_cast<Object*>(this);
171    DCHECK_EQ(obj, obj->GetReadBarrierPointer())
172        << "Bad Brooks pointer: obj=" << reinterpret_cast<void*>(obj)
173        << " ptr=" << reinterpret_cast<void*>(obj->GetReadBarrierPointer());
174  } else {
175    LOG(FATAL) << "Unreachable";
176  }
177}
178
179template<VerifyObjectFlags kVerifyFlags>
180inline bool Object::VerifierInstanceOf(Class* klass) {
181  DCHECK(klass != NULL);
182  DCHECK(GetClass<kVerifyFlags>() != NULL);
183  return klass->IsInterface() || InstanceOf(klass);
184}
185
186template<VerifyObjectFlags kVerifyFlags>
187inline bool Object::InstanceOf(Class* klass) {
188  DCHECK(klass != NULL);
189  DCHECK(GetClass<kVerifyNone>() != NULL);
190  return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
191}
192
193template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
194inline bool Object::IsClass() {
195  Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
196      template GetClass<kVerifyFlags, kReadBarrierOption>();
197  return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis),
198      kReadBarrierOption>() == java_lang_Class;
199}
200
201template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
202inline Class* Object::AsClass() {
203  DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
204  return down_cast<Class*>(this);
205}
206
207template<VerifyObjectFlags kVerifyFlags>
208inline bool Object::IsObjectArray() {
209  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
210  return IsArrayInstance<kVerifyFlags>() &&
211      !GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitive();
212}
213
214template<class T, VerifyObjectFlags kVerifyFlags>
215inline ObjectArray<T>* Object::AsObjectArray() {
216  DCHECK(IsObjectArray<kVerifyFlags>());
217  return down_cast<ObjectArray<T>*>(this);
218}
219
220template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
221inline bool Object::IsArrayInstance() {
222  return GetClass<kVerifyFlags, kReadBarrierOption>()->
223      template IsArrayClass<kVerifyFlags, kReadBarrierOption>();
224}
225
226template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
227inline bool Object::IsArtField() {
228  return GetClass<kVerifyFlags, kReadBarrierOption>()->
229      template IsArtFieldClass<kReadBarrierOption>();
230}
231
232template<VerifyObjectFlags kVerifyFlags>
233inline ArtField* Object::AsArtField() {
234  DCHECK(IsArtField<kVerifyFlags>());
235  return down_cast<ArtField*>(this);
236}
237
238template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
239inline bool Object::IsArtMethod() {
240  return GetClass<kVerifyFlags, kReadBarrierOption>()->
241      template IsArtMethodClass<kReadBarrierOption>();
242}
243
244template<VerifyObjectFlags kVerifyFlags>
245inline ArtMethod* Object::AsArtMethod() {
246  DCHECK(IsArtMethod<kVerifyFlags>());
247  return down_cast<ArtMethod*>(this);
248}
249
250template<VerifyObjectFlags kVerifyFlags>
251inline bool Object::IsReferenceInstance() {
252  return GetClass<kVerifyFlags>()->IsTypeOfReferenceClass();
253}
254
255template<VerifyObjectFlags kVerifyFlags>
256inline Reference* Object::AsReference() {
257  DCHECK(IsReferenceInstance<kVerifyFlags>());
258  return down_cast<Reference*>(this);
259}
260
261template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
262inline Array* Object::AsArray() {
263  DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>()));
264  return down_cast<Array*>(this);
265}
266
267template<VerifyObjectFlags kVerifyFlags>
268inline BooleanArray* Object::AsBooleanArray() {
269  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
270  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
271  DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean());
272  return down_cast<BooleanArray*>(this);
273}
274
275template<VerifyObjectFlags kVerifyFlags>
276inline ByteArray* Object::AsByteArray() {
277  static const VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
278  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
279  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte());
280  return down_cast<ByteArray*>(this);
281}
282
283template<VerifyObjectFlags kVerifyFlags>
284inline ByteArray* Object::AsByteSizedArray() {
285  constexpr VerifyObjectFlags kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
286  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
287  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() ||
288         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean());
289  return down_cast<ByteArray*>(this);
290}
291
292template<VerifyObjectFlags kVerifyFlags>
293inline CharArray* Object::AsCharArray() {
294  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
295  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
296  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
297  return down_cast<CharArray*>(this);
298}
299
300template<VerifyObjectFlags kVerifyFlags>
301inline ShortArray* Object::AsShortArray() {
302  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
303  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
304  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort());
305  return down_cast<ShortArray*>(this);
306}
307
308template<VerifyObjectFlags kVerifyFlags>
309inline ShortArray* Object::AsShortSizedArray() {
310  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
311  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
312  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() ||
313         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar());
314  return down_cast<ShortArray*>(this);
315}
316
317template<VerifyObjectFlags kVerifyFlags>
318inline IntArray* Object::AsIntArray() {
319  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
320  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
321  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
322         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
323  return down_cast<IntArray*>(this);
324}
325
326template<VerifyObjectFlags kVerifyFlags>
327inline LongArray* Object::AsLongArray() {
328  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
329  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
330  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
331         GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
332  return down_cast<LongArray*>(this);
333}
334
335template<VerifyObjectFlags kVerifyFlags>
336inline FloatArray* Object::AsFloatArray() {
337  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
338  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
339  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
340  return down_cast<FloatArray*>(this);
341}
342
343template<VerifyObjectFlags kVerifyFlags>
344inline DoubleArray* Object::AsDoubleArray() {
345  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
346  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
347  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
348  return down_cast<DoubleArray*>(this);
349}
350
351template<VerifyObjectFlags kVerifyFlags>
352inline String* Object::AsString() {
353  DCHECK(GetClass<kVerifyFlags>()->IsStringClass());
354  return down_cast<String*>(this);
355}
356
357template<VerifyObjectFlags kVerifyFlags>
358inline Throwable* Object::AsThrowable() {
359  DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass());
360  return down_cast<Throwable*>(this);
361}
362
363template<VerifyObjectFlags kVerifyFlags>
364inline bool Object::IsWeakReferenceInstance() {
365  return GetClass<kVerifyFlags>()->IsWeakReferenceClass();
366}
367
368template<VerifyObjectFlags kVerifyFlags>
369inline bool Object::IsSoftReferenceInstance() {
370  return GetClass<kVerifyFlags>()->IsSoftReferenceClass();
371}
372
373template<VerifyObjectFlags kVerifyFlags>
374inline bool Object::IsFinalizerReferenceInstance() {
375  return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass();
376}
377
378template<VerifyObjectFlags kVerifyFlags>
379inline FinalizerReference* Object::AsFinalizerReference() {
380  DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>());
381  return down_cast<FinalizerReference*>(this);
382}
383
384template<VerifyObjectFlags kVerifyFlags>
385inline bool Object::IsPhantomReferenceInstance() {
386  return GetClass<kVerifyFlags>()->IsPhantomReferenceClass();
387}
388
389template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
390inline size_t Object::SizeOf() {
391  size_t result;
392  constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
393  if (IsArrayInstance<kVerifyFlags, kReadBarrierOption>()) {
394    result = AsArray<kNewFlags, kReadBarrierOption>()->
395        template SizeOf<kNewFlags, kReadBarrierOption>();
396  } else if (IsClass<kNewFlags, kReadBarrierOption>()) {
397    result = AsClass<kNewFlags, kReadBarrierOption>()->
398        template SizeOf<kNewFlags, kReadBarrierOption>();
399  } else {
400    result = GetClass<kNewFlags, kReadBarrierOption>()->
401        template GetObjectSize<kNewFlags, kReadBarrierOption>();
402  }
403  DCHECK_GE(result, sizeof(Object))
404      << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
405  DCHECK(!(IsArtField<kNewFlags, kReadBarrierOption>()) || result == sizeof(ArtField));
406  return result;
407}
408
409template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
410inline int8_t Object::GetField8(MemberOffset field_offset) {
411  if (kVerifyFlags & kVerifyThis) {
412    VerifyObject(this);
413  }
414  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
415  const int8_t* word_addr = reinterpret_cast<const int8_t*>(raw_addr);
416  if (UNLIKELY(kIsVolatile)) {
417    return reinterpret_cast<const Atomic<int8_t>*>(word_addr)->LoadSequentiallyConsistent();
418  } else {
419    return reinterpret_cast<const Atomic<int8_t>*>(word_addr)->LoadJavaData();
420  }
421}
422
423template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
424    bool kIsVolatile>
425inline void Object::SetField8(MemberOffset field_offset, int8_t new_value) {
426  if (kCheckTransaction) {
427    DCHECK_EQ(false, Runtime::Current()->IsActiveTransaction());
428  }
429  if (kVerifyFlags & kVerifyThis) {
430    VerifyObject(this);
431  }
432  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
433  int8_t* word_addr = reinterpret_cast<int8_t*>(raw_addr);
434  if (kIsVolatile) {
435    reinterpret_cast<Atomic<int8_t>*>(word_addr)->StoreSequentiallyConsistent(new_value);
436  } else {
437    reinterpret_cast<Atomic<int8_t>*>(word_addr)->StoreJavaData(new_value);
438  }
439}
440
441template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
442inline int16_t Object::GetField16(MemberOffset field_offset) {
443  if (kVerifyFlags & kVerifyThis) {
444    VerifyObject(this);
445  }
446  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
447  const int16_t* word_addr = reinterpret_cast<const int16_t*>(raw_addr);
448  if (UNLIKELY(kIsVolatile)) {
449    return reinterpret_cast<const Atomic<int16_t>*>(word_addr)->LoadSequentiallyConsistent();
450  } else {
451    return reinterpret_cast<const Atomic<int16_t>*>(word_addr)->LoadJavaData();
452  }
453}
454
455template<bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
456    bool kIsVolatile>
457inline void Object::SetField16(MemberOffset field_offset, int16_t new_value) {
458  if (kCheckTransaction) {
459    DCHECK_EQ(false, Runtime::Current()->IsActiveTransaction());
460  }
461  if (kVerifyFlags & kVerifyThis) {
462    VerifyObject(this);
463  }
464  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
465  int16_t* word_addr = reinterpret_cast<int16_t*>(raw_addr);
466  if (kIsVolatile) {
467    reinterpret_cast<Atomic<int16_t>*>(word_addr)->StoreSequentiallyConsistent(new_value);
468  } else {
469    reinterpret_cast<Atomic<int16_t>*>(word_addr)->StoreJavaData(new_value);
470  }
471}
472
473template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
474inline int32_t Object::GetField32(MemberOffset field_offset) {
475  if (kVerifyFlags & kVerifyThis) {
476    VerifyObject(this);
477  }
478  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
479  const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
480  if (UNLIKELY(kIsVolatile)) {
481    return reinterpret_cast<const Atomic<int32_t>*>(word_addr)->LoadSequentiallyConsistent();
482  } else {
483    return reinterpret_cast<const Atomic<int32_t>*>(word_addr)->LoadJavaData();
484  }
485}
486
487template<VerifyObjectFlags kVerifyFlags>
488inline int32_t Object::GetField32Volatile(MemberOffset field_offset) {
489  return GetField32<kVerifyFlags, true>(field_offset);
490}
491
492template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
493    bool kIsVolatile>
494inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) {
495  if (kCheckTransaction) {
496    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
497  }
498  if (kTransactionActive) {
499    Runtime::Current()->RecordWriteField32(this, field_offset,
500                                           GetField32<kVerifyFlags, kIsVolatile>(field_offset),
501                                           kIsVolatile);
502  }
503  if (kVerifyFlags & kVerifyThis) {
504    VerifyObject(this);
505  }
506  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
507  int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
508  if (kIsVolatile) {
509    reinterpret_cast<Atomic<int32_t>*>(word_addr)->StoreSequentiallyConsistent(new_value);
510  } else {
511    reinterpret_cast<Atomic<int32_t>*>(word_addr)->StoreJavaData(new_value);
512  }
513}
514
515template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
516inline void Object::SetField32Volatile(MemberOffset field_offset, int32_t new_value) {
517  SetField32<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset, new_value);
518}
519
520// TODO: Pass memory_order_ and strong/weak as arguments to avoid code duplication?
521
522template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
523inline bool Object::CasFieldWeakSequentiallyConsistent32(MemberOffset field_offset,
524                                                         int32_t old_value, int32_t new_value) {
525  if (kCheckTransaction) {
526    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
527  }
528  if (kTransactionActive) {
529    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
530  }
531  if (kVerifyFlags & kVerifyThis) {
532    VerifyObject(this);
533  }
534  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
535  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
536
537  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
538}
539
540template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
541inline bool Object::CasFieldWeakRelaxed32(MemberOffset field_offset,
542                                          int32_t old_value, int32_t new_value) {
543  if (kCheckTransaction) {
544    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
545  }
546  if (kTransactionActive) {
547    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
548  }
549  if (kVerifyFlags & kVerifyThis) {
550    VerifyObject(this);
551  }
552  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
553  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
554
555  return atomic_addr->CompareExchangeWeakRelaxed(old_value, new_value);
556}
557
558template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
559inline bool Object::CasFieldStrongSequentiallyConsistent32(MemberOffset field_offset,
560                                                           int32_t old_value, int32_t new_value) {
561  if (kCheckTransaction) {
562    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
563  }
564  if (kTransactionActive) {
565    Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true);
566  }
567  if (kVerifyFlags & kVerifyThis) {
568    VerifyObject(this);
569  }
570  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
571  AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr);
572
573  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
574}
575
576template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
577inline int64_t Object::GetField64(MemberOffset field_offset) {
578  if (kVerifyFlags & kVerifyThis) {
579    VerifyObject(this);
580  }
581  const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
582  const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
583  if (kIsVolatile) {
584    return reinterpret_cast<const Atomic<int64_t>*>(addr)->LoadSequentiallyConsistent();
585  } else {
586    return reinterpret_cast<const Atomic<int64_t>*>(addr)->LoadJavaData();
587  }
588}
589
590template<VerifyObjectFlags kVerifyFlags>
591inline int64_t Object::GetField64Volatile(MemberOffset field_offset) {
592  return GetField64<kVerifyFlags, true>(field_offset);
593}
594
595template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
596    bool kIsVolatile>
597inline void Object::SetField64(MemberOffset field_offset, int64_t new_value) {
598  if (kCheckTransaction) {
599    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
600  }
601  if (kTransactionActive) {
602    Runtime::Current()->RecordWriteField64(this, field_offset,
603                                           GetField64<kVerifyFlags, kIsVolatile>(field_offset),
604                                           kIsVolatile);
605  }
606  if (kVerifyFlags & kVerifyThis) {
607    VerifyObject(this);
608  }
609  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
610  int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
611  if (kIsVolatile) {
612    reinterpret_cast<Atomic<int64_t>*>(addr)->StoreSequentiallyConsistent(new_value);
613  } else {
614    reinterpret_cast<Atomic<int64_t>*>(addr)->StoreJavaData(new_value);
615  }
616}
617
618template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
619inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_value) {
620  return SetField64<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
621                                                                               new_value);
622}
623
624template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
625inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offset,
626                                                         int64_t old_value, int64_t new_value) {
627  if (kCheckTransaction) {
628    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
629  }
630  if (kTransactionActive) {
631    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
632  }
633  if (kVerifyFlags & kVerifyThis) {
634    VerifyObject(this);
635  }
636  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
637  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
638  return atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_value, new_value);
639}
640
641template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
642inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_offset,
643                                                           int64_t old_value, int64_t new_value) {
644  if (kCheckTransaction) {
645    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
646  }
647  if (kTransactionActive) {
648    Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true);
649  }
650  if (kVerifyFlags & kVerifyThis) {
651    VerifyObject(this);
652  }
653  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
654  Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr);
655  return atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_value, new_value);
656}
657
658template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption,
659         bool kIsVolatile>
660inline T* Object::GetFieldObject(MemberOffset field_offset) {
661  if (kVerifyFlags & kVerifyThis) {
662    VerifyObject(this);
663  }
664  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
665  HeapReference<T>* objref_addr = reinterpret_cast<HeapReference<T>*>(raw_addr);
666  T* result = ReadBarrier::Barrier<T, kReadBarrierOption>(this, field_offset, objref_addr);
667  if (kIsVolatile) {
668    // TODO: Refactor to use a SequentiallyConsistent load instead.
669    QuasiAtomic::ThreadFenceAcquire();  // Ensure visibility of operations preceding store.
670  }
671  if (kVerifyFlags & kVerifyReads) {
672    VerifyObject(result);
673  }
674  return result;
675}
676
677template<class T, VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
678inline T* Object::GetFieldObjectVolatile(MemberOffset field_offset) {
679  return GetFieldObject<T, kVerifyFlags, kReadBarrierOption, true>(field_offset);
680}
681
682template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
683    bool kIsVolatile>
684inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
685                                                      Object* new_value) {
686  if (kCheckTransaction) {
687    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
688  }
689  if (kTransactionActive) {
690    mirror::Object* obj;
691    if (kIsVolatile) {
692      obj = GetFieldObjectVolatile<Object>(field_offset);
693    } else {
694      obj = GetFieldObject<Object>(field_offset);
695    }
696    Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true);
697  }
698  if (kVerifyFlags & kVerifyThis) {
699    VerifyObject(this);
700  }
701  if (kVerifyFlags & kVerifyWrites) {
702    VerifyObject(new_value);
703  }
704  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
705  HeapReference<Object>* objref_addr = reinterpret_cast<HeapReference<Object>*>(raw_addr);
706  if (kIsVolatile) {
707    // TODO: Refactor to use a SequentiallyConsistent store instead.
708    QuasiAtomic::ThreadFenceRelease();  // Ensure that prior accesses are visible before store.
709    objref_addr->Assign(new_value);
710    QuasiAtomic::ThreadFenceSequentiallyConsistent();
711                                // Ensure this store occurs before any volatile loads.
712  } else {
713    objref_addr->Assign(new_value);
714  }
715}
716
717template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags,
718    bool kIsVolatile>
719inline void Object::SetFieldObject(MemberOffset field_offset, Object* new_value) {
720  SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags,
721      kIsVolatile>(field_offset, new_value);
722  if (new_value != nullptr) {
723    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
724    // TODO: Check field assignment could theoretically cause thread suspension, TODO: fix this.
725    CheckFieldAssignment(field_offset, new_value);
726  }
727}
728
729template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
730inline void Object::SetFieldObjectVolatile(MemberOffset field_offset, Object* new_value) {
731  SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags, true>(field_offset,
732                                                                            new_value);
733}
734
735template <VerifyObjectFlags kVerifyFlags>
736inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset field_offset) {
737  if (kVerifyFlags & kVerifyThis) {
738    VerifyObject(this);
739  }
740  return reinterpret_cast<HeapReference<Object>*>(reinterpret_cast<byte*>(this) +
741      field_offset.Int32Value());
742}
743
744template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
745inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
746                                                             Object* old_value, Object* new_value) {
747  if (kCheckTransaction) {
748    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
749  }
750  if (kVerifyFlags & kVerifyThis) {
751    VerifyObject(this);
752  }
753  if (kVerifyFlags & kVerifyWrites) {
754    VerifyObject(new_value);
755  }
756  if (kVerifyFlags & kVerifyReads) {
757    VerifyObject(old_value);
758  }
759  if (kTransactionActive) {
760    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
761  }
762  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
763  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
764  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
765  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
766
767  bool success = atomic_addr->CompareExchangeWeakSequentiallyConsistent(old_ref.reference_,
768                                                                        new_ref.reference_);
769
770  if (success) {
771    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
772  }
773  return success;
774}
775
776template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
777inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
778                                                             Object* old_value, Object* new_value) {
779  if (kCheckTransaction) {
780    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
781  }
782  if (kVerifyFlags & kVerifyThis) {
783    VerifyObject(this);
784  }
785  if (kVerifyFlags & kVerifyWrites) {
786    VerifyObject(new_value);
787  }
788  if (kVerifyFlags & kVerifyReads) {
789    VerifyObject(old_value);
790  }
791  if (kTransactionActive) {
792    Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
793  }
794  HeapReference<Object> old_ref(HeapReference<Object>::FromMirrorPtr(old_value));
795  HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(new_value));
796  byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
797  Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
798
799  bool success = atomic_addr->CompareExchangeStrongSequentiallyConsistent(old_ref.reference_,
800                                                                          new_ref.reference_);
801
802  if (success) {
803    Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
804  }
805  return success;
806}
807
808template<bool kVisitClass, bool kIsStatic, typename Visitor>
809inline void Object::VisitFieldsReferences(uint32_t ref_offsets, const Visitor& visitor) {
810  if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
811    if (!kVisitClass) {
812     // Mask out the class from the reference offsets.
813      ref_offsets ^= kWordHighBitMask;
814    }
815    DCHECK_EQ(ClassOffset().Uint32Value(), 0U);
816    // Found a reference offset bitmap. Visit the specified offsets.
817    while (ref_offsets != 0) {
818      size_t right_shift = CLZ(ref_offsets);
819      MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
820      visitor(this, field_offset, kIsStatic);
821      ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
822    }
823  } else {
824    // There is no reference offset bitmap.  In the non-static case, walk up the class
825    // inheritance hierarchy and find reference offsets the hard way. In the static case, just
826    // consider this class.
827    for (mirror::Class* klass = kIsStatic ? AsClass() : GetClass(); klass != nullptr;
828        klass = kIsStatic ? nullptr : klass->GetSuperClass()) {
829      size_t num_reference_fields =
830          kIsStatic ? klass->NumReferenceStaticFields() : klass->NumReferenceInstanceFields();
831      if (num_reference_fields == 0u) {
832        continue;
833      }
834      MemberOffset field_offset = kIsStatic
835          ? klass->GetFirstReferenceStaticFieldOffset()
836          : klass->GetFirstReferenceInstanceFieldOffset();
837      for (size_t i = 0; i < num_reference_fields; ++i) {
838        // TODO: Do a simpler check?
839        if (kVisitClass || field_offset.Uint32Value() != ClassOffset().Uint32Value()) {
840          visitor(this, field_offset, kIsStatic);
841        }
842        field_offset = MemberOffset(field_offset.Uint32Value() +
843                                    sizeof(mirror::HeapReference<mirror::Object>));
844      }
845    }
846  }
847}
848
849template<bool kVisitClass, typename Visitor>
850inline void Object::VisitInstanceFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
851  VisitFieldsReferences<kVisitClass, false>(
852      klass->GetReferenceInstanceOffsets<kVerifyNone>(), visitor);
853}
854
855template<bool kVisitClass, typename Visitor>
856inline void Object::VisitStaticFieldsReferences(mirror::Class* klass, const Visitor& visitor) {
857  DCHECK(!klass->IsTemp());
858  klass->VisitFieldsReferences<kVisitClass, true>(
859      klass->GetReferenceStaticOffsets<kVerifyNone>(), visitor);
860}
861
862template <const bool kVisitClass, VerifyObjectFlags kVerifyFlags, typename Visitor,
863    typename JavaLangRefVisitor>
864inline void Object::VisitReferences(const Visitor& visitor,
865                                    const JavaLangRefVisitor& ref_visitor) {
866  mirror::Class* klass = GetClass<kVerifyFlags>();
867  if (klass == Class::GetJavaLangClass()) {
868    AsClass<kVerifyNone>()->VisitReferences<kVisitClass>(klass, visitor);
869  } else if (klass->IsArrayClass()) {
870    if (klass->IsObjectArrayClass<kVerifyNone>()) {
871      AsObjectArray<mirror::Object, kVerifyNone>()->VisitReferences<kVisitClass>(visitor);
872    } else if (kVisitClass) {
873      visitor(this, ClassOffset(), false);
874    }
875  } else {
876    DCHECK(!klass->IsVariableSize());
877    VisitInstanceFieldsReferences<kVisitClass>(klass, visitor);
878    if (UNLIKELY(klass->IsTypeOfReferenceClass<kVerifyNone>())) {
879      ref_visitor(klass, AsReference());
880    }
881  }
882}
883}  // namespace mirror
884}  // namespace art
885
886#endif  // ART_RUNTIME_MIRROR_OBJECT_INL_H_
887