diff options
Diffstat (limited to 'compiler/dex/quick/arm64/call_arm64.cc')
-rw-r--r-- | compiler/dex/quick/arm64/call_arm64.cc | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc index 823cb60..3316945 100644 --- a/compiler/dex/quick/arm64/call_arm64.cc +++ b/compiler/dex/quick/arm64/call_arm64.cc @@ -23,10 +23,12 @@ #include "dex/mir_graph.h" #include "dex/quick/mir_to_lir-inl.h" #include "driver/compiler_driver.h" +#include "driver/compiler_options.h" #include "gc/accounting/card_table.h" #include "entrypoints/quick/quick_entrypoints.h" #include "mirror/art_method.h" #include "mirror/object_array-inl.h" +#include "utils/dex_cache_arrays_layout-inl.h" namespace art { @@ -438,13 +440,13 @@ static bool Arm64UseRelativeCall(CompilationUnit* cu, const MethodReference& tar * Bit of a hack here - in the absence of a real scheduling pass, * emit the next instruction in static & direct invoke sequences. */ -static int Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, - int state, const MethodReference& target_method, - uint32_t unused_idx, - uintptr_t direct_code, uintptr_t direct_method, - InvokeType type) { +int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, + int state, const MethodReference& target_method, + uint32_t unused_idx, + uintptr_t direct_code, uintptr_t direct_method, + InvokeType type) { UNUSED(info, unused_idx); - Mir2Lir* cg = static_cast<Mir2Lir*>(cu->cg.get()); + Arm64Mir2Lir* cg = static_cast<Arm64Mir2Lir*>(cu->cg.get()); if (direct_code != 0 && direct_method != 0) { switch (state) { case 0: // Get the current Method* [sets kArg0] @@ -465,17 +467,24 @@ static int Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, return -1; } } else { + bool use_pc_rel = cg->CanUseOpPcRelDexCacheArrayLoad(); RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); switch (state) { case 0: // Get the current Method* [sets kArg0] // TUNING: we can save a reg copy if Method* has been promoted. - cg->LoadCurrMethodDirect(arg0_ref); - break; + if (!use_pc_rel) { + cg->LoadCurrMethodDirect(arg0_ref); + break; + } + ++state; + FALLTHROUGH_INTENDED; case 1: // Get method->dex_cache_resolved_methods_ - cg->LoadRefDisp(arg0_ref, - mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), - arg0_ref, - kNotVolatile); + if (!use_pc_rel) { + cg->LoadRefDisp(arg0_ref, + mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), + arg0_ref, + kNotVolatile); + } // Set up direct code if known. if (direct_code != 0) { if (direct_code != static_cast<uintptr_t>(-1)) { @@ -487,14 +496,23 @@ static int Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, cg->LoadCodeAddress(target_method, type, kInvokeTgt); } } - break; + if (!use_pc_rel || direct_code != 0) { + break; + } + ++state; + FALLTHROUGH_INTENDED; case 2: // Grab target method* CHECK_EQ(cu->dex_file, target_method.dex_file); - cg->LoadRefDisp(arg0_ref, - mirror::ObjectArray<mirror::Object>::OffsetOfElement( - target_method.dex_method_index).Int32Value(), - arg0_ref, - kNotVolatile); + if (!use_pc_rel) { + cg->LoadRefDisp(arg0_ref, + mirror::ObjectArray<mirror::Object>::OffsetOfElement( + target_method.dex_method_index).Int32Value(), + arg0_ref, + kNotVolatile); + } else { + size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index); + cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref); + } break; case 3: // Grab the code from the method* if (direct_code == 0) { |