diff options
author | 2014-01-27 16:50:29 -0800 | |
---|---|---|
committer | 2014-01-27 16:50:29 -0800 | |
commit | bb8f0ab736b61db8f543e433859272e83f96ee9b (patch) | |
tree | 7b7bac5c0e7d0ac9aba91a40e0fbf761cfacb412 | |
parent | 6e65720d99bd3387b72d528a46291f1ed8184ede (diff) |
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
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 36 | ||||
-rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 13 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 2 | ||||
-rw-r--r-- | runtime/arch/quick_alloc_entrypoints.S | 2 | ||||
-rw-r--r-- | runtime/arch/quick_alloc_entrypoints.cc | 4 | ||||
-rw-r--r-- | runtime/arch/x86/quick_entrypoints_x86.S | 10 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.h | 24 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_alloc_entrypoints.cc | 8 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_entrypoints.h | 1 | ||||
-rw-r--r-- | runtime/thread.cc | 1 |
10 files changed, 98 insertions, 3 deletions
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 1f00b2a6a5..19a43b2099 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -207,13 +207,43 @@ void Mir2Lir::GenNewArray(uint32_t type_idx, RegLocation rl_dest, RegLocation rl_src) { FlushAllRegs(); /* Everything to home location */ ThreadOffset func_offset(-1); - if (cu_->compiler_driver->CanAccessTypeWithoutChecks(cu_->method_idx, *cu_->dex_file, + const DexFile* dex_file = cu_->dex_file; + CompilerDriver* driver = cu_->compiler_driver; + if (cu_->compiler_driver->CanAccessTypeWithoutChecks(cu_->method_idx, *dex_file, type_idx)) { - func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocArray); + bool is_type_initialized; // Ignored as an array does not have an initializer. + bool use_direct_type_ptr; + uintptr_t direct_type_ptr; + if (kEmbedClassInCode && + driver->CanEmbedTypeInCode(*dex_file, type_idx, + &is_type_initialized, &use_direct_type_ptr, &direct_type_ptr)) { + // The fast path. + if (!use_direct_type_ptr) { + // Use the literal pool and a PC-relative load from a data word. + LIR* data_target = ScanLiteralPool(class_literal_list_, type_idx, 0); + if (data_target == nullptr) { + data_target = AddWordData(&class_literal_list_, type_idx); + } + LIR* load_pc_rel = OpPcRelLoad(TargetReg(kArg0), data_target); + AppendLIR(load_pc_rel); + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocArrayResolved); + CallRuntimeHelperRegMethodRegLocation(func_offset, TargetReg(kArg0), rl_src, true); + } else { + // Use the direct pointer. + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocArrayResolved); + CallRuntimeHelperImmMethodRegLocation(func_offset, direct_type_ptr, rl_src, true); + } + } else { + // The slow path. + DCHECK_EQ(func_offset.Int32Value(), -1); + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocArray); + CallRuntimeHelperImmMethodRegLocation(func_offset, type_idx, rl_src, true); + } + DCHECK_NE(func_offset.Int32Value(), -1); } else { func_offset= QUICK_ENTRYPOINT_OFFSET(pAllocArrayWithAccessCheck); + CallRuntimeHelperImmMethodRegLocation(func_offset, type_idx, rl_src, true); } - CallRuntimeHelperImmMethodRegLocation(func_offset, type_idx, rl_src, true); RegLocation rl_result = GetReturn(false); StoreValue(rl_dest, rl_result); } diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index f865207fc7..4bc1a37d81 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -153,6 +153,19 @@ void Mir2Lir::CallRuntimeHelperRegMethod(ThreadOffset helper_offset, int arg0, b CallHelper(r_tgt, helper_offset, safepoint_pc); } +void Mir2Lir::CallRuntimeHelperRegMethodRegLocation(ThreadOffset helper_offset, int arg0, + RegLocation arg2, bool safepoint_pc) { + int r_tgt = CallHelperSetup(helper_offset); + DCHECK_NE(TargetReg(kArg1), arg0); + if (TargetReg(kArg0) != arg0) { + OpRegCopy(TargetReg(kArg0), arg0); + } + LoadCurrMethodDirect(TargetReg(kArg1)); + LoadValueDirectFixed(arg2, TargetReg(kArg2)); + ClobberCallerSave(); + CallHelper(r_tgt, helper_offset, safepoint_pc); +} + void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(ThreadOffset helper_offset, RegLocation arg0, RegLocation arg1, bool safepoint_pc) { int r_tgt = CallHelperSetup(helper_offset); diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 60b783d8ee..821e8294e0 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -530,6 +530,8 @@ class Mir2Lir : public Backend { void CallRuntimeHelperImmMethod(ThreadOffset helper_offset, int arg0, bool safepoint_pc); void CallRuntimeHelperRegMethod(ThreadOffset helper_offset, int arg0, bool safepoint_pc); + void CallRuntimeHelperRegMethodRegLocation(ThreadOffset helper_offset, int arg0, + RegLocation arg2, bool safepoint_pc); void CallRuntimeHelperRegLocationRegLocation(ThreadOffset helper_offset, RegLocation arg0, RegLocation arg1, bool safepoint_pc); diff --git a/runtime/arch/quick_alloc_entrypoints.S b/runtime/arch/quick_alloc_entrypoints.S index 4fdcb35930..632c5f372a 100644 --- a/runtime/arch/quick_alloc_entrypoints.S +++ b/runtime/arch/quick_alloc_entrypoints.S @@ -26,6 +26,8 @@ TWO_ARG_DOWNCALL art_quick_alloc_object_initialized\c_suffix, artAllocObjectFrom TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check\c_suffix, artAllocObjectFromCodeWithAccessCheck\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO // Called by managed code to allocate an array. THREE_ARG_DOWNCALL art_quick_alloc_array\c_suffix, artAllocArrayFromCode\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO +// Called by managed code to allocate an array of a resolve class. +THREE_ARG_DOWNCALL art_quick_alloc_array_resolved\c_suffix, artAllocArrayFromCodeResolved\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO // Called by managed code to allocate an array when the caller doesn't know whether it has access // to the created type. THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check\c_suffix, artAllocArrayFromCodeWithAccessCheck\cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO diff --git a/runtime/arch/quick_alloc_entrypoints.cc b/runtime/arch/quick_alloc_entrypoints.cc index 0fad82266c..9363f81cfe 100644 --- a/runtime/arch/quick_alloc_entrypoints.cc +++ b/runtime/arch/quick_alloc_entrypoints.cc @@ -19,6 +19,7 @@ #define GENERATE_ENTRYPOINTS(suffix) \ extern "C" void* art_quick_alloc_array##suffix(uint32_t, void*, int32_t); \ +extern "C" void* art_quick_alloc_array_resolved##suffix(void* klass, void*, int32_t); \ extern "C" void* art_quick_alloc_array_with_access_check##suffix(uint32_t, void*, int32_t); \ extern "C" void* art_quick_alloc_object##suffix(uint32_t type_idx, void* method); \ extern "C" void* art_quick_alloc_object_resolved##suffix(void* klass, void* method); \ @@ -27,6 +28,7 @@ extern "C" void* art_quick_alloc_object_with_access_check##suffix(uint32_t type_ extern "C" void* art_quick_check_and_alloc_array##suffix(uint32_t, void*, int32_t); \ extern "C" void* art_quick_check_and_alloc_array_with_access_check##suffix(uint32_t, void*, int32_t); \ extern "C" void* art_quick_alloc_array##suffix##_instrumented(uint32_t, void*, int32_t); \ +extern "C" void* art_quick_alloc_array_resolved##suffix##_instrumented(void* klass, void*, int32_t); \ extern "C" void* art_quick_alloc_array_with_access_check##suffix##_instrumented(uint32_t, void*, int32_t); \ extern "C" void* art_quick_alloc_object##suffix##_instrumented(uint32_t type_idx, void* method); \ extern "C" void* art_quick_alloc_object_resolved##suffix##_instrumented(void* klass, void* method); \ @@ -37,6 +39,7 @@ extern "C" void* art_quick_check_and_alloc_array_with_access_check##suffix##_ins void SetQuickAllocEntryPoints##suffix(QuickEntryPoints* qpoints, bool instrumented) { \ if (instrumented) { \ qpoints->pAllocArray = art_quick_alloc_array##suffix##_instrumented; \ + qpoints->pAllocArrayResolved = art_quick_alloc_array_resolved##suffix##_instrumented; \ qpoints->pAllocArrayWithAccessCheck = art_quick_alloc_array_with_access_check##suffix##_instrumented; \ qpoints->pAllocObject = art_quick_alloc_object##suffix##_instrumented; \ qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix##_instrumented; \ @@ -46,6 +49,7 @@ void SetQuickAllocEntryPoints##suffix(QuickEntryPoints* qpoints, bool instrument qpoints->pCheckAndAllocArrayWithAccessCheck = art_quick_check_and_alloc_array_with_access_check##suffix##_instrumented; \ } else { \ qpoints->pAllocArray = art_quick_alloc_array##suffix; \ + qpoints->pAllocArrayResolved = art_quick_alloc_array_resolved##suffix; \ qpoints->pAllocArrayWithAccessCheck = art_quick_alloc_array_with_access_check##suffix; \ qpoints->pAllocObject = art_quick_alloc_object##suffix; \ qpoints->pAllocObjectResolved = art_quick_alloc_object_resolved##suffix; \ diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index 48c7d8d5f3..74ec761f5b 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -413,6 +413,8 @@ END_MACRO TWO_ARG_DOWNCALL art_quick_alloc_object_with_access_check ## c_suffix, artAllocObjectFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO #define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(c_suffix, cxx_suffix) \ THREE_ARG_DOWNCALL art_quick_alloc_array ## c_suffix, artAllocArrayFromCode ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO +#define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(c_suffix, cxx_suffix) \ + THREE_ARG_DOWNCALL art_quick_alloc_array_resolved ## c_suffix, artAllocArrayFromCodeResolved ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO #define GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(c_suffix, cxx_suffix) \ THREE_ARG_DOWNCALL art_quick_alloc_array_with_access_check ## c_suffix, artAllocArrayFromCodeWithAccessCheck ## cxx_suffix, RETURN_IF_RESULT_IS_NON_ZERO #define GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(c_suffix, cxx_suffix) \ @@ -425,6 +427,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc, DlMalloc) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc, DlMalloc) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc, DlMalloc) @@ -434,6 +437,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_dlmalloc_instrumented, DlMallo GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_dlmalloc_instrumented, DlMallocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_dlmalloc_instrumented, DlMallocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_dlmalloc_instrumented, DlMallocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_dlmalloc_instrumented, DlMallocInstrumented) @@ -443,6 +447,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc, RosAlloc) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc, RosAlloc) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc, RosAlloc) @@ -452,6 +457,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_rosalloc_instrumented, RosAllo GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_rosalloc_instrumented, RosAllocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_rosalloc_instrumented, RosAllocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_rosalloc_instrumented, RosAllocInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_rosalloc_instrumented, RosAllocInstrumented) @@ -461,6 +467,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer, BumpPointer) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer, BumpPointer) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer, BumpPointer) @@ -470,6 +477,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_bump_pointer_instrumented, Bum GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_bump_pointer_instrumented, BumpPointerInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_bump_pointer_instrumented, BumpPointerInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_bump_pointer_instrumented, BumpPointerInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_bump_pointer_instrumented, BumpPointerInstrumented) @@ -479,6 +487,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab, TLAB) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab, TLAB) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab, TLAB) @@ -488,6 +497,7 @@ GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab_instrumented, TLABInstrum GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab_instrumented, TLABInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented) +GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab_instrumented, TLABInstrumented) GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY(_tlab_instrumented, TLABInstrumented) GENERATE_ALLOC_ENTRYPOINTS_CHECK_AND_ALLOC_ARRAY_WITH_ACCESS_CHECK(_tlab_instrumented, TLABInstrumented) diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 5ee750fa7f..f6e8ca3d64 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -232,6 +232,30 @@ ALWAYS_INLINE static inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, 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 5657092d8d..2e1b69d236 100644 --- a/runtime/entrypoints/quick/quick_alloc_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_alloc_entrypoints.cc @@ -56,6 +56,14 @@ extern "C" mirror::Array* artAllocArrayFromCode##suffix##suffix2( \ 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 bbbc8f24e0..011e92693e 100644 --- a/runtime/entrypoints/quick/quick_entrypoints.h +++ b/runtime/entrypoints/quick/quick_entrypoints.h @@ -40,6 +40,7 @@ class Thread; 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*); diff --git a/runtime/thread.cc b/runtime/thread.cc index e7fd660ae8..d195ebfe49 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -1624,6 +1624,7 @@ static const EntryPointInfo gThreadEntryPointInfo[] = { PORTABLE_ENTRY_POINT_INFO(pPortableResolutionTrampoline), PORTABLE_ENTRY_POINT_INFO(pPortableToInterpreterBridge), QUICK_ENTRY_POINT_INFO(pAllocArray), + QUICK_ENTRY_POINT_INFO(pAllocArrayResolved), QUICK_ENTRY_POINT_INFO(pAllocArrayWithAccessCheck), QUICK_ENTRY_POINT_INFO(pAllocObject), QUICK_ENTRY_POINT_INFO(pAllocObjectResolved), |