ART: Optimize array accesses

Optimize computation of the data offset of arrays by adding
a constant for the array payload field offset, and templatized
versions of the computation. Add a correctness check on runtime
creation.

Templatize CheckVTableHasNoDuplicates.

Decreases dex2oatd preopting of a big app from 165s to 151s.

Bug: 123888325
Test: m test-art-host
Change-Id: I8db9df545dc807a307aef8af7dad7a15757670b1
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index a6a5ba2..40507e7 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -224,14 +224,23 @@
   }
 }
 
+template<typename T, PointerSize kPointerSize, VerifyObjectFlags kVerifyFlags>
+inline T PointerArray::GetElementPtrSize(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>(AsLongArray<kVerifyFlags>()->GetWithoutChecks(idx));
+  }
+  return (T)static_cast<uintptr_t>(AsIntArray<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
   // (for stack traces).
   if (ptr_size == PointerSize::k64) {
-    return (T)static_cast<uintptr_t>(AsLongArray<kVerifyFlags>()->GetWithoutChecks(idx));
+    return GetElementPtrSize<T, PointerSize::k64, kVerifyFlags>(idx);
   }
-  return (T)static_cast<uintptr_t>(AsIntArray<kVerifyFlags>()->GetWithoutChecks(idx));
+  return GetElementPtrSize<T, PointerSize::k32, kVerifyFlags>(idx);
 }
 
 template<bool kTransactionActive, bool kUnchecked>