diff options
author | 2018-11-09 17:12:23 +0000 | |
---|---|---|
committer | 2018-11-12 15:26:21 +0000 | |
commit | 104883b04617a850adf11f05e57c2fd29e09c83c (patch) | |
tree | 51d436588505a3ead506d633bdf97c9b4c934ae0 /runtime/mirror/object-inl.h | |
parent | 00e96d054e2b656d4d0f99fc141d1701af4dba23 (diff) |
Clean up primitive array helpers in Object.
Refactor these helpers and avoid read barriers. Remove
Class::Is{Int,Long}ArrayClass() and use the Object helpers
instead.
Remove the AsByteSizedArray() and AsShortSizedArray()
helpers that essentially break the type system and rewrite
their users, adding appropriate notes. {Float,Double}Array
uses in Unsafe would have previously failed a DCHECK().
Test: Additional test in 004-UnsafeTest.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I88b7e3df7de883f64cfc5eb437a40646f2884685
Diffstat (limited to 'runtime/mirror/object-inl.h')
-rw-r--r-- | runtime/mirror/object-inl.h | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 8ae79a8c66..fcb7479d5d 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -192,113 +192,102 @@ inline Array* Object::AsArray() { return down_cast<Array*>(this); } +template<VerifyObjectFlags kVerifyFlags, Primitive::Type kType> +ALWAYS_INLINE bool Object::IsSpecificPrimitiveArray() { + // We do not need a read barrier here as the primitive type is constant, + // both from-space and to-space component type classes shall yield the same result. + ObjPtr<Class> klass = GetClass<kVerifyFlags, kWithoutReadBarrier>(); + constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); + ObjPtr<Class> const component_type = klass->GetComponentType<kNewFlags, kWithoutReadBarrier>(); + return component_type != nullptr && + component_type->GetPrimitiveType<kNewFlags>() == kType; +} + +template<VerifyObjectFlags kVerifyFlags> +inline bool Object::IsBooleanArray() { + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimBoolean>(); +} + template<VerifyObjectFlags kVerifyFlags> inline BooleanArray* Object::AsBooleanArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->GetComponentType()->IsPrimitiveBoolean()); + DCHECK(IsBooleanArray<kVerifyFlags>()); return down_cast<BooleanArray*>(this); } template<VerifyObjectFlags kVerifyFlags> +inline bool Object::IsByteArray() { + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimByte>(); +} + +template<VerifyObjectFlags kVerifyFlags> inline ByteArray* Object::AsByteArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte()); + DCHECK(IsByteArray<kVerifyFlags>()); return down_cast<ByteArray*>(this); } template<VerifyObjectFlags kVerifyFlags> -inline ByteArray* Object::AsByteSizedArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveByte() || - GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveBoolean()); - return down_cast<ByteArray*>(this); +inline bool Object::IsCharArray() { + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimChar>(); } template<VerifyObjectFlags kVerifyFlags> inline CharArray* Object::AsCharArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); + DCHECK(IsCharArray<kVerifyFlags>()); return down_cast<CharArray*>(this); } template<VerifyObjectFlags kVerifyFlags> -inline ShortArray* Object::AsShortArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort()); - return down_cast<ShortArray*>(this); +inline bool Object::IsShortArray() { + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimShort>(); } template<VerifyObjectFlags kVerifyFlags> -inline ShortArray* Object::AsShortSizedArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveShort() || - GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveChar()); +inline ShortArray* Object::AsShortArray() { + DCHECK(IsShortArray<kVerifyFlags>()); return down_cast<ShortArray*>(this); } -template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> +template<VerifyObjectFlags kVerifyFlags> inline bool Object::IsIntArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - ObjPtr<Class> klass = GetClass<kVerifyFlags, kReadBarrierOption>(); - ObjPtr<Class> component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>(); - return component_type != nullptr && component_type->template IsPrimitiveInt<kNewFlags>(); + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimInt>(); } -template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> +template<VerifyObjectFlags kVerifyFlags> inline IntArray* Object::AsIntArray() { - DCHECK((IsIntArray<kVerifyFlags, kReadBarrierOption>())); + DCHECK((IsIntArray<kVerifyFlags>())); return down_cast<IntArray*>(this); } -template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> +template<VerifyObjectFlags kVerifyFlags> inline bool Object::IsLongArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - ObjPtr<Class> klass = GetClass<kVerifyFlags, kReadBarrierOption>(); - ObjPtr<Class> component_type = klass->GetComponentType<kVerifyFlags, kReadBarrierOption>(); - return component_type != nullptr && component_type->template IsPrimitiveLong<kNewFlags>(); + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimLong>(); } -template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> +template<VerifyObjectFlags kVerifyFlags> inline LongArray* Object::AsLongArray() { - DCHECK((IsLongArray<kVerifyFlags, kReadBarrierOption>())); + DCHECK((IsLongArray<kVerifyFlags>())); return down_cast<LongArray*>(this); } template<VerifyObjectFlags kVerifyFlags> inline bool Object::IsFloatArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); - return component_type != nullptr && component_type->template IsPrimitiveFloat<kNewFlags>(); + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimFloat>(); } template<VerifyObjectFlags kVerifyFlags> inline FloatArray* Object::AsFloatArray() { DCHECK(IsFloatArray<kVerifyFlags>()); - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat()); return down_cast<FloatArray*>(this); } template<VerifyObjectFlags kVerifyFlags> inline bool Object::IsDoubleArray() { - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - auto* component_type = GetClass<kVerifyFlags>()->GetComponentType(); - return component_type != nullptr && component_type->template IsPrimitiveDouble<kNewFlags>(); + return IsSpecificPrimitiveArray<kVerifyFlags, Primitive::kPrimDouble>(); } template<VerifyObjectFlags kVerifyFlags> inline DoubleArray* Object::AsDoubleArray() { DCHECK(IsDoubleArray<kVerifyFlags>()); - constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags); - DCHECK(GetClass<kVerifyFlags>()->IsArrayClass()); - DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble()); return down_cast<DoubleArray*>(this); } |