diff options
Diffstat (limited to 'runtime/mirror')
-rw-r--r-- | runtime/mirror/array-inl.h | 5 | ||||
-rw-r--r-- | runtime/mirror/array.h | 2 | ||||
-rw-r--r-- | runtime/mirror/art_field.cc | 21 | ||||
-rw-r--r-- | runtime/mirror/art_field.h | 4 | ||||
-rw-r--r-- | runtime/mirror/art_method.cc | 6 | ||||
-rw-r--r-- | runtime/mirror/art_method.h | 2 | ||||
-rw-r--r-- | runtime/mirror/class-inl.h | 13 | ||||
-rw-r--r-- | runtime/mirror/class.cc | 10 | ||||
-rw-r--r-- | runtime/mirror/class.h | 16 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 83 | ||||
-rw-r--r-- | runtime/mirror/object.h | 20 |
11 files changed, 125 insertions, 57 deletions
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 3d2fd7b0ae..7f974d0cf0 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -27,10 +27,11 @@ namespace art { namespace mirror { -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline size_t Array::SizeOf() { // This is safe from overflow because the array was already allocated, so we know it's sane. - size_t component_size = GetClass<kVerifyFlags>()->GetComponentSize(); + size_t component_size = + GetClass<kVerifyFlags, kDoReadBarrier>()->template GetComponentSize<kDoReadBarrier>(); // Don't need to check this since we already check this in GetClass. int32_t component_count = GetLength<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(); diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index 772d303360..6bfd5c890f 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -41,7 +41,7 @@ class MANAGED Array : public Object { const SirtRef<IntArray>& dimensions) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> int32_t GetLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc index f91cab1036..7b0b94cd78 100644 --- a/runtime/mirror/art_field.cc +++ b/runtime/mirror/art_field.cc @@ -19,6 +19,7 @@ #include "art_field-inl.h" #include "gc/accounting/card_table-inl.h" #include "object-inl.h" +#include "object_array-inl.h" #include "object_utils.h" #include "runtime.h" #include "scoped_thread_state_change.h" @@ -69,5 +70,25 @@ void ArtField::VisitRoots(RootCallback* callback, void* arg) { } } +// TODO: we could speed up the search if fields are ordered by offsets. +ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) { + DCHECK(klass != nullptr); + ObjectArray<ArtField>* instance_fields = klass->GetIFields(); + if (instance_fields != nullptr) { + for (int32_t i = 0, e = instance_fields->GetLength(); i < e; ++i) { + mirror::ArtField* field = instance_fields->GetWithoutChecks(i); + if (field->GetOffset().Uint32Value() == field_offset) { + return field; + } + } + } + // We did not find field in the class: look into superclass. + if (klass->GetSuperClass() != NULL) { + return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset); + } else { + return nullptr; + } +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h index 0daa838a2c..ba70cc64e3 100644 --- a/runtime/mirror/art_field.h +++ b/runtime/mirror/art_field.h @@ -132,6 +132,10 @@ class MANAGED ArtField : public Object { return (GetAccessFlags() & kAccVolatile) != 0; } + // Returns an instance field with this offset in the given class or nullptr if not found. + static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + private: // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". // The class we are a part of diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index f3303a8267..726004bfee 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -315,13 +315,13 @@ void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* } else { (*art_portable_invoke_stub)(this, args, args_size, self, result, shorty[0]); } - if (UNLIKELY(reinterpret_cast<intptr_t>(self->GetException(NULL)) == -1)) { - // Unusual case where we were running LLVM generated code and an + if (UNLIKELY(self->GetException(nullptr) == Thread::GetDeoptimizationException())) { + // Unusual case where we were running generated code and an // exception was thrown to force the activations to be removed from the // stack. Continue execution in the interpreter. self->ClearException(); ShadowFrame* shadow_frame = self->GetAndClearDeoptimizationShadowFrame(result); - self->SetTopOfStack(NULL, 0); + self->SetTopOfStack(nullptr, 0); self->SetTopOfShadowStack(shadow_frame); interpreter::EnterInterpreterFromDeoptimize(self, shadow_frame, result); } diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index d684266f53..4462036366 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -426,7 +426,9 @@ class MANAGED ArtMethod : public Object { static void SetClass(Class* java_lang_reflect_ArtMethod); + template <bool kDoReadBarrier = true> static Class* GetJavaLangReflectArtMethod() { + // This does not need a RB because it is a root. return java_lang_reflect_ArtMethod_; } diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 025e62a5cb..3c02aa0b49 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -478,6 +478,19 @@ inline void Class::VisitReferences(mirror::Class* klass, const Visitor& visitor) VisitStaticFieldsReferences<kVisitClass>(this, visitor); } +template<bool kDoReadBarrier> +bool Class::IsArtFieldClass() { + Class* java_lang_Class = GetClass<kVerifyNone, kDoReadBarrier>(); + Class* java_lang_reflect_ArtField = + java_lang_Class->GetInstanceField(0)->GetClass<kVerifyNone, kDoReadBarrier>(); + return this == java_lang_reflect_ArtField; +} + +template<bool kDoReadBarrier> +bool Class::IsArtMethodClass() { + return this == ArtMethod::GetJavaLangReflectArtMethod<kDoReadBarrier>(); +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 6dbb29dae3..ad86e1fc88 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -328,16 +328,6 @@ bool Class::IsThrowableClass() { return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this); } -bool Class::IsArtFieldClass() { - Class* java_lang_Class = GetClass(); - Class* java_lang_reflect_ArtField = java_lang_Class->GetInstanceField(0)->GetClass(); - return this == java_lang_reflect_ArtField; -} - -bool Class::IsArtMethodClass() { - return this == ArtMethod::GetJavaLangReflectArtMethod(); -} - void Class::SetClassLoader(ClassLoader* new_class_loader) { if (Runtime::Current()->IsActiveTransaction()) { SetFieldObject<true>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false); diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index d955b9791f..226dee0c9a 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -364,9 +364,9 @@ class MANAGED Class : public Object { return depth; } - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> bool IsArrayClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return GetComponentType<kVerifyFlags>() != NULL; + return GetComponentType<kVerifyFlags, kDoReadBarrier>() != NULL; } bool IsClassClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -375,17 +375,19 @@ class MANAGED Class : public Object { bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + template<bool kDoReadBarrier = true> bool IsArtFieldClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + template<bool kDoReadBarrier = true> bool IsArtMethodClass(); static MemberOffset ComponentTypeOffset() { return OFFSET_OF_OBJECT_MEMBER(Class, component_type_); } - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> Class* GetComponentType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return GetFieldObject<Class, kVerifyFlags>(ComponentTypeOffset(), false); + return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>(ComponentTypeOffset(), false); } void SetComponentType(Class* new_component_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { @@ -395,8 +397,10 @@ class MANAGED Class : public Object { SetFieldObject<false, false>(ComponentTypeOffset(), new_component_type, false); } + template<bool kDoReadBarrier = true> size_t GetComponentSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return Primitive::ComponentSize(GetComponentType()->GetPrimitiveType()); + return Primitive::ComponentSize( + GetComponentType<kDefaultVerifyFlags, kDoReadBarrier>()->GetPrimitiveType()); } bool IsObjectClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { @@ -427,7 +431,7 @@ class MANAGED Class : public Object { return IsClassClass() || IsArrayClass(); } - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> uint32_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false); } diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index b195dea57e..04517ec28b 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -34,9 +34,10 @@ namespace art { namespace mirror { -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline Class* Object::GetClass() { - return GetFieldObject<Class, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false); + return GetFieldObject<Class, kVerifyFlags, kDoReadBarrier>( + OFFSET_OF_OBJECT_MEMBER(Object, klass_), false); } template<VerifyObjectFlags kVerifyFlags> @@ -105,15 +106,42 @@ inline Object* Object::GetReadBarrierPointer() { #endif } -inline void Object::SetReadBarrierPointer(Object* rb_pointer) { +inline void Object::SetReadBarrierPointer(Object* rb_ptr) { #ifdef USE_BAKER_OR_BROOKS_READ_BARRIER DCHECK(kUseBakerOrBrooksReadBarrier); // We don't mark the card as this occurs as part of object allocation. Not all objects have // backing cards, such as large objects. SetFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>( - OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_pointer, false); + OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_), rb_ptr, false); +#else + LOG(FATAL) << "Unreachable"; +#endif +} + +inline bool Object::AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) { +#ifdef USE_BAKER_OR_BROOKS_READ_BARRIER + DCHECK(kUseBakerOrBrooksReadBarrier); + MemberOffset offset = OFFSET_OF_OBJECT_MEMBER(Object, x_rb_ptr_); + byte* raw_addr = reinterpret_cast<byte*>(this) + offset.SizeValue(); + HeapReference<Object>* ref = reinterpret_cast<HeapReference<Object>*>(raw_addr); + HeapReference<Object> expected_ref(HeapReference<Object>::FromMirrorPtr(expected_rb_ptr)); + HeapReference<Object> new_ref(HeapReference<Object>::FromMirrorPtr(rb_ptr)); + uint32_t expected_val = expected_ref.reference_; + uint32_t new_val; + do { + uint32_t old_val = ref->reference_; + if (old_val != expected_val) { + // Lost the race. + return false; + } + new_val = new_ref.reference_; + } while (!__sync_bool_compare_and_swap( + reinterpret_cast<uint32_t*>(raw_addr), expected_val, new_val)); + DCHECK_EQ(new_val, ref->reference_); + return true; #else LOG(FATAL) << "Unreachable"; + return false; #endif } @@ -147,16 +175,17 @@ inline bool Object::InstanceOf(Class* klass) { return klass->IsAssignableFrom(GetClass<kVerifyFlags>()); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline bool Object::IsClass() { - Class* java_lang_Class = GetClass<kVerifyFlags>()->GetClass(); - return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() == + Class* java_lang_Class = + GetClass<kVerifyFlags, kDoReadBarrier>()->template GetClass<kVerifyFlags, kDoReadBarrier>(); + return GetClass<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis), kDoReadBarrier>() == java_lang_Class; } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline Class* Object::AsClass() { - DCHECK(IsClass<kVerifyFlags>()); + DCHECK((IsClass<kVerifyFlags, kDoReadBarrier>())); return down_cast<Class*>(this); } @@ -173,14 +202,15 @@ inline ObjectArray<T>* Object::AsObjectArray() { return down_cast<ObjectArray<T>*>(this); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline bool Object::IsArrayInstance() { - return GetClass<kVerifyFlags>()->IsArrayClass(); + return GetClass<kVerifyFlags, kDoReadBarrier>()-> + template IsArrayClass<kVerifyFlags, kDoReadBarrier>(); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline bool Object::IsArtField() { - return GetClass<kVerifyFlags>()->IsArtFieldClass(); + return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtFieldClass<kDoReadBarrier>(); } template<VerifyObjectFlags kVerifyFlags> @@ -189,9 +219,9 @@ inline ArtField* Object::AsArtField() { return down_cast<ArtField*>(this); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline bool Object::IsArtMethod() { - return GetClass<kVerifyFlags>()->IsArtMethodClass(); + return GetClass<kVerifyFlags, kDoReadBarrier>()->template IsArtMethodClass<kDoReadBarrier>(); } template<VerifyObjectFlags kVerifyFlags> @@ -211,9 +241,9 @@ inline Reference* Object::AsReference() { return down_cast<Reference*>(this); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline Array* Object::AsArray() { - DCHECK(IsArrayInstance<kVerifyFlags>()); + DCHECK((IsArrayInstance<kVerifyFlags, kDoReadBarrier>())); return down_cast<Array*>(this); } @@ -339,20 +369,21 @@ inline bool Object::IsPhantomReferenceInstance() { return GetClass<kVerifyFlags>()->IsPhantomReferenceClass(); } -template<VerifyObjectFlags kVerifyFlags> +template<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier> inline size_t Object::SizeOf() { size_t result; constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis); - if (IsArrayInstance<kVerifyFlags>()) { - result = AsArray<kNewFlags>()->template SizeOf<kNewFlags>(); - } else if (IsClass<kNewFlags>()) { - result = AsClass<kNewFlags>()->template SizeOf<kNewFlags>(); + if (IsArrayInstance<kVerifyFlags, kDoReadBarrier>()) { + result = AsArray<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>(); + } else if (IsClass<kNewFlags, kDoReadBarrier>()) { + result = AsClass<kNewFlags, kDoReadBarrier>()->template SizeOf<kNewFlags, kDoReadBarrier>(); } else { - result = GetClass<kNewFlags>()->GetObjectSize(); + result = GetClass<kNewFlags, kDoReadBarrier>()->GetObjectSize(); } - DCHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(GetClass<kNewFlags>()); - DCHECK(!IsArtField<kNewFlags>() || result == sizeof(ArtField)); - DCHECK(!IsArtMethod<kNewFlags>() || result == sizeof(ArtMethod)); + DCHECK_GE(result, sizeof(Object)) + << " class=" << PrettyTypeOf(GetClass<kNewFlags, kDoReadBarrier>()); + DCHECK(!(IsArtField<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtField)); + DCHECK(!(IsArtMethod<kNewFlags, kDoReadBarrier>()) || result == sizeof(ArtMethod)); return result; } diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index fd31dfbbb5..370b3b89cb 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -72,14 +72,16 @@ class MANAGED LOCKABLE Object { return OFFSET_OF_OBJECT_MEMBER(Object, klass_); } - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> Class* GetClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> void SetClass(Class* new_klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); Object* GetReadBarrierPointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - void SetReadBarrierPointer(Object* rb_pointer) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void SetReadBarrierPointer(Object* rb_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool AtomicSetReadBarrierPointer(Object* expected_rb_ptr, Object* rb_ptr) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void AssertReadBarrierPointer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // The verifier treats all interfaces as java.lang.Object and relies on runtime checks in @@ -89,7 +91,7 @@ class MANAGED LOCKABLE Object { template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> bool InstanceOf(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -116,9 +118,9 @@ class MANAGED LOCKABLE Object { void Wait(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void Wait(Thread* self, int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> bool IsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> Class* AsClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> @@ -126,9 +128,9 @@ class MANAGED LOCKABLE Object { template<class T, VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> ObjectArray<T>* AsObjectArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> bool IsArrayInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> Array* AsArray() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> @@ -161,12 +163,12 @@ class MANAGED LOCKABLE Object { template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> bool IsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> ArtMethod* AsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kDoReadBarrier = true> bool IsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); |