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