diff options
Diffstat (limited to 'compiler/dex')
30 files changed, 198 insertions, 156 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index d1ddfda545..bd590467e3 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -15,13 +15,13 @@ */ #include "art_field-inl.h" +#include "art_method-inl.h" #include "base/logging.h" #include "base/mutex.h" #include "dex_file-inl.h" #include "dex_instruction-inl.h" #include "driver/compiler_driver.h" #include "driver/dex_compilation_unit.h" -#include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/dex_cache.h" #include "thread-inl.h" diff --git a/compiler/dex/mir_method_info.cc b/compiler/dex/mir_method_info.cc index 94be1fd4a5..be913fe634 100644 --- a/compiler/dex/mir_method_info.cc +++ b/compiler/dex/mir_method_info.cc @@ -83,7 +83,7 @@ void MirMethodLoweringInfo::Resolve(CompilerDriver* compiler_driver, MethodReference devirt_ref(it->target_dex_file_, it->target_method_idx_); MethodReference* devirt_target = (it->target_dex_file_ != nullptr) ? &devirt_ref : nullptr; InvokeType invoke_type = it->GetInvokeType(); - mirror::ArtMethod* resolved_method = nullptr; + ArtMethod* resolved_method = nullptr; bool string_init = false; if (default_inliner->IsStringInitMethodIndex(it->MethodIndex())) { diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc index 7679db8bac..7b1ec398d0 100644 --- a/compiler/dex/mir_optimization.cc +++ b/compiler/dex/mir_optimization.cc @@ -249,7 +249,7 @@ int MIRGraph::GetSSAUseCount(int s_reg) { size_t MIRGraph::GetNumBytesForSpecialTemps() const { // This logic is written with assumption that Method* is only special temp. DCHECK_EQ(max_available_special_compiler_temps_, 1u); - return sizeof(StackReference<mirror::ArtMethod>); + return InstructionSetPointerSize(cu_->instruction_set); } size_t MIRGraph::GetNumAvailableVRTemps() { @@ -316,6 +316,7 @@ CompilerTemp* MIRGraph::GetNewCompilerTemp(CompilerTempType ct_type, bool wide) // The vreg is always the first special temp for method ptr. compiler_temp->v_reg = GetFirstSpecialTempVR(); + CHECK(reg_location_ == nullptr); } else if (ct_type == kCompilerTempBackend) { requested_backend_temp_ = true; diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc index 822ea2106f..981ab2c1ee 100644 --- a/compiler/dex/quick/arm/call_arm.cc +++ b/compiler/dex/quick/arm/call_arm.cc @@ -19,6 +19,7 @@ #include "codegen_arm.h" #include "arm_lir.h" +#include "art_method.h" #include "base/bit_utils.h" #include "base/logging.h" #include "dex/mir_graph.h" @@ -27,7 +28,6 @@ #include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "gc/accounting/card_table.h" -#include "mirror/art_method.h" #include "mirror/object_array-inl.h" #include "entrypoints/quick/quick_entrypoints.h" #include "utils/dex_cache_arrays_layout-inl.h" @@ -637,7 +637,7 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info, if (direct_code == 0) { // kInvokeTgt := arg0_ref->entrypoint cg->LoadWordDisp(arg0_ref, - mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArmPointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt)); } break; @@ -678,7 +678,7 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info, case 1: // Get method->dex_cache_resolved_methods_ if (!use_pc_rel) { cg->LoadRefDisp(arg0_ref, - mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), + ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), arg0_ref, kNotVolatile); } @@ -708,14 +708,14 @@ int ArmMir2Lir::ArmNextSDCallInsn(CompilationUnit* cu, CallInfo* info, kNotVolatile); } else { size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index); - cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref); + cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref, false); } break; case 3: // Grab the code from the method* if (direct_code == 0) { // kInvokeTgt := arg0_ref->entrypoint cg->LoadWordDisp(arg0_ref, - mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArmPointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt)); } break; diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h index 83b27df939..b94e707354 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -83,7 +83,8 @@ class ArmMir2Lir FINAL : public Mir2Lir { void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE; - void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE; + void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, + bool wide) OVERRIDE; // Required for target - register utilities. RegStorage TargetReg(SpecialTargetRegister reg) OVERRIDE; diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 7de8e55e56..6d30e72f86 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -1107,7 +1107,9 @@ void ArmMir2Lir::OpPcRelDexCacheArrayAddr(const DexFile* dex_file, int offset, R dex_cache_access_insns_.push_back(movt); } -void ArmMir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) { +void ArmMir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, + bool wide) { + DCHECK(!wide) << "Unsupported"; if (dex_cache_arrays_base_reg_.Valid()) { LoadRefDisp(dex_cache_arrays_base_reg_, offset - dex_cache_arrays_min_offset_, r_dest, kNotVolatile); diff --git a/compiler/dex/quick/arm64/arm64_lir.h b/compiler/dex/quick/arm64/arm64_lir.h index 5bf77aae55..c530a8b23a 100644 --- a/compiler/dex/quick/arm64/arm64_lir.h +++ b/compiler/dex/quick/arm64/arm64_lir.h @@ -71,7 +71,7 @@ namespace art { * | IN[ins-1] | {Note: resides in caller's frame} * | . | * | IN[0] | - * | caller's method (StackReference<ArtMethod>)| {This is a compressed (4-bytes) reference} + * | caller's method ArtMethod* | {Pointer sized reference} * +============================================+ {Note: start of callee's frame} * | spill region | {variable sized - will include lr if non-leaf} * +--------------------------------------------+ @@ -90,7 +90,7 @@ namespace art { * | OUT[outs-2] | * | . | * | OUT[0] | - * | current method (StackReference<ArtMethod>) | <<== sp w/ 16-byte alignment + * | current method ArtMethod* | <<== sp w/ 16-byte alignment * +============================================+ */ diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc index e49e40d868..83a6affe81 100644 --- a/compiler/dex/quick/arm64/call_arm64.cc +++ b/compiler/dex/quick/arm64/call_arm64.cc @@ -19,6 +19,7 @@ #include "codegen_arm64.h" #include "arm64_lir.h" +#include "art_method.h" #include "base/logging.h" #include "dex/mir_graph.h" #include "dex/quick/dex_file_to_method_inliner_map.h" @@ -27,7 +28,6 @@ #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" @@ -456,23 +456,22 @@ static bool Arm64UseRelativeCall(CompilationUnit* cu, const MethodReference& tar */ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state, const MethodReference& target_method, - uint32_t unused_idx, + uint32_t unused_idx ATTRIBUTE_UNUSED, uintptr_t direct_code, uintptr_t direct_method, InvokeType type) { - UNUSED(info, unused_idx); Arm64Mir2Lir* cg = static_cast<Arm64Mir2Lir*>(cu->cg.get()); if (info->string_init_offset != 0) { RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); switch (state) { case 0: { // Grab target method* from thread pointer - cg->LoadRefDisp(rs_xSELF, info->string_init_offset, arg0_ref, kNotVolatile); + cg->LoadWordDisp(rs_xSELF, info->string_init_offset, arg0_ref); break; } case 1: // Grab the code from the method* if (direct_code == 0) { // kInvokeTgt := arg0_ref->entrypoint cg->LoadWordDisp(arg0_ref, - mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArm64PointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt)); } break; @@ -500,7 +499,7 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, } } else { bool use_pc_rel = cg->CanUseOpPcRelDexCacheArrayLoad(); - RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); + RegStorage arg0_ref = cg->TargetPtrReg(kArg0); switch (state) { case 0: // Get the current Method* [sets kArg0] // TUNING: we can save a reg copy if Method* has been promoted. @@ -513,7 +512,7 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, case 1: // Get method->dex_cache_resolved_methods_ if (!use_pc_rel) { cg->LoadRefDisp(arg0_ref, - mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), + ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), arg0_ref, kNotVolatile); } @@ -536,21 +535,19 @@ int Arm64Mir2Lir::Arm64NextSDCallInsn(CompilationUnit* cu, CallInfo* info, case 2: // Grab target method* CHECK_EQ(cu->dex_file, target_method.dex_file); if (!use_pc_rel) { - cg->LoadRefDisp(arg0_ref, - mirror::ObjectArray<mirror::Object>::OffsetOfElement( - target_method.dex_method_index).Int32Value(), - arg0_ref, - kNotVolatile); + cg->LoadWordDisp(arg0_ref, + mirror::Array::DataOffset(kArm64PointerSize).Uint32Value() + + target_method.dex_method_index * kArm64PointerSize, arg0_ref); } else { size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index); - cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref); + cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, arg0_ref, true); } break; case 3: // Grab the code from the method* if (direct_code == 0) { // kInvokeTgt := arg0_ref->entrypoint cg->LoadWordDisp(arg0_ref, - mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + ArtMethod::EntryPointFromQuickCompiledCodeOffset( kArm64PointerSize).Int32Value(), cg->TargetPtrReg(kInvokeTgt)); } break; diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h index 8184f02287..ca2e012950 100644 --- a/compiler/dex/quick/arm64/codegen_arm64.h +++ b/compiler/dex/quick/arm64/codegen_arm64.h @@ -79,7 +79,8 @@ class Arm64Mir2Lir FINAL : public Mir2Lir { void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE; - void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE; + void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, bool wide) + OVERRIDE; LIR* OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, int offset, int check_value, LIR* target, LIR** compare) OVERRIDE; diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc index 08aa5d20d0..31cf6675af 100644 --- a/compiler/dex/quick/arm64/int_arm64.cc +++ b/compiler/dex/quick/arm64/int_arm64.cc @@ -947,14 +947,17 @@ bool Arm64Mir2Lir::CanUseOpPcRelDexCacheArrayLoad() const { return dex_cache_arrays_layout_.Valid(); } -void Arm64Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, - RegStorage r_dest) { +void Arm64Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, + bool wide) { LIR* adrp = NewLIR2(kA64Adrp2xd, r_dest.GetReg(), 0); adrp->operands[2] = WrapPointer(dex_file); adrp->operands[3] = offset; adrp->operands[4] = WrapPointer(adrp); dex_cache_access_insns_.push_back(adrp); - LIR* ldr = LoadBaseDisp(r_dest, 0, r_dest, kReference, kNotVolatile); + if (wide) { + DCHECK(r_dest.Is64Bit()); + } + LIR* ldr = LoadBaseDisp(r_dest, 0, r_dest, wide ? k64 : kReference, kNotVolatile); ldr->operands[4] = adrp->operands[4]; ldr->flags.fixup = kFixupLabel; dex_cache_access_insns_.push_back(ldr); diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index fc32ecd955..d5de18d865 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -859,7 +859,8 @@ void Arm64Mir2Lir::InstallLiteralPools() { // PC-relative references to dex cache arrays. for (LIR* p : dex_cache_access_insns_) { - DCHECK(p->opcode == kA64Adrp2xd || p->opcode == kA64Ldr3rXD); + auto non_wide = UNWIDE(p->opcode); // May be a wide load for ArtMethod*. + DCHECK(non_wide == kA64Adrp2xd || non_wide == kA64Ldr3rXD) << p->opcode << " " << non_wide; const LIR* adrp = UnwrapPointer<LIR>(p->operands[4]); DCHECK_EQ(adrp->opcode, kA64Adrp2xd); const DexFile* dex_file = UnwrapPointer<DexFile>(adrp->operands[2]); @@ -895,8 +896,7 @@ void Arm64Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) rl_src[0] = mir_graph_->GetSrc(mir, 0); rl_src[1] = mir_graph_->GetSrc(mir, 1); rl_src[2]= mir_graph_->GetSrc(mir, 2); - GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], - (opcode == kMirOpMsubInt) ? true : false); + GenMaddMsubInt(rl_dest, rl_src[0], rl_src[1], rl_src[2], opcode == kMirOpMsubInt); break; case kMirOpMaddLong: case kMirOpMsubLong: @@ -904,8 +904,7 @@ void Arm64Mir2Lir::GenMachineSpecificExtendedMethodMIR(BasicBlock* bb, MIR* mir) rl_src[0] = mir_graph_->GetSrcWide(mir, 0); rl_src[1] = mir_graph_->GetSrcWide(mir, 2); rl_src[2] = mir_graph_->GetSrcWide(mir, 4); - GenMaddMsubLong(rl_dest, rl_src[0], rl_src[1], rl_src[2], - (opcode == kMirOpMsubLong) ? true : false); + GenMaddMsubLong(rl_dest, rl_src[0], rl_src[1], rl_src[2], opcode == kMirOpMsubLong); break; default: LOG(FATAL) << "Unexpected opcode: " << static_cast<int>(opcode); diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 86bb69d01e..f4bf31fb8a 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -1298,8 +1298,8 @@ void Mir2Lir::LoadMethodAddress(const MethodReference& target_method, InvokeType // resolve these invokes to the same method, so we don't care which one we record here. data_target->operands[2] = type; } - // Loads an ArtMethod pointer, which is a reference as it lives in the heap. - OpPcRelLoad(TargetReg(symbolic_reg, kRef), data_target); + // Loads an ArtMethod pointer, which is not a reference. + OpPcRelLoad(TargetPtrReg(symbolic_reg), data_target); DCHECK_NE(cu_->instruction_set, kMips) << reinterpret_cast<void*>(data_target); DCHECK_NE(cu_->instruction_set, kMips64) << reinterpret_cast<void*>(data_target); } @@ -1322,7 +1322,8 @@ bool Mir2Lir::CanUseOpPcRelDexCacheArrayLoad() const { void Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file ATTRIBUTE_UNUSED, int offset ATTRIBUTE_UNUSED, - RegStorage r_dest ATTRIBUTE_UNUSED) { + RegStorage r_dest ATTRIBUTE_UNUSED, + bool wide ATTRIBUTE_UNUSED) { LOG(FATAL) << "No generic implementation."; UNREACHABLE(); } diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 63f83f94cf..af108170e6 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -97,11 +97,11 @@ RegStorage Mir2Lir::GenGetOtherTypeForSgetSput(const MirSFieldLoweringInfo& fiel LockTemp(r_base); if (CanUseOpPcRelDexCacheArrayLoad()) { uint32_t offset = dex_cache_arrays_layout_.TypeOffset(field_info.StorageIndex()); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, r_base); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, r_base, false); } else { // Using fixed register to sync with possible call to runtime support. RegStorage r_method = LoadCurrMethodWithHint(r_base); - LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), r_base, + LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), r_base, kNotVolatile); int32_t offset_of_field = ObjArray::OffsetOfElement(field_info.StorageIndex()).Int32Value(); LoadRefDisp(r_base, offset_of_field, r_base, kNotVolatile); @@ -693,7 +693,7 @@ void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, OpSize size) { // Fast path, static storage base is this method's class r_base = AllocTempRef(); RegStorage r_method = LoadCurrMethodWithHint(r_base); - LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base, + LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), r_base, kNotVolatile); } else { // Medium path, static storage base in a different class which requires checks that the other @@ -771,7 +771,7 @@ void Mir2Lir::GenSget(MIR* mir, RegLocation rl_dest, OpSize size, Primitive::Typ // Fast path, static storage base is this method's class r_base = AllocTempRef(); RegStorage r_method = LoadCurrMethodWithHint(r_base); - LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), r_base, + LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), r_base, kNotVolatile); } else { // Medium path, static storage base in a different class which requires checks that the other @@ -1031,10 +1031,10 @@ void Mir2Lir::GenConstClass(uint32_t type_idx, RegLocation rl_dest) { // We don't need access checks, load type from dex cache if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg, false); } else { int32_t dex_cache_offset = - mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(); + ArtMethod::DexCacheResolvedTypesOffset().Int32Value(); RegStorage res_reg = AllocTempRef(); RegStorage r_method = LoadCurrMethodWithHint(res_reg); LoadRefDisp(r_method, dex_cache_offset, res_reg, kNotVolatile); @@ -1066,13 +1066,12 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) { RegStorage ret0 = TargetReg(kRet0, kRef); if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.StringOffset(string_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, ret0); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, ret0, false); } else { // Method to declaring class. RegStorage arg0 = TargetReg(kArg0, kRef); RegStorage r_method = LoadCurrMethodWithHint(arg0); - LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), - arg0, kNotVolatile); + LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), arg0, kNotVolatile); // Declaring class to dex cache strings. LoadRefDisp(arg0, mirror::Class::DexCacheStringsOffset().Int32Value(), arg0, kNotVolatile); @@ -1086,11 +1085,11 @@ void Mir2Lir::GenConstString(uint32_t string_idx, RegLocation rl_dest) { RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true); if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.StringOffset(string_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, rl_result.reg, false); } else { RegLocation rl_method = LoadCurrMethod(); RegStorage res_reg = AllocTempRef(); - LoadRefDisp(rl_method.reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), res_reg, + LoadRefDisp(rl_method.reg, ArtMethod::DeclaringClassOffset().Int32Value(), res_reg, kNotVolatile); LoadRefDisp(res_reg, mirror::Class::DexCacheStringsOffset().Int32Value(), res_reg, kNotVolatile); @@ -1173,18 +1172,18 @@ void Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, Re if (use_declaring_class) { RegStorage r_method = LoadCurrMethodWithHint(check_class); - LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), check_class, + LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), check_class, kNotVolatile); LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class, kNotVolatile); } else if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, check_class); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, check_class, false); LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class, kNotVolatile); } else { RegStorage r_method = LoadCurrMethodWithHint(check_class); - LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), + LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), check_class, kNotVolatile); LoadRefDisp(object.reg, mirror::Object::ClassOffset().Int32Value(), object_class, kNotVolatile); @@ -1232,7 +1231,7 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know } else if (use_declaring_class) { RegStorage r_method = LoadCurrMethodWithHint(TargetReg(kArg1, kRef)); LoadValueDirectFixed(rl_src, ref_reg); // kArg0 <= ref - LoadRefDisp(r_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), + LoadRefDisp(r_method, ArtMethod::DeclaringClassOffset().Int32Value(), class_reg, kNotVolatile); } else { if (can_assume_type_is_in_dex_cache) { @@ -1242,11 +1241,11 @@ void Mir2Lir::GenInstanceofCallingHelper(bool needs_access_check, bool type_know if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg, false); } else { RegStorage r_method = LoadCurrMethodWithHint(class_reg); // Load dex cache entry into class_reg (kArg2) - LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), + LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg, kNotVolatile); int32_t offset_of_type = ClassArray::OffsetOfElement(type_idx).Int32Value(); LoadRefDisp(class_reg, offset_of_type, class_reg, kNotVolatile); @@ -1367,17 +1366,17 @@ void Mir2Lir::GenCheckCast(int opt_flags, uint32_t insn_idx, uint32_t type_idx, OpRegCopy(class_reg, TargetReg(kRet0, kRef)); // Align usage with fast path } else if (use_declaring_class) { RegStorage method_reg = LoadCurrMethodWithHint(TargetReg(kArg1, kRef)); - LoadRefDisp(method_reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), + LoadRefDisp(method_reg, ArtMethod::DeclaringClassOffset().Int32Value(), class_reg, kNotVolatile); } else { // Load dex cache entry into class_reg (kArg2) if (CanUseOpPcRelDexCacheArrayLoad()) { size_t offset = dex_cache_arrays_layout_.TypeOffset(type_idx); - OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg); + OpPcRelDexCacheArrayLoad(cu_->dex_file, offset, class_reg, false); } else { RegStorage r_method = LoadCurrMethodWithHint(class_reg); - LoadRefDisp(r_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), + LoadRefDisp(r_method, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg, kNotVolatile); int32_t offset_of_type = ClassArray::OffsetOfElement(type_idx).Int32Value(); LoadRefDisp(class_reg, offset_of_type, class_reg, kNotVolatile); diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index ab011fc0b2..1f114cf336 100755 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -398,7 +398,7 @@ void Mir2Lir::CallRuntimeHelperRegLocationRegLocationRegLocationRegLocation( // TODO: Support 64-bit argument registers. void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { /* - * Dummy up a RegLocation for the incoming StackReference<mirror::ArtMethod> + * Dummy up a RegLocation for the incoming ArtMethod* * It will attempt to keep kArg0 live (or copy it to home location * if promoted). */ @@ -407,10 +407,15 @@ void Mir2Lir::FlushIns(RegLocation* ArgLocs, RegLocation rl_method) { rl_src.reg = TargetReg(kArg0, kRef); rl_src.home = false; MarkLive(rl_src); - StoreValue(rl_method, rl_src); + if (cu_->target64) { + DCHECK(rl_method.wide); + StoreValueWide(rl_method, rl_src); + } else { + StoreValue(rl_method, rl_src); + } // If Method* has been promoted, explicitly flush if (rl_method.location == kLocPhysReg) { - StoreRefDisp(TargetPtrReg(kSp), 0, rl_src.reg, kNotVolatile); + StoreBaseDisp(TargetPtrReg(kSp), 0, rl_src.reg, kWord, kNotVolatile); } if (mir_graph_->GetNumOfInVRs() == 0) { @@ -498,7 +503,7 @@ static void CommonCallCodeLoadClassIntoArg0(const CallInfo* info, Mir2Lir* cg) { static bool CommonCallCodeLoadCodePointerIntoInvokeTgt(const RegStorage* alt_from, const CompilationUnit* cu, Mir2Lir* cg) { if (cu->instruction_set != kX86 && cu->instruction_set != kX86_64) { - int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset( InstructionSetPointerSize(cu->instruction_set)).Int32Value(); // Get the compiled code address [use *alt_from or kArg0, set kInvokeTgt] cg->LoadWordDisp(alt_from == nullptr ? cg->TargetReg(kArg0, kRef) : *alt_from, offset, @@ -535,10 +540,12 @@ static int NextVCallInsn(CompilationUnit* cu, CallInfo* info, break; case 2: { // Get this->klass_.embedded_vtable[method_idx] [usr kArg0, set kArg0] - int32_t offset = mirror::Class::EmbeddedVTableOffset().Uint32Value() + - method_idx * sizeof(mirror::Class::VTableEntry); + const size_t pointer_size = InstructionSetPointerSize( + cu->compiler_driver->GetInstructionSet()); + int32_t offset = mirror::Class::EmbeddedVTableEntryOffset( + method_idx, pointer_size).Uint32Value(); // Load target method from embedded vtable to kArg0 [use kArg0, set kArg0] - cg->LoadRefDisp(cg->TargetReg(kArg0, kRef), offset, cg->TargetReg(kArg0, kRef), kNotVolatile); + cg->LoadWordDisp(cg->TargetPtrReg(kArg0), offset, cg->TargetPtrReg(kArg0)); break; } case 3: @@ -580,10 +587,12 @@ static int NextInterfaceCallInsn(CompilationUnit* cu, CallInfo* info, int state, // Includes a null-check. break; case 3: { // Get target method [use kInvokeTgt, set kArg0] - int32_t offset = mirror::Class::EmbeddedImTableOffset().Uint32Value() + - (method_idx % mirror::Class::kImtSize) * sizeof(mirror::Class::ImTableEntry); + const size_t pointer_size = InstructionSetPointerSize( + cu->compiler_driver->GetInstructionSet()); + int32_t offset = mirror::Class::EmbeddedImTableEntryOffset( + method_idx % mirror::Class::kImtSize, pointer_size).Uint32Value(); // Load target method from embedded imtable to kArg0 [use kArg0, set kArg0] - cg->LoadRefDisp(cg->TargetReg(kArg0, kRef), offset, cg->TargetReg(kArg0, kRef), kNotVolatile); + cg->LoadWordDisp(cg->TargetPtrReg(kArg0), offset, cg->TargetPtrReg(kArg0)); break; } case 4: @@ -967,7 +976,7 @@ bool Mir2Lir::GenInlinedReferenceGetReferent(CallInfo* info) { RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true); GenNullCheck(rl_obj.reg, info->opt_flags); LoadRefDisp(rl_obj.reg, mirror::Reference::ReferentOffset().Int32Value(), rl_result.reg, - kNotVolatile); + kNotVolatile); MarkPossibleNullPointerException(info->opt_flags); StoreValue(rl_dest, rl_result); @@ -1418,7 +1427,7 @@ bool Mir2Lir::GenInlinedCurrentThread(CallInfo* info) { RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true); - if (Is64BitInstructionSet(cu_->instruction_set)) { + if (cu_->target64) { LoadRefDisp(TargetPtrReg(kSelf), Thread::PeerOffset<8>().Int32Value(), rl_result.reg, kNotVolatile); } else { diff --git a/compiler/dex/quick/gen_loadstore.cc b/compiler/dex/quick/gen_loadstore.cc index 4215e8bc50..aa95e77f6d 100644 --- a/compiler/dex/quick/gen_loadstore.cc +++ b/compiler/dex/quick/gen_loadstore.cc @@ -42,7 +42,7 @@ LIR* Mir2Lir::LoadConstant(RegStorage r_dest, int value) { * register liveness. That is the responsibility of the caller. */ void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) { - rl_src = UpdateLoc(rl_src); + rl_src = rl_src.wide ? UpdateLocWide(rl_src) : UpdateLoc(rl_src); if (rl_src.location == kLocPhysReg) { OpRegCopy(r_dest, rl_src.reg); } else if (IsInexpensiveConstant(rl_src)) { @@ -53,11 +53,15 @@ void Mir2Lir::LoadValueDirect(RegLocation rl_src, RegStorage r_dest) { DCHECK((rl_src.location == kLocDalvikFrame) || (rl_src.location == kLocCompilerTemp)); ScopedMemRefType mem_ref_type(this, ResourceMask::kDalvikReg); + OpSize op_size; if (rl_src.ref) { - LoadRefDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, kNotVolatile); + op_size = kReference; + } else if (rl_src.wide) { + op_size = k64; } else { - Load32Disp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest); + op_size = k32; } + LoadBaseDisp(TargetPtrReg(kSp), SRegOffset(rl_src.s_reg_low), r_dest, op_size, kNotVolatile); } } @@ -337,7 +341,11 @@ void Mir2Lir::StoreFinalValueWide(RegLocation rl_dest, RegLocation rl_src) { /* Utilities to load the current Method* */ void Mir2Lir::LoadCurrMethodDirect(RegStorage r_tgt) { - LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt); + if (GetCompilationUnit()->target64) { + LoadValueDirectWideFixed(mir_graph_->GetMethodLoc(), r_tgt); + } else { + LoadValueDirectFixed(mir_graph_->GetMethodLoc(), r_tgt); + } } RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) { @@ -355,7 +363,9 @@ RegStorage Mir2Lir::LoadCurrMethodWithHint(RegStorage r_hint) { } RegLocation Mir2Lir::LoadCurrMethod() { - return LoadValue(mir_graph_->GetMethodLoc(), kRefReg); + return GetCompilationUnit()->target64 ? + LoadValueWide(mir_graph_->GetMethodLoc(), kCoreReg) : + LoadValue(mir_graph_->GetMethodLoc(), kRefReg); } RegLocation Mir2Lir::ForceTemp(RegLocation loc) { diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc index 3d253842c9..da12d8e3bf 100644 --- a/compiler/dex/quick/mips/call_mips.cc +++ b/compiler/dex/quick/mips/call_mips.cc @@ -18,6 +18,7 @@ #include "codegen_mips.h" +#include "art_method.h" #include "base/logging.h" #include "dex/mir_graph.h" #include "dex/quick/dex_file_to_method_inliner_map.h" @@ -26,7 +27,6 @@ #include "entrypoints/quick/quick_entrypoints.h" #include "gc/accounting/card_table.h" #include "mips_lir.h" -#include "mirror/art_method.h" #include "mirror/object_array-inl.h" namespace art { @@ -407,12 +407,12 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state, RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); switch (state) { case 0: { // Grab target method* from thread pointer - cg->LoadRefDisp(cg->TargetPtrReg(kSelf), info->string_init_offset, arg0_ref, kNotVolatile); + cg->LoadWordDisp(cg->TargetPtrReg(kSelf), info->string_init_offset, arg0_ref); break; } case 1: // Grab the code from the method* if (direct_code == 0) { - int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset( InstructionSetPointerSize(cu->instruction_set)).Int32Value(); cg->LoadWordDisp(arg0_ref, offset, cg->TargetPtrReg(kInvokeTgt)); } @@ -454,7 +454,7 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state, break; case 1: // Get method->dex_cache_resolved_methods_ cg->LoadRefDisp(arg0_ref, - mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), + ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), arg0_ref, kNotVolatile); // Set up direct code if known. @@ -471,17 +471,18 @@ static int NextSDCallInsn(CompilationUnit* cu, CallInfo* info, int state, } } break; - case 2: // Grab target method* + 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); + const size_t pointer_size = GetInstructionSetPointerSize(cu->instruction_set); + cg->LoadWordDisp(arg0_ref, + mirror::Array::DataOffset(pointer_size).Uint32Value() + + target_method.dex_method_index * pointer_size, arg0_ref); break; + } case 3: // Grab the code from the method* if (direct_code == 0) { - int32_t offset = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + int32_t offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset( InstructionSetPointerSize(cu->instruction_set)).Int32Value(); // Get the compiled code address [use *alt_from or kArg0, set kInvokeTgt] cg->LoadWordDisp(arg0_ref, offset, cg->TargetPtrReg(kInvokeTgt)); diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index e3e87ecb13..7ca03cf0ee 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -1232,6 +1232,10 @@ bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) { ResetRegPool(); int start_vreg = mir_graph_->GetFirstInVR(); AppendLIR(NewLIR0(kPseudoPrologueBegin)); + DCHECK_EQ(cu_->target64, Is64BitInstructionSet(cu_->instruction_set)); + if (cu_->target64) { + DCHECK(mir_graph_->GetMethodLoc().wide); + } GenEntrySequence(&mir_graph_->reg_location_[start_vreg], mir_graph_->GetMethodLoc()); AppendLIR(NewLIR0(kPseudoPrologueEnd)); DCHECK_EQ(cfi_.GetCurrentCFAOffset(), frame_size_); diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index d54616f47c..73787e958e 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -982,12 +982,11 @@ class Mir2Lir { } // Load a reference at base + displacement and decompress into register. LIR* LoadRefDisp(RegStorage r_base, int displacement, RegStorage r_dest, - VolatileKind is_volatile) { + VolatileKind is_volatile) { return LoadBaseDisp(r_base, displacement, r_dest, kReference, is_volatile); } // Load a reference at base + index and decompress into register. - LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, - int scale) { + LIR* LoadRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, int scale) { return LoadBaseIndexed(r_base, r_index, r_dest, scale, kReference); } // Load Dalvik value with 32-bit memory storage. If compressed object reference, decompress. @@ -1008,12 +1007,11 @@ class Mir2Lir { } // Store an uncompressed reference into a compressed 32-bit container. LIR* StoreRefDisp(RegStorage r_base, int displacement, RegStorage r_src, - VolatileKind is_volatile) { + VolatileKind is_volatile) { return StoreBaseDisp(r_base, displacement, r_src, kReference, is_volatile); } // Store an uncompressed reference into a compressed 32-bit container by index. - LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, - int scale) { + LIR* StoreRefIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, int scale) { return StoreBaseIndexed(r_base, r_index, r_src, scale, kReference); } // Store 32 bits, regardless of target. @@ -1117,8 +1115,10 @@ class Mir2Lir { * @param dex_file the dex file associated with the target dex cache. * @param offset the offset of the element in the fixed dex cache arrays' layout. * @param r_dest the register where to load the element. + * @param wide, load 64 bits if true, otherwise 32 bits. */ - virtual void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest); + virtual void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, + bool wide); // Routines that work for the generic case, but may be overriden by target. /* diff --git a/compiler/dex/quick/quick_cfi_test.cc b/compiler/dex/quick/quick_cfi_test.cc index b3c73557a7..8694ebc738 100644 --- a/compiler/dex/quick/quick_cfi_test.cc +++ b/compiler/dex/quick/quick_cfi_test.cc @@ -100,7 +100,8 @@ class QuickCFITest : public CFITest { } } m2l->AdjustSpillMask(); - m2l->GenEntrySequence(nullptr, m2l->LocCReturnRef()); + m2l->GenEntrySequence(nullptr, m2l->GetCompilationUnit()->target64 ? + m2l->LocCReturnWide() : m2l->LocCReturnRef()); m2l->GenExitSequence(); m2l->HandleSlowPaths(); m2l->AssembleLIR(); diff --git a/compiler/dex/quick/quick_cfi_test_expected.inc b/compiler/dex/quick/quick_cfi_test_expected.inc index 48109d2f44..52d66a40a8 100644 --- a/compiler/dex/quick/quick_cfi_test_expected.inc +++ b/compiler/dex/quick/quick_cfi_test_expected.inc @@ -34,7 +34,7 @@ static constexpr uint8_t expected_cfi_kThumb2[] = { static constexpr uint8_t expected_asm_kArm64[] = { 0xFF, 0x03, 0x01, 0xD1, 0xE8, 0xA7, 0x01, 0x6D, 0xF3, 0xD3, 0x02, 0xA9, - 0xFE, 0x1F, 0x00, 0xF9, 0xE0, 0x03, 0x00, 0xB9, 0xE8, 0xA7, 0x41, 0x6D, + 0xFE, 0x1F, 0x00, 0xF9, 0xE0, 0x03, 0x00, 0xF9, 0xE8, 0xA7, 0x41, 0x6D, 0xF3, 0xD3, 0x42, 0xA9, 0xFE, 0x1F, 0x40, 0xF9, 0xFF, 0x03, 0x01, 0x91, 0xC0, 0x03, 0x5F, 0xD6, }; @@ -54,7 +54,7 @@ static constexpr uint8_t expected_cfi_kArm64[] = { // 0x0000000c: .cfi_offset: r20 at cfa-16 // 0x0000000c: str lr, [sp, #56] // 0x00000010: .cfi_offset: r30 at cfa-8 -// 0x00000010: str w0, [sp] +// 0x00000010: str x0, [sp] // 0x00000014: .cfi_remember_state // 0x00000014: ldp d8, d9, [sp, #24] // 0x00000018: .cfi_restore_extended: r72 @@ -101,15 +101,15 @@ static constexpr uint8_t expected_cfi_kX86[] = { static constexpr uint8_t expected_asm_kX86_64[] = { 0x48, 0x83, 0xEC, 0x38, 0x48, 0x89, 0x5C, 0x24, 0x28, 0x48, 0x89, 0x6C, 0x24, 0x30, 0xF2, 0x44, 0x0F, 0x11, 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F, - 0x11, 0x6C, 0x24, 0x20, 0x48, 0x8B, 0xC7, 0x89, 0x3C, 0x24, 0x48, 0x8B, - 0x5C, 0x24, 0x28, 0x48, 0x8B, 0x6C, 0x24, 0x30, 0xF2, 0x44, 0x0F, 0x10, - 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F, 0x10, 0x6C, 0x24, 0x20, 0x48, 0x83, - 0xC4, 0x38, 0xC3, 0x00, + 0x11, 0x6C, 0x24, 0x20, 0x48, 0x8B, 0xC7, 0x48, 0x89, 0x3C, 0x24, 0x48, + 0x8B, 0x5C, 0x24, 0x28, 0x48, 0x8B, 0x6C, 0x24, 0x30, 0xF2, 0x44, 0x0F, + 0x10, 0x64, 0x24, 0x18, 0xF2, 0x44, 0x0F, 0x10, 0x6C, 0x24, 0x20, 0x48, + 0x83, 0xC4, 0x38, 0xC3, }; static constexpr uint8_t expected_cfi_kX86_64[] = { 0x44, 0x0E, 0x40, 0x45, 0x83, 0x06, 0x45, 0x86, 0x04, 0x47, 0x9D, 0x0A, - 0x47, 0x9E, 0x08, 0x46, 0x0A, 0x45, 0xC3, 0x45, 0xC6, 0x47, 0xDD, 0x47, - 0xDE, 0x44, 0x0E, 0x08, 0x42, 0x0B, 0x0E, 0x40, + 0x47, 0x9E, 0x08, 0x47, 0x0A, 0x45, 0xC3, 0x45, 0xC6, 0x47, 0xDD, 0x47, + 0xDE, 0x44, 0x0E, 0x08, 0x41, 0x0B, 0x0E, 0x40, }; // 0x00000000: subq rsp, 56 // 0x00000004: .cfi_def_cfa_offset: 64 @@ -122,20 +122,19 @@ static constexpr uint8_t expected_cfi_kX86_64[] = { // 0x00000015: movsd [rsp + 32], xmm13 // 0x0000001c: .cfi_offset: r30 at cfa-32 // 0x0000001c: movq rax, rdi -// 0x0000001f: mov [rsp], edi -// 0x00000022: .cfi_remember_state -// 0x00000022: movq rbx, [rsp + 40] -// 0x00000027: .cfi_restore: r3 -// 0x00000027: movq rbp, [rsp + 48] -// 0x0000002c: .cfi_restore: r6 -// 0x0000002c: movsd xmm12, [rsp + 24] -// 0x00000033: .cfi_restore: r29 -// 0x00000033: movsd xmm13, [rsp + 32] -// 0x0000003a: .cfi_restore: r30 -// 0x0000003a: addq rsp, 56 -// 0x0000003e: .cfi_def_cfa_offset: 8 -// 0x0000003e: ret -// 0x0000003f: addb al, al +// 0x0000001f: movq [rsp], rdi +// 0x00000023: .cfi_remember_state +// 0x00000023: movq rbx, [rsp + 40] +// 0x00000028: .cfi_restore: r3 +// 0x00000028: movq rbp, [rsp + 48] +// 0x0000002d: .cfi_restore: r6 +// 0x0000002d: movsd xmm12, [rsp + 24] +// 0x00000034: .cfi_restore: r29 +// 0x00000034: movsd xmm13, [rsp + 32] +// 0x0000003b: .cfi_restore: r30 +// 0x0000003b: addq rsp, 56 +// 0x0000003f: .cfi_def_cfa_offset: 8 +// 0x0000003f: ret // 0x00000040: .cfi_restore_state // 0x00000040: .cfi_def_cfa_offset: 64 @@ -172,7 +171,7 @@ static constexpr uint8_t expected_cfi_kMips[] = { // 0x00000028: .cfi_restore: r31 // 0x00000028: addiu r29, r29, 64 // 0x0000002c: .cfi_def_cfa_offset: 0 -// 0x0000002c: jalr r0, r31 +// 0x0000002c: jr r31 // 0x00000030: nop // 0x00000034: .cfi_restore_state // 0x00000034: .cfi_def_cfa_offset: 64 @@ -180,7 +179,7 @@ static constexpr uint8_t expected_cfi_kMips[] = { static constexpr uint8_t expected_asm_kMips64[] = { 0xE8, 0xFF, 0xBD, 0x67, 0x10, 0x00, 0xB2, 0xFF, 0x08, 0x00, 0xB3, 0xFF, 0x00, 0x00, 0xBF, 0xFF, 0xD8, 0xFF, 0xBD, 0x67, 0x25, 0x10, 0x80, 0x00, - 0x00, 0x00, 0xA4, 0xAF, 0x38, 0x00, 0xB2, 0xDF, 0x30, 0x00, 0xB3, 0xDF, + 0x00, 0x00, 0xA4, 0xFF, 0x38, 0x00, 0xB2, 0xDF, 0x30, 0x00, 0xB3, 0xDF, 0x28, 0x00, 0xBF, 0xDF, 0x40, 0x00, 0xBD, 0x67, 0x09, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, }; @@ -200,7 +199,7 @@ static constexpr uint8_t expected_cfi_kMips64[] = { // 0x00000010: daddiu r29, r29, -40 // 0x00000014: .cfi_def_cfa_offset: 64 // 0x00000014: or r2, r4, r0 -// 0x00000018: sw r4, +0(r29) +// 0x00000018: sd r4, +0(r29) // 0x0000001c: .cfi_remember_state // 0x0000001c: ld r18, +56(r29) // 0x00000020: .cfi_restore: r18 @@ -214,4 +213,3 @@ static constexpr uint8_t expected_cfi_kMips64[] = { // 0x00000030: nop // 0x00000034: .cfi_restore_state // 0x00000034: .cfi_def_cfa_offset: 64 - diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc index 7ca438225f..58236e2216 100644 --- a/compiler/dex/quick/quick_compiler.cc +++ b/compiler/dex/quick/quick_compiler.cc @@ -18,6 +18,7 @@ #include <cstdint> +#include "art_method-inl.h" #include "base/dumpable.h" #include "base/logging.h" #include "base/macros.h" @@ -37,7 +38,6 @@ #include "elf_writer_quick.h" #include "jni/quick/jni_compiler.h" #include "mir_to_lir.h" -#include "mirror/art_method-inl.h" #include "mirror/object.h" #include "runtime.h" @@ -787,7 +787,7 @@ CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags, return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file); } -uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const { +uintptr_t QuickCompiler::GetEntryPointOf(ArtMethod* method) const { return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize( InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet()))); } diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h index 8d2c324a70..43dd5786af 100644 --- a/compiler/dex/quick/quick_compiler.h +++ b/compiler/dex/quick/quick_compiler.h @@ -49,7 +49,7 @@ class QuickCompiler : public Compiler { uint32_t method_idx, const DexFile& dex_file) const OVERRIDE; - uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE + uintptr_t GetEntryPointOf(ArtMethod* method) const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); static Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit); diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc index 249575761e..43167a187f 100644 --- a/compiler/dex/quick/x86/call_x86.cc +++ b/compiler/dex/quick/x86/call_x86.cc @@ -18,13 +18,13 @@ #include "codegen_x86.h" +#include "art_method.h" #include "base/logging.h" #include "dex/quick/dex_file_to_method_inliner_map.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 "mirror/art_method.h" #include "mirror/object_array-inl.h" #include "utils/dex_cache_arrays_layout-inl.h" #include "x86_lir.h" @@ -379,7 +379,8 @@ int X86Mir2Lir::X86NextSDCallInsn(CompilationUnit* cu, CallInfo* info, case 0: { CHECK_EQ(cu->dex_file, target_method.dex_file); size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index); - cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, cg->TargetReg(kArg0, kRef)); + cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, cg->TargetReg(kArg0, kRef), + cu->target64); break; } default: @@ -394,18 +395,20 @@ int X86Mir2Lir::X86NextSDCallInsn(CompilationUnit* cu, CallInfo* info, break; case 1: // Get method->dex_cache_resolved_methods_ cg->LoadRefDisp(arg0_ref, - mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), + ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), arg0_ref, kNotVolatile); break; - case 2: // Grab target method* + 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); + const size_t pointer_size = GetInstructionSetPointerSize(cu->instruction_set); + cg->LoadWordDisp(arg0_ref, + mirror::Array::DataOffset(pointer_size).Uint32Value() + + target_method.dex_method_index * pointer_size, + arg0_ref); break; + } default: return -1; } diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index 5a465203bc..11d9d4ac34 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -105,7 +105,8 @@ class X86Mir2Lir FINAL : public Mir2Lir { void UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) OVERRIDE; bool CanUseOpPcRelDexCacheArrayLoad() const OVERRIDE; - void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest) OVERRIDE; + void OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, bool wide) + OVERRIDE; void GenImplicitNullCheck(RegStorage reg, int opt_flags) OVERRIDE; diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc index 9bbb5f84be..d993d934a5 100755 --- a/compiler/dex/quick/x86/int_x86.cc +++ b/compiler/dex/quick/x86/int_x86.cc @@ -18,11 +18,11 @@ #include "codegen_x86.h" +#include "art_method.h" #include "base/bit_utils.h" #include "base/logging.h" #include "dex/quick/mir_to_lir-inl.h" #include "dex/reg_storage_eq.h" -#include "mirror/art_method.h" #include "mirror/array-inl.h" #include "x86_lir.h" @@ -1410,16 +1410,18 @@ RegStorage X86Mir2Lir::GetPcAndAnchor(LIR** anchor, RegStorage r_tmp) { } } -void X86Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, - RegStorage r_dest) { +void X86Mir2Lir::OpPcRelDexCacheArrayLoad(const DexFile* dex_file, int offset, RegStorage r_dest, + bool wide) { if (cu_->target64) { - LIR* mov = NewLIR3(kX86Mov32RM, r_dest.GetReg(), kRIPReg, kDummy32BitOffset); + LIR* mov = NewLIR3(wide ? kX86Mov64RM : kX86Mov32RM, r_dest.GetReg(), kRIPReg, + kDummy32BitOffset); mov->flags.fixup = kFixupLabel; mov->operands[3] = WrapPointer(dex_file); mov->operands[4] = offset; mov->target = mov; // Used for pc_insn_offset (not used by x86-64 relative patcher). dex_cache_access_insns_.push_back(mov); } else { + CHECK(!wide) << "Unsupported"; // Get the PC to a register and get the anchor. Use r_dest for the temp if needed. LIR* anchor; RegStorage r_pc = GetPcAndAnchor(&anchor, r_dest); @@ -3022,20 +3024,20 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, if (rl_method.location == kLocPhysReg) { if (use_declaring_class) { - LoadRefDisp(rl_method.reg, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), + LoadRefDisp(rl_method.reg, ArtMethod::DeclaringClassOffset().Int32Value(), check_class, kNotVolatile); } else { - LoadRefDisp(rl_method.reg, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), + LoadRefDisp(rl_method.reg, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), check_class, kNotVolatile); LoadRefDisp(check_class, offset_of_type, check_class, kNotVolatile); } } else { LoadCurrMethodDirect(check_class); if (use_declaring_class) { - LoadRefDisp(check_class, mirror::ArtMethod::DeclaringClassOffset().Int32Value(), + LoadRefDisp(check_class, ArtMethod::DeclaringClassOffset().Int32Value(), check_class, kNotVolatile); } else { - LoadRefDisp(check_class, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), + LoadRefDisp(check_class, ArtMethod::DexCacheResolvedTypesOffset().Int32Value(), check_class, kNotVolatile); LoadRefDisp(check_class, offset_of_type, check_class, kNotVolatile); } @@ -3059,7 +3061,7 @@ void X86Mir2Lir::GenInstanceofFinal(bool use_declaring_class, uint32_t type_idx, } void X86Mir2Lir::GenArithOpInt(Instruction::Code opcode, RegLocation rl_dest, - RegLocation rl_lhs, RegLocation rl_rhs, int flags) { + RegLocation rl_lhs, RegLocation rl_rhs, int flags) { OpKind op = kOpBkpt; bool is_div_rem = false; bool unary = false; diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 2f211da264..c62cd47315 100755 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -21,6 +21,7 @@ #include <string> #include "arch/instruction_set_features.h" +#include "art_method.h" #include "backend_x86.h" #include "base/logging.h" #include "dex/compiler_ir.h" @@ -28,7 +29,6 @@ #include "dex/reg_storage_eq.h" #include "driver/compiler_driver.h" #include "mirror/array-inl.h" -#include "mirror/art_method.h" #include "mirror/string.h" #include "oat.h" #include "x86_lir.h" @@ -744,6 +744,7 @@ void X86Mir2Lir::SpillCoreRegs() { const RegStorage rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32; for (int reg = 0; mask != 0u; mask >>= 1, reg++) { if ((mask & 0x1) != 0u) { + DCHECK_NE(offset, 0) << "offset 0 should be for method"; RegStorage r_src = cu_->target64 ? RegStorage::Solo64(reg) : RegStorage::Solo32(reg); StoreBaseDisp(rs_rSP, offset, r_src, size, kNotVolatile); cfi_.RelOffset(DwarfCoreReg(cu_->target64, reg), offset); @@ -1026,7 +1027,7 @@ LIR* X86Mir2Lir::GenCallInsn(const MirMethodLoweringInfo& method_info) { call_insn = CallWithLinkerFixup(method_info.GetTargetMethod(), method_info.GetSharpType()); } else { call_insn = OpMem(kOpBlx, TargetReg(kArg0, kRef), - mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset( + ArtMethod::EntryPointFromQuickCompiledCodeOffset( cu_->target64 ? 8 : 4).Int32Value()); } } else { @@ -1103,7 +1104,7 @@ void X86Mir2Lir::InstallLiteralPools() { // PC-relative references to dex cache arrays. for (LIR* p : dex_cache_access_insns_) { - DCHECK(p->opcode == kX86Mov32RM); + DCHECK(p->opcode == kX86Mov32RM || p->opcode == kX86Mov64RM); const DexFile* dex_file = UnwrapPointer<DexFile>(p->operands[3]); uint32_t offset = p->operands[4]; // The offset to patch is the last 4 bytes of the instruction. diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h index 57db0158e4..d6a6a60d3d 100644 --- a/compiler/dex/quick/x86/x86_lir.h +++ b/compiler/dex/quick/x86/x86_lir.h @@ -82,7 +82,7 @@ namespace art { * | IN[ins-1] | {Note: resides in caller's frame} * | . | * | IN[0] | - * | caller's Method* | + * | caller's ArtMethod* | * +===========================+ {Note: start of callee's frame} * | return address | {pushed by call} * | spill region | {variable sized} @@ -104,7 +104,7 @@ namespace art { * | OUT[outs-2] | * | . | * | OUT[0] | - * | StackReference<ArtMethod> | <<== sp w/ 16-byte alignment + * | ArtMethod* | <<== sp w/ 16-byte alignment * +===========================+ */ diff --git a/compiler/dex/type_inference.cc b/compiler/dex/type_inference.cc index cd6467f4e5..a0dfcbee5b 100644 --- a/compiler/dex/type_inference.cc +++ b/compiler/dex/type_inference.cc @@ -686,8 +686,8 @@ TypeInference::CheckCastData* TypeInference::InitializeCheckCastData(MIRGraph* m void TypeInference::InitializeSRegs() { std::fill_n(sregs_, num_sregs_, Type::Unknown()); - /* Treat ArtMethod* as a normal reference */ - sregs_[mir_graph_->GetMethodSReg()] = Type::NonArrayRefType(); + /* Treat ArtMethod* specially since they are pointer sized */ + sregs_[mir_graph_->GetMethodSReg()] = Type::ArtMethodType(cu_->target64); // Initialize parameter SSA regs at method entry. int32_t entry_param_s_reg = mir_graph_->GetFirstInVR(); diff --git a/compiler/dex/type_inference.h b/compiler/dex/type_inference.h index 85f79af36e..adc3b54bc9 100644 --- a/compiler/dex/type_inference.h +++ b/compiler/dex/type_inference.h @@ -81,6 +81,10 @@ class TypeInference : public DeletableArenaObject<kArenaAllocMisc> { return Type(kFlagLowWord | kFlagNarrow | kFlagRef); } + static Type ArtMethodType(bool wide) { + return Type(kFlagLowWord | kFlagRef | (wide ? kFlagWide : kFlagNarrow)); + } + static Type ObjectArrayType() { return Type(kFlagNarrow | kFlagRef | kFlagLowWord | (1u << kBitArrayDepthStart) | kFlagArrayNarrow | kFlagArrayRef); diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc index e788261ad0..ac7a4a7758 100644 --- a/compiler/dex/verified_method.cc +++ b/compiler/dex/verified_method.cc @@ -20,12 +20,12 @@ #include <memory> #include <vector> +#include "art_method-inl.h" #include "base/logging.h" #include "base/stl_util.h" #include "dex_file.h" #include "dex_instruction-inl.h" #include "dex_instruction_utils.h" -#include "mirror/art_method-inl.h" #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" #include "mirror/object-inl.h" @@ -212,7 +212,7 @@ bool VerifiedMethod::GenerateDequickenMap(verifier::MethodVerifier* method_verif if (is_virtual_quick || is_range_quick) { uint32_t dex_pc = inst->GetDexPc(insns); verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc); - mirror::ArtMethod* method = + ArtMethod* method = method_verifier->GetQuickInvokedMethod(inst, line, is_range_quick, true); if (method == nullptr) { // It can be null if the line wasn't verified since it was unreachable. @@ -284,20 +284,24 @@ void VerifiedMethod::GenerateDevirtMap(verifier::MethodVerifier* method_verifier // We can't devirtualize abstract classes except on arrays of abstract classes. continue; } - mirror::ArtMethod* abstract_method = method_verifier->GetDexCache()->GetResolvedMethod( - is_range ? inst->VRegB_3rc() : inst->VRegB_35c()); + auto* cl = Runtime::Current()->GetClassLinker(); + size_t pointer_size = cl->GetImagePointerSize(); + ArtMethod* abstract_method = method_verifier->GetDexCache()->GetResolvedMethod( + is_range ? inst->VRegB_3rc() : inst->VRegB_35c(), pointer_size); if (abstract_method == nullptr) { // If the method is not found in the cache this means that it was never found // by ResolveMethodAndCheckAccess() called when verifying invoke_*. continue; } // Find the concrete method. - mirror::ArtMethod* concrete_method = nullptr; + ArtMethod* concrete_method = nullptr; if (is_interface) { - concrete_method = reg_type.GetClass()->FindVirtualMethodForInterface(abstract_method); + concrete_method = reg_type.GetClass()->FindVirtualMethodForInterface( + abstract_method, pointer_size); } if (is_virtual) { - concrete_method = reg_type.GetClass()->FindVirtualMethodForVirtual(abstract_method); + concrete_method = reg_type.GetClass()->FindVirtualMethodForVirtual( + abstract_method, pointer_size); } if (concrete_method == nullptr || concrete_method->IsAbstract()) { // In cases where concrete_method is not found, or is abstract, continue to the next invoke. |