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