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 = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V", 390 kRuntimePointerSize); 391 392 // create instruction data for invoke-direct {v0, v1} of method with fake index 393 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 394 const Instruction* inst = Instruction::At(inst_data); 395 396 JValue result; 397 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 398 const char* base_string = "hello_world"; 399 mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 400 mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 401 shadow_frame->SetVRegReference(0, reference_empty_string); 402 shadow_frame->SetVRegReference(1, string_arg); 403 404 interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result); 405 mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 406 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 407 408 if (string_arg->IsCompressed() && string_result->IsCompressed()) { 409 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(), 410 string_arg->GetLength() * sizeof(uint8_t)), 0); 411 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) { 412 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 413 string_arg->GetLength() * sizeof(uint16_t)), 0); 414 } else { 415 bool equal = true; 416 for (int i = 0; i < string_arg->GetLength(); ++i) { 417 if (string_arg->CharAt(i) != string_result->CharAt(i)) { 418 equal = false; 419 break; 420 } 421 } 422 EXPECT_EQ(equal, true); 423 } 424 425 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 426 } 427 428 // Tests the exceptions that should be checked before modifying the destination. 429 // (Doesn't check the object vs primitive case ATM.) 430 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 431 Thread* self = Thread::Current(); 432 ScopedObjectAccess soa(self); 433 JValue result; 434 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 435 436 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 437 // allocate. 438 StackHandleScope<2> hs_misc(self); 439 Handle<mirror::Class> object_class( 440 hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 441 442 StackHandleScope<3> hs_data(self); 443 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 444 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 445 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 446 447 Handle<mirror::ObjectArray<mirror::Object>> array( 448 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 449 450 RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 451 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 452 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 453 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 454 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 455 RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 456 457 mirror::ObjectArray<mirror::Object>* class_as_array = 458 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 459 RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 460 RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 461 462 ShadowFrame::DeleteDeoptimizedFrame(tmp); 463 } 464 465 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 466 Thread* self = Thread::Current(); 467 ScopedObjectAccess soa(self); 468 JValue result; 469 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 470 471 StackHandleScope<1> hs_object(self); 472 Handle<mirror::Class> object_class( 473 hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 474 475 // Simple test: 476 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 477 { 478 StackHandleScope<3> hs_src(self); 479 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 480 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 481 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 482 483 StackHandleScope<3> hs_dst(self); 484 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 485 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 486 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 487 488 StackHandleScope<3> hs_expected(self); 489 hs_expected.NewHandle(hs_dst.GetReference(0)); 490 hs_expected.NewHandle(hs_dst.GetReference(1)); 491 hs_expected.NewHandle(hs_src.GetReference(1)); 492 493 RunArrayCopy(self, 494 tmp, 495 false, 496 object_class.Get(), 497 object_class.Get(), 498 hs_src, 499 1, 500 hs_dst, 501 2, 502 1, 503 hs_expected); 504 } 505 506 // Simple test: 507 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 508 { 509 StackHandleScope<3> hs_src(self); 510 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 511 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 512 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 513 514 StackHandleScope<3> hs_dst(self); 515 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 516 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 517 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 518 519 StackHandleScope<3> hs_expected(self); 520 hs_expected.NewHandle(hs_dst.GetReference(0)); 521 hs_expected.NewHandle(hs_src.GetReference(1)); 522 hs_expected.NewHandle(hs_dst.GetReference(2)); 523 524 RunArrayCopy(self, 525 tmp, 526 false, 527 object_class.Get(), 528 mirror::String::GetJavaLangString(), 529 hs_src, 530 1, 531 hs_dst, 532 1, 533 1, 534 hs_expected); 535 } 536 537 // Simple test: 538 // [1,*,3] into [4,5,6] = [1,5,6] + exc 539 { 540 StackHandleScope<3> hs_src(self); 541 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 542 hs_src.NewHandle(mirror::String::GetJavaLangString()); 543 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 544 545 StackHandleScope<3> hs_dst(self); 546 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 547 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 548 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 549 550 StackHandleScope<3> hs_expected(self); 551 hs_expected.NewHandle(hs_src.GetReference(0)); 552 hs_expected.NewHandle(hs_dst.GetReference(1)); 553 hs_expected.NewHandle(hs_dst.GetReference(2)); 554 555 RunArrayCopy(self, 556 tmp, 557 true, 558 object_class.Get(), 559 mirror::String::GetJavaLangString(), 560 hs_src, 561 0, 562 hs_dst, 563 0, 564 3, 565 hs_expected); 566 } 567 568 ShadowFrame::DeleteDeoptimizedFrame(tmp); 569 } 570 571 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) { 572 Thread* self = Thread::Current(); 573 ScopedObjectAccess soa(self); 574 575 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 576 577 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 578 // suffixes). 579 constexpr const char* test_string = "-2147483646"; 580 constexpr int32_t test_values[] = { 581 6, 582 46, 583 646, 584 3646, 585 83646, 586 483646, 587 7483646, 588 47483646, 589 147483646, 590 2147483646, 591 -2147483646 592 }; 593 594 static_assert(arraysize(test_values) == 11U, "test_values"); 595 CHECK_EQ(strlen(test_string), 11U); 596 597 for (size_t i = 0; i <= 10; ++i) { 598 const char* test_value = &test_string[10 - i]; 599 600 StackHandleScope<1> hs_str(self); 601 Handle<mirror::String> h_str( 602 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 603 ASSERT_NE(h_str.Get(), nullptr); 604 ASSERT_FALSE(self->IsExceptionPending()); 605 606 tmp->SetVRegReference(0, h_str.Get()); 607 608 JValue result; 609 UnstartedIntegerParseInt(self, tmp, &result, 0); 610 611 ASSERT_FALSE(self->IsExceptionPending()); 612 EXPECT_EQ(result.GetI(), test_values[i]); 613 } 614 615 ShadowFrame::DeleteDeoptimizedFrame(tmp); 616 } 617 618 // Right now the same as Integer.Parse 619 TEST_F(UnstartedRuntimeTest, LongParseLongTest) { 620 Thread* self = Thread::Current(); 621 ScopedObjectAccess soa(self); 622 623 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 624 625 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 626 // suffixes). 627 constexpr const char* test_string = "-2147483646"; 628 constexpr int64_t test_values[] = { 629 6, 630 46, 631 646, 632 3646, 633 83646, 634 483646, 635 7483646, 636 47483646, 637 147483646, 638 2147483646, 639 -2147483646 640 }; 641 642 static_assert(arraysize(test_values) == 11U, "test_values"); 643 CHECK_EQ(strlen(test_string), 11U); 644 645 for (size_t i = 0; i <= 10; ++i) { 646 const char* test_value = &test_string[10 - i]; 647 648 StackHandleScope<1> hs_str(self); 649 Handle<mirror::String> h_str( 650 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 651 ASSERT_NE(h_str.Get(), nullptr); 652 ASSERT_FALSE(self->IsExceptionPending()); 653 654 tmp->SetVRegReference(0, h_str.Get()); 655 656 JValue result; 657 UnstartedLongParseLong(self, tmp, &result, 0); 658 659 ASSERT_FALSE(self->IsExceptionPending()); 660 EXPECT_EQ(result.GetJ(), test_values[i]); 661 } 662 663 ShadowFrame::DeleteDeoptimizedFrame(tmp); 664 } 665 666 TEST_F(UnstartedRuntimeTest, Ceil) { 667 Thread* self = Thread::Current(); 668 ScopedObjectAccess soa(self); 669 670 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 671 672 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 673 constexpr double inf = std::numeric_limits<double>::infinity(); 674 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 675 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 676 constexpr double test_pairs[][2] = { 677 { -0.0, -0.0 }, 678 { 0.0, 0.0 }, 679 { -0.5, -0.0 }, 680 { -1.0, -1.0 }, 681 { 0.5, 1.0 }, 682 { 1.0, 1.0 }, 683 { nan, nan }, 684 { inf, inf }, 685 { -inf, -inf }, 686 { ld1, ld1 }, 687 { ld2, ld2 } 688 }; 689 690 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs)); 691 692 ShadowFrame::DeleteDeoptimizedFrame(tmp); 693 } 694 695 TEST_F(UnstartedRuntimeTest, Floor) { 696 Thread* self = Thread::Current(); 697 ScopedObjectAccess soa(self); 698 699 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 700 701 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 702 constexpr double inf = std::numeric_limits<double>::infinity(); 703 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 704 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 705 constexpr double test_pairs[][2] = { 706 { -0.0, -0.0 }, 707 { 0.0, 0.0 }, 708 { -0.5, -1.0 }, 709 { -1.0, -1.0 }, 710 { 0.5, 0.0 }, 711 { 1.0, 1.0 }, 712 { nan, nan }, 713 { inf, inf }, 714 { -inf, -inf }, 715 { ld1, ld1 }, 716 { ld2, ld2 } 717 }; 718 719 TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs)); 720 721 ShadowFrame::DeleteDeoptimizedFrame(tmp); 722 } 723 724 TEST_F(UnstartedRuntimeTest, ToLowerUpper) { 725 Thread* self = Thread::Current(); 726 ScopedObjectAccess soa(self); 727 728 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 729 730 std::locale c_locale("C"); 731 732 // Check ASCII. 733 for (uint32_t i = 0; i < 128; ++i) { 734 bool c_upper = std::isupper(static_cast<char>(i), c_locale); 735 bool c_lower = std::islower(static_cast<char>(i), c_locale); 736 EXPECT_FALSE(c_upper && c_lower) << i; 737 738 // Check toLowerCase. 739 { 740 JValue result; 741 tmp->SetVReg(0, static_cast<int32_t>(i)); 742 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 743 ASSERT_FALSE(self->IsExceptionPending()); 744 uint32_t lower_result = static_cast<uint32_t>(result.GetI()); 745 if (c_lower) { 746 EXPECT_EQ(i, lower_result); 747 } else if (c_upper) { 748 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)), 749 lower_result); 750 } else { 751 EXPECT_EQ(i, lower_result); 752 } 753 } 754 755 // Check toUpperCase. 756 { 757 JValue result2; 758 tmp->SetVReg(0, static_cast<int32_t>(i)); 759 UnstartedCharacterToUpperCase(self, tmp, &result2, 0); 760 ASSERT_FALSE(self->IsExceptionPending()); 761 uint32_t upper_result = static_cast<uint32_t>(result2.GetI()); 762 if (c_upper) { 763 EXPECT_EQ(i, upper_result); 764 } else if (c_lower) { 765 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)), 766 upper_result); 767 } else { 768 EXPECT_EQ(i, upper_result); 769 } 770 } 771 } 772 773 // Check abort for other things. Can't test all. 774 775 PrepareForAborts(); 776 777 for (uint32_t i = 128; i < 256; ++i) { 778 { 779 JValue result; 780 tmp->SetVReg(0, static_cast<int32_t>(i)); 781 Transaction transaction; 782 Runtime::Current()->EnterTransactionMode(&transaction); 783 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 784 Runtime::Current()->ExitTransactionMode(); 785 ASSERT_TRUE(self->IsExceptionPending()); 786 ASSERT_TRUE(transaction.IsAborted()); 787 } 788 { 789 JValue result; 790 tmp->SetVReg(0, static_cast<int32_t>(i)); 791 Transaction transaction; 792 Runtime::Current()->EnterTransactionMode(&transaction); 793 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 794 Runtime::Current()->ExitTransactionMode(); 795 ASSERT_TRUE(self->IsExceptionPending()); 796 ASSERT_TRUE(transaction.IsAborted()); 797 } 798 } 799 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) { 800 { 801 JValue result; 802 tmp->SetVReg(0, static_cast<int32_t>(i)); 803 Transaction transaction; 804 Runtime::Current()->EnterTransactionMode(&transaction); 805 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 806 Runtime::Current()->ExitTransactionMode(); 807 ASSERT_TRUE(self->IsExceptionPending()); 808 ASSERT_TRUE(transaction.IsAborted()); 809 } 810 { 811 JValue result; 812 tmp->SetVReg(0, static_cast<int32_t>(i)); 813 Transaction transaction; 814 Runtime::Current()->EnterTransactionMode(&transaction); 815 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 816 Runtime::Current()->ExitTransactionMode(); 817 ASSERT_TRUE(self->IsExceptionPending()); 818 ASSERT_TRUE(transaction.IsAborted()); 819 } 820 } 821 822 ShadowFrame::DeleteDeoptimizedFrame(tmp); 823 } 824 825 TEST_F(UnstartedRuntimeTest, Sin) { 826 Thread* self = Thread::Current(); 827 ScopedObjectAccess soa(self); 828 829 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 830 831 // Test an important value, PI/6. That's the one we see in practice. 832 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 833 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 834 835 JValue result; 836 UnstartedMathSin(self, tmp, &result, 0); 837 838 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 839 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult); 840 841 ShadowFrame::DeleteDeoptimizedFrame(tmp); 842 } 843 844 TEST_F(UnstartedRuntimeTest, Cos) { 845 Thread* self = Thread::Current(); 846 ScopedObjectAccess soa(self); 847 848 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 849 850 // Test an important value, PI/6. That's the one we see in practice. 851 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 852 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 853 854 JValue result; 855 UnstartedMathCos(self, tmp, &result, 0); 856 857 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 858 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult); 859 860 ShadowFrame::DeleteDeoptimizedFrame(tmp); 861 } 862 863 TEST_F(UnstartedRuntimeTest, Pow) { 864 // Valgrind seems to get this wrong, actually. Disable for valgrind. 865 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) { 866 return; 867 } 868 869 Thread* self = Thread::Current(); 870 ScopedObjectAccess soa(self); 871 872 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 873 874 // Test an important pair. 875 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000); 876 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000); 877 878 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1)); 879 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2)); 880 881 JValue result; 882 UnstartedMathPow(self, tmp, &result, 0); 883 884 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 885 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult); 886 887 ShadowFrame::DeleteDeoptimizedFrame(tmp); 888 } 889 890 TEST_F(UnstartedRuntimeTest, IsAnonymousClass) { 891 Thread* self = Thread::Current(); 892 ScopedObjectAccess soa(self); 893 894 JValue result; 895 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 896 897 mirror::Class* class_klass = mirror::Class::GetJavaLangClass(); 898 shadow_frame->SetVRegReference(0, class_klass); 899 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 900 EXPECT_EQ(result.GetZ(), 0); 901 902 jobject class_loader = LoadDex("Nested"); 903 StackHandleScope<1> hs(soa.Self()); 904 Handle<mirror::ClassLoader> loader( 905 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 906 mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader); 907 ASSERT_TRUE(c != nullptr); 908 shadow_frame->SetVRegReference(0, c); 909 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0); 910 EXPECT_EQ(result.GetZ(), 1); 911 912 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 913 } 914 915 TEST_F(UnstartedRuntimeTest, GetDeclaringClass) { 916 Thread* self = Thread::Current(); 917 ScopedObjectAccess soa(self); 918 919 JValue result; 920 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 921 922 jobject class_loader = LoadDex("Nested"); 923 StackHandleScope<4> hs(self); 924 Handle<mirror::ClassLoader> loader( 925 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); 926 927 Handle<mirror::Class> nested_klass(hs.NewHandle( 928 class_linker_->FindClass(soa.Self(), "LNested;", loader))); 929 Handle<mirror::Class> inner_klass(hs.NewHandle( 930 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader))); 931 Handle<mirror::Class> anon_klass(hs.NewHandle( 932 class_linker_->FindClass(soa.Self(), "LNested$1;", loader))); 933 934 shadow_frame->SetVRegReference(0, nested_klass.Get()); 935 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 936 EXPECT_EQ(result.GetL(), nullptr); 937 938 shadow_frame->SetVRegReference(0, inner_klass.Get()); 939 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 940 EXPECT_EQ(result.GetL(), nested_klass.Get()); 941 942 shadow_frame->SetVRegReference(0, anon_klass.Get()); 943 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0); 944 EXPECT_EQ(result.GetL(), nullptr); 945 946 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 947 } 948 949 TEST_F(UnstartedRuntimeTest, ThreadLocalGet) { 950 Thread* self = Thread::Current(); 951 ScopedObjectAccess soa(self); 952 953 JValue result; 954 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 955 956 StackHandleScope<1> hs(self); 957 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 958 959 // Positive test. See that We get something for float conversion. 960 { 961 Handle<mirror::Class> floating_decimal = hs.NewHandle( 962 class_linker->FindClass(self, 963 "Lsun/misc/FloatingDecimal;", 964 ScopedNullHandle<mirror::ClassLoader>())); 965 ASSERT_TRUE(floating_decimal != nullptr); 966 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true)); 967 968 ArtMethod* caller_method = floating_decimal->FindDeclaredDirectMethod( 969 "getBinaryToASCIIBuffer", 970 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;", 971 class_linker->GetImagePointerSize()); 972 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail); 973 ASSERT_TRUE(caller_method != nullptr); 974 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 975 shadow_frame->SetLink(caller_frame); 976 977 UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 978 EXPECT_TRUE(result.GetL() != nullptr); 979 EXPECT_FALSE(self->IsExceptionPending()); 980 981 ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 982 } 983 984 // Negative test. 985 PrepareForAborts(); 986 987 { 988 // Just use a method in Class. 989 ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass(); 990 ArtMethod* caller_method = 991 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin(); 992 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0); 993 shadow_frame->SetLink(caller_frame); 994 995 Transaction transaction; 996 Runtime::Current()->EnterTransactionMode(&transaction); 997 UnstartedThreadLocalGet(self, shadow_frame, &result, 0); 998 Runtime::Current()->ExitTransactionMode(); 999 ASSERT_TRUE(self->IsExceptionPending()); 1000 ASSERT_TRUE(transaction.IsAborted()); 1001 self->ClearException(); 1002 1003 ShadowFrame::DeleteDeoptimizedFrame(caller_frame); 1004 } 1005 1006 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1007 } 1008 1009 TEST_F(UnstartedRuntimeTest, FloatConversion) { 1010 Thread* self = Thread::Current(); 1011 ScopedObjectAccess soa(self); 1012 1013 StackHandleScope<1> hs(self); 1014 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1015 Handle<mirror::Class> double_class = hs.NewHandle( 1016 class_linker->FindClass(self, 1017 "Ljava/lang/Double;", 1018 ScopedNullHandle<mirror::ClassLoader>())); 1019 ASSERT_TRUE(double_class != nullptr); 1020 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true)); 1021 1022 ArtMethod* method = double_class->FindDeclaredDirectMethod("toString", 1023 "(D)Ljava/lang/String;", 1024 class_linker->GetImagePointerSize()); 1025 ASSERT_TRUE(method != nullptr); 1026 1027 // create instruction data for invoke-direct {v0, v1} of method with fake index 1028 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 1029 const Instruction* inst = Instruction::At(inst_data); 1030 1031 JValue result; 1032 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 1033 shadow_frame->SetVRegDouble(0, 1.23); 1034 interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result); 1035 ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL()); 1036 ASSERT_TRUE(string_result != nullptr); 1037 1038 std::string mod_utf = string_result->ToModifiedUtf8(); 1039 EXPECT_EQ("1.23", mod_utf); 1040 1041 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1042 } 1043 1044 TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) { 1045 Thread* self = Thread::Current(); 1046 ScopedObjectAccess soa(self); 1047 1048 JValue result; 1049 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1050 1051 StackHandleScope<1> hs(self); 1052 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1053 Handle<mirror::Class> thread_class = hs.NewHandle( 1054 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>())); 1055 ASSERT_TRUE(thread_class.Get() != nullptr); 1056 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true)); 1057 1058 // Negative test. In general, currentThread should fail (as we should not leak a peer that will 1059 // be recreated at runtime). 1060 PrepareForAborts(); 1061 1062 { 1063 Transaction transaction; 1064 Runtime::Current()->EnterTransactionMode(&transaction); 1065 UnstartedThreadCurrentThread(self, shadow_frame, &result, 0); 1066 Runtime::Current()->ExitTransactionMode(); 1067 ASSERT_TRUE(self->IsExceptionPending()); 1068 ASSERT_TRUE(transaction.IsAborted()); 1069 self->ClearException(); 1070 } 1071 1072 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1073 } 1074 1075 TEST_F(UnstartedRuntimeTest, LogManager) { 1076 Thread* self = Thread::Current(); 1077 ScopedObjectAccess soa(self); 1078 1079 StackHandleScope<1> hs(self); 1080 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1081 Handle<mirror::Class> log_manager_class = hs.NewHandle( 1082 class_linker->FindClass(self, 1083 "Ljava/util/logging/LogManager;", 1084 ScopedNullHandle<mirror::ClassLoader>())); 1085 ASSERT_TRUE(log_manager_class.Get() != nullptr); 1086 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true)); 1087 } 1088 1089 class UnstartedClassForNameTest : public UnstartedRuntimeTest { 1090 public: 1091 template <typename T> 1092 void RunTest(T& runner, bool in_transaction, bool should_succeed) { 1093 Thread* self = Thread::Current(); 1094 ScopedObjectAccess soa(self); 1095 1096 // Ensure that Class is initialized. 1097 { 1098 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1099 StackHandleScope<1> hs(self); 1100 Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass()); 1101 CHECK(class_linker->EnsureInitialized(self, h_class, true, true)); 1102 } 1103 1104 // A selection of classes from different core classpath components. 1105 constexpr const char* kTestCases[] = { 1106 "java.net.CookieManager", // From libcore. 1107 "dalvik.system.ClassExt", // From libart. 1108 }; 1109 1110 if (in_transaction) { 1111 // For transaction mode, we cannot load any classes, as the pre-fence initialization of 1112 // classes isn't transactional. Load them ahead of time. 1113 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1114 for (const char* name : kTestCases) { 1115 class_linker->FindClass(self, 1116 DotToDescriptor(name).c_str(), 1117 ScopedNullHandle<mirror::ClassLoader>()); 1118 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump(); 1119 } 1120 } 1121 1122 if (!should_succeed) { 1123 // Negative test. In general, currentThread should fail (as we should not leak a peer that will 1124 // be recreated at runtime). 1125 PrepareForAborts(); 1126 } 1127 1128 JValue result; 1129 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1130 1131 for (const char* name : kTestCases) { 1132 mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name); 1133 CHECK(name_string != nullptr); 1134 1135 Transaction transaction; 1136 if (in_transaction) { 1137 Runtime::Current()->EnterTransactionMode(&transaction); 1138 } 1139 CHECK(!self->IsExceptionPending()); 1140 1141 runner(self, shadow_frame, name_string, &result); 1142 1143 if (in_transaction) { 1144 Runtime::Current()->ExitTransactionMode(); 1145 } 1146 1147 if (should_succeed) { 1148 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump(); 1149 CHECK(result.GetL() != nullptr) << name; 1150 } else { 1151 CHECK(self->IsExceptionPending()) << name; 1152 if (in_transaction) { 1153 ASSERT_TRUE(transaction.IsAborted()); 1154 } 1155 self->ClearException(); 1156 } 1157 } 1158 1159 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1160 } 1161 1162 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) { 1163 Thread* self = Thread::Current(); 1164 StackHandleScope<2> hs(self); 1165 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr); 1166 1167 { 1168 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1169 1170 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable. 1171 Handle<mirror::Class> boot_cp_class = hs.NewHandle( 1172 class_linker->FindClass(self, 1173 "Ljava/lang/BootClassLoader;", 1174 ScopedNullHandle<mirror::ClassLoader>())); 1175 CHECK(boot_cp_class != nullptr); 1176 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true)); 1177 1178 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader()); 1179 CHECK(boot_cp != nullptr); 1180 1181 ArtMethod* boot_cp_init = boot_cp_class->FindDeclaredDirectMethod( 1182 "<init>", "()V", class_linker->GetImagePointerSize()); 1183 CHECK(boot_cp_init != nullptr); 1184 1185 JValue result; 1186 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0); 1187 shadow_frame->SetVRegReference(0, boot_cp.Get()); 1188 1189 // create instruction data for invoke-direct {v0} of method with fake index 1190 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 }; 1191 const Instruction* inst = Instruction::At(inst_data); 1192 1193 interpreter::DoCall<false, false>(boot_cp_init, 1194 self, 1195 *shadow_frame, 1196 inst, 1197 inst_data[0], 1198 &result); 1199 CHECK(!self->IsExceptionPending()); 1200 1201 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1202 } 1203 1204 return boot_cp.Get(); 1205 } 1206 }; 1207 1208 TEST_F(UnstartedClassForNameTest, ClassForName) { 1209 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1210 REQUIRES_SHARED(Locks::mutator_lock_) { 1211 shadow_frame->SetVRegReference(0, name); 1212 UnstartedClassForName(self, shadow_frame, result, 0); 1213 }; 1214 RunTest(runner, false, true); 1215 } 1216 1217 TEST_F(UnstartedClassForNameTest, ClassForNameLong) { 1218 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1219 REQUIRES_SHARED(Locks::mutator_lock_) { 1220 shadow_frame->SetVRegReference(0, name); 1221 shadow_frame->SetVReg(1, 0); 1222 shadow_frame->SetVRegReference(2, nullptr); 1223 UnstartedClassForNameLong(self, shadow_frame, result, 0); 1224 }; 1225 RunTest(runner, false, true); 1226 } 1227 1228 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) { 1229 Thread* self = Thread::Current(); 1230 ScopedObjectAccess soa(self); 1231 1232 StackHandleScope<1> hs(self); 1233 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 1234 1235 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1236 REQUIRES_SHARED(Locks::mutator_lock_) { 1237 shadow_frame->SetVRegReference(0, name); 1238 shadow_frame->SetVReg(1, 0); 1239 shadow_frame->SetVRegReference(2, boot_cp.Get()); 1240 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1241 }; 1242 RunTest(runner, false, true); 1243 } 1244 1245 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) { 1246 Thread* self = Thread::Current(); 1247 ScopedObjectAccess soa(self); 1248 1249 StackHandleScope<1> hs(self); 1250 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader()); 1251 1252 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1253 REQUIRES_SHARED(Locks::mutator_lock_) { 1254 shadow_frame->SetVRegReference(0, name); 1255 shadow_frame->SetVReg(1, 0); 1256 shadow_frame->SetVRegReference(2, boot_cp.Get()); 1257 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1258 }; 1259 RunTest(runner, true, true); 1260 } 1261 1262 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) { 1263 Thread* self = Thread::Current(); 1264 ScopedObjectAccess soa(self); 1265 1266 StackHandleScope<2> hs(self); 1267 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1268 jobject path_jobj = class_linker->CreatePathClassLoader(self, {}); 1269 ASSERT_TRUE(path_jobj != nullptr); 1270 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>( 1271 self->DecodeJObject(path_jobj)->AsClassLoader()); 1272 1273 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result) 1274 REQUIRES_SHARED(Locks::mutator_lock_) { 1275 shadow_frame->SetVRegReference(0, name); 1276 shadow_frame->SetVReg(1, 0); 1277 shadow_frame->SetVRegReference(2, path_cp.Get()); 1278 UnstartedClassForNameLong(th, shadow_frame, result, 0); 1279 }; 1280 RunTest(runner, true, false); 1281 } 1282 1283 TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) { 1284 Thread* self = Thread::Current(); 1285 ScopedObjectAccess soa(self); 1286 1287 StackHandleScope<1> hs(self); 1288 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1289 Handle<mirror::Class> list_class = hs.NewHandle( 1290 class_linker->FindClass(self, 1291 "Ljava/util/List;", 1292 ScopedNullHandle<mirror::ClassLoader>())); 1293 ASSERT_TRUE(list_class.Get() != nullptr); 1294 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true)); 1295 1296 JValue result; 1297 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1298 1299 shadow_frame->SetVRegReference(0, list_class.Get()); 1300 UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0); 1301 ASSERT_TRUE(result.GetL() != nullptr); 1302 ASSERT_FALSE(self->IsExceptionPending()); 1303 1304 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1305 1306 ASSERT_TRUE(result.GetL()->IsObjectArray()); 1307 ObjPtr<mirror::ObjectArray<mirror::Object>> array = 1308 result.GetL()->AsObjectArray<mirror::Object>(); 1309 std::ostringstream oss; 1310 for (int32_t i = 0; i != array->GetLength(); ++i) { 1311 ObjPtr<mirror::Object> elem = array->Get(i); 1312 ASSERT_TRUE(elem != nullptr); 1313 ASSERT_TRUE(elem->IsString()); 1314 oss << elem->AsString()->ToModifiedUtf8(); 1315 } 1316 std::string output_string = oss.str(); 1317 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;"); 1318 } 1319 1320 TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) { 1321 Thread* self = Thread::Current(); 1322 ScopedObjectAccess soa(self); 1323 1324 StackHandleScope<4> hs(self); 1325 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1326 1327 // Get Throwable. 1328 Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable()); 1329 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true)); 1330 1331 // Get an input object. 1332 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd")); 1333 1334 // Find the constructor. 1335 ArtMethod* throw_cons = throw_class->FindDeclaredDirectMethod( 1336 "<init>", "(Ljava/lang/String;)V", class_linker->GetImagePointerSize()); 1337 ASSERT_TRUE(throw_cons != nullptr); 1338 1339 Handle<mirror::Constructor> cons = hs.NewHandle( 1340 mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(self, throw_cons)); 1341 ASSERT_TRUE(cons != nullptr); 1342 1343 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle( 1344 mirror::ObjectArray<mirror::Object>::Alloc( 1345 self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1)); 1346 ASSERT_TRUE(args != nullptr); 1347 args->Set(0, input.Get()); 1348 1349 // OK, we're ready now. 1350 JValue result; 1351 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1352 shadow_frame->SetVRegReference(0, cons.Get()); 1353 shadow_frame->SetVRegReference(1, args.Get()); 1354 UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0); 1355 1356 ASSERT_TRUE(result.GetL() != nullptr); 1357 ASSERT_FALSE(self->IsExceptionPending()); 1358 1359 // Should be a new object. 1360 ASSERT_NE(result.GetL(), input.Get()); 1361 // Should be a String. 1362 ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass()); 1363 // Should have the right string. 1364 ObjPtr<mirror::String> result_msg = 1365 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage(); 1366 EXPECT_EQ(input.Get(), result_msg.Ptr()); 1367 1368 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 1369 } 1370 1371 TEST_F(UnstartedRuntimeTest, IdentityHashCode) { 1372 Thread* self = Thread::Current(); 1373 ScopedObjectAccess soa(self); 1374 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 1375 1376 JValue result; 1377 UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1378 1379 EXPECT_EQ(0, result.GetI()); 1380 ASSERT_FALSE(self->IsExceptionPending()); 1381 1382 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd"); 1383 tmp->SetVRegReference(0, str.Ptr()); 1384 UnstartedSystemIdentityHashCode(self, tmp, &result, 0); 1385 EXPECT_NE(0, result.GetI()); 1386 EXPECT_EQ(str->IdentityHashCode(), result.GetI()); 1387 ASSERT_FALSE(self->IsExceptionPending()); 1388 1389 ShadowFrame::DeleteDeoptimizedFrame(tmp); 1390 } 1391 1392 } // namespace interpreter 1393 } // namespace art 1394