summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2015-04-22 11:51:52 +0100
committer Vladimir Marko <vmarko@google.com> 2015-04-22 13:20:21 +0100
commitfac10700fd99516e8a14f751fe35553021ce6982 (patch)
tree38030555c6644ee7207daafad81563c34ad3c208
parentf888d5d6584efb66ecd9eed94879679a65712336 (diff)
Quick: Remove broken Mir2Lir::LocToRegClass().
Its use in intrinsics has been bogus. In all other instances it's been used under the assumption that the inferred type matches the return type of associated calls. However, if the type inference identifies a type mismatch, the assumption doesn't hold and there isn't necessarily a valid value that the function could reasonably return. Bug: 19918641 Change-Id: I050934e6f9eb00427d0b888ee29ae9eeb509bb3f
-rw-r--r--compiler/dex/quick/arm/fp_arm.cc6
-rw-r--r--compiler/dex/quick/arm/int_arm.cc4
-rw-r--r--compiler/dex/quick/dex_file_method_inliner.cc5
-rw-r--r--compiler/dex/quick/gen_common.cc8
-rwxr-xr-xcompiler/dex/quick/gen_invoke.cc16
-rw-r--r--compiler/dex/quick/mir_to_lir.cc26
-rw-r--r--compiler/dex/quick/mir_to_lir.h6
-rwxr-xr-xcompiler/dex/quick/x86/fp_x86.cc6
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc2
9 files changed, 31 insertions, 48 deletions
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc
index eb1383fcff..94fc4743a4 100644
--- a/compiler/dex/quick/arm/fp_arm.cc
+++ b/compiler/dex/quick/arm/fp_arm.cc
@@ -187,7 +187,8 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, Re
return;
}
case Instruction::FLOAT_TO_LONG:
- GenConversionCall(kQuickF2l, rl_dest, rl_src);
+ CheckEntrypointTypes<kQuickF2l, int64_t, float>(); // int64_t -> kCoreReg
+ GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg);
return;
case Instruction::LONG_TO_FLOAT: {
rl_src = LoadValueWide(rl_src, kFPReg);
@@ -217,7 +218,8 @@ void ArmMir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest, Re
return;
}
case Instruction::DOUBLE_TO_LONG:
- GenConversionCall(kQuickD2l, rl_dest, rl_src);
+ CheckEntrypointTypes<kQuickD2l, int64_t, double>(); // int64_t -> kCoreReg
+ GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg);
return;
default:
LOG(FATAL) << "Unexpected opcode: " << opcode;
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 47669db979..62903afbbc 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -882,7 +882,7 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
RegLocation rl_new_value;
if (!is_long) {
- rl_new_value = LoadValue(rl_src_new_value, LocToRegClass(rl_src_new_value));
+ rl_new_value = LoadValue(rl_src_new_value, is_object ? kRefReg : kCoreReg);
} else if (load_early) {
rl_new_value = LoadValueWide(rl_src_new_value, kCoreReg);
}
@@ -905,7 +905,7 @@ bool ArmMir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
RegLocation rl_expected;
if (!is_long) {
- rl_expected = LoadValue(rl_src_expected, LocToRegClass(rl_src_new_value));
+ rl_expected = LoadValue(rl_src_expected, is_object ? kRefReg : kCoreReg);
} else if (load_early) {
rl_expected = LoadValueWide(rl_src_expected, kCoreReg);
} else {
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index 4ac6c0c5b5..818112d390 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -368,9 +368,9 @@ const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods
#define UNSAFE_GET_PUT(type, code, type_flags) \
INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
- type_flags & ~kIntrinsicFlagIsObject), \
+ type_flags), \
INTRINSIC(SunMiscUnsafe, Get ## type ## Volatile, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
- (type_flags | kIntrinsicFlagIsVolatile) & ~kIntrinsicFlagIsObject), \
+ type_flags | kIntrinsicFlagIsVolatile), \
INTRINSIC(SunMiscUnsafe, Put ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
type_flags), \
INTRINSIC(SunMiscUnsafe, Put ## type ## Volatile, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
@@ -507,6 +507,7 @@ bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) {
intrinsic.d.data & kIntrinsicFlagIsObject);
case kIntrinsicUnsafeGet:
return backend->GenInlinedUnsafeGet(info, intrinsic.d.data & kIntrinsicFlagIsLong,
+ intrinsic.d.data & kIntrinsicFlagIsObject,
intrinsic.d.data & kIntrinsicFlagIsVolatile);
case kIntrinsicUnsafePut:
return backend->GenInlinedUnsafePut(info, intrinsic.d.data & kIntrinsicFlagIsLong,
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index b132c4cc54..1a72cd7c71 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -2088,7 +2088,7 @@ void Mir2Lir::GenConst(RegLocation rl_dest, int value) {
}
void Mir2Lir::GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest,
- RegLocation rl_src) {
+ RegLocation rl_src, RegisterClass return_reg_class) {
/*
* Don't optimize the register usage since it calls out to support
* functions
@@ -2097,12 +2097,10 @@ void Mir2Lir::GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_d
FlushAllRegs(); /* Send everything to home location */
CallRuntimeHelperRegLocation(trampoline, rl_src, false);
if (rl_dest.wide) {
- RegLocation rl_result;
- rl_result = GetReturnWide(LocToRegClass(rl_dest));
+ RegLocation rl_result = GetReturnWide(return_reg_class);
StoreValueWide(rl_dest, rl_result);
} else {
- RegLocation rl_result;
- rl_result = GetReturn(LocToRegClass(rl_dest));
+ RegLocation rl_result = GetReturn(return_reg_class);
StoreValue(rl_dest, rl_result);
}
}
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index db7095dafb..1eb3a5f1b5 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -882,8 +882,6 @@ RegLocation Mir2Lir::InlineTarget(CallInfo* info) {
ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
} else {
res = info->result;
- DCHECK_EQ(LocToRegClass(res),
- ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
}
return res;
}
@@ -896,8 +894,6 @@ RegLocation Mir2Lir::InlineTargetWide(CallInfo* info) {
mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
} else {
res = info->result;
- DCHECK_EQ(LocToRegClass(res),
- ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]));
}
return res;
}
@@ -1338,7 +1334,7 @@ bool Mir2Lir::GenInlinedCurrentThread(CallInfo* info) {
}
bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info,
- bool is_long, bool is_volatile) {
+ bool is_long, bool is_object, bool is_volatile) {
if (cu_->instruction_set == kMips || cu_->instruction_set == kMips64) {
// TODO: add Mips and Mips64 implementations.
return false;
@@ -1351,7 +1347,7 @@ bool Mir2Lir::GenInlinedUnsafeGet(CallInfo* info,
RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
RegLocation rl_offset = LoadValue(rl_src_offset, kCoreReg);
- RegLocation rl_result = EvalLoc(rl_dest, LocToRegClass(rl_dest), true);
+ RegLocation rl_result = EvalLoc(rl_dest, is_object ? kRefReg : kCoreReg, true);
if (is_long) {
if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64
|| cu_->instruction_set == kArm64) {
@@ -1411,7 +1407,7 @@ bool Mir2Lir::GenInlinedUnsafePut(CallInfo* info, bool is_long,
FreeTemp(rl_temp_offset);
}
} else {
- rl_value = LoadValue(rl_src_value, LocToRegClass(rl_src_value));
+ rl_value = LoadValue(rl_src_value, is_object ? kRefReg : kCoreReg);
if (rl_value.ref) {
StoreRefIndexed(rl_object.reg, rl_offset.reg, rl_value.reg, 0);
} else {
@@ -1499,11 +1495,13 @@ void Mir2Lir::GenInvokeNoInline(CallInfo* info) {
FreeCallTemps();
if (info->result.location != kLocInvalid) {
// We have a following MOVE_RESULT - do it now.
+ RegisterClass reg_class =
+ ShortyToRegClass(mir_graph_->GetShortyFromMethodReference(info->method_ref)[0]);
if (info->result.wide) {
- RegLocation ret_loc = GetReturnWide(LocToRegClass(info->result));
+ RegLocation ret_loc = GetReturnWide(reg_class);
StoreValueWide(info->result, ret_loc);
} else {
- RegLocation ret_loc = GetReturn(LocToRegClass(info->result));
+ RegLocation ret_loc = GetReturn(reg_class);
StoreValue(info->result, ret_loc);
}
}
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 961cd4f06b..2deb72722f 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -104,19 +104,6 @@ RegisterClass Mir2Lir::ShortyToRegClass(char shorty_type) {
return res;
}
-RegisterClass Mir2Lir::LocToRegClass(RegLocation loc) {
- RegisterClass res;
- if (loc.fp) {
- DCHECK(!loc.ref) << "At most, one of ref/fp may be set";
- res = kFPReg;
- } else if (loc.ref) {
- res = kRefReg;
- } else {
- res = kCoreReg;
- }
- return res;
-}
-
void Mir2Lir::LockArg(size_t in_position) {
RegStorage reg_arg = in_to_reg_storage_mapping_.GetReg(in_position);
@@ -560,25 +547,20 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
if (!kLeafOptimization || !mir_graph_->MethodIsLeaf()) {
GenSuspendTest(opt_flags);
}
- DCHECK_EQ(LocToRegClass(rl_src[0]), ShortyToRegClass(cu_->shorty[0]));
- StoreValue(GetReturn(LocToRegClass(rl_src[0])), rl_src[0]);
+ StoreValue(GetReturn(ShortyToRegClass(cu_->shorty[0])), rl_src[0]);
break;
case Instruction::RETURN_WIDE:
if (!kLeafOptimization || !mir_graph_->MethodIsLeaf()) {
GenSuspendTest(opt_flags);
}
- DCHECK_EQ(LocToRegClass(rl_src[0]), ShortyToRegClass(cu_->shorty[0]));
- StoreValueWide(GetReturnWide(LocToRegClass(rl_src[0])), rl_src[0]);
- break;
-
- case Instruction::MOVE_RESULT_WIDE:
- StoreValueWide(rl_dest, GetReturnWide(LocToRegClass(rl_dest)));
+ StoreValueWide(GetReturnWide(ShortyToRegClass(cu_->shorty[0])), rl_src[0]);
break;
case Instruction::MOVE_RESULT:
+ case Instruction::MOVE_RESULT_WIDE:
case Instruction::MOVE_RESULT_OBJECT:
- StoreValue(rl_dest, GetReturn(LocToRegClass(rl_dest)));
+ // Already processed with invoke or filled-new-array.
break;
case Instruction::MOVE:
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index db59714742..f9efe37cc9 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -634,7 +634,6 @@ class Mir2Lir {
}
RegisterClass ShortyToRegClass(char shorty_type);
- RegisterClass LocToRegClass(RegLocation loc);
int ComputeFrameSize();
void Materialize();
virtual CompiledMethod* GetCompiledMethod();
@@ -846,7 +845,8 @@ class Mir2Lir {
RegLocation rl_src, int lit);
virtual void GenArithOpLong(Instruction::Code opcode, RegLocation rl_dest,
RegLocation rl_src1, RegLocation rl_src2, int flags);
- void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src);
+ void GenConversionCall(QuickEntrypointEnum trampoline, RegLocation rl_dest, RegLocation rl_src,
+ RegisterClass return_reg_class);
void GenSuspendTest(int opt_flags);
void GenSuspendTestAndBranch(int opt_flags, LIR* target);
@@ -954,7 +954,7 @@ class Mir2Lir {
virtual bool GenInlinedIndexOf(CallInfo* info, bool zero_based);
bool GenInlinedStringCompareTo(CallInfo* info);
virtual bool GenInlinedCurrentThread(CallInfo* info);
- bool GenInlinedUnsafeGet(CallInfo* info, bool is_long, bool is_volatile);
+ bool GenInlinedUnsafeGet(CallInfo* info, bool is_long, bool is_object, bool is_volatile);
bool GenInlinedUnsafePut(CallInfo* info, bool is_long, bool is_object,
bool is_volatile, bool is_ordered);
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index cfe0480c54..10af31a0c9 100755
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -309,7 +309,8 @@ void X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
} else {
- GenConversionCall(kQuickF2l, rl_dest, rl_src);
+ CheckEntrypointTypes<kQuickF2l, int64_t, float>(); // int64_t -> kCoreReg
+ GenConversionCall(kQuickF2l, rl_dest, rl_src, kCoreReg);
}
return;
case Instruction::DOUBLE_TO_LONG:
@@ -334,7 +335,8 @@ void X86Mir2Lir::GenConversion(Instruction::Code opcode, RegLocation rl_dest,
branch_normal->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
} else {
- GenConversionCall(kQuickD2l, rl_dest, rl_src);
+ CheckEntrypointTypes<kQuickD2l, int64_t, double>(); // int64_t -> kCoreReg
+ GenConversionCall(kQuickD2l, rl_dest, rl_src, kCoreReg);
}
return;
default:
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 1043815e10..2c13b6173f 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -1229,7 +1229,7 @@ bool X86Mir2Lir::GenInlinedCas(CallInfo* info, bool is_long, bool is_object) {
LockTemp(rs_r0);
RegLocation rl_object = LoadValue(rl_src_obj, kRefReg);
- RegLocation rl_new_value = LoadValue(rl_src_new_value, LocToRegClass(rl_src_new_value));
+ RegLocation rl_new_value = LoadValue(rl_src_new_value, is_object ? kRefReg : kCoreReg);
if (is_object && !mir_graph_->IsConstantNullRef(rl_new_value)) {
// Mark card for object assuming new value is stored.