summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/quick/arm/assemble_arm.cc14
-rw-r--r--compiler/dex/quick/arm/int_arm.cc1
-rw-r--r--compiler/dex/quick/arm64/assemble_arm64.cc4
-rw-r--r--compiler/dex/quick/dex_file_method_inliner.cc2
-rwxr-xr-xcompiler/dex/quick/gen_invoke.cc20
-rw-r--r--compiler/dex/quick/mips/utility_mips.cc14
-rw-r--r--compiler/dex/quick/mir_to_lir.cc3
-rw-r--r--compiler/dex/verification_results.cc7
-rw-r--r--compiler/driver/compiler_driver.cc8
-rw-r--r--compiler/jit/jit_compiler.cc17
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;