Embed array class pointers at array allocation sites.

Following https://android-review.googlesource.com/#/c/79302, embed
array class pointers at array allocation sites in the compiled code.

Change-Id: I67a1292466dfbb7f48e746e5060e992dd93525c5
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 5ee750f..f6e8ca3 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -232,6 +232,30 @@
   return mirror::Array::Alloc<kInstrumented>(self, klass, component_count, allocator_type);
 }
 
+template <bool kAccessCheck, bool kInstrumented>
+ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
+                                                                      mirror::ArtMethod* method,
+                                                                      int32_t component_count,
+                                                                      Thread* self,
+                                                                      gc::AllocatorType allocator_type)
+    NO_THREAD_SAFETY_ANALYSIS {
+  DCHECK(klass != nullptr);
+  if (UNLIKELY(component_count < 0)) {
+    ThrowNegativeArraySizeException(component_count);
+    return nullptr;  // Failure
+  }
+  if (kAccessCheck) {
+    mirror::Class* referrer = method->GetDeclaringClass();
+    if (UNLIKELY(!referrer->CanAccess(klass))) {
+      ThrowIllegalAccessErrorClass(referrer, klass);
+      return nullptr;  // Failure
+    }
+  }
+  // No need to retry a slow-path allocation as the above code won't
+  // cause a GC or thread suspension.
+  return mirror::Array::Alloc<kInstrumented>(self, klass, component_count, allocator_type);
+}
+
 extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::ArtMethod* method,
                                                  int32_t component_count, Thread* self,
                                                  bool access_check,
diff --git a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
index 5657092..2e1b69d 100644
--- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc
@@ -56,6 +56,14 @@
   return AllocArrayFromCode<false, instrumented_bool>(type_idx, method, component_count, self, \
                                                       allocator_type); \
 } \
+extern "C" mirror::Array* artAllocArrayFromCodeResolved##suffix##suffix2( \
+    mirror::Class* klass, mirror::ArtMethod* method, int32_t component_count, Thread* self, \
+    mirror::ArtMethod** sp) \
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { \
+  FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); \
+  return AllocArrayFromCodeResolved<false, instrumented_bool>(klass, method, component_count, self, \
+                                                              allocator_type); \
+} \
 extern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck##suffix##suffix2( \
     uint32_t type_idx, mirror::ArtMethod* method, int32_t component_count, Thread* self, \
     mirror::ArtMethod** sp) \
diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h
index bbbc8f2..011e926 100644
--- a/runtime/entrypoints/quick/quick_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_entrypoints.h
@@ -40,6 +40,7 @@
 struct PACKED(4) QuickEntryPoints {
   // Alloc
   void* (*pAllocArray)(uint32_t, void*, int32_t);
+  void* (*pAllocArrayResolved)(void*, void*, int32_t);
   void* (*pAllocArrayWithAccessCheck)(uint32_t, void*, int32_t);
   void* (*pAllocObject)(uint32_t, void*);
   void* (*pAllocObjectResolved)(void*, void*);