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/memory_tool.h" 24 #include "class_linker.h" 25 #include "common_runtime_test.h" 26 #include "dex_instruction.h" 27 #include "handle.h" 28 #include "handle_scope-inl.h" 29 #include "interpreter/interpreter_common.h" 30 #include "mirror/class_loader.h" 31 #include "mirror/string-inl.h" 32 #include "runtime.h" 33 #include "scoped_thread_state_change.h" 34 #include "thread.h" 35 #include "transaction.h" 36 37 namespace art { 38 namespace interpreter { 39 40 class UnstartedRuntimeTest : public CommonRuntimeTest { 41 protected: 42 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million 43 // test friends. 44 45 // Methods that intercept available libcore implementations. 46 #define UNSTARTED_DIRECT(Name, SigIgnored) \ 47 static void Unstarted ## Name(Thread* self, \ 48 ShadowFrame* shadow_frame, \ 49 JValue* result, \ 50 size_t arg_offset) \ 51 SHARED_REQUIRES(Locks::mutator_lock_) { \ 52 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \ 53 } 54 #include "unstarted_runtime_list.h" 55 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT) 56 #undef UNSTARTED_RUNTIME_DIRECT_LIST 57 #undef UNSTARTED_RUNTIME_JNI_LIST 58 #undef UNSTARTED_DIRECT 59 60 // Methods that are native. 61 #define UNSTARTED_JNI(Name, SigIgnored) \ 62 static void UnstartedJNI ## Name(Thread* self, \ 63 ArtMethod* method, \ 64 mirror::Object* receiver, \ 65 uint32_t* args, \ 66 JValue* result) \ 67 SHARED_REQUIRES(Locks::mutator_lock_) { \ 68 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \ 69 } 70 #include "unstarted_runtime_list.h" 71 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI) 72 #undef UNSTARTED_RUNTIME_DIRECT_LIST 73 #undef UNSTARTED_RUNTIME_JNI_LIST 74 #undef UNSTARTED_JNI 75 76 // Helpers for ArrayCopy. 77 // 78 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size 79 // of three everywhere. That is enough to test all cases. 80 81 static mirror::ObjectArray<mirror::Object>* CreateObjectArray( 82 Thread* self, 83 mirror::Class* component_type, 84 const StackHandleScope<3>& data) 85 SHARED_REQUIRES(Locks::mutator_lock_) { 86 Runtime* runtime = Runtime::Current(); 87 mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type); 88 CHECK(array_type != nullptr); 89 mirror::ObjectArray<mirror::Object>* result = 90 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3); 91 CHECK(result != nullptr); 92 for (size_t i = 0; i < 3; ++i) { 93 result->Set(static_cast<int32_t>(i), data.GetReference(i)); 94 CHECK(!self->IsExceptionPending()); 95 } 96 return result; 97 } 98 99 static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array, 100 const StackHandleScope<3>& data) 101 SHARED_REQUIRES(Locks::mutator_lock_) { 102 CHECK_EQ(array->GetLength(), 3); 103 CHECK_EQ(data.NumberOfReferences(), 3U); 104 for (size_t i = 0; i < 3; ++i) { 105 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i; 106 } 107 } 108 109 void RunArrayCopy(Thread* self, 110 ShadowFrame* tmp, 111 bool expect_exception, 112 mirror::ObjectArray<mirror::Object>* src, 113 int32_t src_pos, 114 mirror::ObjectArray<mirror::Object>* dst, 115 int32_t dst_pos, 116 int32_t length) 117 SHARED_REQUIRES(Locks::mutator_lock_) { 118 JValue result; 119 tmp->SetVRegReference(0, src); 120 tmp->SetVReg(1, src_pos); 121 tmp->SetVRegReference(2, dst); 122 tmp->SetVReg(3, dst_pos); 123 tmp->SetVReg(4, length); 124 UnstartedSystemArraycopy(self, tmp, &result, 0); 125 bool exception_pending = self->IsExceptionPending(); 126 EXPECT_EQ(exception_pending, expect_exception); 127 if (exception_pending) { 128 self->ClearException(); 129 } 130 } 131 132 void RunArrayCopy(Thread* self, 133 ShadowFrame* tmp, 134 bool expect_exception, 135 mirror::Class* src_component_class, 136 mirror::Class* dst_component_class, 137 const StackHandleScope<3>& src_data, 138 int32_t src_pos, 139 const StackHandleScope<3>& dst_data, 140 int32_t dst_pos, 141 int32_t length, 142 const StackHandleScope<3>& expected_result) 143 SHARED_REQUIRES(Locks::mutator_lock_) { 144 StackHandleScope<3> hs_misc(self); 145 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class)); 146 147 Handle<mirror::ObjectArray<mirror::Object>> src_handle( 148 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data))); 149 150 Handle<mirror::ObjectArray<mirror::Object>> dst_handle( 151 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data))); 152 153 RunArrayCopy(self, 154 tmp, 155 expect_exception, 156 src_handle.Get(), 157 src_pos, 158 dst_handle.Get(), 159 dst_pos, 160 length); 161 CheckObjectArray(dst_handle.Get(), expected_result); 162 } 163 164 void TestCeilFloor(bool ceil, 165 Thread* self, 166 ShadowFrame* tmp, 167 double const test_pairs[][2], 168 size_t num_pairs) 169 SHARED_REQUIRES(Locks::mutator_lock_) { 170 for (size_t i = 0; i < num_pairs; ++i) { 171 tmp->SetVRegDouble(0, test_pairs[i][0]); 172 173 JValue result; 174 if (ceil) { 175 UnstartedMathCeil(self, tmp, &result, 0); 176 } else { 177 UnstartedMathFloor(self, tmp, &result, 0); 178 } 179 180 ASSERT_FALSE(self->IsExceptionPending()); 181 182 // We want precise results. 183 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD()); 184 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]); 185 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1]; 186 } 187 } 188 189 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the 190 // loading code doesn't work under transactions. 191 void PrepareForAborts() SHARED_REQUIRES(Locks::mutator_lock_) { 192 mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass( 193 Thread::Current(), 194 Transaction::kAbortExceptionSignature, 195 ScopedNullHandle<mirror::ClassLoader>()); 196 CHECK(result != nullptr); 197 } 198 }; 199 200 TEST_F(UnstartedRuntimeTest, MemoryPeekByte) { 201 Thread* self = Thread::Current(); 202 203 ScopedObjectAccess soa(self); 204 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 205 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 206 const uint8_t* base_ptr = base_array; 207 208 JValue result; 209 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 210 211 for (int32_t i = 0; i < kBaseLen; ++i) { 212 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 213 214 UnstartedMemoryPeekByte(self, tmp, &result, 0); 215 216 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i])); 217 } 218 219 ShadowFrame::DeleteDeoptimizedFrame(tmp); 220 } 221 222 TEST_F(UnstartedRuntimeTest, MemoryPeekShort) { 223 Thread* self = Thread::Current(); 224 225 ScopedObjectAccess soa(self); 226 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 227 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 228 const uint8_t* base_ptr = base_array; 229 230 JValue result; 231 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 232 233 int32_t adjusted_length = kBaseLen - sizeof(int16_t); 234 for (int32_t i = 0; i < adjusted_length; ++i) { 235 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 236 237 UnstartedMemoryPeekShort(self, tmp, &result, 0); 238 239 typedef int16_t unaligned_short __attribute__ ((aligned (1))); 240 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i); 241 EXPECT_EQ(result.GetS(), *short_ptr); 242 } 243 244 ShadowFrame::DeleteDeoptimizedFrame(tmp); 245 } 246 247 TEST_F(UnstartedRuntimeTest, MemoryPeekInt) { 248 Thread* self = Thread::Current(); 249 250 ScopedObjectAccess soa(self); 251 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 252 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 253 const uint8_t* base_ptr = base_array; 254 255 JValue result; 256 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 257 258 int32_t adjusted_length = kBaseLen - sizeof(int32_t); 259 for (int32_t i = 0; i < adjusted_length; ++i) { 260 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 261 262 UnstartedMemoryPeekInt(self, tmp, &result, 0); 263 264 typedef int32_t unaligned_int __attribute__ ((aligned (1))); 265 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i); 266 EXPECT_EQ(result.GetI(), *int_ptr); 267 } 268 269 ShadowFrame::DeleteDeoptimizedFrame(tmp); 270 } 271 272 TEST_F(UnstartedRuntimeTest, MemoryPeekLong) { 273 Thread* self = Thread::Current(); 274 275 ScopedObjectAccess soa(self); 276 constexpr const uint8_t base_array[] = "abcdefghijklmnop"; 277 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t); 278 const uint8_t* base_ptr = base_array; 279 280 JValue result; 281 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 282 283 int32_t adjusted_length = kBaseLen - sizeof(int64_t); 284 for (int32_t i = 0; i < adjusted_length; ++i) { 285 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i))); 286 287 UnstartedMemoryPeekLong(self, tmp, &result, 0); 288 289 typedef int64_t unaligned_long __attribute__ ((aligned (1))); 290 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i); 291 EXPECT_EQ(result.GetJ(), *long_ptr); 292 } 293 294 ShadowFrame::DeleteDeoptimizedFrame(tmp); 295 } 296 297 TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) { 298 Thread* self = Thread::Current(); 299 300 ScopedObjectAccess soa(self); 301 StackHandleScope<2> hs(self); 302 // TODO: Actual UTF. 303 constexpr const char base_string[] = "abcdefghijklmnop"; 304 Handle<mirror::String> h_test_string(hs.NewHandle( 305 mirror::String::AllocFromModifiedUtf8(self, base_string))); 306 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1; 307 Handle<mirror::CharArray> h_char_array(hs.NewHandle( 308 mirror::CharArray::Alloc(self, kBaseLen))); 309 // A buffer so we can make sure we only modify the elements targetted. 310 uint16_t buf[kBaseLen]; 311 312 JValue result; 313 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 314 315 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) { 316 for (int32_t count = 0; count <= kBaseLen; ++count) { 317 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) { 318 // Only do it when in bounds. 319 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) { 320 tmp->SetVRegReference(0, h_test_string.Get()); 321 tmp->SetVReg(1, start_index); 322 tmp->SetVReg(2, count); 323 tmp->SetVRegReference(3, h_char_array.Get()); 324 tmp->SetVReg(3, trg_offset); 325 326 // Copy the char_array into buf. 327 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t)); 328 329 UnstartedStringCharAt(self, tmp, &result, 0); 330 331 uint16_t* data = h_char_array->GetData(); 332 333 bool success = true; 334 335 // First segment should be unchanged. 336 for (int32_t i = 0; i < trg_offset; ++i) { 337 success = success && (data[i] == buf[i]); 338 } 339 // Second segment should be a copy. 340 for (int32_t i = trg_offset; i < trg_offset + count; ++i) { 341 success = success && (data[i] == buf[i - trg_offset + start_index]); 342 } 343 // Third segment should be unchanged. 344 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) { 345 success = success && (data[i] == buf[i]); 346 } 347 348 EXPECT_TRUE(success); 349 } 350 } 351 } 352 } 353 354 ShadowFrame::DeleteDeoptimizedFrame(tmp); 355 } 356 357 TEST_F(UnstartedRuntimeTest, StringCharAt) { 358 Thread* self = Thread::Current(); 359 360 ScopedObjectAccess soa(self); 361 // TODO: Actual UTF. 362 constexpr const char* base_string = "abcdefghijklmnop"; 363 int32_t base_len = static_cast<int32_t>(strlen(base_string)); 364 mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string); 365 366 JValue result; 367 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 368 369 for (int32_t i = 0; i < base_len; ++i) { 370 tmp->SetVRegReference(0, test_string); 371 tmp->SetVReg(1, i); 372 373 UnstartedStringCharAt(self, tmp, &result, 0); 374 375 EXPECT_EQ(result.GetI(), base_string[i]); 376 } 377 378 ShadowFrame::DeleteDeoptimizedFrame(tmp); 379 } 380 381 TEST_F(UnstartedRuntimeTest, StringInit) { 382 Thread* self = Thread::Current(); 383 ScopedObjectAccess soa(self); 384 mirror::Class* klass = mirror::String::GetJavaLangString(); 385 ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V", 386 sizeof(void*)); 387 388 // create instruction data for invoke-direct {v0, v1} of method with fake index 389 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 }; 390 const Instruction* inst = Instruction::At(inst_data); 391 392 JValue result; 393 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0); 394 const char* base_string = "hello_world"; 395 mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string); 396 mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, ""); 397 shadow_frame->SetVRegReference(0, reference_empty_string); 398 shadow_frame->SetVRegReference(1, string_arg); 399 400 interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result); 401 mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL()); 402 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength()); 403 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(), 404 string_arg->GetLength() * sizeof(uint16_t)), 0); 405 406 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame); 407 } 408 409 // Tests the exceptions that should be checked before modifying the destination. 410 // (Doesn't check the object vs primitive case ATM.) 411 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) { 412 Thread* self = Thread::Current(); 413 ScopedObjectAccess soa(self); 414 JValue result; 415 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 416 417 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we 418 // allocate. 419 StackHandleScope<2> hs_misc(self); 420 Handle<mirror::Class> object_class( 421 hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 422 423 StackHandleScope<3> hs_data(self); 424 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 425 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 426 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 427 428 Handle<mirror::ObjectArray<mirror::Object>> array( 429 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data))); 430 431 RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0); 432 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0); 433 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1); 434 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4); 435 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3); 436 RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3); 437 438 mirror::ObjectArray<mirror::Object>* class_as_array = 439 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()); 440 RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0); 441 RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0); 442 443 ShadowFrame::DeleteDeoptimizedFrame(tmp); 444 } 445 446 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) { 447 Thread* self = Thread::Current(); 448 ScopedObjectAccess soa(self); 449 JValue result; 450 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 451 452 StackHandleScope<1> hs_object(self); 453 Handle<mirror::Class> object_class( 454 hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass())); 455 456 // Simple test: 457 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6] 458 { 459 StackHandleScope<3> hs_src(self); 460 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 461 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 462 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 463 464 StackHandleScope<3> hs_dst(self); 465 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 466 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 467 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 468 469 StackHandleScope<3> hs_expected(self); 470 hs_expected.NewHandle(hs_dst.GetReference(0)); 471 hs_expected.NewHandle(hs_dst.GetReference(1)); 472 hs_expected.NewHandle(hs_src.GetReference(1)); 473 474 RunArrayCopy(self, 475 tmp, 476 false, 477 object_class.Get(), 478 object_class.Get(), 479 hs_src, 480 1, 481 hs_dst, 482 2, 483 1, 484 hs_expected); 485 } 486 487 // Simple test: 488 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[]) 489 { 490 StackHandleScope<3> hs_src(self); 491 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 492 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2")); 493 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 494 495 StackHandleScope<3> hs_dst(self); 496 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 497 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 498 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 499 500 StackHandleScope<3> hs_expected(self); 501 hs_expected.NewHandle(hs_dst.GetReference(0)); 502 hs_expected.NewHandle(hs_src.GetReference(1)); 503 hs_expected.NewHandle(hs_dst.GetReference(2)); 504 505 RunArrayCopy(self, 506 tmp, 507 false, 508 object_class.Get(), 509 mirror::String::GetJavaLangString(), 510 hs_src, 511 1, 512 hs_dst, 513 1, 514 1, 515 hs_expected); 516 } 517 518 // Simple test: 519 // [1,*,3] into [4,5,6] = [1,5,6] + exc 520 { 521 StackHandleScope<3> hs_src(self); 522 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1")); 523 hs_src.NewHandle(mirror::String::GetJavaLangString()); 524 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3")); 525 526 StackHandleScope<3> hs_dst(self); 527 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4")); 528 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5")); 529 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6")); 530 531 StackHandleScope<3> hs_expected(self); 532 hs_expected.NewHandle(hs_src.GetReference(0)); 533 hs_expected.NewHandle(hs_dst.GetReference(1)); 534 hs_expected.NewHandle(hs_dst.GetReference(2)); 535 536 RunArrayCopy(self, 537 tmp, 538 true, 539 object_class.Get(), 540 mirror::String::GetJavaLangString(), 541 hs_src, 542 0, 543 hs_dst, 544 0, 545 3, 546 hs_expected); 547 } 548 549 ShadowFrame::DeleteDeoptimizedFrame(tmp); 550 } 551 552 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) { 553 Thread* self = Thread::Current(); 554 ScopedObjectAccess soa(self); 555 556 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 557 558 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 559 // suffixes). 560 constexpr const char* test_string = "-2147483646"; 561 constexpr int32_t test_values[] = { 562 6, 563 46, 564 646, 565 3646, 566 83646, 567 483646, 568 7483646, 569 47483646, 570 147483646, 571 2147483646, 572 -2147483646 573 }; 574 575 static_assert(arraysize(test_values) == 11U, "test_values"); 576 CHECK_EQ(strlen(test_string), 11U); 577 578 for (size_t i = 0; i <= 10; ++i) { 579 const char* test_value = &test_string[10 - i]; 580 581 StackHandleScope<1> hs_str(self); 582 Handle<mirror::String> h_str( 583 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 584 ASSERT_NE(h_str.Get(), nullptr); 585 ASSERT_FALSE(self->IsExceptionPending()); 586 587 tmp->SetVRegReference(0, h_str.Get()); 588 589 JValue result; 590 UnstartedIntegerParseInt(self, tmp, &result, 0); 591 592 ASSERT_FALSE(self->IsExceptionPending()); 593 EXPECT_EQ(result.GetI(), test_values[i]); 594 } 595 596 ShadowFrame::DeleteDeoptimizedFrame(tmp); 597 } 598 599 // Right now the same as Integer.Parse 600 TEST_F(UnstartedRuntimeTest, LongParseLongTest) { 601 Thread* self = Thread::Current(); 602 ScopedObjectAccess soa(self); 603 604 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 605 606 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all 607 // suffixes). 608 constexpr const char* test_string = "-2147483646"; 609 constexpr int64_t test_values[] = { 610 6, 611 46, 612 646, 613 3646, 614 83646, 615 483646, 616 7483646, 617 47483646, 618 147483646, 619 2147483646, 620 -2147483646 621 }; 622 623 static_assert(arraysize(test_values) == 11U, "test_values"); 624 CHECK_EQ(strlen(test_string), 11U); 625 626 for (size_t i = 0; i <= 10; ++i) { 627 const char* test_value = &test_string[10 - i]; 628 629 StackHandleScope<1> hs_str(self); 630 Handle<mirror::String> h_str( 631 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value))); 632 ASSERT_NE(h_str.Get(), nullptr); 633 ASSERT_FALSE(self->IsExceptionPending()); 634 635 tmp->SetVRegReference(0, h_str.Get()); 636 637 JValue result; 638 UnstartedLongParseLong(self, tmp, &result, 0); 639 640 ASSERT_FALSE(self->IsExceptionPending()); 641 EXPECT_EQ(result.GetJ(), test_values[i]); 642 } 643 644 ShadowFrame::DeleteDeoptimizedFrame(tmp); 645 } 646 647 TEST_F(UnstartedRuntimeTest, Ceil) { 648 Thread* self = Thread::Current(); 649 ScopedObjectAccess soa(self); 650 651 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 652 653 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 654 constexpr double inf = std::numeric_limits<double>::infinity(); 655 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 656 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 657 constexpr double test_pairs[][2] = { 658 { -0.0, -0.0 }, 659 { 0.0, 0.0 }, 660 { -0.5, -0.0 }, 661 { -1.0, -1.0 }, 662 { 0.5, 1.0 }, 663 { 1.0, 1.0 }, 664 { nan, nan }, 665 { inf, inf }, 666 { -inf, -inf }, 667 { ld1, ld1 }, 668 { ld2, ld2 } 669 }; 670 671 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs)); 672 673 ShadowFrame::DeleteDeoptimizedFrame(tmp); 674 } 675 676 TEST_F(UnstartedRuntimeTest, Floor) { 677 Thread* self = Thread::Current(); 678 ScopedObjectAccess soa(self); 679 680 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 681 682 constexpr double nan = std::numeric_limits<double>::quiet_NaN(); 683 constexpr double inf = std::numeric_limits<double>::infinity(); 684 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1); 685 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55); 686 constexpr double test_pairs[][2] = { 687 { -0.0, -0.0 }, 688 { 0.0, 0.0 }, 689 { -0.5, -1.0 }, 690 { -1.0, -1.0 }, 691 { 0.5, 0.0 }, 692 { 1.0, 1.0 }, 693 { nan, nan }, 694 { inf, inf }, 695 { -inf, -inf }, 696 { ld1, ld1 }, 697 { ld2, ld2 } 698 }; 699 700 TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs)); 701 702 ShadowFrame::DeleteDeoptimizedFrame(tmp); 703 } 704 705 TEST_F(UnstartedRuntimeTest, ToLowerUpper) { 706 Thread* self = Thread::Current(); 707 ScopedObjectAccess soa(self); 708 709 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 710 711 std::locale c_locale("C"); 712 713 // Check ASCII. 714 for (uint32_t i = 0; i < 128; ++i) { 715 bool c_upper = std::isupper(static_cast<char>(i), c_locale); 716 bool c_lower = std::islower(static_cast<char>(i), c_locale); 717 EXPECT_FALSE(c_upper && c_lower) << i; 718 719 // Check toLowerCase. 720 { 721 JValue result; 722 tmp->SetVReg(0, static_cast<int32_t>(i)); 723 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 724 ASSERT_FALSE(self->IsExceptionPending()); 725 uint32_t lower_result = static_cast<uint32_t>(result.GetI()); 726 if (c_lower) { 727 EXPECT_EQ(i, lower_result); 728 } else if (c_upper) { 729 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)), 730 lower_result); 731 } else { 732 EXPECT_EQ(i, lower_result); 733 } 734 } 735 736 // Check toUpperCase. 737 { 738 JValue result2; 739 tmp->SetVReg(0, static_cast<int32_t>(i)); 740 UnstartedCharacterToUpperCase(self, tmp, &result2, 0); 741 ASSERT_FALSE(self->IsExceptionPending()); 742 uint32_t upper_result = static_cast<uint32_t>(result2.GetI()); 743 if (c_upper) { 744 EXPECT_EQ(i, upper_result); 745 } else if (c_lower) { 746 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)), 747 upper_result); 748 } else { 749 EXPECT_EQ(i, upper_result); 750 } 751 } 752 } 753 754 // Check abort for other things. Can't test all. 755 756 PrepareForAborts(); 757 758 for (uint32_t i = 128; i < 256; ++i) { 759 { 760 JValue result; 761 tmp->SetVReg(0, static_cast<int32_t>(i)); 762 Transaction transaction; 763 Runtime::Current()->EnterTransactionMode(&transaction); 764 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 765 Runtime::Current()->ExitTransactionMode(); 766 ASSERT_TRUE(self->IsExceptionPending()); 767 ASSERT_TRUE(transaction.IsAborted()); 768 } 769 { 770 JValue result; 771 tmp->SetVReg(0, static_cast<int32_t>(i)); 772 Transaction transaction; 773 Runtime::Current()->EnterTransactionMode(&transaction); 774 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 775 Runtime::Current()->ExitTransactionMode(); 776 ASSERT_TRUE(self->IsExceptionPending()); 777 ASSERT_TRUE(transaction.IsAborted()); 778 } 779 } 780 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) { 781 { 782 JValue result; 783 tmp->SetVReg(0, static_cast<int32_t>(i)); 784 Transaction transaction; 785 Runtime::Current()->EnterTransactionMode(&transaction); 786 UnstartedCharacterToLowerCase(self, tmp, &result, 0); 787 Runtime::Current()->ExitTransactionMode(); 788 ASSERT_TRUE(self->IsExceptionPending()); 789 ASSERT_TRUE(transaction.IsAborted()); 790 } 791 { 792 JValue result; 793 tmp->SetVReg(0, static_cast<int32_t>(i)); 794 Transaction transaction; 795 Runtime::Current()->EnterTransactionMode(&transaction); 796 UnstartedCharacterToUpperCase(self, tmp, &result, 0); 797 Runtime::Current()->ExitTransactionMode(); 798 ASSERT_TRUE(self->IsExceptionPending()); 799 ASSERT_TRUE(transaction.IsAborted()); 800 } 801 } 802 803 ShadowFrame::DeleteDeoptimizedFrame(tmp); 804 } 805 806 TEST_F(UnstartedRuntimeTest, Sin) { 807 Thread* self = Thread::Current(); 808 ScopedObjectAccess soa(self); 809 810 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 811 812 // Test an important value, PI/6. That's the one we see in practice. 813 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 814 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 815 816 JValue result; 817 UnstartedMathSin(self, tmp, &result, 0); 818 819 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 820 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult); 821 822 ShadowFrame::DeleteDeoptimizedFrame(tmp); 823 } 824 825 TEST_F(UnstartedRuntimeTest, Cos) { 826 Thread* self = Thread::Current(); 827 ScopedObjectAccess soa(self); 828 829 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 830 831 // Test an important value, PI/6. That's the one we see in practice. 832 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365); 833 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue)); 834 835 JValue result; 836 UnstartedMathCos(self, tmp, &result, 0); 837 838 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 839 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult); 840 841 ShadowFrame::DeleteDeoptimizedFrame(tmp); 842 } 843 844 TEST_F(UnstartedRuntimeTest, Pow) { 845 // Valgrind seems to get this wrong, actually. Disable for valgrind. 846 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) { 847 return; 848 } 849 850 Thread* self = Thread::Current(); 851 ScopedObjectAccess soa(self); 852 853 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0); 854 855 // Test an important pair. 856 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000); 857 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000); 858 859 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1)); 860 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2)); 861 862 JValue result; 863 UnstartedMathPow(self, tmp, &result, 0); 864 865 const uint64_t lresult = static_cast<uint64_t>(result.GetJ()); 866 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult); 867 868 ShadowFrame::DeleteDeoptimizedFrame(tmp); 869 } 870 871 } // namespace interpreter 872 } // namespace art 873