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