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