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