1 /* 2 * Copyright (C) 2015 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 "unstarted_runtime.h" 18 19 #include <limits> 20 #include <locale> 21 22 #include "base/casts.h" 23 #include "base/enums.h" 24 #include "base/memory_tool.h" 25 #include "class_linker.h" 26 #include "common_runtime_test.h" 27 #include "dex/descriptors_names.h" 28 #include "dex/dex_instruction.h" 29 #include "handle.h" 30 #include "handle_scope-inl.h" 31 #include "interpreter/interpreter_common.h" 32 #include "mirror/class_loader.h" 33 #include "mirror/object-inl.h" 34 #include "mirror/object_array-inl.h" 35 #include "mirror/string-inl.h" 36 #include "runtime.h" 37 #include "scoped_thread_state_change-inl.h" 38 #include "thread.h" 39 #include "transaction.h" 40 41 namespace art { 42 namespace interpreter { 43 44 class UnstartedRuntimeTest : public CommonRuntimeTest { 45 protected: 46 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 47 // test friends. 48 49 // Methods that intercept available libcore implementations. 50 #define UNSTARTED_DIRECT(Name, SigIgnored) \ 51 static void Unstarted ## Name(Thread* self, \ 52 ShadowFrame* shadow_frame, \ 53 JValue* result, \ 54 size_t arg_offset) \ 55 REQUIRES_SHARED(Locks::mutator_lock_) { \ 56 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 57 } 58 #include "unstarted_runtime_list.h" 59 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 60 #undef UNSTARTED_RUNTIME_DIRECT_LIST 61 #undef UNSTARTED_RUNTIME_JNI_LIST 62 #undef UNSTARTED_DIRECT 63 64 // Methods that are native. 65 #define UNSTARTED_JNI(Name, SigIgnored) \ 66 static void UnstartedJNI ## Name(Thread* self, \ 67 ArtMethod* method, \ 68 mirror::Object* receiver, \ 69 uint32_t* args, \ 70 JValue* result) \ 71 REQUIRES_SHARED(Locks::mutator_lock_) { \ 72 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 73 } 74 #include "unstarted_runtime_list.h" 75 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 76 #undef UNSTARTED_RUNTIME_DIRECT_LIST 77 #undef UNSTARTED_RUNTIME_JNI_LIST 78 #undef UNSTARTED_JNI 79 80 // Helpers for ArrayCopy. 81 // 82 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size 83 // of three everywhere. That is enough to test all cases. 84 85 static mirror::ObjectArray<mirror::Object>* CreateObjectArray( 86 Thread* self, 87 ObjPtr<mirror::Class> component_type, 88 const StackHandleScope<3>& data) 89 REQUIRES_SHARED(Locks::mutator_lock_) { 90 Runtime* runtime = Runtime::Current(); 91 ObjPtr<mirror::Class> array_type = 92 runtime->GetClassLinker()->FindArrayClass(self, &component_type); 93 CHECK(array_type != nullptr); 94 ObjPtr<mirror::ObjectArray<mirror::Object>> result = 95 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3); 96 CHECK(result != nullptr); 97 for (size_t i = 0; i < 3; ++i) { 98 result->Set(static_cast<int32_t>(i), data.GetReference(i)); 99 CHECK(!self->IsExceptionPending()); 100 } 101 return result.Ptr(); 102 } 103 104 static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, 105 const StackHandleScope<3>& data) 106 REQUIRES_SHARED(Locks::mutator_lock_) { 107 CHECK_EQ(array->GetLength(), 3); 108 CHECK_EQ(data.NumberOfReferences(), 3U); 109 for (size_t i = 0; i < 3; ++i) { 110 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i; 111 } 112 } 113 114 void RunArrayCopy(Thread* self, 115 ShadowFrame* tmp, 116 bool expect_exception, 117 mirror::ObjectArray<mirror::Object>* src, 118 int32_t src_pos, 119 mirror::ObjectArray<mirror::Object>* dst, 120 int32_t dst_pos, 121 int32_t length) 122 REQUIRES_SHARED(Locks::mutator_lock_) { 123 JValue result; 124 tmp->SetVRegReference(0, src); 125 tmp->SetVReg(1, src_pos); 126 tmp->SetVRegReference(2, dst); 127 tmp->SetVReg(3, dst_pos); 128 tmp->SetVReg(4, length); 129 UnstartedSystemArraycopy(self, tmp, &result, 0); 130 bool exception_pending = self->IsExceptionPending(); 131 EXPECT_EQ(exception_pending, expect_exception); 132 if (exception_pending) { 133 self->ClearException(); 134 } 135 } 136 137 void RunArrayCopy(Thread* self, 138 ShadowFrame* tmp, 139 bool expect_exception, 140 mirror::Class* src_component_class, 141 mirror::Class* dst_component_class, 142 const StackHandleScope<3>& src_data, 143 int32_t src_pos, 144 const StackHandleScope<3>& dst_data, 145 int32_t dst_pos, 146 int32_t length, 147 const StackHandleScope<3>& expected_result) 148 REQUIRES_SHARED(Locks::mutator_lock_) { 149 StackHandleScope<3> hs_misc(self); 150 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class)); 151 152 Handle<mirror::ObjectArray<mirror::Object>> src_handle( 153 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data))); 154 155 Handle<mirror::ObjectArray<mirror::Object>> dst_handle( 156 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data))); 157 158 RunArrayCopy(self, 159 tmp, 160 expect_exception, 161 src_handle.Get(), 162 src_pos, 163 dst_handle.Get(), 164 dst_pos, 165 length); 166 CheckObjectArray(dst_handle.Get(), expected_result); 167 } 168 169 void TestCeilFloor(bool ceil, 170 Thread* self, 171 ShadowFrame* tmp, 172 double const test_pairs[][2], 173 size_t num_pairs) 174 REQUIRES_SHARED(Locks::mutator_lock_) { 175 for (size_t i = 0; i < num_pairs; ++i) { 176 tmp->SetVRegDouble(0, test_pairs[i][0]); 177 178 JValue result; 179 if (ceil) { 180 UnstartedMathCeil(self, tmp, &result, 0); 181 } else { 182 UnstartedMathFloor(self, tmp, &result, 0); 183 } 184 185 ASSERT_FALSE(self->IsExceptionPending()); 186 187 // We want precise results. 188 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD()); 189 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]); 190 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1]; 191 } 192 } 193 194 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the 195 // loading code doesn't work under transactions. 196 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) { 197 mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass( 198 Thread::Current(), 199 Transaction::kAbortExceptionSignature, 200 ScopedNullHandle<mirror::ClassLoader>()); 201 CHECK(result != nullptr); 202 } 203 }; 204 205 TEST_F(UnstartedRuntimeTest, MemoryPeekByte) { 206 Thread* self = Thread::Current(); 207 208 ScopedObjectAccess soa(self); 209 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 210 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 211 const uint8_t* base_ptr = base_array; 212 213 JValue result; 214 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 215 216 for (int32_t i = 0; i < kBaseLen; ++i) { 217 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 218 219 UnstartedMemoryPeekByte(self, tmp, &result, 0); 220 221 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i])); 222 } 223 224 ShadowFrame::DeleteDeoptimizedFrame(tmp); 225 } 226 227 TEST_F(UnstartedRuntimeTest, MemoryPeekShort) { 228 Thread* self = Thread::Current(); 229 230 ScopedObjectAccess soa(self); 231 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 232 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 233 const uint8_t* base_ptr = base_array; 234 235 JValue result; 236 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 237 238 int32_t adjusted_length = kBaseLen - sizeof(int16_t); 239 for (int32_t i = 0; i < adjusted_length; ++i) { 240 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 241 242 UnstartedMemoryPeekShort(self, tmp, &result, 0); 243 244 typedef int16_t unaligned_short __attribute__ ((aligned (1))); 245 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i); 246 EXPECT_EQ(result.GetS(), *short_ptr); 247 } 248 249 ShadowFrame::DeleteDeoptimizedFrame(tmp); 250 } 251 252 TEST_F(UnstartedRuntimeTest, MemoryPeekInt) { 253 Thread* self = Thread::Current(); 254 255 ScopedObjectAccess soa(self); 256 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 257 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 258 const uint8_t* base_ptr = base_array; 259 260 JValue result; 261 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 262 263 int32_t adjusted_length = kBaseLen - sizeof(int32_t); 264 for (int32_t i = 0; i < adjusted_length; ++i) { 265 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 266 267 UnstartedMemoryPeekInt(self, tmp, &result, 0); 268 269 typedef int32_t unaligned_int __attribute__ ((aligned (1))); 270 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i); 271 EXPECT_EQ(result.GetI(), *int_ptr); 272 } 273 274 ShadowFrame::DeleteDeoptimizedFrame(tmp); 275 } 276 277 TEST_F(UnstartedRuntimeTest, MemoryPeekLong) { 278 Thread* self = Thread::Current(); 279 280 ScopedObjectAccess soa(self); 281 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 282 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 283 const uint8_t* base_ptr = base_array; 284 285 JValue result; 286 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 287 288 int32_t adjusted_length = kBaseLen - sizeof(int64_t); 289 for (int32_t i = 0; i < adjusted_length; ++i) { 290 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 291 292 UnstartedMemoryPeekLong(self, tmp, &result, 0); 293 294 typedef int64_t unaligned_long __attribute__ ((aligned (1))); 295 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i); 296 EXPECT_EQ(result.GetJ(), *long_ptr); 297 } 298 299 ShadowFrame::DeleteDeoptimizedFrame(tmp); 300 } 301 302 TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) { 303 Thread* self = Thread::Current(); 304 305 ScopedObjectAccess soa(self); 306 StackHandleScope<2> hs(self); 307 // TODO: Actual UTF. 308 constexpr const char base_string[] = "abcdefghijklmnop"; 309 Handle<mirror::String> h_test_string(hs.NewHandle( 310 mirror::String::AllocFromModifiedUtf8(self, base_string))); 311 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1; 312 Handle<mirror::CharArray> h_char_array(hs.NewHandle( 313 mirror::CharArray::Alloc(self, kBaseLen))); 314 // A buffer so we can make sure we only modify the elements targetted. 315 uint16_t buf[kBaseLen]; 316 317 JValue result; 318 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 319 320 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) { 321 for (int32_t count = 0; count <= kBaseLen; ++count) { 322 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) { 323 // Only do it when in bounds. 324 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) { 325 tmp->SetVRegReference(0, h_test_string.Get()); 326 tmp->SetVReg(1, start_index); 327 tmp->SetVReg(2, count); 328 tmp->SetVRegReference(3, h_char_array.Get()); 329 tmp->SetVReg(3, trg_offset); 330 331 // Copy the char_array into buf. 332 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t)); 333 334 UnstartedStringCharAt(self, tmp, &result, 0); 335 336 uint16_t* data = h_char_array->GetData(); 337 338 bool success = true; 339 340 // First segment should be unchanged. 341 for (int32_t i = 0; i < trg_offset; ++i) { 342 success = success && (data[i] == buf[i]); 343 } 344 // Second segment should be a copy. 345 for (int32_t i = trg_offset; i < trg_offset + count; ++i) { 346 success = success && (data[i] == buf[i - trg_offset + start_index]); 347 } 348 // Third segment should be unchanged. 349 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) { 350 success = success && (data[i] == buf[i]); 351 } 352 353 EXPECT_TRUE(success); 354 } 355 } 356 } 357 } 358 359 ShadowFrame::DeleteDeoptimizedFrame(tmp); 360 } 361 362 TEST_F(UnstartedRuntimeTest, StringCharAt) { 363 Thread* self = Thread::Current(); 364 365 ScopedObjectAccess soa(self); 366 // TODO: Actual UTF. 367 constexpr const char* base_string = "abcdefghijklmnop"; 368 int32_t base_len = static_cast<int32_t>(strlen(base_string)); 369 mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); 370 371 JValue result; 372 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 373 374 for (int32_t i = 0; i < base_len; ++i) { 375 tmp->SetVRegReference(0, test_string); 376 tmp->SetVReg(1, i); 377 378 UnstartedStringCharAt(self, tmp, &result, 0); 379 380 EXPECT_EQ(result.GetI(), base_string[i]); 381 } 382 383 ShadowFrame::DeleteDeoptimizedFrame(tmp); 384 } 385 386 TEST_F(UnstartedRuntimeTest, StringInit) { 387 Thread* self = Thread::Current(); 388 ScopedObjectAccess soa(self); 389 mirror::Class* klass = mirror::String::GetJavaLangString(); 390 ArtMethod* method = 391 klass->FindConstructor("(Ljava/lang/String;)V", 392 Runtime::Current()->GetClassLinker()->GetImagePointerSize()); 393 ASSERT_TRUE(method != nullptr); 394 395 // create instruction data for invoke-direct {v0, v1} of method with fake index 396 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 397 398 JValue result; 399 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 400 const char* base_string = "hello_world"; 401 mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 402 mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 403 shadow_frame->SetVRegReference(0, reference_empty_string); 404 shadow_frame->SetVRegReference(1, string_arg); 405 406 interpreter::DoCall<false, false>(method, 407 self, 408 *shadow_frame, 409 Instruction::At(inst_data), 410 inst_data[0], 411 &result); 412 mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 413 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 414 415 if (string_arg->IsCompressed() && string_result->IsCompressed()) { 416 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(), 417 string_arg->GetLength() * sizeof(uint8_t)), 0); 418 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) { 419 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 420 string_arg->GetLength() * sizeof(uint16_t)), 0); 421 } else { 422 bool equal = true; 423 for (int i = 0; i < string_arg->GetLength(); ++i) { 424 if (string_arg->CharAt(i) != string_result->CharAt(i)) { 425 equal = false; 426 break; 427 } 428 } 429 EXPECT_EQ(equal, true); 430 } 431 432 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 433 } 434 435 // Tests the exceptions that should be checked before modifying the destination. 436 // (Doesn't check the object vs primitive case ATM.) 437 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 438 Thread* self = Thread::Current(); 439 ScopedObjectAccess soa(self); 440 JValue result; 441 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 442 443 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 444 // allocate. 445 StackHandleScope<2> hs_misc(self); 446 Handle<mirror::Class> object_class( 447 hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 448 449 StackHandleScope<3> hs_data(self); 450 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 451 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 452 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 453 454 Handle<mirror::ObjectArray<mirror::Object>> array( 455 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 456 457 RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 458 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 459 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 460 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 461 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 462 RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 463 464 mirror::ObjectArray<mirror::Object>* class_as_array = 465 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 466 RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 467 RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 468 469 ShadowFrame::DeleteDeoptimizedFrame(tmp); 470 } 471 472 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 473 Thread* self = Thread::Current(); 474 ScopedObjectAccess soa(self); 475 JValue result; 476 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 477 478 StackHandleScope<1> hs_object(self); 479 Handle<mirror::Class> object_class( 480 hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 481 482 // Simple test: 483 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 484 { 485 StackHandleScope<3> hs_src(self); 486 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 487 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 488 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 489 490 StackHandleScope<3> hs_dst(self); 491 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 492 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 493 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 494 495 StackHandleScope<3> hs_expected(self); 496 hs_expected.NewHandle(hs_dst.GetReference(0)); 497 hs_expected.NewHandle(hs_dst.GetReference(1)); 498 hs_expected.NewHandle(hs_src.GetReference(1)); 499 500 RunArrayCopy(self, 501 tmp, 502 false, 503 object_class.Get(), 504 object_class.Get(), 505 hs_src, 506 1, 507 hs_dst, 508 2, 509 1, 510 hs_expected); 511 } 512 513 // Simple test: 514 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 515 { 516 StackHandleScope<3> hs_src(self); 517 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 518 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 519 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 520 521 StackHandleScope<3> hs_dst(self); 522 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 523 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 524 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 525 526 StackHandleScope<3> hs_expected(self); 527 hs_expected.NewHandle(hs_dst.GetReference(0)); 528 hs_expected.NewHandle(hs_src.GetReference(1)); 529 hs_expected.NewHandle(hs_dst.GetReference(2)); 530 531 RunArrayCopy(self, 532 tmp, 533 false, 534 object_class.Get(), 535 mirror::String::GetJavaLangString(), 536 hs_src, 537 1, 538 hs_dst, 539 1, 540 1, 541 hs_expected); 542 } 543 544 // Simple test: 545 // [1,*,3] into [4,5,6] = [1,5,6] + exc 546 { 547 StackHandleScope<3> hs_src(self); 548 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 549 hs_src.NewHandle(mirror::String::GetJavaLangString()); 550 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 551 552 StackHandleScope<3> hs_dst(self); 553 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 554 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 555 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 556 557 StackHandleScope<3> hs_expected(self); 558 hs_expected.NewHandle(hs_src.GetReference(0)); 559 hs_expected.NewHandle(hs_dst.GetReference(1)); 560 hs_expected.NewHandle(hs_dst.GetReference(2)); 561 562 RunArrayCopy(self, 563 tmp, 564 true, 565 object_class.Get(), 566 mirror::String::GetJavaLangString(), 567 hs_src, 568 0, 569 hs_dst, 570 0, 571 3, 572 hs_expected); 573 } 574 575 ShadowFrame::DeleteDeoptimizedFrame(tmp); 576 } 577 578 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) { 579 Thread* self = Thread::Current(); 580 ScopedObjectAccess soa(self); 581 582 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 583 584 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 585 // suffixes). 586 constexpr const char* test_string = "-2147483646"; 587 constexpr int32_t test_values[] = { 588 6, 589 46, 590 646, 591 3646, 592 83646, 593 483646, 594 7483646, 595 47483646, 596 147483646, 597 2147483646, 598 -2147483646 599 }; 600 601 static_assert(arraysize(test_values) == 11U, "test_values"); 602 CHECK_EQ(strlen(test_string), 11U); 603 604 for (size_t i = 0; i <= 10; ++i) { 605 const char* test_value = &test_string[10 - i]; 606 607 StackHandleScope<1> hs_str(self); 608 Handle<mirror::String> h_str( 609 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 610 ASSERT_NE(h_str.Get(), nullptr); 611 ASSERT_FALSE(self->IsExceptionPending()); 612 613 tmp->SetVRegReference(0, h_str.Get()); 614 615 JValue result; 616 UnstartedIntegerParseInt(self, tmp, &result, 0); 617 618 ASSERT_FALSE(self->IsExceptionPending()); 619 EXPECT_EQ(result.GetI(), test_values[i]); 620 } 621 622 ShadowFrame::DeleteDeoptimizedFrame(tmp); 623 } 624 625 // Right now the same as Integer.Parse 626 TEST_F(UnstartedRuntimeTest, LongParseLongTest) { 627 Thread* self = Thread::Current(); 628 ScopedObjectAccess soa(self); 629 630 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 631 632 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 633 // suffixes). 634 constexpr const char* test_string = "-2147483646"; 635 constexpr int64_t test_values[] = { 636 6, 637 46, 638 646, 639 3646, 640 83646, 641 483646, 642 7483646, 643 47483646, 644 147483646, 645 2147483646, 646 -2147483646 647 }; 648 649 static_assert(arraysize(test_values) == 11U, "test_values"); 650 CHECK_EQ(strlen(test_string), 11U); 651 652 for (size_t i = 0; i <= 10; ++i) { 653 const char* test_value = &test_string[10 - i]; 654 655 StackHandleScope<1> hs_str(self); 656 Handle<mirror::String> h_str( 657 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 658 ASSERT_NE(h_str.Get(), nullptr); 659 ASSERT_FALSE(self->IsExceptionPending()); 660 661 tmp->SetVRegReference(0, h_str.Get()); 662 663 JValue result; 664 UnstartedLongParseLong(self, tmp, &result, 0); 665 666 ASSERT_FALSE(self->IsExceptionPending()); 667 EXPECT_EQ(result.GetJ(), test_values[i]); 668 } 669 670 ShadowFrame::DeleteDeoptimizedFrame(tmp); 671 } 672 673 TEST_F(UnstartedRuntimeTest, Ceil) { 674 Thread* self = Thread::Current(); 675 ScopedObjectAccess soa(self); 676 677 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 678 679 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 680 constexpr double inf = std::numeric_limits<double>::infinity(); 681 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 682 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 683 constexpr double test_pairs[][2] = { 684 { -0.0, -0.0 }, 685 { 0.0, 0.0 }, 686 { -0.5, -0.0 }, 687 { -1.0, -1.0 }, 688 { 0.5, 1.0 }, 689 { 1.0, 1.0 }, 690 { nan, nan }, 691 { inf, inf }, 692 { -inf, -inf }, 693 { ld1, ld1 }, 694 { ld2, ld2 } 695 }; 696 697 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs)); 698 699 ShadowFrame::DeleteDeoptimizedFrame(tmp); 700 } 701 702 TEST_F(UnstartedRuntimeTest, Floor) { 703 Thread* self = Thread::Current(); 704 ScopedObjectAccess soa(self); 705 706 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 707 708 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 709 constexpr double inf = std::numeric_limits<double>::infinity(); 710 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 711 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 712 constexpr double test_pairs[][2] = { 713 { -0.0, -0.0 }, 714 { 0.0, 0.0 }, 715 { -0.5, -1.0 }, 716 { -1.0, -1.0 }, 717 { 0.5, 0.0 }, 718 { 1.0, 1.0 }, 719 { nan, nan }, 720 { inf, inf }, 721 { -inf, -inf }, 722 { ld1, ld1 }, 723 { ld2, ld2 } 724 }; 725 726 TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs)); 727 728 ShadowFrame::DeleteDeoptimizedFrame(tmp); 729 } 730 731 TEST_F(UnstartedRuntimeTest, ToLowerUpper) { 732 Thread* self = Thread::Current(); 733 ScopedObjectAccess soa(self); 734 735 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 736 737 std::locale c_locale("C"); 738 739 // Check ASCII. 740 for (uint32_t i = 0; i < 128; ++i) { 741 bool c_upper = std::isupper(static_cast<char>(i), c_locale); 742 bool c_lower = std::islower(static_cast<char>(i), c_locale); 743 EXPECT_FALSE(c_upper && c_lower) << i; 744 745 // Check toLowerCase. 746 { 747 JValue result; 748 tmp->SetVReg(0, static_cast<int32_t>(i)); 749 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 750 ASSERT_FALSE(self->IsExceptionPending()); 751 uint32_t lower_result = static_cast<uint32_t>(result.GetI()); 752 if (c_lower) { 753 EXPECT_EQ(i, lower_result); 754 } else if (c_upper) { 755 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)), 756 lower_result); 757 } else { 758 EXPECT_EQ(i, lower_result); 759 } 760 } 761 762 // Check toUpperCase. 763 { 764 JValue result2; 765 tmp->SetVReg(0, static_cast<int32_t>(i)); 766 UnstartedCharacterToUpperCase(self, tmp, &result2, 0); 767 ASSERT_FALSE(self->IsExceptionPending()); 768 uint32_t upper_result = static_cast<uint32_t>(result2.GetI()); 769 if (c_upper) { 770 EXPECT_EQ(i, upper_result); 771 } else if (c_lower) { 772 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)), 773 upper_result); 774 } else { 775 EXPECT_EQ(i, upper_result); 776 } 777 } 778 } 779 780 // Check abort for other things. Can't test all. 781 782 PrepareForAborts(); 783 784 for (uint32_t i = 128; i < 256; ++i) { 785 { 786 JValue result; 787 tmp->SetVReg(0, static_cast<int32_t>(i)); 788 Runtime::Current()->EnterTransactionMode(); 789 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 790 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 791 Runtime::Current()->ExitTransactionMode(); 792 ASSERT_TRUE(self->IsExceptionPending()); 793 } 794 { 795 JValue result; 796 tmp->SetVReg(0, static_cast<int32_t>(i)); 797 Runtime::Current()->EnterTransactionMode(); 798 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 799 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 800 Runtime::Current()->ExitTransactionMode(); 801 ASSERT_TRUE(self->IsExceptionPending()); 802 } 803 } 804 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) { 805 { 806 JValue result; 807 tmp->SetVReg(0, static_cast<int32_t>(i)); 808 Runtime::Current()->EnterTransactionMode(); 809 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 810 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 811 Runtime::Current()->ExitTransactionMode(); 812 ASSERT_TRUE(self->IsExceptionPending()); 813 } 814 { 815 JValue result; 816 tmp->SetVReg(0, static_cast<int32_t>(i)); 817 Runtime::Current()->EnterTransactionMode(); 818 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 819 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 820 Runtime::Current()->ExitTransactionMode(); 821 ASSERT_TRUE(self->IsExceptionPending()); 822 } 823 } 824 825 ShadowFrame::DeleteDeoptimizedFrame(tmp); 826 } 827 828 TEST_F(UnstartedRuntimeTest, Sin) { 829 Thread* self = Thread::Current(); 830 ScopedObjectAccess soa(self); 831 832 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 833 834 // Test an important value, PI/6. That's the one we see in practice. 835 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 836 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 837 838 JValue result; 839 UnstartedMathSin(self, tmp, &result, 0); 840 841 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 842 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult); 843 844 ShadowFrame::DeleteDeoptimizedFrame(tmp); 845 } 846 847 TEST_F(UnstartedRuntimeTest, Cos) { 848 Thread* self = Thread::Current(); 849 ScopedObjectAccess soa(self); 850 851 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 852 853 // Test an important value, PI/6. That's the one we see in practice. 854 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 855 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 856 857 JValue result; 858 UnstartedMathCos(self, tmp, &result, 0); 859 860 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 861 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult); 862 863 ShadowFrame::DeleteDeoptimizedFrame(tmp); 864 } 865 866 TEST_F(UnstartedRuntimeTest, Pow) { 867 // Valgrind seems to get this wrong, actually. Disable for valgrind. 868 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) { 869 return; 870 } 871 872 Thread* self = Thread::Current(); 873 ScopedObjectAccess soa(self); 874 875 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 876 877 // Test an important pair. 878 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000); 879 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000); 880 881 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1)); 882 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2)); 883 884 JValue result; 885 UnstartedMathPow(self, tmp, &result, 0); 886 887 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 888 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult); 889 890 ShadowFrame::DeleteDeoptimizedFrame(tmp); 891 } 892 893 TEST_F(UnstartedRuntimeTest, IsAnonymousClass) { 894 Thread* self = Thread::Current(); 895 ScopedObjectAccess soa(self); 896 897 JValue result; 898 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 899 900 mirror::Class* class_klass = mirror::Class::GetJavaLangClass(); 901 shadow_frame->SetVRegReference(0, class_klass); 902 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 903 EXPECT_EQ(result.GetZ(), 0); 904 905 jobject class_loader = LoadDex("Nested"); 906 StackHandleScope<1> hs(soa.Self()); 907 Handle<mirror::ClassLoader> loader( 908 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 909 mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader); 910 ASSERT_TRUE(c != nullptr); 911 shadow_frame->SetVRegReference(0, c); 912 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 913 EXPECT_EQ(result.GetZ(), 1); 914 915 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 916 } 917 918 TEST_F(UnstartedRuntimeTest, GetDeclaringClass) { 919 Thread* self = Thread::Current(); 920 ScopedObjectAccess soa(self); 921 922 JValue result; 923 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 924 925 jobject class_loader = LoadDex("Nested"); 926 StackHandleScope<4> hs(self); 927 Handle<mirror::ClassLoader> loader( 928 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 929 930 Handle<mirror::Class> nested_klass(hs.NewHandle( 931 class_linker_->FindClass(soa.Self(), "LNested;", loader))); 932 Handle<mirror::Class> inner_klass(hs.NewHandle( 933 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader))); 934 Handle<mirror::Class> anon_klass(hs.NewHandle( 935 class_linker_->FindClass(soa.Self(), "LNested$1;", loader))); 936 937 shadow_frame->SetVRegReference(0, nested_klass.Get()); 938 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 939 EXPECT_EQ(result.GetL(), nullptr); 940 941 shadow_frame->SetVRegReference(0, inner_klass.Get()); 942 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 943 EXPECT_EQ(result.GetL(), nested_klass.Get()); 944 945 shadow_frame->SetVRegReference(0, anon_klass.Get()); 946 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 947 EXPECT_EQ(result.GetL(), nullptr); 948 949 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 950 } 951 952 TEST_F(UnstartedRuntimeTest, ThreadLocalGet) { 953 Thread* self = Thread::Current(); 954 ScopedObjectAccess soa(self); 955 956 JValue result; 957 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 958 959 StackHandleScope<1> hs(self); 960 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 961 962 // Positive test. See that We get something for float conversion. 963 { 964 Handle<mirror::Class> floating_decimal = hs.NewHandle( 965 class_linker->FindClass(self, 966 "Lsun/misc/FloatingDecimal;", 967 ScopedNullHandle<mirror::ClassLoader>())); 968 ASSERT_TRUE(floating_decimal != nullptr); 969 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true)); 970 971 ArtMethod* caller_method = floating_decimal->FindClassMethod( 972 "getBinaryToASCIIBuffer", 973 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;", 974 class_linker->GetImagePointerSize()); 975 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail); 976 ASSERT_TRUE(caller_method != nullptr); 977 ASSERT_TRUE(caller_method->IsDirect()); 978 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get()); 979 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 980 shadow_frame->SetLink(caller_frame); 981 982 UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 983 EXPECT_TRUE(result.GetL() != nullptr); 984 EXPECT_FALSE(self->IsExceptionPending()); 985 986 ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 987 } 988 989 // Negative test. 990 PrepareForAborts(); 991 992 { 993 // Just use a method in Class. 994 ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); 995 ArtMethod* caller_method = 996 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin(); 997 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 998 shadow_frame->SetLink(caller_frame); 999 1000 Runtime::Current()->EnterTransactionMode(); 1001 UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 1002 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 1003 Runtime::Current()->ExitTransactionMode(); 1004 ASSERT_TRUE(self->IsExceptionPending()); 1005 self->ClearException(); 1006 1007 ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 1008 } 1009 1010 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1011 } 1012 1013 TEST_F(UnstartedRuntimeTest, FloatConversion) { 1014 Thread* self = Thread::Current(); 1015 ScopedObjectAccess soa(self); 1016 1017 StackHandleScope<1> hs(self); 1018 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1019 Handle<mirror::Class> double_class = hs.NewHandle( 1020 class_linker->FindClass(self, 1021 "Ljava/lang/Double;", 1022 ScopedNullHandle<mirror::ClassLoader>())); 1023 ASSERT_TRUE(double_class != nullptr); 1024 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true)); 1025 1026 ArtMethod* method = double_class->FindClassMethod("toString", 1027 "(D)Ljava/lang/String;", 1028 class_linker->GetImagePointerSize()); 1029 ASSERT_TRUE(method != nullptr); 1030 ASSERT_TRUE(method->IsDirect()); 1031 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get()); 1032 1033 // create instruction data for invoke-direct {v0, v1} of method with fake index 1034 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 1035 1036 JValue result; 1037 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 1038 shadow_frame->SetVRegDouble(0, 1.23); 1039 interpreter::DoCall<false, false>(method, 1040 self, 1041 *shadow_frame, 1042 Instruction::At(inst_data), 1043 inst_data[0], 1044 &result); 1045 ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL()); 1046 ASSERT_TRUE(string_result != nullptr); 1047 1048 std::string mod_utf = string_result->ToModifiedUtf8(); 1049 EXPECT_EQ("1.23", mod_utf); 1050 1051 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1052 } 1053 1054 TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) { 1055 Thread* self = Thread::Current(); 1056 ScopedObjectAccess soa(self); 1057 1058 JValue result; 1059 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1060 1061 StackHandleScope<1> hs(self); 1062 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1063 Handle<mirror::Class> thread_class = hs.NewHandle( 1064 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>())); 1065 ASSERT_TRUE(thread_class.Get() != nullptr); 1066 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true)); 1067 1068 // Negative test. In general, currentThread should fail (as we should not leak a peer that will 1069 // be recreated at runtime). 1070 PrepareForAborts(); 1071 1072 { 1073 Runtime::Current()->EnterTransactionMode(); 1074 UnstartedThreadCurrentThread(self, shadow_frame, &result, 0); 1075 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 1076 Runtime::Current()->ExitTransactionMode(); 1077 ASSERT_TRUE(self->IsExceptionPending()); 1078 self->ClearException(); 1079 } 1080 1081 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1082 } 1083 1084 TEST_F(UnstartedRuntimeTest, LogManager) { 1085 Thread* self = Thread::Current(); 1086 ScopedObjectAccess soa(self); 1087 1088 StackHandleScope<1> hs(self); 1089 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1090 Handle<mirror::Class> log_manager_class = hs.NewHandle( 1091 class_linker->FindClass(self, 1092 "Ljava/util/logging/LogManager;", 1093 ScopedNullHandle<mirror::ClassLoader>())); 1094 ASSERT_TRUE(log_manager_class.Get() != nullptr); 1095 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true)); 1096 } 1097 1098 class UnstartedClassForNameTest : public UnstartedRuntimeTest { 1099 public: 1100 template <typename T> 1101 void RunTest(T& runner, bool in_transaction, bool should_succeed) { 1102 Thread* self = Thread::Current(); 1103 ScopedObjectAccess soa(self); 1104 1105 // Ensure that Class is initialized. 1106 { 1107 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1108 StackHandleScope<1> hs(self); 1109 Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass()); 1110 CHECK(class_linker->EnsureInitialized(self, h_class, true, true)); 1111 } 1112 1113 // A selection of classes from different core classpath components. 1114 constexpr const char* kTestCases[] = { 1115 "java.net.CookieManager", // From libcore. 1116 "dalvik.system.ClassExt", // From libart. 1117 }; 1118 1119 if (in_transaction) { 1120 // For transaction mode, we cannot load any classes, as the pre-fence initialization of 1121 // classes isn't transactional. Load them ahead of time. 1122 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1123 for (const char* name : kTestCases) { 1124 class_linker->FindClass(self, 1125 DotToDescriptor(name).c_str(), 1126 ScopedNullHandle<mirror::ClassLoader>()); 1127 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump(); 1128 } 1129 } 1130 1131 if (!should_succeed) { 1132 // Negative test. In general, currentThread should fail (as we should not leak a peer that will 1133 // be recreated at runtime). 1134 PrepareForAborts(); 1135 } 1136 1137 JValue result; 1138 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1139 1140 for (const char* name : kTestCases) { 1141 mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name); 1142 CHECK(name_string != nullptr); 1143 1144 if (in_transaction) { 1145 Runtime::Current()->EnterTransactionMode(); 1146 } 1147 CHECK(!self->IsExceptionPending()); 1148 1149 runner(self, shadow_frame, name_string, &result); 1150 1151 if (should_succeed) { 1152 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump(); 1153 CHECK(result.GetL() != nullptr) << name; 1154 } else { 1155 CHECK(self->IsExceptionPending()) << name; 1156 if (in_transaction) { 1157 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted()); 1158 } 1159 self->ClearException(); 1160 } 1161 1162 if (in_transaction) { 1163 Runtime::Current()->ExitTransactionMode(); 1164 } 1165 } 1166 1167 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1168 } 1169 1170 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) { 1171 Thread* self = Thread::Current(); 1172 StackHandleScope<2> hs(self); 1173 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr); 1174 1175 { 1176 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1177 1178 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable. 1179 Handle<mirror::Class> boot_cp_class = hs.NewHandle( 1180 class_linker->FindClass(self, 1181 "Ljava/lang/BootClassLoader;", 1182 ScopedNullHandle<mirror::ClassLoader>())); 1183 CHECK(boot_cp_class != nullptr); 1184 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true)); 1185 1186 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader()); 1187 CHECK(boot_cp != nullptr); 1188 1189 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor( 1190 "()V", class_linker->GetImagePointerSize()); 1191 CHECK(boot_cp_init != nullptr); 1192 1193 JValue result; 1194 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0); 1195 shadow_frame->SetVRegReference(0, boot_cp.Get()); 1196 1197 // create instruction data for invoke-direct {v0} of method with fake index 1198 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 }; 1199 1200 interpreter::DoCall<false, false>(boot_cp_init, 1201 self, 1202 *shadow_frame, 1203 Instruction::At(inst_data), 1204 inst_data[0], 1205 &result); 1206 CHECK(!self->IsExceptionPending()); 1207 1208 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1209 } 1210 1211 return boot_cp.Get(); 1212 } 1213 }; 1214 1215 TEST_F(UnstartedClassForNameTest, ClassForName) { 1216 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1217 REQUIRES_SHARED(Locks::mutator_lock_) { 1218 shadow_frame->SetVRegReference(0, name); 1219 UnstartedClassForName(self, shadow_frame, result, 0); 1220 }; 1221 RunTest(runner, false, true); 1222 } 1223 1224 TEST_F(UnstartedClassForNameTest, ClassForNameLong) { 1225 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1226 REQUIRES_SHARED(Locks::mutator_lock_) { 1227 shadow_frame->SetVRegReference(0, name); 1228 shadow_frame->SetVReg(1, 0); 1229 shadow_frame->SetVRegReference(2, nullptr); 1230 UnstartedClassForNameLong(self, shadow_frame, result, 0); 1231 }; 1232 RunTest(runner, false, true); 1233 } 1234 1235 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) { 1236 Thread* self = Thread::Current(); 1237 ScopedObjectAccess soa(self); 1238 1239 StackHandleScope<1> hs(self); 1240 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 1241 1242 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1243 REQUIRES_SHARED(Locks::mutator_lock_) { 1244 shadow_frame->SetVRegReference(0, name); 1245 shadow_frame->SetVReg(1, 0); 1246 shadow_frame->SetVRegReference(2, boot_cp.Get()); 1247 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1248 }; 1249 RunTest(runner, false, true); 1250 } 1251 1252 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) { 1253 Thread* self = Thread::Current(); 1254 ScopedObjectAccess soa(self); 1255 1256 StackHandleScope<1> hs(self); 1257 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 1258 1259 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1260 REQUIRES_SHARED(Locks::mutator_lock_) { 1261 shadow_frame->SetVRegReference(0, name); 1262 shadow_frame->SetVReg(1, 0); 1263 shadow_frame->SetVRegReference(2, boot_cp.Get()); 1264 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1265 }; 1266 RunTest(runner, true, true); 1267 } 1268 1269 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) { 1270 Thread* self = Thread::Current(); 1271 ScopedObjectAccess soa(self); 1272 1273 StackHandleScope<2> hs(self); 1274 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1275 jobject path_jobj = class_linker->CreatePathClassLoader(self, {}); 1276 ASSERT_TRUE(path_jobj != nullptr); 1277 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>( 1278 self->DecodeJObject(path_jobj)->AsClassLoader()); 1279 1280 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1281 REQUIRES_SHARED(Locks::mutator_lock_) { 1282 shadow_frame->SetVRegReference(0, name); 1283 shadow_frame->SetVReg(1, 0); 1284 shadow_frame->SetVRegReference(2, path_cp.Get()); 1285 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1286 }; 1287 RunTest(runner, true, false); 1288 } 1289 1290 TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) { 1291 Thread* self = Thread::Current(); 1292 ScopedObjectAccess soa(self); 1293 1294 StackHandleScope<1> hs(self); 1295 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1296 Handle<mirror::Class> list_class = hs.NewHandle( 1297 class_linker->FindClass(self, 1298 "Ljava/util/List;", 1299 ScopedNullHandle<mirror::ClassLoader>())); 1300 ASSERT_TRUE(list_class.Get() != nullptr); 1301 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true)); 1302 1303 JValue result; 1304 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1305 1306 shadow_frame->SetVRegReference(0, list_class.Get()); 1307 UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0); 1308 ASSERT_TRUE(result.GetL() != nullptr); 1309 ASSERT_FALSE(self->IsExceptionPending()); 1310 1311 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1312 1313 ASSERT_TRUE(result.GetL()->IsObjectArray()); 1314 ObjPtr<mirror::ObjectArray<mirror::Object>> array = 1315 result.GetL()->AsObjectArray<mirror::Object>(); 1316 std::ostringstream oss; 1317 for (int32_t i = 0; i != array->GetLength(); ++i) { 1318 ObjPtr<mirror::Object> elem = array->Get(i); 1319 ASSERT_TRUE(elem != nullptr); 1320 ASSERT_TRUE(elem->IsString()); 1321 oss << elem->AsString()->ToModifiedUtf8(); 1322 } 1323 std::string output_string = oss.str(); 1324 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;"); 1325 } 1326 1327 TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) { 1328 Thread* self = Thread::Current(); 1329 ScopedObjectAccess soa(self); 1330 1331 StackHandleScope<4> hs(self); 1332 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1333 1334 // Get Throwable. 1335 Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable()); 1336 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true)); 1337 1338 // Get an input object. 1339 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd")); 1340 1341 // Find the constructor. 1342 ArtMethod* throw_cons = throw_class->FindConstructor( 1343 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize()); 1344 ASSERT_TRUE(throw_cons != nullptr); 1345 Handle<mirror::Constructor> cons; 1346 if (class_linker->GetImagePointerSize() == PointerSize::k64) { 1347 cons = hs.NewHandle( 1348 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons)); 1349 ASSERT_TRUE(cons != nullptr); 1350 } else { 1351 cons = hs.NewHandle( 1352 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons)); 1353 ASSERT_TRUE(cons != nullptr); 1354 } 1355 1356 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle( 1357 mirror::ObjectArray<mirror::Object>::Alloc( 1358 self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1)); 1359 ASSERT_TRUE(args != nullptr); 1360 args->Set(0, input.Get()); 1361 1362 // OK, we're ready now. 1363 JValue result; 1364 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1365 shadow_frame->SetVRegReference(0, cons.Get()); 1366 shadow_frame->SetVRegReference(1, args.Get()); 1367 UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0); 1368 1369 ASSERT_TRUE(result.GetL() != nullptr); 1370 ASSERT_FALSE(self->IsExceptionPending()); 1371 1372 // Should be a new object. 1373 ASSERT_NE(result.GetL(), input.Get()); 1374 // Should be a String. 1375 ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass()); 1376 // Should have the right string. 1377 ObjPtr<mirror::String> result_msg = 1378 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage(); 1379 EXPECT_EQ(input.Get(), result_msg.Ptr()); 1380 1381 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1382 } 1383 1384 TEST_F(UnstartedRuntimeTest, IdentityHashCode) { 1385 Thread* self = Thread::Current(); 1386 ScopedObjectAccess soa(self); 1387 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1388 1389 JValue result; 1390 UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1391 1392 EXPECT_EQ(0, result.GetI()); 1393 ASSERT_FALSE(self->IsExceptionPending()); 1394 1395 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd"); 1396 tmp->SetVRegReference(0, str.Ptr()); 1397 UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1398 EXPECT_NE(0, result.GetI()); 1399 EXPECT_EQ(str->IdentityHashCode(), result.GetI()); 1400 ASSERT_FALSE(self->IsExceptionPending()); 1401 1402 ShadowFrame::DeleteDeoptimizedFrame(tmp); 1403 } 1404 1405 } // namespace interpreter 1406 } // namespace art 1407