summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/class_linker.cc4
-rw-r--r--runtime/mirror/array-inl.h9
-rw-r--r--runtime/mirror/array.h6
-rw-r--r--runtime/mirror/object-inl.h12
-rw-r--r--runtime/mirror/object.h4
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_);