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