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*);