diff options
| -rw-r--r-- | runtime/class_linker.cc | 4 | ||||
| -rw-r--r-- | runtime/mirror/array-inl.h | 9 | ||||
| -rw-r--r-- | runtime/mirror/array.h | 6 | ||||
| -rw-r--r-- | runtime/mirror/object-inl.h | 12 | ||||
| -rw-r--r-- | runtime/mirror/object.h | 4 |
5 files changed, 32 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index cb1fbfe630..ef0d72fb65 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -7090,7 +7090,9 @@ static void CheckVTableHasNoDuplicates(Thread* self, Handle<mirror::Class> klass MethodNameAndSignatureComparator name_comparator( vtable_entry->GetInterfaceMethodIfProxy(kPointerSize)); for (int32_t j = i + 1; j < num_entries; j++) { - ArtMethod* other_entry = vtable->GetElementPtrSize<ArtMethod*, kPointerSize>(j); + // Can use Unchecked here as the outer loop already ensured that the arrays are correct + // wrt/ kPointerSize. + ArtMethod* other_entry = vtable->GetElementPtrSizeUnchecked<ArtMethod*, kPointerSize>(j); if (!klass->CanAccessMember(other_entry->GetDeclaringClass(), other_entry->GetAccessFlags())) { continue; diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 40507e7aee..c4a892b856 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -233,6 +233,15 @@ inline T PointerArray::GetElementPtrSize(uint32_t idx) { } return (T)static_cast<uintptr_t>(AsIntArray<kVerifyFlags>()->GetWithoutChecks(idx)); } +template<typename T, PointerSize kPointerSize, VerifyObjectFlags kVerifyFlags> +inline T PointerArray::GetElementPtrSizeUnchecked(uint32_t idx) { + // C style casts here since we sometimes have T be a pointer, or sometimes an integer + // (for stack traces). + if (kPointerSize == PointerSize::k64) { + return (T)static_cast<uintptr_t>(AsLongArrayUnchecked<kVerifyFlags>()->GetWithoutChecks(idx)); + } + return (T)static_cast<uintptr_t>(AsIntArrayUnchecked<kVerifyFlags>()->GetWithoutChecks(idx)); +} template<typename T, VerifyObjectFlags kVerifyFlags> inline T PointerArray::GetElementPtrSize(uint32_t idx, PointerSize ptr_size) { // C style casts here since we sometimes have T be a pointer, or sometimes an integer diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index ce64272cf5..2e894d5dde 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -224,6 +224,12 @@ class PointerArray : public Array { template<typename T, PointerSize kPtrSize, VerifyObjectFlags kVerifyFlags = kVerifyNone> T GetElementPtrSize(uint32_t idx) REQUIRES_SHARED(Locks::mutator_lock_); + // Same as GetElementPtrSize, but uses unchecked version of array conversion. It is thus not + // checked whether kPtrSize matches the underlying array. Only use after at least one invocation + // of GetElementPtrSize! + template<typename T, PointerSize kPtrSize, VerifyObjectFlags kVerifyFlags = kVerifyNone> + T GetElementPtrSizeUnchecked(uint32_t idx) + REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kVerifyNone> void** ElementAddress(size_t index, PointerSize ptr_size) REQUIRES_SHARED(Locks::mutator_lock_) { diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 2c2ad9b9b0..005e272a7f 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -253,9 +253,13 @@ inline bool Object::IsIntArray() { } template<VerifyObjectFlags kVerifyFlags> +inline IntArray* Object::AsIntArrayUnchecked() { + return down_cast<IntArray*>(this); +} +template<VerifyObjectFlags kVerifyFlags> inline IntArray* Object::AsIntArray() { DCHECK((IsIntArray<kVerifyFlags>())); - return down_cast<IntArray*>(this); + return AsIntArrayUnchecked<kVerifyFlags>(); } template<VerifyObjectFlags kVerifyFlags> @@ -264,9 +268,13 @@ inline bool Object::IsLongArray() { } template<VerifyObjectFlags kVerifyFlags> +inline LongArray* Object::AsLongArrayUnchecked() { + return down_cast<LongArray*>(this); +} +template<VerifyObjectFlags kVerifyFlags> inline LongArray* Object::AsLongArray() { DCHECK((IsLongArray<kVerifyFlags>())); - return down_cast<LongArray*>(this); + return AsLongArrayUnchecked<kVerifyFlags>(); } template<VerifyObjectFlags kVerifyFlags> diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index ba222f6695..ca8867d80c 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -223,11 +223,15 @@ class MANAGED LOCKABLE Object { bool IsIntArray() REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> IntArray* AsIntArray() REQUIRES_SHARED(Locks::mutator_lock_); + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + IntArray* AsIntArrayUnchecked() REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> bool IsLongArray() REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> LongArray* AsLongArray() REQUIRES_SHARED(Locks::mutator_lock_); + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> + LongArray* AsLongArrayUnchecked() REQUIRES_SHARED(Locks::mutator_lock_); template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> bool IsFloatArray() REQUIRES_SHARED(Locks::mutator_lock_); |