diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/dex/quick/arm/assemble_arm.cc | 14 | ||||
| -rw-r--r-- | compiler/dex/quick/arm/int_arm.cc | 1 | ||||
| -rw-r--r-- | compiler/dex/quick/arm64/assemble_arm64.cc | 4 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.cc | 2 | ||||
| -rwxr-xr-x | compiler/dex/quick/gen_invoke.cc | 20 | ||||
| -rw-r--r-- | compiler/dex/quick/mips/utility_mips.cc | 14 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 3 | ||||
| -rw-r--r-- | compiler/dex/verification_results.cc | 7 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 8 | ||||
| -rw-r--r-- | compiler/jit/jit_compiler.cc | 17 |
10 files changed, 71 insertions, 19 deletions
diff --git a/compiler/dex/quick/arm/assemble_arm.cc b/compiler/dex/quick/arm/assemble_arm.cc index 3d64833942..8833da324f 100644 --- a/compiler/dex/quick/arm/assemble_arm.cc +++ b/compiler/dex/quick/arm/assemble_arm.cc @@ -117,11 +117,11 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { "add", "!0C, !1C", 2, kFixupNone), ENCODING_MAP(kThumbAddPcRel, 0xa000, kFmtBitBlt, 10, 8, kFmtBitBlt, 7, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_TERTIARY_OP | IS_BRANCH | NEEDS_FIXUP, + kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0 | REG_USE_PC | NEEDS_FIXUP, "add", "!0C, pc, #!1E", 2, kFixupLoad), ENCODING_MAP(kThumbAddSpRel, 0xa800, kFmtBitBlt, 10, 8, kFmtSkip, -1, -1, kFmtBitBlt, 7, 0, - kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF_SP | REG_USE_SP, + kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0 | REG_USE_SP, "add", "!0C, sp, #!2E", 2, kFixupNone), ENCODING_MAP(kThumbAddSpI7, 0xb000, kFmtBitBlt, 6, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1, @@ -182,7 +182,7 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { "blx", "!0C", 2, kFixupNone), ENCODING_MAP(kThumbBx, 0x4700, kFmtBitBlt, 6, 3, kFmtUnused, -1, -1, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_UNARY_OP | IS_BRANCH, + kFmtUnused, -1, -1, IS_UNARY_OP | REG_USE0 | IS_BRANCH, "bx", "!0C", 2, kFixupNone), ENCODING_MAP(kThumbCmnRR, 0x42c0, kFmtBitBlt, 2, 0, kFmtBitBlt, 5, 3, kFmtUnused, -1, -1, @@ -693,7 +693,7 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { ENCODING_MAP(kThumb2AdcRRR, 0xeb500000, /* setflags encoding */ kFmtBitBlt, 11, 8, kFmtBitBlt, 19, 16, kFmtBitBlt, 3, 0, kFmtShift, -1, -1, - IS_QUAD_OP | REG_DEF0_USE12 | SETS_CCODES, + IS_QUAD_OP | REG_DEF0_USE12 | SETS_CCODES | USES_CCODES, "adcs", "!0C, !1C, !2C!3H", 4, kFixupNone), ENCODING_MAP(kThumb2AndRRR, 0xea000000, kFmtBitBlt, 11, 8, kFmtBitBlt, 19, 16, kFmtBitBlt, 3, 0, @@ -835,15 +835,15 @@ const ArmEncodingMap ArmMir2Lir::EncodingMap[kArmLast] = { "it:!1b", "!0c", 2, kFixupNone), ENCODING_MAP(kThumb2Fmstat, 0xeef1fa10, kFmtUnused, -1, -1, kFmtUnused, -1, -1, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, NO_OPERAND | SETS_CCODES, + kFmtUnused, -1, -1, NO_OPERAND | SETS_CCODES | USES_CCODES, "fmstat", "", 4, kFixupNone), ENCODING_MAP(kThumb2Vcmpd, 0xeeb40b40, kFmtDfp, 22, 12, kFmtDfp, 5, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE01, + kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE01 | SETS_CCODES, "vcmp.f64", "!0S, !1S", 4, kFixupNone), ENCODING_MAP(kThumb2Vcmps, 0xeeb40a40, kFmtSfp, 22, 12, kFmtSfp, 5, 0, kFmtUnused, -1, -1, - kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE01, + kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE01 | SETS_CCODES, "vcmp.f32", "!0s, !1s", 4, kFixupNone), ENCODING_MAP(kThumb2LdrPcRel12, 0xf8df0000, kFmtBitBlt, 15, 12, kFmtBitBlt, 11, 0, kFmtUnused, -1, -1, diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc index 3159886826..2a4d27ba57 100644 --- a/compiler/dex/quick/arm/int_arm.cc +++ b/compiler/dex/quick/arm/int_arm.cc @@ -1079,6 +1079,7 @@ bool ArmMir2Lir::GenInlinedArrayCopyCharArray(CallInfo* info) { } LIR* ArmMir2Lir::OpPcRelLoad(RegStorage reg, LIR* target) { + ScopedMemRefType mem_ref_type(this, ResourceMask::kLiteral); return RawLIR(current_dalvik_offset_, kThumb2LdrPcRel12, reg.GetReg(), 0, 0, 0, 0, target); } diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc index 806617be2a..aa5e5b4719 100644 --- a/compiler/dex/quick/arm64/assemble_arm64.cc +++ b/compiler/dex/quick/arm64/assemble_arm64.cc @@ -111,7 +111,7 @@ namespace art { const A64EncodingMap Arm64Mir2Lir::EncodingMap[kA64Last] = { ENCODING_MAP(WIDE(kA64Adc3rrr), SF_VARIANTS(0x1a000000), kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtRegR, 20, 16, - kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12, + kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12 | USES_CCODES, "adc", "!0r, !1r, !2r", kFixupNone), ENCODING_MAP(WIDE(kA64Add4RRdT), SF_VARIANTS(0x11000000), kFmtRegROrSp, 4, 0, kFmtRegROrSp, 9, 5, kFmtBitBlt, 21, 10, @@ -518,7 +518,7 @@ const A64EncodingMap Arm64Mir2Lir::EncodingMap[kA64Last] = { "ror", "!0r, !1r, !2r", kFixupNone), ENCODING_MAP(WIDE(kA64Sbc3rrr), SF_VARIANTS(0x5a000000), kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtRegR, 20, 16, - kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12, + kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12 | USES_CCODES, "sbc", "!0r, !1r, !2r", kFixupNone), ENCODING_MAP(WIDE(kA64Sbfm4rrdd), SF_N_VARIANTS(0x13000000), kFmtRegR, 4, 0, kFmtRegR, 9, 5, kFmtBitBlt, 21, 16, diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index f636e3b880..8e3f4ef726 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -718,7 +718,7 @@ bool DexFileMethodInliner::AddInlineMethod(int32_t method_idx, const InlineMetho if (PrettyMethod(method_idx, *dex_file_) == "int java.lang.String.length()") { // TODO: String.length is both kIntrinsicIsEmptyOrLength and kInlineOpIGet. } else { - LOG(ERROR) << "Inliner: " << PrettyMethod(method_idx, *dex_file_) << " already inline"; + LOG(WARNING) << "Inliner: " << PrettyMethod(method_idx, *dex_file_) << " already inline"; } return false; } diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 040b07cedd..01f1d375ed 100755 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -248,14 +248,16 @@ void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(QuickEntrypointEnum trampo if (arg0.wide == 0) { LoadValueDirectFixed(arg0, TargetReg(arg0.fp ? kFArg0 : kArg0, kNotWide)); if (arg1.wide == 0) { + // For Mips, when the 1st arg is integral, then remaining arg are passed in core reg. if (cu_->instruction_set == kMips) { - LoadValueDirectFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg1, kNotWide)); + LoadValueDirectFixed(arg1, TargetReg((arg1.fp && arg0.fp) ? kFArg2 : kArg1, kNotWide)); } else { LoadValueDirectFixed(arg1, TargetReg(arg1.fp ? kFArg1 : kArg1, kNotWide)); } } else { + // For Mips, when the 1st arg is integral, then remaining arg are passed in core reg. if (cu_->instruction_set == kMips) { - LoadValueDirectWideFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg2, kWide)); + LoadValueDirectWideFixed(arg1, TargetReg((arg1.fp && arg0.fp) ? kFArg2 : kArg2, kWide)); } else { LoadValueDirectWideFixed(arg1, TargetReg(arg1.fp ? kFArg1 : kArg1, kWide)); } @@ -263,9 +265,19 @@ void Mir2Lir::CallRuntimeHelperRegLocationRegLocation(QuickEntrypointEnum trampo } else { LoadValueDirectWideFixed(arg0, TargetReg(arg0.fp ? kFArg0 : kArg0, kWide)); if (arg1.wide == 0) { - LoadValueDirectFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg2, kNotWide)); + // For Mips, when the 1st arg is integral, then remaining arg are passed in core reg. + if (cu_->instruction_set == kMips) { + LoadValueDirectFixed(arg1, TargetReg((arg1.fp && arg0.fp) ? kFArg2 : kArg2, kNotWide)); + } else { + LoadValueDirectFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg2, kNotWide)); + } } else { - LoadValueDirectWideFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg2, kWide)); + // For Mips, when the 1st arg is integral, then remaining arg are passed in core reg. + if (cu_->instruction_set == kMips) { + LoadValueDirectWideFixed(arg1, TargetReg((arg1.fp && arg0.fp) ? kFArg2 : kArg2, kWide)); + } else { + LoadValueDirectWideFixed(arg1, TargetReg(arg1.fp ? kFArg2 : kArg2, kWide)); + } } } } diff --git a/compiler/dex/quick/mips/utility_mips.cc b/compiler/dex/quick/mips/utility_mips.cc index ec6edabdbd..2d26922dca 100644 --- a/compiler/dex/quick/mips/utility_mips.cc +++ b/compiler/dex/quick/mips/utility_mips.cc @@ -17,6 +17,7 @@ #include "codegen_mips.h" #include "arch/mips/instruction_set_features_mips.h" +#include "arch/mips/entrypoints_direct_mips.h" #include "base/logging.h" #include "dex/quick/mir_to_lir-inl.h" #include "dex/reg_storage_eq.h" @@ -708,7 +709,18 @@ LIR* MipsMir2Lir::OpCondBranch(ConditionCode cc, LIR* target) { } LIR* MipsMir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) { - UNUSED(trampoline); // The address of the trampoline is already loaded into r_tgt. + if (IsDirectEntrypoint(trampoline)) { + // Reserve argument space on stack (for $a0-$a3) for + // entrypoints that directly reference native implementations. + // This is not safe in general, as it violates the frame size + // of the Quick method, but it is used here only for calling + // native functions, outside of the runtime. + OpRegImm(kOpSub, rs_rSP, 16); + LIR* retVal = OpReg(op, r_tgt); + OpRegImm(kOpAdd, rs_rSP, 16); + return retVal; + } + return OpReg(op, r_tgt); } diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index 966a92d290..83486265c4 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -587,6 +587,9 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::MOVE_FROM16: case Instruction::MOVE_OBJECT_FROM16: StoreValue(rl_dest, rl_src[0]); + if (rl_src[0].is_const && (mir_graph_->ConstantValue(rl_src[0]) == 0)) { + Workaround7250540(rl_dest, RegStorage::InvalidReg()); + } break; case Instruction::MOVE_WIDE: diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 51a3d84382..150bdaca67 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -71,8 +71,11 @@ bool VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method DCHECK_EQ(it->second->GetSafeCastSet().size(), verified_method->GetSafeCastSet().size()); } DCHECK_EQ(it->second->GetDexGcMap().size(), verified_method->GetDexGcMap().size()); - delete it->second; - verified_methods_.erase(it); + // Delete the new verified method since there was already an existing one registered. It + // is unsafe to replace the existing one since the JIT may be using it to generate a + // native GC map. + delete verified_method; + return true; } verified_methods_.Put(ref, verified_method); DCHECK(verified_methods_.find(ref) != verified_methods_.end()); diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 15b3d08a37..90e63e9674 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -1316,6 +1316,14 @@ void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType } } } + if (runtime->UseJit()) { + // If we are the JIT, then don't allow a direct call to the interpreter bridge since this will + // never be updated even after we compile the method. + if (runtime->GetClassLinker()->IsQuickToInterpreterBridge( + reinterpret_cast<const void*>(compiler_->GetEntryPointOf(method)))) { + use_dex_cache = true; + } + } if (method_code_in_boot) { *stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot; } diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index b1d972e44e..0283791e28 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -76,7 +76,7 @@ JitCompiler::JitCompiler() : total_time_(0) { false, false, false, - true, // pic + false, // pic nullptr, pass_manager_options, nullptr)); @@ -132,7 +132,20 @@ bool JitCompiler::CompileMethod(Thread* self, mirror::ArtMethod* method) { return false; } total_time_ += NanoTime() - start_time; - const bool result = MakeExecutable(compiled_method, h_method.Get()); + // Don't add the method if we are supposed to be deoptimized. + bool result = false; + if (!runtime->GetInstrumentation()->AreAllMethodsDeoptimized()) { + const void* code = Runtime::Current()->GetClassLinker()->GetOatMethodQuickCodeFor( + h_method.Get()); + if (code != nullptr) { + // Already have some compiled code, just use this instead of linking. + // TODO: Fix recompilation. + h_method->SetEntryPointFromQuickCompiledCode(code); + result = true; + } else { + result = MakeExecutable(compiled_method, h_method.Get()); + } + } // Remove the compiled method to save memory. compiler_driver_->RemoveCompiledMethod(method_ref); return result; |