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