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 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> 49 inline Class* Object::GetClass() { 50 return GetFieldObject<Class, kVerifyFlags, kReadBarrierOption>( 51 OFFSET_OF_OBJECT_MEMBER(Object, klass_)); 52 } 53 54 template<VerifyObjectFlags kVerifyFlags> 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> 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> 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 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 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 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 104 inline uint32_t Object::GetLockOwnerThreadId() { 105 return Monitor::GetLockOwnerThreadId(this); 106 } 107 108 inline mirror::Object* Object::MonitorEnter(Thread* self) { 109 return Monitor::MonitorEnter(self, this); 110 } 111 112 inline bool Object::MonitorExit(Thread* self) { 113 return Monitor::MonitorExit(self, this); 114 } 115 116 inline void Object::Notify(Thread* self) { 117 Monitor::Notify(self, this); 118 } 119 120 inline void Object::NotifyAll(Thread* self) { 121 Monitor::NotifyAll(self, this); 122 } 123 124 inline void Object::Wait(Thread* self) { 125 Monitor::Wait(self, this, 0, 0, true, kWaiting); 126 } 127 128 inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { 129 Monitor::Wait(self, this, ms, ns, true, kTimedWaiting); 130 } 131 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 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> 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 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> 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> 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> 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> 253 inline Class* Object::AsClass() { 254 DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>())); 255 return down_cast<Class*>(this); 256 } 257 258 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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> 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> 273 inline bool Object::IsArrayInstance() { 274 return GetClass<kVerifyFlags, kReadBarrierOption>()-> 275 template IsArrayClass<kVerifyFlags, kReadBarrierOption>(); 276 } 277 278 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 279 inline bool Object::IsReferenceInstance() { 280 return GetClass<kVerifyFlags, kReadBarrierOption>()->IsTypeOfReferenceClass(); 281 } 282 283 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 284 inline Reference* Object::AsReference() { 285 DCHECK((IsReferenceInstance<kVerifyFlags, kReadBarrierOption>())); 286 return down_cast<Reference*>(this); 287 } 288 289 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 290 inline Array* Object::AsArray() { 291 DCHECK((IsArrayInstance<kVerifyFlags, kReadBarrierOption>())); 292 return down_cast<Array*>(this); 293 } 294 295 template<VerifyObjectFlags kVerifyFlags> 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> 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> 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> 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> 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> 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> 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> 354 inline IntArray* Object::AsIntArray() { 355 DCHECK((IsIntArray<kVerifyFlags, kReadBarrierOption>())); 356 return down_cast<IntArray*>(this); 357 } 358 359 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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> 368 inline LongArray* Object::AsLongArray() { 369 DCHECK((IsLongArray<kVerifyFlags, kReadBarrierOption>())); 370 return down_cast<LongArray*>(this); 371 } 372 373 template<VerifyObjectFlags kVerifyFlags> 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> 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> 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> 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> 406 inline bool Object::IsString() { 407 return GetClass<kVerifyFlags, kReadBarrierOption>()->IsStringClass(); 408 } 409 410 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 411 inline String* Object::AsString() { 412 DCHECK((IsString<kVerifyFlags, kReadBarrierOption>())); 413 return down_cast<String*>(this); 414 } 415 416 template<VerifyObjectFlags kVerifyFlags> 417 inline Throwable* Object::AsThrowable() { 418 DCHECK(GetClass<kVerifyFlags>()->IsThrowableClass()); 419 return down_cast<Throwable*>(this); 420 } 421 422 template<VerifyObjectFlags kVerifyFlags> 423 inline bool Object::IsWeakReferenceInstance() { 424 return GetClass<kVerifyFlags>()->IsWeakReferenceClass(); 425 } 426 427 template<VerifyObjectFlags kVerifyFlags> 428 inline bool Object::IsSoftReferenceInstance() { 429 return GetClass<kVerifyFlags>()->IsSoftReferenceClass(); 430 } 431 432 template<VerifyObjectFlags kVerifyFlags> 433 inline bool Object::IsFinalizerReferenceInstance() { 434 return GetClass<kVerifyFlags>()->IsFinalizerReferenceClass(); 435 } 436 437 template<VerifyObjectFlags kVerifyFlags> 438 inline FinalizerReference* Object::AsFinalizerReference() { 439 DCHECK(IsFinalizerReferenceInstance<kVerifyFlags>()); 440 return down_cast<FinalizerReference*>(this); 441 } 442 443 template<VerifyObjectFlags kVerifyFlags> 444 inline bool Object::IsPhantomReferenceInstance() { 445 return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); 446 } 447 448 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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> 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> 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> 487 inline uint8_t Object::GetFieldBooleanVolatile(MemberOffset field_offset) { 488 return GetFieldBoolean<kVerifyFlags, true>(field_offset); 489 } 490 491 template<VerifyObjectFlags kVerifyFlags> 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> 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> 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> 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> 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> 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> 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> 561 inline uint16_t Object::GetFieldCharVolatile(MemberOffset field_offset) { 562 return GetFieldChar<kVerifyFlags, true>(field_offset); 563 } 564 565 template<VerifyObjectFlags kVerifyFlags> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 1097 inline bool Object::IsClassLoader() { 1098 return GetClass<kVerifyFlags, kReadBarrierOption>()->IsClassLoaderClass(); 1099 } 1100 1101 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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> 1108 inline bool Object::IsDexCache() { 1109 return GetClass<kVerifyFlags, kReadBarrierOption>()->IsDexCacheClass(); 1110 } 1111 1112 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> 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> 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