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/bit_vector.h" 22 #include "base/casts.h" 23 #include "base/scoped_arena_allocator.h" 24 #include "common_runtime_test.h" 25 #include "compiler_callbacks.h" 26 #include "reg_type_cache-inl.h" 27 #include "reg_type-inl.h" 28 #include "scoped_thread_state_change-inl.h" 29 #include "thread-current-inl.h" 30 31 namespace art { 32 namespace verifier { 33 34 class RegTypeTest : public CommonRuntimeTest {}; 35 36 TEST_F(RegTypeTest, ConstLoHi) { 37 // Tests creating primitive types types. 38 ArenaStack stack(Runtime::Current()->GetArenaPool()); 39 ScopedArenaAllocator allocator(&stack); 40 ScopedObjectAccess soa(Thread::Current()); 41 RegTypeCache cache(true, allocator); 42 const RegType& ref_type_const_0 = cache.FromCat1Const(10, true); 43 const RegType& ref_type_const_1 = cache.FromCat1Const(10, true); 44 const RegType& ref_type_const_2 = cache.FromCat1Const(30, true); 45 const RegType& ref_type_const_3 = cache.FromCat1Const(30, false); 46 EXPECT_TRUE(ref_type_const_0.Equals(ref_type_const_1)); 47 EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_2)); 48 EXPECT_FALSE(ref_type_const_0.Equals(ref_type_const_3)); 49 50 const RegType& ref_type_const_wide_0 = cache.FromCat2ConstHi(50, true); 51 const RegType& ref_type_const_wide_1 = cache.FromCat2ConstHi(50, true); 52 EXPECT_TRUE(ref_type_const_wide_0.Equals(ref_type_const_wide_1)); 53 54 const RegType& ref_type_const_wide_2 = cache.FromCat2ConstLo(50, true); 55 const RegType& ref_type_const_wide_3 = cache.FromCat2ConstLo(50, true); 56 const RegType& ref_type_const_wide_4 = cache.FromCat2ConstLo(55, true); 57 EXPECT_TRUE(ref_type_const_wide_2.Equals(ref_type_const_wide_3)); 58 EXPECT_FALSE(ref_type_const_wide_2.Equals(ref_type_const_wide_4)); 59 } 60 61 TEST_F(RegTypeTest, Pairs) { 62 ArenaStack stack(Runtime::Current()->GetArenaPool()); 63 ScopedArenaAllocator allocator(&stack); 64 ScopedObjectAccess soa(Thread::Current()); 65 RegTypeCache cache(true, allocator); 66 int64_t val = static_cast<int32_t>(1234); 67 const RegType& precise_lo = cache.FromCat2ConstLo(static_cast<int32_t>(val), true); 68 const RegType& precise_hi = cache.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true); 69 const RegType& precise_const = cache.FromCat1Const(static_cast<int32_t>(val >> 32), true); 70 const RegType& long_lo = cache.LongLo(); 71 const RegType& long_hi = cache.LongHi(); 72 // Check sanity of types. 73 EXPECT_TRUE(precise_lo.IsLowHalf()); 74 EXPECT_FALSE(precise_hi.IsLowHalf()); 75 EXPECT_FALSE(precise_lo.IsHighHalf()); 76 EXPECT_TRUE(precise_hi.IsHighHalf()); 77 EXPECT_TRUE(long_hi.IsLongHighTypes()); 78 EXPECT_TRUE(precise_hi.IsLongHighTypes()); 79 // Check Pairing. 80 EXPECT_FALSE(precise_lo.CheckWidePair(precise_const)); 81 EXPECT_TRUE(precise_lo.CheckWidePair(precise_hi)); 82 // Test Merging. 83 EXPECT_TRUE((long_lo.Merge(precise_lo, &cache, /* verifier */ nullptr)).IsLongTypes()); 84 EXPECT_TRUE((long_hi.Merge(precise_hi, &cache, /* verifier */ nullptr)).IsLongHighTypes()); 85 } 86 87 TEST_F(RegTypeTest, Primitives) { 88 ArenaStack stack(Runtime::Current()->GetArenaPool()); 89 ScopedArenaAllocator allocator(&stack); 90 ScopedObjectAccess soa(Thread::Current()); 91 RegTypeCache cache(true, allocator); 92 93 const RegType& bool_reg_type = cache.Boolean(); 94 EXPECT_FALSE(bool_reg_type.IsUndefined()); 95 EXPECT_FALSE(bool_reg_type.IsConflict()); 96 EXPECT_FALSE(bool_reg_type.IsZero()); 97 EXPECT_FALSE(bool_reg_type.IsOne()); 98 EXPECT_FALSE(bool_reg_type.IsLongConstant()); 99 EXPECT_TRUE(bool_reg_type.IsBoolean()); 100 EXPECT_FALSE(bool_reg_type.IsByte()); 101 EXPECT_FALSE(bool_reg_type.IsChar()); 102 EXPECT_FALSE(bool_reg_type.IsShort()); 103 EXPECT_FALSE(bool_reg_type.IsInteger()); 104 EXPECT_FALSE(bool_reg_type.IsLong()); 105 EXPECT_FALSE(bool_reg_type.IsFloat()); 106 EXPECT_FALSE(bool_reg_type.IsDouble()); 107 EXPECT_FALSE(bool_reg_type.IsReference()); 108 EXPECT_FALSE(bool_reg_type.IsLowHalf()); 109 EXPECT_FALSE(bool_reg_type.IsHighHalf()); 110 EXPECT_FALSE(bool_reg_type.IsLongOrDoubleTypes()); 111 EXPECT_FALSE(bool_reg_type.IsReferenceTypes()); 112 EXPECT_TRUE(bool_reg_type.IsCategory1Types()); 113 EXPECT_FALSE(bool_reg_type.IsCategory2Types()); 114 EXPECT_TRUE(bool_reg_type.IsBooleanTypes()); 115 EXPECT_TRUE(bool_reg_type.IsByteTypes()); 116 EXPECT_TRUE(bool_reg_type.IsShortTypes()); 117 EXPECT_TRUE(bool_reg_type.IsCharTypes()); 118 EXPECT_TRUE(bool_reg_type.IsIntegralTypes()); 119 EXPECT_FALSE(bool_reg_type.IsFloatTypes()); 120 EXPECT_FALSE(bool_reg_type.IsLongTypes()); 121 EXPECT_FALSE(bool_reg_type.IsDoubleTypes()); 122 EXPECT_TRUE(bool_reg_type.IsArrayIndexTypes()); 123 EXPECT_FALSE(bool_reg_type.IsNonZeroReferenceTypes()); 124 EXPECT_TRUE(bool_reg_type.HasClass()); 125 126 const RegType& byte_reg_type = cache.Byte(); 127 EXPECT_FALSE(byte_reg_type.IsUndefined()); 128 EXPECT_FALSE(byte_reg_type.IsConflict()); 129 EXPECT_FALSE(byte_reg_type.IsZero()); 130 EXPECT_FALSE(byte_reg_type.IsOne()); 131 EXPECT_FALSE(byte_reg_type.IsLongConstant()); 132 EXPECT_FALSE(byte_reg_type.IsBoolean()); 133 EXPECT_TRUE(byte_reg_type.IsByte()); 134 EXPECT_FALSE(byte_reg_type.IsChar()); 135 EXPECT_FALSE(byte_reg_type.IsShort()); 136 EXPECT_FALSE(byte_reg_type.IsInteger()); 137 EXPECT_FALSE(byte_reg_type.IsLong()); 138 EXPECT_FALSE(byte_reg_type.IsFloat()); 139 EXPECT_FALSE(byte_reg_type.IsDouble()); 140 EXPECT_FALSE(byte_reg_type.IsReference()); 141 EXPECT_FALSE(byte_reg_type.IsLowHalf()); 142 EXPECT_FALSE(byte_reg_type.IsHighHalf()); 143 EXPECT_FALSE(byte_reg_type.IsLongOrDoubleTypes()); 144 EXPECT_FALSE(byte_reg_type.IsReferenceTypes()); 145 EXPECT_TRUE(byte_reg_type.IsCategory1Types()); 146 EXPECT_FALSE(byte_reg_type.IsCategory2Types()); 147 EXPECT_FALSE(byte_reg_type.IsBooleanTypes()); 148 EXPECT_TRUE(byte_reg_type.IsByteTypes()); 149 EXPECT_TRUE(byte_reg_type.IsShortTypes()); 150 EXPECT_FALSE(byte_reg_type.IsCharTypes()); 151 EXPECT_TRUE(byte_reg_type.IsIntegralTypes()); 152 EXPECT_FALSE(byte_reg_type.IsFloatTypes()); 153 EXPECT_FALSE(byte_reg_type.IsLongTypes()); 154 EXPECT_FALSE(byte_reg_type.IsDoubleTypes()); 155 EXPECT_TRUE(byte_reg_type.IsArrayIndexTypes()); 156 EXPECT_FALSE(byte_reg_type.IsNonZeroReferenceTypes()); 157 EXPECT_TRUE(byte_reg_type.HasClass()); 158 159 const RegType& char_reg_type = cache.Char(); 160 EXPECT_FALSE(char_reg_type.IsUndefined()); 161 EXPECT_FALSE(char_reg_type.IsConflict()); 162 EXPECT_FALSE(char_reg_type.IsZero()); 163 EXPECT_FALSE(char_reg_type.IsOne()); 164 EXPECT_FALSE(char_reg_type.IsLongConstant()); 165 EXPECT_FALSE(char_reg_type.IsBoolean()); 166 EXPECT_FALSE(char_reg_type.IsByte()); 167 EXPECT_TRUE(char_reg_type.IsChar()); 168 EXPECT_FALSE(char_reg_type.IsShort()); 169 EXPECT_FALSE(char_reg_type.IsInteger()); 170 EXPECT_FALSE(char_reg_type.IsLong()); 171 EXPECT_FALSE(char_reg_type.IsFloat()); 172 EXPECT_FALSE(char_reg_type.IsDouble()); 173 EXPECT_FALSE(char_reg_type.IsReference()); 174 EXPECT_FALSE(char_reg_type.IsLowHalf()); 175 EXPECT_FALSE(char_reg_type.IsHighHalf()); 176 EXPECT_FALSE(char_reg_type.IsLongOrDoubleTypes()); 177 EXPECT_FALSE(char_reg_type.IsReferenceTypes()); 178 EXPECT_TRUE(char_reg_type.IsCategory1Types()); 179 EXPECT_FALSE(char_reg_type.IsCategory2Types()); 180 EXPECT_FALSE(char_reg_type.IsBooleanTypes()); 181 EXPECT_FALSE(char_reg_type.IsByteTypes()); 182 EXPECT_FALSE(char_reg_type.IsShortTypes()); 183 EXPECT_TRUE(char_reg_type.IsCharTypes()); 184 EXPECT_TRUE(char_reg_type.IsIntegralTypes()); 185 EXPECT_FALSE(char_reg_type.IsFloatTypes()); 186 EXPECT_FALSE(char_reg_type.IsLongTypes()); 187 EXPECT_FALSE(char_reg_type.IsDoubleTypes()); 188 EXPECT_TRUE(char_reg_type.IsArrayIndexTypes()); 189 EXPECT_FALSE(char_reg_type.IsNonZeroReferenceTypes()); 190 EXPECT_TRUE(char_reg_type.HasClass()); 191 192 const RegType& short_reg_type = cache.Short(); 193 EXPECT_FALSE(short_reg_type.IsUndefined()); 194 EXPECT_FALSE(short_reg_type.IsConflict()); 195 EXPECT_FALSE(short_reg_type.IsZero()); 196 EXPECT_FALSE(short_reg_type.IsOne()); 197 EXPECT_FALSE(short_reg_type.IsLongConstant()); 198 EXPECT_FALSE(short_reg_type.IsBoolean()); 199 EXPECT_FALSE(short_reg_type.IsByte()); 200 EXPECT_FALSE(short_reg_type.IsChar()); 201 EXPECT_TRUE(short_reg_type.IsShort()); 202 EXPECT_FALSE(short_reg_type.IsInteger()); 203 EXPECT_FALSE(short_reg_type.IsLong()); 204 EXPECT_FALSE(short_reg_type.IsFloat()); 205 EXPECT_FALSE(short_reg_type.IsDouble()); 206 EXPECT_FALSE(short_reg_type.IsReference()); 207 EXPECT_FALSE(short_reg_type.IsLowHalf()); 208 EXPECT_FALSE(short_reg_type.IsHighHalf()); 209 EXPECT_FALSE(short_reg_type.IsLongOrDoubleTypes()); 210 EXPECT_FALSE(short_reg_type.IsReferenceTypes()); 211 EXPECT_TRUE(short_reg_type.IsCategory1Types()); 212 EXPECT_FALSE(short_reg_type.IsCategory2Types()); 213 EXPECT_FALSE(short_reg_type.IsBooleanTypes()); 214 EXPECT_FALSE(short_reg_type.IsByteTypes()); 215 EXPECT_TRUE(short_reg_type.IsShortTypes()); 216 EXPECT_FALSE(short_reg_type.IsCharTypes()); 217 EXPECT_TRUE(short_reg_type.IsIntegralTypes()); 218 EXPECT_FALSE(short_reg_type.IsFloatTypes()); 219 EXPECT_FALSE(short_reg_type.IsLongTypes()); 220 EXPECT_FALSE(short_reg_type.IsDoubleTypes()); 221 EXPECT_TRUE(short_reg_type.IsArrayIndexTypes()); 222 EXPECT_FALSE(short_reg_type.IsNonZeroReferenceTypes()); 223 EXPECT_TRUE(short_reg_type.HasClass()); 224 225 const RegType& int_reg_type = cache.Integer(); 226 EXPECT_FALSE(int_reg_type.IsUndefined()); 227 EXPECT_FALSE(int_reg_type.IsConflict()); 228 EXPECT_FALSE(int_reg_type.IsZero()); 229 EXPECT_FALSE(int_reg_type.IsOne()); 230 EXPECT_FALSE(int_reg_type.IsLongConstant()); 231 EXPECT_FALSE(int_reg_type.IsBoolean()); 232 EXPECT_FALSE(int_reg_type.IsByte()); 233 EXPECT_FALSE(int_reg_type.IsChar()); 234 EXPECT_FALSE(int_reg_type.IsShort()); 235 EXPECT_TRUE(int_reg_type.IsInteger()); 236 EXPECT_FALSE(int_reg_type.IsLong()); 237 EXPECT_FALSE(int_reg_type.IsFloat()); 238 EXPECT_FALSE(int_reg_type.IsDouble()); 239 EXPECT_FALSE(int_reg_type.IsReference()); 240 EXPECT_FALSE(int_reg_type.IsLowHalf()); 241 EXPECT_FALSE(int_reg_type.IsHighHalf()); 242 EXPECT_FALSE(int_reg_type.IsLongOrDoubleTypes()); 243 EXPECT_FALSE(int_reg_type.IsReferenceTypes()); 244 EXPECT_TRUE(int_reg_type.IsCategory1Types()); 245 EXPECT_FALSE(int_reg_type.IsCategory2Types()); 246 EXPECT_FALSE(int_reg_type.IsBooleanTypes()); 247 EXPECT_FALSE(int_reg_type.IsByteTypes()); 248 EXPECT_FALSE(int_reg_type.IsShortTypes()); 249 EXPECT_FALSE(int_reg_type.IsCharTypes()); 250 EXPECT_TRUE(int_reg_type.IsIntegralTypes()); 251 EXPECT_FALSE(int_reg_type.IsFloatTypes()); 252 EXPECT_FALSE(int_reg_type.IsLongTypes()); 253 EXPECT_FALSE(int_reg_type.IsDoubleTypes()); 254 EXPECT_TRUE(int_reg_type.IsArrayIndexTypes()); 255 EXPECT_FALSE(int_reg_type.IsNonZeroReferenceTypes()); 256 EXPECT_TRUE(int_reg_type.HasClass()); 257 258 const RegType& long_reg_type = cache.LongLo(); 259 EXPECT_FALSE(long_reg_type.IsUndefined()); 260 EXPECT_FALSE(long_reg_type.IsConflict()); 261 EXPECT_FALSE(long_reg_type.IsZero()); 262 EXPECT_FALSE(long_reg_type.IsOne()); 263 EXPECT_FALSE(long_reg_type.IsLongConstant()); 264 EXPECT_FALSE(long_reg_type.IsBoolean()); 265 EXPECT_FALSE(long_reg_type.IsByte()); 266 EXPECT_FALSE(long_reg_type.IsChar()); 267 EXPECT_FALSE(long_reg_type.IsShort()); 268 EXPECT_FALSE(long_reg_type.IsInteger()); 269 EXPECT_TRUE(long_reg_type.IsLong()); 270 EXPECT_FALSE(long_reg_type.IsFloat()); 271 EXPECT_FALSE(long_reg_type.IsDouble()); 272 EXPECT_FALSE(long_reg_type.IsReference()); 273 EXPECT_TRUE(long_reg_type.IsLowHalf()); 274 EXPECT_FALSE(long_reg_type.IsHighHalf()); 275 EXPECT_TRUE(long_reg_type.IsLongOrDoubleTypes()); 276 EXPECT_FALSE(long_reg_type.IsReferenceTypes()); 277 EXPECT_FALSE(long_reg_type.IsCategory1Types()); 278 EXPECT_TRUE(long_reg_type.IsCategory2Types()); 279 EXPECT_FALSE(long_reg_type.IsBooleanTypes()); 280 EXPECT_FALSE(long_reg_type.IsByteTypes()); 281 EXPECT_FALSE(long_reg_type.IsShortTypes()); 282 EXPECT_FALSE(long_reg_type.IsCharTypes()); 283 EXPECT_FALSE(long_reg_type.IsIntegralTypes()); 284 EXPECT_FALSE(long_reg_type.IsFloatTypes()); 285 EXPECT_TRUE(long_reg_type.IsLongTypes()); 286 EXPECT_FALSE(long_reg_type.IsDoubleTypes()); 287 EXPECT_FALSE(long_reg_type.IsArrayIndexTypes()); 288 EXPECT_FALSE(long_reg_type.IsNonZeroReferenceTypes()); 289 EXPECT_TRUE(long_reg_type.HasClass()); 290 291 const RegType& float_reg_type = cache.Float(); 292 EXPECT_FALSE(float_reg_type.IsUndefined()); 293 EXPECT_FALSE(float_reg_type.IsConflict()); 294 EXPECT_FALSE(float_reg_type.IsZero()); 295 EXPECT_FALSE(float_reg_type.IsOne()); 296 EXPECT_FALSE(float_reg_type.IsLongConstant()); 297 EXPECT_FALSE(float_reg_type.IsBoolean()); 298 EXPECT_FALSE(float_reg_type.IsByte()); 299 EXPECT_FALSE(float_reg_type.IsChar()); 300 EXPECT_FALSE(float_reg_type.IsShort()); 301 EXPECT_FALSE(float_reg_type.IsInteger()); 302 EXPECT_FALSE(float_reg_type.IsLong()); 303 EXPECT_TRUE(float_reg_type.IsFloat()); 304 EXPECT_FALSE(float_reg_type.IsDouble()); 305 EXPECT_FALSE(float_reg_type.IsReference()); 306 EXPECT_FALSE(float_reg_type.IsLowHalf()); 307 EXPECT_FALSE(float_reg_type.IsHighHalf()); 308 EXPECT_FALSE(float_reg_type.IsLongOrDoubleTypes()); 309 EXPECT_FALSE(float_reg_type.IsReferenceTypes()); 310 EXPECT_TRUE(float_reg_type.IsCategory1Types()); 311 EXPECT_FALSE(float_reg_type.IsCategory2Types()); 312 EXPECT_FALSE(float_reg_type.IsBooleanTypes()); 313 EXPECT_FALSE(float_reg_type.IsByteTypes()); 314 EXPECT_FALSE(float_reg_type.IsShortTypes()); 315 EXPECT_FALSE(float_reg_type.IsCharTypes()); 316 EXPECT_FALSE(float_reg_type.IsIntegralTypes()); 317 EXPECT_TRUE(float_reg_type.IsFloatTypes()); 318 EXPECT_FALSE(float_reg_type.IsLongTypes()); 319 EXPECT_FALSE(float_reg_type.IsDoubleTypes()); 320 EXPECT_FALSE(float_reg_type.IsArrayIndexTypes()); 321 EXPECT_FALSE(float_reg_type.IsNonZeroReferenceTypes()); 322 EXPECT_TRUE(float_reg_type.HasClass()); 323 324 const RegType& double_reg_type = cache.DoubleLo(); 325 EXPECT_FALSE(double_reg_type.IsUndefined()); 326 EXPECT_FALSE(double_reg_type.IsConflict()); 327 EXPECT_FALSE(double_reg_type.IsZero()); 328 EXPECT_FALSE(double_reg_type.IsOne()); 329 EXPECT_FALSE(double_reg_type.IsLongConstant()); 330 EXPECT_FALSE(double_reg_type.IsBoolean()); 331 EXPECT_FALSE(double_reg_type.IsByte()); 332 EXPECT_FALSE(double_reg_type.IsChar()); 333 EXPECT_FALSE(double_reg_type.IsShort()); 334 EXPECT_FALSE(double_reg_type.IsInteger()); 335 EXPECT_FALSE(double_reg_type.IsLong()); 336 EXPECT_FALSE(double_reg_type.IsFloat()); 337 EXPECT_TRUE(double_reg_type.IsDouble()); 338 EXPECT_FALSE(double_reg_type.IsReference()); 339 EXPECT_TRUE(double_reg_type.IsLowHalf()); 340 EXPECT_FALSE(double_reg_type.IsHighHalf()); 341 EXPECT_TRUE(double_reg_type.IsLongOrDoubleTypes()); 342 EXPECT_FALSE(double_reg_type.IsReferenceTypes()); 343 EXPECT_FALSE(double_reg_type.IsCategory1Types()); 344 EXPECT_TRUE(double_reg_type.IsCategory2Types()); 345 EXPECT_FALSE(double_reg_type.IsBooleanTypes()); 346 EXPECT_FALSE(double_reg_type.IsByteTypes()); 347 EXPECT_FALSE(double_reg_type.IsShortTypes()); 348 EXPECT_FALSE(double_reg_type.IsCharTypes()); 349 EXPECT_FALSE(double_reg_type.IsIntegralTypes()); 350 EXPECT_FALSE(double_reg_type.IsFloatTypes()); 351 EXPECT_FALSE(double_reg_type.IsLongTypes()); 352 EXPECT_TRUE(double_reg_type.IsDoubleTypes()); 353 EXPECT_FALSE(double_reg_type.IsArrayIndexTypes()); 354 EXPECT_FALSE(double_reg_type.IsNonZeroReferenceTypes()); 355 EXPECT_TRUE(double_reg_type.HasClass()); 356 } 357 358 class RegTypeReferenceTest : public CommonRuntimeTest {}; 359 360 TEST_F(RegTypeReferenceTest, JavalangObjectImprecise) { 361 // Tests matching precisions. A reference type that was created precise doesn't 362 // match the one that is imprecise. 363 ArenaStack stack(Runtime::Current()->GetArenaPool()); 364 ScopedArenaAllocator allocator(&stack); 365 ScopedObjectAccess soa(Thread::Current()); 366 RegTypeCache cache(true, allocator); 367 const RegType& imprecise_obj = cache.JavaLangObject(false); 368 const RegType& precise_obj = cache.JavaLangObject(true); 369 const RegType& precise_obj_2 = cache.FromDescriptor(nullptr, "Ljava/lang/Object;", true); 370 371 EXPECT_TRUE(precise_obj.Equals(precise_obj_2)); 372 EXPECT_FALSE(imprecise_obj.Equals(precise_obj)); 373 EXPECT_FALSE(imprecise_obj.Equals(precise_obj)); 374 EXPECT_FALSE(imprecise_obj.Equals(precise_obj_2)); 375 } 376 377 TEST_F(RegTypeReferenceTest, UnresolvedType) { 378 // Tests creating unresolved types. Miss for the first time asking the cache and 379 // a hit second time. 380 ArenaStack stack(Runtime::Current()->GetArenaPool()); 381 ScopedArenaAllocator allocator(&stack); 382 ScopedObjectAccess soa(Thread::Current()); 383 RegTypeCache cache(true, allocator); 384 const RegType& ref_type_0 = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 385 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 386 EXPECT_TRUE(ref_type_0.IsNonZeroReferenceTypes()); 387 388 const RegType& ref_type_1 = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 389 EXPECT_TRUE(ref_type_0.Equals(ref_type_1)); 390 391 const RegType& unresolved_super_class = cache.FromUnresolvedSuperClass(ref_type_0); 392 EXPECT_TRUE(unresolved_super_class.IsUnresolvedSuperClass()); 393 EXPECT_TRUE(unresolved_super_class.IsNonZeroReferenceTypes()); 394 } 395 396 TEST_F(RegTypeReferenceTest, UnresolvedUnintializedType) { 397 // Tests creating types uninitialized types from unresolved types. 398 ArenaStack stack(Runtime::Current()->GetArenaPool()); 399 ScopedArenaAllocator allocator(&stack); 400 ScopedObjectAccess soa(Thread::Current()); 401 RegTypeCache cache(true, allocator); 402 const RegType& ref_type_0 = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 403 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 404 const RegType& ref_type = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 405 EXPECT_TRUE(ref_type_0.Equals(ref_type)); 406 // Create an uninitialized type of this unresolved type 407 const RegType& unresolved_unintialised = cache.Uninitialized(ref_type, 1101ull); 408 EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); 409 EXPECT_TRUE(unresolved_unintialised.IsUninitializedTypes()); 410 EXPECT_TRUE(unresolved_unintialised.IsNonZeroReferenceTypes()); 411 // Create an uninitialized type of this unresolved type with different PC 412 const RegType& ref_type_unresolved_unintialised_1 = cache.Uninitialized(ref_type, 1102ull); 413 EXPECT_TRUE(unresolved_unintialised.IsUnresolvedAndUninitializedReference()); 414 EXPECT_FALSE(unresolved_unintialised.Equals(ref_type_unresolved_unintialised_1)); 415 // Create an uninitialized type of this unresolved type with the same PC 416 const RegType& unresolved_unintialised_2 = cache.Uninitialized(ref_type, 1101ull); 417 EXPECT_TRUE(unresolved_unintialised.Equals(unresolved_unintialised_2)); 418 } 419 420 TEST_F(RegTypeReferenceTest, Dump) { 421 // Tests types for proper Dump messages. 422 ArenaStack stack(Runtime::Current()->GetArenaPool()); 423 ScopedArenaAllocator allocator(&stack); 424 ScopedObjectAccess soa(Thread::Current()); 425 RegTypeCache cache(true, allocator); 426 const RegType& unresolved_ref = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 427 const RegType& unresolved_ref_another = cache.FromDescriptor(nullptr, "Ljava/lang/DoesNotExistEither;", true); 428 const RegType& resolved_ref = cache.JavaLangString(); 429 const RegType& resolved_unintialiesd = cache.Uninitialized(resolved_ref, 10); 430 const RegType& unresolved_unintialized = cache.Uninitialized(unresolved_ref, 12); 431 const RegType& unresolved_merged = cache.FromUnresolvedMerge( 432 unresolved_ref, unresolved_ref_another, /* verifier */ nullptr); 433 434 std::string expected = "Unresolved Reference: java.lang.DoesNotExist"; 435 EXPECT_EQ(expected, unresolved_ref.Dump()); 436 expected = "Precise Reference: java.lang.String"; 437 EXPECT_EQ(expected, resolved_ref.Dump()); 438 expected ="Uninitialized Reference: java.lang.String Allocation PC: 10"; 439 EXPECT_EQ(expected, resolved_unintialiesd.Dump()); 440 expected = "Unresolved And Uninitialized Reference: java.lang.DoesNotExist Allocation PC: 12"; 441 EXPECT_EQ(expected, unresolved_unintialized.Dump()); 442 expected = "UnresolvedMergedReferences(Zero/null | Unresolved Reference: java.lang.DoesNotExist, Unresolved Reference: java.lang.DoesNotExistEither)"; 443 EXPECT_EQ(expected, unresolved_merged.Dump()); 444 } 445 446 TEST_F(RegTypeReferenceTest, JavalangString) { 447 // Add a class to the cache then look for the same class and make sure it is a 448 // Hit the second time. Then check for the same effect when using 449 // The JavaLangObject method instead of FromDescriptor. String class is final. 450 ArenaStack stack(Runtime::Current()->GetArenaPool()); 451 ScopedArenaAllocator allocator(&stack); 452 ScopedObjectAccess soa(Thread::Current()); 453 RegTypeCache cache(true, allocator); 454 const RegType& ref_type = cache.JavaLangString(); 455 const RegType& ref_type_2 = cache.JavaLangString(); 456 const RegType& ref_type_3 = cache.FromDescriptor(nullptr, "Ljava/lang/String;", true); 457 458 EXPECT_TRUE(ref_type.Equals(ref_type_2)); 459 EXPECT_TRUE(ref_type_2.Equals(ref_type_3)); 460 EXPECT_TRUE(ref_type.IsPreciseReference()); 461 462 // Create an uninitialized type out of this: 463 const RegType& ref_type_unintialized = cache.Uninitialized(ref_type, 0110ull); 464 EXPECT_TRUE(ref_type_unintialized.IsUninitializedReference()); 465 EXPECT_FALSE(ref_type_unintialized.IsUnresolvedAndUninitializedReference()); 466 } 467 468 TEST_F(RegTypeReferenceTest, JavalangObject) { 469 // Add a class to the cache then look for the same class and make sure it is a 470 // Hit the second time. Then I am checking for the same effect when using 471 // The JavaLangObject method instead of FromDescriptor. Object Class in not final. 472 ArenaStack stack(Runtime::Current()->GetArenaPool()); 473 ScopedArenaAllocator allocator(&stack); 474 ScopedObjectAccess soa(Thread::Current()); 475 RegTypeCache cache(true, allocator); 476 const RegType& ref_type = cache.JavaLangObject(true); 477 const RegType& ref_type_2 = cache.JavaLangObject(true); 478 const RegType& ref_type_3 = cache.FromDescriptor(nullptr, "Ljava/lang/Object;", true); 479 480 EXPECT_TRUE(ref_type.Equals(ref_type_2)); 481 EXPECT_TRUE(ref_type_3.Equals(ref_type_2)); 482 EXPECT_EQ(ref_type.GetId(), ref_type_3.GetId()); 483 } 484 TEST_F(RegTypeReferenceTest, Merging) { 485 // Tests merging logic 486 // String and object , LUB is object. 487 ScopedObjectAccess soa(Thread::Current()); 488 ArenaStack stack(Runtime::Current()->GetArenaPool()); 489 ScopedArenaAllocator allocator(&stack); 490 RegTypeCache cache_new(true, allocator); 491 const RegType& string = cache_new.JavaLangString(); 492 const RegType& Object = cache_new.JavaLangObject(true); 493 EXPECT_TRUE(string.Merge(Object, &cache_new, /* verifier */ nullptr).IsJavaLangObject()); 494 // Merge two unresolved types. 495 const RegType& ref_type_0 = cache_new.FromDescriptor(nullptr, "Ljava/lang/DoesNotExist;", true); 496 EXPECT_TRUE(ref_type_0.IsUnresolvedReference()); 497 const RegType& ref_type_1 = cache_new.FromDescriptor(nullptr, "Ljava/lang/DoesNotExistToo;", true); 498 EXPECT_FALSE(ref_type_0.Equals(ref_type_1)); 499 500 const RegType& merged = ref_type_1.Merge(ref_type_0, &cache_new, /* verifier */ nullptr); 501 EXPECT_TRUE(merged.IsUnresolvedMergedReference()); 502 RegType& merged_nonconst = const_cast<RegType&>(merged); 503 504 const BitVector& unresolved_parts = 505 down_cast<UnresolvedMergedType*>(&merged_nonconst)->GetUnresolvedTypes(); 506 EXPECT_TRUE(unresolved_parts.IsBitSet(ref_type_0.GetId())); 507 EXPECT_TRUE(unresolved_parts.IsBitSet(ref_type_1.GetId())); 508 } 509 510 TEST_F(RegTypeTest, MergingFloat) { 511 // Testing merging logic with float and float constants. 512 ArenaStack stack(Runtime::Current()->GetArenaPool()); 513 ScopedArenaAllocator allocator(&stack); 514 ScopedObjectAccess soa(Thread::Current()); 515 RegTypeCache cache_new(true, allocator); 516 517 constexpr int32_t kTestConstantValue = 10; 518 const RegType& float_type = cache_new.Float(); 519 const RegType& precise_cst = cache_new.FromCat1Const(kTestConstantValue, true); 520 const RegType& imprecise_cst = cache_new.FromCat1Const(kTestConstantValue, false); 521 { 522 // float MERGE precise cst => float. 523 const RegType& merged = float_type.Merge(precise_cst, &cache_new, /* verifier */ nullptr); 524 EXPECT_TRUE(merged.IsFloat()); 525 } 526 { 527 // precise cst MERGE float => float. 528 const RegType& merged = precise_cst.Merge(float_type, &cache_new, /* verifier */ nullptr); 529 EXPECT_TRUE(merged.IsFloat()); 530 } 531 { 532 // float MERGE imprecise cst => float. 533 const RegType& merged = float_type.Merge(imprecise_cst, &cache_new, /* verifier */ nullptr); 534 EXPECT_TRUE(merged.IsFloat()); 535 } 536 { 537 // imprecise cst MERGE float => float. 538 const RegType& merged = imprecise_cst.Merge(float_type, &cache_new, /* verifier */ nullptr); 539 EXPECT_TRUE(merged.IsFloat()); 540 } 541 } 542 543 TEST_F(RegTypeTest, MergingLong) { 544 // Testing merging logic with long and long constants. 545 ArenaStack stack(Runtime::Current()->GetArenaPool()); 546 ScopedArenaAllocator allocator(&stack); 547 ScopedObjectAccess soa(Thread::Current()); 548 RegTypeCache cache_new(true, allocator); 549 550 constexpr int32_t kTestConstantValue = 10; 551 const RegType& long_lo_type = cache_new.LongLo(); 552 const RegType& long_hi_type = cache_new.LongHi(); 553 const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); 554 const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); 555 const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); 556 const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); 557 { 558 // lo MERGE precise cst lo => lo. 559 const RegType& merged = long_lo_type.Merge(precise_cst_lo, &cache_new, /* verifier */ nullptr); 560 EXPECT_TRUE(merged.IsLongLo()); 561 } 562 { 563 // precise cst lo MERGE lo => lo. 564 const RegType& merged = precise_cst_lo.Merge(long_lo_type, &cache_new, /* verifier */ nullptr); 565 EXPECT_TRUE(merged.IsLongLo()); 566 } 567 { 568 // lo MERGE imprecise cst lo => lo. 569 const RegType& merged = long_lo_type.Merge( 570 imprecise_cst_lo, &cache_new, /* verifier */ nullptr); 571 EXPECT_TRUE(merged.IsLongLo()); 572 } 573 { 574 // imprecise cst lo MERGE lo => lo. 575 const RegType& merged = imprecise_cst_lo.Merge( 576 long_lo_type, &cache_new, /* verifier */ nullptr); 577 EXPECT_TRUE(merged.IsLongLo()); 578 } 579 { 580 // hi MERGE precise cst hi => hi. 581 const RegType& merged = long_hi_type.Merge(precise_cst_hi, &cache_new, /* verifier */ nullptr); 582 EXPECT_TRUE(merged.IsLongHi()); 583 } 584 { 585 // precise cst hi MERGE hi => hi. 586 const RegType& merged = precise_cst_hi.Merge(long_hi_type, &cache_new, /* verifier */ nullptr); 587 EXPECT_TRUE(merged.IsLongHi()); 588 } 589 { 590 // hi MERGE imprecise cst hi => hi. 591 const RegType& merged = long_hi_type.Merge( 592 imprecise_cst_hi, &cache_new, /* verifier */ nullptr); 593 EXPECT_TRUE(merged.IsLongHi()); 594 } 595 { 596 // imprecise cst hi MERGE hi => hi. 597 const RegType& merged = imprecise_cst_hi.Merge( 598 long_hi_type, &cache_new, /* verifier */ nullptr); 599 EXPECT_TRUE(merged.IsLongHi()); 600 } 601 } 602 603 TEST_F(RegTypeTest, MergingDouble) { 604 // Testing merging logic with double and double constants. 605 ArenaStack stack(Runtime::Current()->GetArenaPool()); 606 ScopedArenaAllocator allocator(&stack); 607 ScopedObjectAccess soa(Thread::Current()); 608 RegTypeCache cache_new(true, allocator); 609 610 constexpr int32_t kTestConstantValue = 10; 611 const RegType& double_lo_type = cache_new.DoubleLo(); 612 const RegType& double_hi_type = cache_new.DoubleHi(); 613 const RegType& precise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, true); 614 const RegType& imprecise_cst_lo = cache_new.FromCat2ConstLo(kTestConstantValue, false); 615 const RegType& precise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, true); 616 const RegType& imprecise_cst_hi = cache_new.FromCat2ConstHi(kTestConstantValue, false); 617 { 618 // lo MERGE precise cst lo => lo. 619 const RegType& merged = double_lo_type.Merge( 620 precise_cst_lo, &cache_new, /* verifier */ nullptr); 621 EXPECT_TRUE(merged.IsDoubleLo()); 622 } 623 { 624 // precise cst lo MERGE lo => lo. 625 const RegType& merged = precise_cst_lo.Merge( 626 double_lo_type, &cache_new, /* verifier */ nullptr); 627 EXPECT_TRUE(merged.IsDoubleLo()); 628 } 629 { 630 // lo MERGE imprecise cst lo => lo. 631 const RegType& merged = double_lo_type.Merge( 632 imprecise_cst_lo, &cache_new, /* verifier */ nullptr); 633 EXPECT_TRUE(merged.IsDoubleLo()); 634 } 635 { 636 // imprecise cst lo MERGE lo => lo. 637 const RegType& merged = imprecise_cst_lo.Merge( 638 double_lo_type, &cache_new, /* verifier */ nullptr); 639 EXPECT_TRUE(merged.IsDoubleLo()); 640 } 641 { 642 // hi MERGE precise cst hi => hi. 643 const RegType& merged = double_hi_type.Merge( 644 precise_cst_hi, &cache_new, /* verifier */ nullptr); 645 EXPECT_TRUE(merged.IsDoubleHi()); 646 } 647 { 648 // precise cst hi MERGE hi => hi. 649 const RegType& merged = precise_cst_hi.Merge( 650 double_hi_type, &cache_new, /* verifier */ nullptr); 651 EXPECT_TRUE(merged.IsDoubleHi()); 652 } 653 { 654 // hi MERGE imprecise cst hi => hi. 655 const RegType& merged = double_hi_type.Merge( 656 imprecise_cst_hi, &cache_new, /* verifier */ nullptr); 657 EXPECT_TRUE(merged.IsDoubleHi()); 658 } 659 { 660 // imprecise cst hi MERGE hi => hi. 661 const RegType& merged = imprecise_cst_hi.Merge( 662 double_hi_type, &cache_new, /* verifier */ nullptr); 663 EXPECT_TRUE(merged.IsDoubleHi()); 664 } 665 } 666 667 TEST_F(RegTypeTest, ConstPrecision) { 668 // Tests creating primitive types types. 669 ArenaStack stack(Runtime::Current()->GetArenaPool()); 670 ScopedArenaAllocator allocator(&stack); 671 ScopedObjectAccess soa(Thread::Current()); 672 RegTypeCache cache_new(true, allocator); 673 const RegType& imprecise_const = cache_new.FromCat1Const(10, false); 674 const RegType& precise_const = cache_new.FromCat1Const(10, true); 675 676 EXPECT_TRUE(imprecise_const.IsImpreciseConstant()); 677 EXPECT_TRUE(precise_const.IsPreciseConstant()); 678 EXPECT_FALSE(imprecise_const.Equals(precise_const)); 679 } 680 681 class RegTypeOOMTest : public RegTypeTest { 682 protected: 683 void SetUpRuntimeOptions(RuntimeOptions *options) OVERRIDE { 684 // Use a smaller heap 685 for (std::pair<std::string, const void*>& pair : *options) { 686 if (pair.first.find("-Xmx") == 0) { 687 pair.first = "-Xmx4M"; // Smallest we can go. 688 } 689 } 690 options->push_back(std::make_pair("-Xint", nullptr)); 691 692 // We must not appear to be a compiler, or we'll abort on the host. 693 callbacks_.reset(); 694 } 695 696 static const size_t kMaxHandles = 1000000; // Use arbitrary large amount for now. 697 static void FillHeap(Thread* self, 698 ClassLinker* class_linker, 699 std::unique_ptr<StackHandleScope<kMaxHandles>>* hsp, 700 std::vector<MutableHandle<mirror::Object>>* handles) 701 REQUIRES_SHARED(Locks::mutator_lock_) { 702 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB); 703 704 hsp->reset(new StackHandleScope<kMaxHandles>(self)); 705 // Class java.lang.Object. 706 Handle<mirror::Class> c((*hsp)->NewHandle( 707 class_linker->FindSystemClass(self, "Ljava/lang/Object;"))); 708 // Array helps to fill memory faster. 709 Handle<mirror::Class> ca((*hsp)->NewHandle( 710 class_linker->FindSystemClass(self, "[Ljava/lang/Object;"))); 711 712 // Start allocating with 128K 713 size_t length = 128 * KB / 4; 714 while (length > 10) { 715 MutableHandle<mirror::Object> h((*hsp)->NewHandle<mirror::Object>( 716 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), length / 4))); 717 if (self->IsExceptionPending() || h == nullptr) { 718 self->ClearException(); 719 720 // Try a smaller length 721 length = length / 8; 722 // Use at most half the reported free space. 723 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory(); 724 if (length * 8 > mem) { 725 length = mem / 8; 726 } 727 } else { 728 handles->push_back(h); 729 } 730 } 731 732 // Allocate simple objects till it fails. 733 while (!self->IsExceptionPending()) { 734 MutableHandle<mirror::Object> h = (*hsp)->NewHandle<mirror::Object>(c->AllocObject(self)); 735 if (!self->IsExceptionPending() && h != nullptr) { 736 handles->push_back(h); 737 } 738 } 739 self->ClearException(); 740 } 741 }; 742 743 TEST_F(RegTypeOOMTest, ClassJoinOOM) { 744 // Tests that we don't abort with OOMs. 745 746 ArenaStack stack(Runtime::Current()->GetArenaPool()); 747 ScopedArenaAllocator allocator(&stack); 748 ScopedObjectAccess soa(Thread::Current()); 749 750 // We cannot allow moving GC. Otherwise we'd have to ensure the reg types are updated (reference 751 // reg types store a class pointer in a GCRoot, which is normally updated through active verifiers 752 // being registered with their thread), which is unnecessarily complex. 753 Runtime::Current()->GetHeap()->IncrementDisableMovingGC(soa.Self()); 754 755 // We merge nested array of primitive wrappers. These have a join type of an array of Number of 756 // the same depth. We start with depth five, as we want at least two newly created classes to 757 // test recursion (it's just more likely that nobody uses such deep arrays in runtime bringup). 758 constexpr const char* kIntArrayFive = "[[[[[Ljava/lang/Integer;"; 759 constexpr const char* kFloatArrayFive = "[[[[[Ljava/lang/Float;"; 760 constexpr const char* kNumberArrayFour = "[[[[Ljava/lang/Number;"; 761 constexpr const char* kNumberArrayFive = "[[[[[Ljava/lang/Number;"; 762 763 RegTypeCache cache(true, allocator); 764 const RegType& int_array_array = cache.From(nullptr, kIntArrayFive, false); 765 ASSERT_TRUE(int_array_array.HasClass()); 766 const RegType& float_array_array = cache.From(nullptr, kFloatArrayFive, false); 767 ASSERT_TRUE(float_array_array.HasClass()); 768 769 // Check assumptions: the joined classes don't exist, yet. 770 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 771 ASSERT_TRUE(class_linker->LookupClass(soa.Self(), kNumberArrayFour, nullptr) == nullptr); 772 ASSERT_TRUE(class_linker->LookupClass(soa.Self(), kNumberArrayFive, nullptr) == nullptr); 773 774 // Fill the heap. 775 std::unique_ptr<StackHandleScope<kMaxHandles>> hsp; 776 std::vector<MutableHandle<mirror::Object>> handles; 777 FillHeap(soa.Self(), class_linker, &hsp, &handles); 778 779 const RegType& join_type = int_array_array.Merge(float_array_array, &cache, nullptr); 780 ASSERT_TRUE(join_type.IsUnresolvedReference()); 781 782 Runtime::Current()->GetHeap()->DecrementDisableMovingGC(soa.Self()); 783 } 784 785 } // namespace verifier 786 } // namespace art 787