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