diff options
author | Sebastien Hertz <shertz@google.com> | 2014-03-14 17:58:54 +0100 |
---|---|---|
committer | Sebastien Hertz <shertz@google.com> | 2014-03-14 18:09:49 +0100 |
commit | aa0c00c97bc1fe5c8def7c6cdebfd119e86d07e5 (patch) | |
tree | 2557e1aeb5a1830c72733797f86ea9bf72418228 /runtime/verifier | |
parent | 37d4c1db4d705f5a28001f65afdd68d0527948d8 (diff) | |
download | art-aa0c00c97bc1fe5c8def7c6cdebfd119e86d07e5.zip art-aa0c00c97bc1fe5c8def7c6cdebfd119e86d07e5.tar.gz art-aa0c00c97bc1fe5c8def7c6cdebfd119e86d07e5.tar.bz2 |
Fix reg type merging in the verifier
Fixes bad merging of float, long and double reg types with constant types. Adds
merging tests in reg_type_test.
Bug: https://code.google.com/p/android/issues/detail?id=66434
Bug: 13464407
Change-Id: I56761f5f5562b742d0ef9cc66b58d55f7b668949
Diffstat (limited to 'runtime/verifier')
-rw-r--r-- | runtime/verifier/method_verifier.cc | 1 | ||||
-rw-r--r-- | runtime/verifier/reg_type.cc | 2 | ||||
-rw-r--r-- | runtime/verifier/reg_type_test.cc | 139 |
3 files changed, 140 insertions, 2 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index c4c3082..fb2d29f 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3905,6 +3905,7 @@ const RegType& MethodVerifier::GetDeclaringClass() { std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) { RegisterLine* line = reg_table_.GetLine(dex_pc); + DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc); std::vector<int32_t> result; for (size_t i = 0; i < line->NumRegs(); ++i) { const RegType& type = line->GetRegisterType(i); diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index 63f0ff4..c6f3e5c 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -777,7 +777,7 @@ int32_t ConstantType::ConstantValueHi() const { } static const RegType& SelectNonConstant(const RegType& a, const RegType& b) { - return a.IsConstant() ? b : a; + return a.IsConstantTypes() ? b : a; } const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const { diff --git a/runtime/verifier/reg_type_test.cc b/runtime/verifier/reg_type_test.cc index 1a64c00..1695fc5 100644 --- a/runtime/verifier/reg_type_test.cc +++ b/runtime/verifier/reg_type_test.cc @@ -335,7 +335,6 @@ TEST_F(RegTypeTest, Primitives) { EXPECT_FALSE(double_reg_type.IsNonZeroReferenceTypes()); } - class RegTypeReferenceTest : public CommonRuntimeTest {}; TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) { @@ -472,6 +471,144 @@ TEST_F(RegTypeReferenceTest, Merging) { EXPECT_EQ(ref_type_1.GetId(), *((++merged_ids.begin()))); } +TEST_F(RegTypeReferenceTest, MergingFloat) { + // Testing merging logic with float and float constants. + ScopedObjectAccess soa(Thread::Current()); + RegTypeCache cache_new(true); + + constexpr int32_t kTestConstantValue = 10; + const RegType& float_type = cache_new.Float(); + const RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true); + const RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false); + { + // float MERGE precise cst => float. + const RegType& merged = float_type.Merge(precise_cst, &cache_new); + EXPECT_TRUE(merged.IsFloat()); + } + { + // precise cst MERGE float => float. + const RegType& merged = precise_cst.Merge(float_type, &cache_new); + EXPECT_TRUE(merged.IsFloat()); + } + { + // float MERGE imprecise cst => float. + const RegType& merged = float_type.Merge(imprecise_cst, &cache_new); + EXPECT_TRUE(merged.IsFloat()); + } + { + // imprecise cst MERGE float => float. + const RegType& merged = imprecise_cst.Merge(float_type, &cache_new); + EXPECT_TRUE(merged.IsFloat()); + } +} + +TEST_F(RegTypeReferenceTest, MergingLong) { + // Testing merging logic with long and long constants. + ScopedObjectAccess soa(Thread::Current()); + RegTypeCache cache_new(true); + + constexpr int32_t kTestConstantValue = 10; + const RegType& long_lo_type = cache_new.LongLo(); + const RegType& long_hi_type = cache_new.LongHi(); + const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); + const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); + const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); + const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); + { + // lo MERGE precise cst lo => lo. + const RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new); + EXPECT_TRUE(merged.IsLongLo()); + } + { + // precise cst lo MERGE lo => lo. + const RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new); + EXPECT_TRUE(merged.IsLongLo()); + } + { + // lo MERGE imprecise cst lo => lo. + const RegType& merged = long_lo_type.Merge(imprecise_cst_lo, &cache_new); + EXPECT_TRUE(merged.IsLongLo()); + } + { + // imprecise cst lo MERGE lo => lo. + const RegType& merged = imprecise_cst_lo.Merge(long_lo_type, &cache_new); + EXPECT_TRUE(merged.IsLongLo()); + } + { + // hi MERGE precise cst hi => hi. + const RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new); + EXPECT_TRUE(merged.IsLongHi()); + } + { + // precise cst hi MERGE hi => hi. + const RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new); + EXPECT_TRUE(merged.IsLongHi()); + } + { + // hi MERGE imprecise cst hi => hi. + const RegType& merged = long_hi_type.Merge(imprecise_cst_hi, &cache_new); + EXPECT_TRUE(merged.IsLongHi()); + } + { + // imprecise cst hi MERGE hi => hi. + const RegType& merged = imprecise_cst_hi.Merge(long_hi_type, &cache_new); + EXPECT_TRUE(merged.IsLongHi()); + } +} + +TEST_F(RegTypeReferenceTest, MergingDouble) { + // Testing merging logic with double and double constants. + ScopedObjectAccess soa(Thread::Current()); + RegTypeCache cache_new(true); + + constexpr int32_t kTestConstantValue = 10; + const RegType& double_lo_type = cache_new.DoubleLo(); + const RegType& double_hi_type = cache_new.DoubleHi(); + const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); + const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); + const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); + const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); + { + // lo MERGE precise cst lo => lo. + const RegType& merged = double_lo_type.Merge(precise_cst_lo, &cache_new); + EXPECT_TRUE(merged.IsDoubleLo()); + } + { + // precise cst lo MERGE lo => lo. + const RegType& merged = precise_cst_lo.Merge(double_lo_type, &cache_new); + EXPECT_TRUE(merged.IsDoubleLo()); + } + { + // lo MERGE imprecise cst lo => lo. + const RegType& merged = double_lo_type.Merge(imprecise_cst_lo, &cache_new); + EXPECT_TRUE(merged.IsDoubleLo()); + } + { + // imprecise cst lo MERGE lo => lo. + const RegType& merged = imprecise_cst_lo.Merge(double_lo_type, &cache_new); + EXPECT_TRUE(merged.IsDoubleLo()); + } + { + // hi MERGE precise cst hi => hi. + const RegType& merged = double_hi_type.Merge(precise_cst_hi, &cache_new); + EXPECT_TRUE(merged.IsDoubleHi()); + } + { + // precise cst hi MERGE hi => hi. + const RegType& merged = precise_cst_hi.Merge(double_hi_type, &cache_new); + EXPECT_TRUE(merged.IsDoubleHi()); + } + { + // hi MERGE imprecise cst hi => hi. + const RegType& merged = double_hi_type.Merge(imprecise_cst_hi, &cache_new); + EXPECT_TRUE(merged.IsDoubleHi()); + } + { + // imprecise cst hi MERGE hi => hi. + const RegType& merged = imprecise_cst_hi.Merge(double_hi_type, &cache_new); + EXPECT_TRUE(merged.IsDoubleHi()); + } +} TEST_F(RegTypeTest, ConstPrecision) { // Tests creating primitive types types. |