1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "reg_type.h" 18 19 #include <set> 20 21 #include "base/casts.h" 22 #include "common_runtime_test.h" 23 #include "reg_type_cache-inl.h" 24 #include "scoped_thread_state_change.h" 25 #include "thread-inl.h" 26 27 namespace art { 28 namespace verifier { 29 30 class RegTypeTest : public CommonRuntimeTest {}; 31 32 TEST_F(RegTypeTest, ConstLoHi) { 33 // Tests creating primitive types types. 34 ScopedObjectAccess soa(Thread::Current()); 35 RegTypeCache cache(true); 36 RegType& ref_type_const_0 = cache.FromCat1Const(10, true); 37 RegType& ref_type_const_1 = cache.FromCat1Const(10, true); 38 RegType& ref_type_const_2 = cache.FromCat1Const(30, true); 39 RegType& ref_type_const_3 = cache.FromCat1Const(30, false); 40 EXPECT_TRUE(ref_type_const_0.Equals(ref_type_const_1)); 41 EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_2)); 42 EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_3)); 43 44 RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true); 45 RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true); 46 EXPECT_TRUE(ref_type_const_wide_0.Equals(ref_type_const_wide_1)); 47 48 RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true); 49 RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true); 50 RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true); 51 EXPECT_TRUE(ref_type_const_wide_2.Equals(ref_type_const_wide_3)); 52 EXPECT_FALSE(ref_type_const_wide_2.Equals(ref_type_const_wide_4)); 53 } 54 55 TEST_F(RegTypeTest, Pairs) { 56 ScopedObjectAccess soa(Thread::Current()); 57 RegTypeCache cache(true); 58 int64_t val = static_cast<int32_t>(1234); 59 RegType& precise_lo = cache.FromCat2ConstLo(static_cast<int32_t>(val), true); 60 RegType& precise_hi = cache.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 61 RegType& precise_const = cache.FromCat1Const(static_cast<int32_t>(val >> 32), true); 62 RegType& long_lo = cache.LongLo(); 63 RegType& long_hi = cache.LongHi(); 64 // Check sanity of types. 65 EXPECT_TRUE(precise_lo.IsLowHalf()); 66 EXPECT_FALSE(precise_hi.IsLowHalf()); 67 EXPECT_FALSE(precise_lo.IsHighHalf()); 68 EXPECT_TRUE(precise_hi.IsHighHalf()); 69 EXPECT_TRUE(long_hi.IsLongHighTypes()); 70 EXPECT_TRUE(precise_hi.IsLongHighTypes()); 71 // Check Pairing. 72 EXPECT_FALSE(precise_lo.CheckWidePair(precise_const)); 73 EXPECT_TRUE(precise_lo.CheckWidePair(precise_hi)); 74 // Test Merging. 75 EXPECT_TRUE((long_lo.Merge(precise_lo, &cache)).IsLongTypes()); 76 EXPECT_TRUE((long_hi.Merge(precise_hi, &cache)).IsLongHighTypes()); 77 } 78 79 TEST_F(RegTypeTest, Primitives) { 80 ScopedObjectAccess soa(Thread::Current()); 81 RegTypeCache cache(true); 82 83 RegType& bool_reg_type = cache.Boolean(); 84 EXPECT_FALSE(bool_reg_type.IsUndefined()); 85 EXPECT_FALSE(bool_reg_type.IsConflict()); 86 EXPECT_FALSE(bool_reg_type.IsZero()); 87 EXPECT_FALSE(bool_reg_type.IsOne()); 88 EXPECT_FALSE(bool_reg_type.IsLongConstant()); 89 EXPECT_TRUE(bool_reg_type.IsBoolean()); 90 EXPECT_FALSE(bool_reg_type.IsByte()); 91 EXPECT_FALSE(bool_reg_type.IsChar()); 92 EXPECT_FALSE(bool_reg_type.IsShort()); 93 EXPECT_FALSE(bool_reg_type.IsInteger()); 94 EXPECT_FALSE(bool_reg_type.IsLong()); 95 EXPECT_FALSE(bool_reg_type.IsFloat()); 96 EXPECT_FALSE(bool_reg_type.IsDouble()); 97 EXPECT_FALSE(bool_reg_type.IsReference()); 98 EXPECT_FALSE(bool_reg_type.IsLowHalf()); 99 EXPECT_FALSE(bool_reg_type.IsHighHalf()); 100 EXPECT_FALSE(bool_reg_type.IsLongOrDoubleTypes()); 101 EXPECT_FALSE(bool_reg_type.IsReferenceTypes()); 102 EXPECT_TRUE(bool_reg_type.IsCategory1Types()); 103 EXPECT_FALSE(bool_reg_type.IsCategory2Types()); 104 EXPECT_TRUE(bool_reg_type.IsBooleanTypes()); 105 EXPECT_TRUE(bool_reg_type.IsByteTypes()); 106 EXPECT_TRUE(bool_reg_type.IsShortTypes()); 107 EXPECT_TRUE(bool_reg_type.IsCharTypes()); 108 EXPECT_TRUE(bool_reg_type.IsIntegralTypes()); 109 EXPECT_FALSE(bool_reg_type.IsFloatTypes()); 110 EXPECT_FALSE(bool_reg_type.IsLongTypes()); 111 EXPECT_FALSE(bool_reg_type.IsDoubleTypes()); 112 EXPECT_TRUE(bool_reg_type.IsArrayIndexTypes()); 113 EXPECT_FALSE(bool_reg_type.IsNonZeroReferenceTypes()); 114 115 RegType& byte_reg_type = cache.Byte(); 116 EXPECT_FALSE(byte_reg_type.IsUndefined()); 117 EXPECT_FALSE(byte_reg_type.IsConflict()); 118 EXPECT_FALSE(byte_reg_type.IsZero()); 119 EXPECT_FALSE(byte_reg_type.IsOne()); 120 EXPECT_FALSE(byte_reg_type.IsLongConstant()); 121 EXPECT_FALSE(byte_reg_type.IsBoolean()); 122 EXPECT_TRUE(byte_reg_type.IsByte()); 123 EXPECT_FALSE(byte_reg_type.IsChar()); 124 EXPECT_FALSE(byte_reg_type.IsShort()); 125 EXPECT_FALSE(byte_reg_type.IsInteger()); 126 EXPECT_FALSE(byte_reg_type.IsLong()); 127 EXPECT_FALSE(byte_reg_type.IsFloat()); 128 EXPECT_FALSE(byte_reg_type.IsDouble()); 129 EXPECT_FALSE(byte_reg_type.IsReference()); 130 EXPECT_FALSE(byte_reg_type.IsLowHalf()); 131 EXPECT_FALSE(byte_reg_type.IsHighHalf()); 132 EXPECT_FALSE(byte_reg_type.IsLongOrDoubleTypes()); 133 EXPECT_FALSE(byte_reg_type.IsReferenceTypes()); 134 EXPECT_TRUE(byte_reg_type.IsCategory1Types()); 135 EXPECT_FALSE(byte_reg_type.IsCategory2Types()); 136 EXPECT_FALSE(byte_reg_type.IsBooleanTypes()); 137 EXPECT_TRUE(byte_reg_type.IsByteTypes()); 138 EXPECT_TRUE(byte_reg_type.IsShortTypes()); 139 EXPECT_FALSE(byte_reg_type.IsCharTypes()); 140 EXPECT_TRUE(byte_reg_type.IsIntegralTypes()); 141 EXPECT_FALSE(byte_reg_type.IsFloatTypes()); 142 EXPECT_FALSE(byte_reg_type.IsLongTypes()); 143 EXPECT_FALSE(byte_reg_type.IsDoubleTypes()); 144 EXPECT_TRUE(byte_reg_type.IsArrayIndexTypes()); 145 EXPECT_FALSE(byte_reg_type.IsNonZeroReferenceTypes()); 146 147 RegType& char_reg_type = cache.Char(); 148 EXPECT_FALSE(char_reg_type.IsUndefined()); 149 EXPECT_FALSE(char_reg_type.IsConflict()); 150 EXPECT_FALSE(char_reg_type.IsZero()); 151 EXPECT_FALSE(char_reg_type.IsOne()); 152 EXPECT_FALSE(char_reg_type.IsLongConstant()); 153 EXPECT_FALSE(char_reg_type.IsBoolean()); 154 EXPECT_FALSE(char_reg_type.IsByte()); 155 EXPECT_TRUE(char_reg_type.IsChar()); 156 EXPECT_FALSE(char_reg_type.IsShort()); 157 EXPECT_FALSE(char_reg_type.IsInteger()); 158 EXPECT_FALSE(char_reg_type.IsLong()); 159 EXPECT_FALSE(char_reg_type.IsFloat()); 160 EXPECT_FALSE(char_reg_type.IsDouble()); 161 EXPECT_FALSE(char_reg_type.IsReference()); 162 EXPECT_FALSE(char_reg_type.IsLowHalf()); 163 EXPECT_FALSE(char_reg_type.IsHighHalf()); 164 EXPECT_FALSE(char_reg_type.IsLongOrDoubleTypes()); 165 EXPECT_FALSE(char_reg_type.IsReferenceTypes()); 166 EXPECT_TRUE(char_reg_type.IsCategory1Types()); 167 EXPECT_FALSE(char_reg_type.IsCategory2Types()); 168 EXPECT_FALSE(char_reg_type.IsBooleanTypes()); 169 EXPECT_FALSE(char_reg_type.IsByteTypes()); 170 EXPECT_FALSE(char_reg_type.IsShortTypes()); 171 EXPECT_TRUE(char_reg_type.IsCharTypes()); 172 EXPECT_TRUE(char_reg_type.IsIntegralTypes()); 173 EXPECT_FALSE(char_reg_type.IsFloatTypes()); 174 EXPECT_FALSE(char_reg_type.IsLongTypes()); 175 EXPECT_FALSE(char_reg_type.IsDoubleTypes()); 176 EXPECT_TRUE(char_reg_type.IsArrayIndexTypes()); 177 EXPECT_FALSE(char_reg_type.IsNonZeroReferenceTypes()); 178 179 RegType& short_reg_type = cache.Short(); 180 EXPECT_FALSE(short_reg_type.IsUndefined()); 181 EXPECT_FALSE(short_reg_type.IsConflict()); 182 EXPECT_FALSE(short_reg_type.IsZero()); 183 EXPECT_FALSE(short_reg_type.IsOne()); 184 EXPECT_FALSE(short_reg_type.IsLongConstant()); 185 EXPECT_FALSE(short_reg_type.IsBoolean()); 186 EXPECT_FALSE(short_reg_type.IsByte()); 187 EXPECT_FALSE(short_reg_type.IsChar()); 188 EXPECT_TRUE(short_reg_type.IsShort()); 189 EXPECT_FALSE(short_reg_type.IsInteger()); 190 EXPECT_FALSE(short_reg_type.IsLong()); 191 EXPECT_FALSE(short_reg_type.IsFloat()); 192 EXPECT_FALSE(short_reg_type.IsDouble()); 193 EXPECT_FALSE(short_reg_type.IsReference()); 194 EXPECT_FALSE(short_reg_type.IsLowHalf()); 195 EXPECT_FALSE(short_reg_type.IsHighHalf()); 196 EXPECT_FALSE(short_reg_type.IsLongOrDoubleTypes()); 197 EXPECT_FALSE(short_reg_type.IsReferenceTypes()); 198 EXPECT_TRUE(short_reg_type.IsCategory1Types()); 199 EXPECT_FALSE(short_reg_type.IsCategory2Types()); 200 EXPECT_FALSE(short_reg_type.IsBooleanTypes()); 201 EXPECT_FALSE(short_reg_type.IsByteTypes()); 202 EXPECT_TRUE(short_reg_type.IsShortTypes()); 203 EXPECT_FALSE(short_reg_type.IsCharTypes()); 204 EXPECT_TRUE(short_reg_type.IsIntegralTypes()); 205 EXPECT_FALSE(short_reg_type.IsFloatTypes()); 206 EXPECT_FALSE(short_reg_type.IsLongTypes()); 207 EXPECT_FALSE(short_reg_type.IsDoubleTypes()); 208 EXPECT_TRUE(short_reg_type.IsArrayIndexTypes()); 209 EXPECT_FALSE(short_reg_type.IsNonZeroReferenceTypes()); 210 211 RegType& int_reg_type = cache.Integer(); 212 EXPECT_FALSE(int_reg_type.IsUndefined()); 213 EXPECT_FALSE(int_reg_type.IsConflict()); 214 EXPECT_FALSE(int_reg_type.IsZero()); 215 EXPECT_FALSE(int_reg_type.IsOne()); 216 EXPECT_FALSE(int_reg_type.IsLongConstant()); 217 EXPECT_FALSE(int_reg_type.IsBoolean()); 218 EXPECT_FALSE(int_reg_type.IsByte()); 219 EXPECT_FALSE(int_reg_type.IsChar()); 220 EXPECT_FALSE(int_reg_type.IsShort()); 221 EXPECT_TRUE(int_reg_type.IsInteger()); 222 EXPECT_FALSE(int_reg_type.IsLong()); 223 EXPECT_FALSE(int_reg_type.IsFloat()); 224 EXPECT_FALSE(int_reg_type.IsDouble()); 225 EXPECT_FALSE(int_reg_type.IsReference()); 226 EXPECT_FALSE(int_reg_type.IsLowHalf()); 227 EXPECT_FALSE(int_reg_type.IsHighHalf()); 228 EXPECT_FALSE(int_reg_type.IsLongOrDoubleTypes()); 229 EXPECT_FALSE(int_reg_type.IsReferenceTypes()); 230 EXPECT_TRUE(int_reg_type.IsCategory1Types()); 231 EXPECT_FALSE(int_reg_type.IsCategory2Types()); 232 EXPECT_FALSE(int_reg_type.IsBooleanTypes()); 233 EXPECT_FALSE(int_reg_type.IsByteTypes()); 234 EXPECT_FALSE(int_reg_type.IsShortTypes()); 235 EXPECT_FALSE(int_reg_type.IsCharTypes()); 236 EXPECT_TRUE(int_reg_type.IsIntegralTypes()); 237 EXPECT_FALSE(int_reg_type.IsFloatTypes()); 238 EXPECT_FALSE(int_reg_type.IsLongTypes()); 239 EXPECT_FALSE(int_reg_type.IsDoubleTypes()); 240 EXPECT_TRUE(int_reg_type.IsArrayIndexTypes()); 241 EXPECT_FALSE(int_reg_type.IsNonZeroReferenceTypes()); 242 243 RegType& long_reg_type = cache.LongLo(); 244 EXPECT_FALSE(long_reg_type.IsUndefined()); 245 EXPECT_FALSE(long_reg_type.IsConflict()); 246 EXPECT_FALSE(long_reg_type.IsZero()); 247 EXPECT_FALSE(long_reg_type.IsOne()); 248 EXPECT_FALSE(long_reg_type.IsLongConstant()); 249 EXPECT_FALSE(long_reg_type.IsBoolean()); 250 EXPECT_FALSE(long_reg_type.IsByte()); 251 EXPECT_FALSE(long_reg_type.IsChar()); 252 EXPECT_FALSE(long_reg_type.IsShort()); 253 EXPECT_FALSE(long_reg_type.IsInteger()); 254 EXPECT_TRUE(long_reg_type.IsLong()); 255 EXPECT_FALSE(long_reg_type.IsFloat()); 256 EXPECT_FALSE(long_reg_type.IsDouble()); 257 EXPECT_FALSE(long_reg_type.IsReference()); 258 EXPECT_TRUE(long_reg_type.IsLowHalf()); 259 EXPECT_FALSE(long_reg_type.IsHighHalf()); 260 EXPECT_TRUE(long_reg_type.IsLongOrDoubleTypes()); 261 EXPECT_FALSE(long_reg_type.IsReferenceTypes()); 262 EXPECT_FALSE(long_reg_type.IsCategory1Types()); 263 EXPECT_TRUE(long_reg_type.IsCategory2Types()); 264 EXPECT_FALSE(long_reg_type.IsBooleanTypes()); 265 EXPECT_FALSE(long_reg_type.IsByteTypes()); 266 EXPECT_FALSE(long_reg_type.IsShortTypes()); 267 EXPECT_FALSE(long_reg_type.IsCharTypes()); 268 EXPECT_FALSE(long_reg_type.IsIntegralTypes()); 269 EXPECT_FALSE(long_reg_type.IsFloatTypes()); 270 EXPECT_TRUE(long_reg_type.IsLongTypes()); 271 EXPECT_FALSE(long_reg_type.IsDoubleTypes()); 272 EXPECT_FALSE(long_reg_type.IsArrayIndexTypes()); 273 EXPECT_FALSE(long_reg_type.IsNonZeroReferenceTypes()); 274 275 RegType& float_reg_type = cache.Float(); 276 EXPECT_FALSE(float_reg_type.IsUndefined()); 277 EXPECT_FALSE(float_reg_type.IsConflict()); 278 EXPECT_FALSE(float_reg_type.IsZero()); 279 EXPECT_FALSE(float_reg_type.IsOne()); 280 EXPECT_FALSE(float_reg_type.IsLongConstant()); 281 EXPECT_FALSE(float_reg_type.IsBoolean()); 282 EXPECT_FALSE(float_reg_type.IsByte()); 283 EXPECT_FALSE(float_reg_type.IsChar()); 284 EXPECT_FALSE(float_reg_type.IsShort()); 285 EXPECT_FALSE(float_reg_type.IsInteger()); 286 EXPECT_FALSE(float_reg_type.IsLong()); 287 EXPECT_TRUE(float_reg_type.IsFloat()); 288 EXPECT_FALSE(float_reg_type.IsDouble()); 289 EXPECT_FALSE(float_reg_type.IsReference()); 290 EXPECT_FALSE(float_reg_type.IsLowHalf()); 291 EXPECT_FALSE(float_reg_type.IsHighHalf()); 292 EXPECT_FALSE(float_reg_type.IsLongOrDoubleTypes()); 293 EXPECT_FALSE(float_reg_type.IsReferenceTypes()); 294 EXPECT_TRUE(float_reg_type.IsCategory1Types()); 295 EXPECT_FALSE(float_reg_type.IsCategory2Types()); 296 EXPECT_FALSE(float_reg_type.IsBooleanTypes()); 297 EXPECT_FALSE(float_reg_type.IsByteTypes()); 298 EXPECT_FALSE(float_reg_type.IsShortTypes()); 299 EXPECT_FALSE(float_reg_type.IsCharTypes()); 300 EXPECT_FALSE(float_reg_type.IsIntegralTypes()); 301 EXPECT_TRUE(float_reg_type.IsFloatTypes()); 302 EXPECT_FALSE(float_reg_type.IsLongTypes()); 303 EXPECT_FALSE(float_reg_type.IsDoubleTypes()); 304 EXPECT_FALSE(float_reg_type.IsArrayIndexTypes()); 305 EXPECT_FALSE(float_reg_type.IsNonZeroReferenceTypes()); 306 307 RegType& double_reg_type = cache.DoubleLo(); 308 EXPECT_FALSE(double_reg_type.IsUndefined()); 309 EXPECT_FALSE(double_reg_type.IsConflict()); 310 EXPECT_FALSE(double_reg_type.IsZero()); 311 EXPECT_FALSE(double_reg_type.IsOne()); 312 EXPECT_FALSE(double_reg_type.IsLongConstant()); 313 EXPECT_FALSE(double_reg_type.IsBoolean()); 314 EXPECT_FALSE(double_reg_type.IsByte()); 315 EXPECT_FALSE(double_reg_type.IsChar()); 316 EXPECT_FALSE(double_reg_type.IsShort()); 317 EXPECT_FALSE(double_reg_type.IsInteger()); 318 EXPECT_FALSE(double_reg_type.IsLong()); 319 EXPECT_FALSE(double_reg_type.IsFloat()); 320 EXPECT_TRUE(double_reg_type.IsDouble()); 321 EXPECT_FALSE(double_reg_type.IsReference()); 322 EXPECT_TRUE(double_reg_type.IsLowHalf()); 323 EXPECT_FALSE(double_reg_type.IsHighHalf()); 324 EXPECT_TRUE(double_reg_type.IsLongOrDoubleTypes()); 325 EXPECT_FALSE(double_reg_type.IsReferenceTypes()); 326 EXPECT_FALSE(double_reg_type.IsCategory1Types()); 327 EXPECT_TRUE(double_reg_type.IsCategory2Types()); 328 EXPECT_FALSE(double_reg_type.IsBooleanTypes()); 329 EXPECT_FALSE(double_reg_type.IsByteTypes()); 330 EXPECT_FALSE(double_reg_type.IsShortTypes()); 331 EXPECT_FALSE(double_reg_type.IsCharTypes()); 332 EXPECT_FALSE(double_reg_type.IsIntegralTypes()); 333 EXPECT_FALSE(double_reg_type.IsFloatTypes()); 334 EXPECT_FALSE(double_reg_type.IsLongTypes()); 335 EXPECT_TRUE(double_reg_type.IsDoubleTypes()); 336 EXPECT_FALSE(double_reg_type.IsArrayIndexTypes()); 337 EXPECT_FALSE(double_reg_type.IsNonZeroReferenceTypes()); 338 } 339 340 class RegTypeReferenceTest : public CommonRuntimeTest {}; 341 342 TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) { 343 // Tests matching precisions. A reference type that was created precise doesn't 344 // match the one that is imprecise. 345 ScopedObjectAccess soa(Thread::Current()); 346 RegTypeCache cache(true); 347 RegType& imprecise_obj = cache.JavaLangObject(false); 348 RegType& precise_obj = cache.JavaLangObject(true); 349 RegType& precise_obj_2 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); 350 351 EXPECT_TRUE(precise_obj.Equals(precise_obj_2)); 352 EXPECT_FALSE(imprecise_obj.Equals(precise_obj)); 353 EXPECT_FALSE(imprecise_obj.Equals(precise_obj)); 354 EXPECT_FALSE(imprecise_obj.Equals(precise_obj_2)); 355 } 356 357 TEST_F(RegTypeReferenceTest, UnresolvedType) { 358 // Tests creating unresolved types. Miss for the first time asking the cache and 359 // a hit second time. 360 ScopedObjectAccess soa(Thread::Current()); 361 RegTypeCache cache(true); 362 RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 363 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 364 EXPECT_TRUE(ref_type_0.IsNonZeroReferenceTypes()); 365 366 RegType& ref_type_1 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 367 EXPECT_TRUE(ref_type_0.Equals(ref_type_1)); 368 369 RegType& unresolved_super_class = cache.FromUnresolvedSuperClass(ref_type_0); 370 EXPECT_TRUE(unresolved_super_class.IsUnresolvedSuperClass()); 371 EXPECT_TRUE(unresolved_super_class.IsNonZeroReferenceTypes()); 372 } 373 374 TEST_F(RegTypeReferenceTest, UnresolvedUnintializedType) { 375 // Tests creating types uninitialized types from unresolved types. 376 ScopedObjectAccess soa(Thread::Current()); 377 RegTypeCache cache(true); 378 RegType& ref_type_0 = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 379 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 380 RegType& ref_type = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 381 EXPECT_TRUE(ref_type_0.Equals(ref_type)); 382 // Create an uninitialized type of this unresolved type 383 RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull); 384 EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); 385 EXPECT_TRUE(unresolved_unintialised.IsUninitializedTypes()); 386 EXPECT_TRUE(unresolved_unintialised.IsNonZeroReferenceTypes()); 387 // Create an uninitialized type of this unresolved type with different PC 388 RegType& ref_type_unresolved_unintialised_1 = cache.Uninitialized(ref_type, 1102ull); 389 EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); 390 EXPECT_FALSE(unresolved_unintialised.Equals(ref_type_unresolved_unintialised_1)); 391 // Create an uninitialized type of this unresolved type with the same PC 392 RegType& unresolved_unintialised_2 = cache.Uninitialized(ref_type, 1101ull); 393 EXPECT_TRUE(unresolved_unintialised.Equals(unresolved_unintialised_2)); 394 } 395 396 TEST_F(RegTypeReferenceTest, Dump) { 397 // Tests types for proper Dump messages. 398 ScopedObjectAccess soa(Thread::Current()); 399 RegTypeCache cache(true); 400 RegType& unresolved_ref = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 401 RegType& unresolved_ref_another = cache.FromDescriptor(NULL, "Ljava/lang/DoesNotExistEither;", true); 402 RegType& resolved_ref = cache.JavaLangString(); 403 RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10); 404 RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12); 405 RegType& unresolved_merged = cache.FromUnresolvedMerge(unresolved_ref, unresolved_ref_another); 406 407 std::string expected = "Unresolved Reference: java.lang.DoesNotExist"; 408 EXPECT_EQ(expected, unresolved_ref.Dump()); 409 expected = "Precise Reference: java.lang.String"; 410 EXPECT_EQ(expected, resolved_ref.Dump()); 411 expected ="Uninitialized Reference: java.lang.String Allocation PC: 10"; 412 EXPECT_EQ(expected, resolved_unintialiesd.Dump()); 413 expected = "Unresolved And Uninitialized Reference: java.lang.DoesNotExist Allocation PC: 12"; 414 EXPECT_EQ(expected, unresolved_unintialized.Dump()); 415 expected = "UnresolvedMergedReferences(Unresolved Reference: java.lang.DoesNotExist, Unresolved Reference: java.lang.DoesNotExistEither)"; 416 EXPECT_EQ(expected, unresolved_merged.Dump()); 417 } 418 419 TEST_F(RegTypeReferenceTest, JavalangString) { 420 // Add a class to the cache then look for the same class and make sure it is a 421 // Hit the second time. Then check for the same effect when using 422 // The JavaLangObject method instead of FromDescriptor. String class is final. 423 ScopedObjectAccess soa(Thread::Current()); 424 RegTypeCache cache(true); 425 RegType& ref_type = cache.JavaLangString(); 426 RegType& ref_type_2 = cache.JavaLangString(); 427 RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/String;", true); 428 429 EXPECT_TRUE(ref_type.Equals(ref_type_2)); 430 EXPECT_TRUE(ref_type_2.Equals(ref_type_3)); 431 EXPECT_TRUE(ref_type.IsPreciseReference()); 432 433 // Create an uninitialized type out of this: 434 RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull); 435 EXPECT_TRUE(ref_type_unintialized.IsUninitializedReference()); 436 EXPECT_FALSE(ref_type_unintialized.IsUnresolvedAndUninitializedReference()); 437 } 438 439 TEST_F(RegTypeReferenceTest, JavalangObject) { 440 // Add a class to the cache then look for the same class and make sure it is a 441 // Hit the second time. Then I am checking for the same effect when using 442 // The JavaLangObject method instead of FromDescriptor. Object Class in not final. 443 ScopedObjectAccess soa(Thread::Current()); 444 RegTypeCache cache(true); 445 RegType& ref_type = cache.JavaLangObject(true); 446 RegType& ref_type_2 = cache.JavaLangObject(true); 447 RegType& ref_type_3 = cache.FromDescriptor(NULL, "Ljava/lang/Object;", true); 448 449 EXPECT_TRUE(ref_type.Equals(ref_type_2)); 450 EXPECT_TRUE(ref_type_3.Equals(ref_type_2)); 451 EXPECT_EQ(ref_type.GetId(), ref_type_3.GetId()); 452 } 453 TEST_F(RegTypeReferenceTest, Merging) { 454 // Tests merging logic 455 // String and object , LUB is object. 456 ScopedObjectAccess soa(Thread::Current()); 457 RegTypeCache cache_new(true); 458 RegType& string = cache_new.JavaLangString(); 459 RegType& Object = cache_new.JavaLangObject(true); 460 EXPECT_TRUE(string.Merge(Object, &cache_new).IsJavaLangObject()); 461 // Merge two unresolved types. 462 RegType& ref_type_0 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExist;", true); 463 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 464 RegType& ref_type_1 = cache_new.FromDescriptor(NULL, "Ljava/lang/DoesNotExistToo;", true); 465 EXPECT_FALSE(ref_type_0.Equals(ref_type_1)); 466 467 RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new); 468 EXPECT_TRUE(merged.IsUnresolvedMergedReference()); 469 470 std::set<uint16_t> merged_ids = (down_cast<UnresolvedMergedType*>(&merged))->GetMergedTypes(); 471 EXPECT_EQ(ref_type_0.GetId(), *(merged_ids.begin())); 472 EXPECT_EQ(ref_type_1.GetId(), *((++merged_ids.begin()))); 473 } 474 475 TEST_F(RegTypeTest, MergingFloat) { 476 // Testing merging logic with float and float constants. 477 ScopedObjectAccess soa(Thread::Current()); 478 RegTypeCache cache_new(true); 479 480 constexpr int32_t kTestConstantValue = 10; 481 RegType& float_type = cache_new.Float(); 482 RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true); 483 RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false); 484 { 485 // float MERGE precise cst => float. 486 RegType& merged = float_type.Merge(precise_cst, &cache_new); 487 EXPECT_TRUE(merged.IsFloat()); 488 } 489 { 490 // precise cst MERGE float => float. 491 RegType& merged = precise_cst.Merge(float_type, &cache_new); 492 EXPECT_TRUE(merged.IsFloat()); 493 } 494 { 495 // float MERGE imprecise cst => float. 496 RegType& merged = float_type.Merge(imprecise_cst, &cache_new); 497 EXPECT_TRUE(merged.IsFloat()); 498 } 499 { 500 // imprecise cst MERGE float => float. 501 RegType& merged = imprecise_cst.Merge(float_type, &cache_new); 502 EXPECT_TRUE(merged.IsFloat()); 503 } 504 } 505 506 TEST_F(RegTypeTest, MergingLong) { 507 // Testing merging logic with long and long constants. 508 ScopedObjectAccess soa(Thread::Current()); 509 RegTypeCache cache_new(true); 510 511 constexpr int32_t kTestConstantValue = 10; 512 RegType& long_lo_type = cache_new.LongLo(); 513 RegType& long_hi_type = cache_new.LongHi(); 514 RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); 515 RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); 516 RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); 517 RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); 518 { 519 // lo MERGE precise cst lo => lo. 520 RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new); 521 EXPECT_TRUE(merged.IsLongLo()); 522 } 523 { 524 // precise cst lo MERGE lo => lo. 525 RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new); 526 EXPECT_TRUE(merged.IsLongLo()); 527 } 528 { 529 // lo MERGE imprecise cst lo => lo. 530 RegType& merged = long_lo_type.Merge(imprecise_cst_lo, &cache_new); 531 EXPECT_TRUE(merged.IsLongLo()); 532 } 533 { 534 // imprecise cst lo MERGE lo => lo. 535 RegType& merged = imprecise_cst_lo.Merge(long_lo_type, &cache_new); 536 EXPECT_TRUE(merged.IsLongLo()); 537 } 538 { 539 // hi MERGE precise cst hi => hi. 540 RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new); 541 EXPECT_TRUE(merged.IsLongHi()); 542 } 543 { 544 // precise cst hi MERGE hi => hi. 545 RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new); 546 EXPECT_TRUE(merged.IsLongHi()); 547 } 548 { 549 // hi MERGE imprecise cst hi => hi. 550 RegType& merged = long_hi_type.Merge(imprecise_cst_hi, &cache_new); 551 EXPECT_TRUE(merged.IsLongHi()); 552 } 553 { 554 // imprecise cst hi MERGE hi => hi. 555 RegType& merged = imprecise_cst_hi.Merge(long_hi_type, &cache_new); 556 EXPECT_TRUE(merged.IsLongHi()); 557 } 558 } 559 560 TEST_F(RegTypeTest, MergingDouble) { 561 // Testing merging logic with double and double constants. 562 ScopedObjectAccess soa(Thread::Current()); 563 RegTypeCache cache_new(true); 564 565 constexpr int32_t kTestConstantValue = 10; 566 RegType& double_lo_type = cache_new.DoubleLo(); 567 RegType& double_hi_type = cache_new.DoubleHi(); 568 RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); 569 RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); 570 RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); 571 RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); 572 { 573 // lo MERGE precise cst lo => lo. 574 RegType& merged = double_lo_type.Merge(precise_cst_lo, &cache_new); 575 EXPECT_TRUE(merged.IsDoubleLo()); 576 } 577 { 578 // precise cst lo MERGE lo => lo. 579 RegType& merged = precise_cst_lo.Merge(double_lo_type, &cache_new); 580 EXPECT_TRUE(merged.IsDoubleLo()); 581 } 582 { 583 // lo MERGE imprecise cst lo => lo. 584 RegType& merged = double_lo_type.Merge(imprecise_cst_lo, &cache_new); 585 EXPECT_TRUE(merged.IsDoubleLo()); 586 } 587 { 588 // imprecise cst lo MERGE lo => lo. 589 RegType& merged = imprecise_cst_lo.Merge(double_lo_type, &cache_new); 590 EXPECT_TRUE(merged.IsDoubleLo()); 591 } 592 { 593 // hi MERGE precise cst hi => hi. 594 RegType& merged = double_hi_type.Merge(precise_cst_hi, &cache_new); 595 EXPECT_TRUE(merged.IsDoubleHi()); 596 } 597 { 598 // precise cst hi MERGE hi => hi. 599 RegType& merged = precise_cst_hi.Merge(double_hi_type, &cache_new); 600 EXPECT_TRUE(merged.IsDoubleHi()); 601 } 602 { 603 // hi MERGE imprecise cst hi => hi. 604 RegType& merged = double_hi_type.Merge(imprecise_cst_hi, &cache_new); 605 EXPECT_TRUE(merged.IsDoubleHi()); 606 } 607 { 608 // imprecise cst hi MERGE hi => hi. 609 RegType& merged = imprecise_cst_hi.Merge(double_hi_type, &cache_new); 610 EXPECT_TRUE(merged.IsDoubleHi()); 611 } 612 } 613 614 TEST_F(RegTypeTest, ConstPrecision) { 615 // Tests creating primitive types types. 616 ScopedObjectAccess soa(Thread::Current()); 617 RegTypeCache cache_new(true); 618 RegType& imprecise_const = cache_new.FromCat1Const(10, false); 619 RegType& precise_const = cache_new.FromCat1Const(10, true); 620 621 EXPECT_TRUE(imprecise_const.IsImpreciseConstant()); 622 EXPECT_TRUE(precise_const.IsPreciseConstant()); 623 EXPECT_FALSE(imprecise_const.Equals(precise_const)); 624 } 625 626 } // namespace verifier 627 } // namespace art 628