From be1ca55db3362f5b100c4c65da5342fd299520bb Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Wed, 15 Jan 2014 11:46:48 -0800 Subject: Use direct class pointers at allocation sites in the compiled code. - Rather than looking up a class from its type ID (and checking if it's resolved/initialized, resolving/initializing if not), use direct class pointers, if possible (boot-code-to-boot-class pointers and app-code-to-boot-class pointers.) - This results in a 1-2% speedup in Ritz MemAllocTest on Nexus 4. - Embedding the object size (along with class pointers) caused a 1-2% slowdown in MemAllocTest and isn't implemented in this change. - TODO: do the same for array allocations. - TODO: when/if an application gets its own image, implement app-code-to-app-class pointers. - Fix a -XX:gc bug. cf. https://android-review.googlesource.com/79460/ - Add /tmp/android-data/dalvik-cache to the list of locations to remove oat files in clean-oat-host. cf. https://android-review.googlesource.com/79550 - Add back a dropped UNLIKELY in FindMethodFromCode(). cf. https://android-review.googlesource.com/74205 Bug: 9986565 Change-Id: I590b96bd21f7a7472f88e36752e675547559a5b1 --- compiler/dex/quick/gen_common.cc | 49 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'compiler/dex/quick/gen_common.cc') diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 3bd0298a22..daf21df19d 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -19,6 +19,7 @@ #include "dex/quick/mir_to_lir-inl.h" #include "entrypoints/quick/quick_entrypoints.h" #include "mirror/array.h" +#include "mirror/object-inl.h" #include "verifier/method_verifier.h" namespace art { @@ -883,13 +884,53 @@ void Mir2Lir::GenNewInstance(uint32_t type_idx, RegLocation rl_dest) { // alloc will always check for resolution, do we also need to verify // access because the verifier was unable to? ThreadOffset func_offset(-1); - if (cu_->compiler_driver->CanAccessInstantiableTypeWithoutChecks( - cu_->method_idx, *cu_->dex_file, type_idx)) { - func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObject); + const DexFile* dex_file = cu_->dex_file; + CompilerDriver* driver = cu_->compiler_driver; + if (driver->CanAccessInstantiableTypeWithoutChecks( + cu_->method_idx, *dex_file, type_idx)) { + bool is_type_initialized; + 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); + if (!is_type_initialized) { + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObjectResolved); + CallRuntimeHelperRegMethod(func_offset, TargetReg(kArg0), true); + } else { + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObjectInitialized); + CallRuntimeHelperRegMethod(func_offset, TargetReg(kArg0), true); + } + } else { + // Use the direct pointer. + if (!is_type_initialized) { + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObjectResolved); + CallRuntimeHelperImmMethod(func_offset, direct_type_ptr, true); + } else { + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObjectInitialized); + CallRuntimeHelperImmMethod(func_offset, direct_type_ptr, true); + } + } + } else { + // The slow path. + DCHECK_EQ(func_offset.Int32Value(), -1); + func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObject); + CallRuntimeHelperImmMethod(func_offset, type_idx, true); + } + DCHECK_NE(func_offset.Int32Value(), -1); } else { func_offset = QUICK_ENTRYPOINT_OFFSET(pAllocObjectWithAccessCheck); + CallRuntimeHelperImmMethod(func_offset, type_idx, true); } - CallRuntimeHelperImmMethod(func_offset, type_idx, true); RegLocation rl_result = GetReturn(false); StoreValue(rl_dest, rl_result); } -- cgit v1.2.3-59-g8ed1b