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_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 |
8 files changed, 97 insertions, 54 deletions
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 3d2fd7b..7f974d0 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 772d303..6bfd5c8 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_method.h b/runtime/mirror/art_method.h index fd5ac19..f513a04 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -423,7 +423,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 025e62a..3c02aa0 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 6dbb29d..ad86e1f 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 d955b97..226dee0 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 a6db387..fd4b5ff 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> @@ -104,15 +105,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 } @@ -146,16 +174,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); } @@ -172,14 +201,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> @@ -188,9 +218,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> @@ -210,9 +240,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); } @@ -338,20 +368,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 f652202..7e222a4 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_); @@ -114,9 +116,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> @@ -124,9 +126,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> @@ -159,12 +161,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_); |