Merge "Set the type of a RegStorage correctly"
diff --git a/compiler/dex/quick/arm/fp_arm.cc b/compiler/dex/quick/arm/fp_arm.cc
index bb02f74..dde8ff0 100644
--- a/compiler/dex/quick/arm/fp_arm.cc
+++ b/compiler/dex/quick/arm/fp_arm.cc
@@ -141,8 +141,11 @@
break;
case Instruction::LONG_TO_DOUBLE: {
rl_src = LoadValueWide(rl_src, kFPReg);
- RegStorage src_low = rl_src.reg.DoubleToLowSingle();
- RegStorage src_high = rl_src.reg.DoubleToHighSingle();
+ RegisterInfo* info = GetRegInfo(rl_src.reg);
+ RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg();
+ DCHECK(src_low.Valid());
+ RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg();
+ DCHECK(src_high.Valid());
rl_result = EvalLoc(rl_dest, kFPReg, true);
RegStorage tmp1 = AllocTempDouble();
RegStorage tmp2 = AllocTempDouble();
@@ -161,8 +164,11 @@
return;
case Instruction::LONG_TO_FLOAT: {
rl_src = LoadValueWide(rl_src, kFPReg);
- RegStorage src_low = rl_src.reg.DoubleToLowSingle();
- RegStorage src_high = rl_src.reg.DoubleToHighSingle();
+ RegisterInfo* info = GetRegInfo(rl_src.reg);
+ RegStorage src_low = info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg();
+ DCHECK(src_low.Valid());
+ RegStorage src_high = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg();
+ DCHECK(src_high.Valid());
rl_result = EvalLoc(rl_dest, kFPReg, true);
// Allocate temp registers.
RegStorage high_val = AllocTempDouble();
@@ -334,22 +340,11 @@
bool ArmMir2Lir::GenInlinedSqrt(CallInfo* info) {
DCHECK_EQ(cu_->instruction_set, kThumb2);
- LIR *branch;
RegLocation rl_src = info->args[0];
RegLocation rl_dest = InlineTargetWide(info); // double place for result
rl_src = LoadValueWide(rl_src, kFPReg);
RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true);
NewLIR2(kThumb2Vsqrtd, rl_result.reg.GetReg(), rl_src.reg.GetReg());
- NewLIR2(kThumb2Vcmpd, rl_result.reg.GetReg(), rl_result.reg.GetReg());
- NewLIR0(kThumb2Fmstat);
- branch = NewLIR2(kThumbBCond, 0, kArmCondEq);
- ClobberCallerSave();
- LockCallTemps(); // Using fixed registers
- RegStorage r_tgt = LoadHelper(QUICK_ENTRYPOINT_OFFSET(4, pSqrt));
- NewLIR3(kThumb2Fmrrd, rs_r0.GetReg(), rs_r1.GetReg(), rl_src.reg.GetReg());
- NewLIR1(kThumbBlxR, r_tgt.GetReg());
- NewLIR3(kThumb2Fmdrr, rl_result.reg.GetReg(), rs_r0.GetReg(), rs_r1.GetReg());
- branch->target = NewLIR0(kPseudoTargetLabel);
StoreValueWide(rl_dest, rl_result);
return true;
}
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index 1520c52..309f676 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -575,10 +575,10 @@
// Redirect single precision's master storage to master.
info->SetMaster(dp_reg_info);
// Singles should show a single 32-bit mask bit, at first referring to the low half.
- DCHECK_EQ(info->StorageMask(), 0x1U);
+ DCHECK_EQ(info->StorageMask(), RegisterInfo::kLowSingleStorageMask);
if (sp_reg_num & 1) {
- // For odd singles, change to user the high word of the backing double.
- info->SetStorageMask(0x2);
+ // For odd singles, change to use the high word of the backing double.
+ info->SetStorageMask(RegisterInfo::kHighSingleStorageMask);
}
}
@@ -786,10 +786,13 @@
}
}
if (res.Valid()) {
+ RegisterInfo* info = GetRegInfo(res);
promotion_map_[p_map_idx].fp_location = kLocPhysReg;
- promotion_map_[p_map_idx].FpReg = res.DoubleToLowSingle().GetReg();
+ promotion_map_[p_map_idx].FpReg =
+ info->FindMatchingView(RegisterInfo::kLowSingleStorageMask)->GetReg().GetReg();
promotion_map_[p_map_idx+1].fp_location = kLocPhysReg;
- promotion_map_[p_map_idx+1].FpReg = res.DoubleToHighSingle().GetReg();
+ promotion_map_[p_map_idx+1].FpReg =
+ info->FindMatchingView(RegisterInfo::kHighSingleStorageMask)->GetReg().GetReg();
}
return res;
}
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 256135d..3fbbc4e 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -1201,21 +1201,27 @@
}
RegLocation Mir2Lir::NarrowRegLoc(RegLocation loc) {
- loc.wide = false;
if (loc.location == kLocPhysReg) {
+ DCHECK(!loc.reg.Is32Bit());
if (loc.reg.IsPair()) {
- loc.reg = loc.reg.GetLow();
+ RegisterInfo* info_lo = GetRegInfo(loc.reg.GetLow());
+ RegisterInfo* info_hi = GetRegInfo(loc.reg.GetHigh());
+ info_lo->SetIsWide(false);
+ info_hi->SetIsWide(false);
+ loc.reg = info_lo->GetReg();
} else {
- // FIXME: temp workaround.
- // Issue here: how do we narrow to a 32-bit value in 64-bit container?
- // Probably the wrong thing to narrow the RegStorage container here. That
- // should be a target decision. At the RegLocation level, we're only
- // modifying the view of the Dalvik value - this is orthogonal to the storage
- // container size. Consider this a temp workaround.
- DCHECK(loc.reg.IsDouble());
- loc.reg = loc.reg.DoubleToLowSingle();
+ RegisterInfo* info = GetRegInfo(loc.reg);
+ RegisterInfo* info_new = info->FindMatchingView(RegisterInfo::k32SoloStorageMask);
+ DCHECK(info_new != nullptr);
+ if (info->IsLive() && (info->SReg() == loc.s_reg_low)) {
+ info->MarkDead();
+ info_new->MarkLive(loc.s_reg_low);
+ }
+ loc.reg = info_new->GetReg();
}
+ DCHECK(loc.reg.Valid());
}
+ loc.wide = false;
return loc;
}
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index 5ec1ca9..a6d56bd 100644
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -864,8 +864,17 @@
// Wide spans, we need the 2nd half of uses[2].
rl_arg = UpdateLocWide(rl_use2);
if (rl_arg.location == kLocPhysReg) {
- // NOTE: not correct for 64-bit core regs, but this needs rewriting for hard-float.
- reg = rl_arg.reg.IsPair() ? rl_arg.reg.GetHigh() : rl_arg.reg.DoubleToHighSingle();
+ if (rl_arg.reg.IsPair()) {
+ reg = rl_arg.reg.GetHigh();
+ } else {
+ RegisterInfo* info = GetRegInfo(rl_arg.reg);
+ info = info->FindMatchingView(RegisterInfo::kHighSingleStorageMask);
+ if (info == nullptr) {
+ // NOTE: For hard float convention we won't split arguments across reg/mem.
+ UNIMPLEMENTED(FATAL) << "Needs hard float api.";
+ }
+ reg = info->GetReg();
+ }
} else {
// kArg2 & rArg3 can safely be used here
reg = TargetReg(kArg3);
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index f58f078..361aba8 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -332,6 +332,15 @@
return arena->Alloc(size, kArenaAllocRegAlloc);
}
+ static const uint32_t k32SoloStorageMask = 0x00000001;
+ static const uint32_t kLowSingleStorageMask = 0x00000001;
+ static const uint32_t kHighSingleStorageMask = 0x00000002;
+ static const uint32_t k64SoloStorageMask = 0x00000003;
+ static const uint32_t k128SoloStorageMask = 0x0000000f;
+ static const uint32_t k256SoloStorageMask = 0x000000ff;
+ static const uint32_t k512SoloStorageMask = 0x0000ffff;
+ static const uint32_t k1024SoloStorageMask = 0xffffffff;
+
bool InUse() { return (storage_mask_ & master_->used_storage_) != 0; }
void MarkInUse() { master_->used_storage_ |= storage_mask_; }
void MarkFree() { master_->used_storage_ &= ~storage_mask_; }
@@ -389,7 +398,15 @@
LIR* DefEnd() { return def_end_; }
void SetDefEnd(LIR* def_end) { def_end_ = def_end; }
void ResetDefBody() { def_start_ = def_end_ = nullptr; }
-
+ // Find member of aliased set matching storage_used; return nullptr if none.
+ RegisterInfo* FindMatchingView(uint32_t storage_used) {
+ RegisterInfo* res = Master();
+ for (; res != nullptr; res = res->GetAliasChain()) {
+ if (res->StorageMask() == storage_used)
+ break;
+ }
+ return res;
+ }
private:
RegStorage reg_;
@@ -648,7 +665,7 @@
virtual void EndInvoke(CallInfo* info) {}
- // Handle bookkeeping to convert a wide RegLocation to a narow RegLocation. No code generated.
+ // Handle bookkeeping to convert a wide RegLocation to a narrow RegLocation. No code generated.
RegLocation NarrowRegLoc(RegLocation loc);
// Shared by all targets - implemented in local_optimizations.cc
diff --git a/compiler/dex/reg_storage.h b/compiler/dex/reg_storage.h
index 2f7e701..7e50c31 100644
--- a/compiler/dex/reg_storage.h
+++ b/compiler/dex/reg_storage.h
@@ -225,24 +225,6 @@
return reg_ & kRegNumMask;
}
- // Aliased double to low single.
- RegStorage DoubleToLowSingle() const {
- DCHECK(IsDouble());
- return FloatSolo32(GetRegNum() << 1);
- }
-
- // Aliased double to high single.
- RegStorage DoubleToHighSingle() const {
- DCHECK(IsDouble());
- return FloatSolo32((GetRegNum() << 1) + 1);
- }
-
- // Single to aliased double.
- RegStorage SingleToDouble() const {
- DCHECK(IsSingle());
- return FloatSolo64(GetRegNum() >> 1);
- }
-
// Is register number in 0..7?
bool Low8() const {
return GetRegNum() < 8;
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 3304561..8d4e283 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1135,7 +1135,7 @@
if (dex_method_idx != DexFile::kDexNoIndex) {
target_method->dex_method_index = dex_method_idx;
} else {
- if (compiling_boot) {
+ if (compiling_boot && !use_dex_cache) {
target_method->dex_method_index = method->GetDexMethodIndex();
target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
}
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 6812f3c..49cf71b 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -180,7 +180,7 @@
EXPECT_EQ(80U, sizeof(OatHeader));
EXPECT_EQ(8U, sizeof(OatMethodOffsets));
EXPECT_EQ(24U, sizeof(OatQuickMethodHeader));
- EXPECT_EQ(80 * GetInstructionSetPointerSize(kRuntimeISA), sizeof(QuickEntryPoints));
+ EXPECT_EQ(79 * GetInstructionSetPointerSize(kRuntimeISA), sizeof(QuickEntryPoints));
}
TEST_F(OatTest, OatHeaderIsValid) {
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 23e3433..340a83e 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -196,7 +196,6 @@
qpoints->pCmplDouble = CmplDouble;
qpoints->pCmplFloat = CmplFloat;
qpoints->pFmod = fmod;
- qpoints->pSqrt = sqrt;
qpoints->pL2d = __aeabi_l2d;
qpoints->pFmodf = fmodf;
qpoints->pL2f = __aeabi_l2f;
diff --git a/runtime/arch/arm64/entrypoints_init_arm64.cc b/runtime/arch/arm64/entrypoints_init_arm64.cc
index cb9f53b..46e819e 100644
--- a/runtime/arch/arm64/entrypoints_init_arm64.cc
+++ b/runtime/arch/arm64/entrypoints_init_arm64.cc
@@ -182,7 +182,6 @@
qpoints->pCmplDouble = CmplDouble;
qpoints->pCmplFloat = CmplFloat;
qpoints->pFmod = fmod;
- qpoints->pSqrt = sqrt;
qpoints->pL2d = NULL;
qpoints->pFmodf = fmodf;
qpoints->pL2f = NULL;
diff --git a/runtime/arch/x86/entrypoints_init_x86.cc b/runtime/arch/x86/entrypoints_init_x86.cc
index 8ad29dd..c53fa1e 100644
--- a/runtime/arch/x86/entrypoints_init_x86.cc
+++ b/runtime/arch/x86/entrypoints_init_x86.cc
@@ -177,7 +177,6 @@
// points->pCmplDouble = NULL; // Not needed on x86.
// points->pCmplFloat = NULL; // Not needed on x86.
qpoints->pFmod = art_quick_fmod;
- // qpoints->pSqrt = NULL; // Not needed on x86.
// qpoints->pL2d = NULL; // Not needed on x86.
qpoints->pFmodf = art_quick_fmodf;
// qpoints->pL2f = NULL; // Not needed on x86.
diff --git a/runtime/arch/x86_64/entrypoints_init_x86_64.cc b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
index 86dcf36..aeda072 100644
--- a/runtime/arch/x86_64/entrypoints_init_x86_64.cc
+++ b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
@@ -176,7 +176,6 @@
// points->pCmplDouble = NULL; // Not needed on x86.
// points->pCmplFloat = NULL; // Not needed on x86.
qpoints->pFmod = fmod;
- // qpoints->pSqrt = NULL; // Not needed on x86.
// qpoints->pL2d = NULL; // Not needed on x86.
qpoints->pFmodf = fmodf;
// qpoints->pL2f = NULL; // Not needed on x86.
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index a1c8c71..17d1ffc 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -698,6 +698,7 @@
const byte* file_end = begin_ + size_;
for (uint32_t i = 0; i < size; i++) {
+ CHECK_LT(i, size); // b/15014252 Prevents hitting the impossible case below
if (UNLIKELY(ptr_ >= file_end)) {
ErrorStringPrintf("String data would go beyond end-of-file");
return false;
@@ -710,6 +711,7 @@
case 0x00:
// Special case of bit pattern 0xxx.
if (UNLIKELY(byte == 0)) {
+ CHECK_LT(i, size); // b/15014252 Actually hit this impossible case with clang
ErrorStringPrintf("String data shorter than indicated utf16_size %x", size);
return false;
}
diff --git a/runtime/entrypoints/quick/quick_entrypoints.h b/runtime/entrypoints/quick/quick_entrypoints.h
index ec69e28..7bd1582 100644
--- a/runtime/entrypoints/quick/quick_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_entrypoints.h
@@ -98,7 +98,6 @@
int32_t (*pCmplDouble)(double, double);
int32_t (*pCmplFloat)(float, float);
double (*pFmod)(double, double);
- double (*pSqrt)(double);
double (*pL2d)(int64_t);
float (*pFmodf)(float, float);
float (*pL2f)(int64_t);
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 10d335e..9c14a4f 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
namespace art {
const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '2', '9', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '3', '0', '\0' };
OatHeader::OatHeader() {
memset(this, 0, sizeof(*this));
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 41cfc58..55bec1e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1816,7 +1816,6 @@
QUICK_ENTRY_POINT_INFO(pCmplDouble)
QUICK_ENTRY_POINT_INFO(pCmplFloat)
QUICK_ENTRY_POINT_INFO(pFmod)
- QUICK_ENTRY_POINT_INFO(pSqrt)
QUICK_ENTRY_POINT_INFO(pL2d)
QUICK_ENTRY_POINT_INFO(pFmodf)
QUICK_ENTRY_POINT_INFO(pL2f)